forked from SpinTools/seratoparser
/
history.go
145 lines (122 loc) · 5.59 KB
/
history.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package seratoparser
import (
"bufio"
"github.com/romana/rlog"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strings"
)
// HistoryPath is the path inside the _Serato_ folder that contains History data
var HistoryPath = "/History"
// SessionPath is the path inside the _Serato_/History folder that contains all the played Sessions.
var SessionPath = HistoryPath + "/Sessions"
// GetHistorySessions returns a list of all Serato History session files in the users Serato directory.
func (p Parser) GetHistorySessions() []fs.FileInfo {
var sessionFiles []fs.FileInfo
var err error
//historySessionDir := currentUser.HomeDir + "/Music/_Serato_/History/Sessions"
historySessionDir := filepath.FromSlash(p.FilePath + SessionPath)
sessionFiles, err = ioutil.ReadDir(historySessionDir)
// Remove .DS_STORE files.
for i := 0; i < len(sessionFiles); i++ {
if !strings.HasSuffix(sessionFiles[i].Name(), ".session") {
sessionFiles = append(sessionFiles[:i], sessionFiles[i+1:]...)
i--
}
}
if err != nil || len(sessionFiles) == 0 {
rlog.Critical(err)
return sessionFiles
}
sort.Slice(sessionFiles, func(i, j int) bool {
return sessionFiles[i].ModTime().Unix() > sessionFiles[j].ModTime().Unix()
})
return sessionFiles
}
// ReadHistorySession returns all track entities within the provided filepath.
func (p Parser) ReadHistorySession(fileName string) []HistoryEntity {
var historyEntities []HistoryEntity
historySessionFilepath := filepath.FromSlash(p.FilePath + SessionPath + "/" + fileName)
seratoFile, err := filepath.Abs(historySessionFilepath)
if err != nil || seratoFile == "" {
rlog.Critical(err)
return historyEntities
}
// Only read files that exist, and then report errors if we cant read it
_, err = os.Stat(seratoFile)
if err != nil {
rlog.Critical(err)
return historyEntities
}
if os.IsNotExist(err) {
rlog.Critical(err)
return historyEntities
}
ioFile, err := os.Open(seratoFile)
if err != nil {
rlog.Critical(err)
return historyEntities
}
defer ioFile.Close()
seratoVolume = volumeName(seratoFile)
fileBuffer := bufio.NewReader(ioFile)
fileExt := filepath.Ext(seratoFile)
if fileExt == ".session" {
if !fileHeader(fileBuffer, "<1.0", "/Serato Scratch LIVE Review") {
rlog.Critical("ReadFile: Unable to parse history |", seratoFile)
}
}
defer func() {
if r := recover(); r != nil {
rlog.Warn("Recovered in fileReader", r)
}
}()
for {
nextTag1, eof := parseFilePeek(fileBuffer, 1)
nextTag4, _ := parseFilePeek(fileBuffer, 4)
if eof || string(nextTag1) == "" {
break
} else if string(nextTag4) == "osrt" {
fileCrateColumns(fileBuffer)
} else if string(nextTag4) == "otrk" || string(nextTag4) == "oent" { //|| string(nextTag4) == "oses" {
for {
name, data, eof := parseField(fileBuffer)
// break if we don't need to be here
// TODO: What is oses?
if eof || (name != "otrk" && name != "oent") { //&& name != "oses") {
break
}
dataBuffer := *bufio.NewReader(strings.NewReader(data))
if name == "oent" {
for {
dataName, dataValue, eof := parseField(&dataBuffer)
if eof || dataName != "adat" {
break
}
historyEntity := HistoryEntity{}
parseAdat(dataValue, &historyEntity)
historyEntities = append(historyEntities, historyEntity)
}
} else if name == "oses" {
for {
dataName, dataValue, eof := parseField(&dataBuffer)
if eof || dataName != "adat" {
break
}
rlog.Println(dataName)
rlog.Println(dataValue)
rlog.Println("--------")
historyEntity := HistoryEntity{}
parseAdat(dataValue, &historyEntity)
}
}
}
} else {
parseFileLen(fileBuffer, 1)
}
}
return historyEntities
}