mirror of
https://git.sr.ht/~phw/scotty
synced 2025-04-18 19:19:28 +02:00
Implemented scrobbler.log writer
This commit is contained in:
parent
0b3b3b768d
commit
e9b7aabc0a
1 changed files with 71 additions and 6 deletions
|
@ -60,16 +60,16 @@ func (b ScrobblerLogBackend) ExportListens(oldestTimestamp time.Time) ([]Listen,
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
csvReader := csv.NewReader(reader)
|
tsvReader := csv.NewReader(reader)
|
||||||
csvReader.Comma = '\t'
|
tsvReader.Comma = '\t'
|
||||||
// Row length is often flexible
|
// Row length is often flexible
|
||||||
csvReader.FieldsPerRecord = -1
|
tsvReader.FieldsPerRecord = -1
|
||||||
|
|
||||||
listens := make([]Listen, 0)
|
listens := make([]Listen, 0)
|
||||||
for {
|
for {
|
||||||
// A row is:
|
// A row is:
|
||||||
// artistName releaseName trackName trackNumber duration rating timestamp recordingMbid
|
// artistName releaseName trackName trackNumber duration rating timestamp recordingMbid
|
||||||
row, err := csvReader.Read()
|
row, err := tsvReader.Read()
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
break
|
break
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
@ -80,7 +80,7 @@ func (b ScrobblerLogBackend) ExportListens(oldestTimestamp time.Time) ([]Listen,
|
||||||
|
|
||||||
// We consider only the last field (recording MBID) optional
|
// We consider only the last field (recording MBID) optional
|
||||||
if len(row) < 7 {
|
if len(row) < 7 {
|
||||||
line, _ := csvReader.FieldPos(0)
|
line, _ := tsvReader.FieldPos(0)
|
||||||
return nil, errors.New(fmt.Sprintf(
|
return nil, errors.New(fmt.Sprintf(
|
||||||
"Invalid record in %s line %v", b.filePath, line))
|
"Invalid record in %s line %v", b.filePath, line))
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,56 @@ func (b ScrobblerLogBackend) ExportListens(oldestTimestamp time.Time) ([]Listen,
|
||||||
return listens, nil
|
return listens, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b ScrobblerLogBackend) ImportListens(listens []Listen, oldestTimestamp time.Time) (ImportResult, error) {
|
||||||
|
result := ImportResult{
|
||||||
|
Count: 0,
|
||||||
|
LastTimestamp: oldestTimestamp,
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create(b.filePath)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
err = writeHeader(file)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tsvWriter := csv.NewWriter(file)
|
||||||
|
tsvWriter.Comma = '\t'
|
||||||
|
|
||||||
|
for _, listen := range listens {
|
||||||
|
result.Count += 1
|
||||||
|
if listen.ListenedAt.Unix() > result.LastTimestamp.Unix() {
|
||||||
|
result.LastTimestamp = listen.ListenedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
// A row is:
|
||||||
|
// artistName releaseName trackName trackNumber duration rating timestamp recordingMbid
|
||||||
|
rating := listen.AdditionalInfo["rockbox_rating"]
|
||||||
|
if rating == "" {
|
||||||
|
rating = "L"
|
||||||
|
}
|
||||||
|
tsvWriter.Write([]string{
|
||||||
|
listen.ArtistName(),
|
||||||
|
listen.ReleaseName,
|
||||||
|
listen.TrackName,
|
||||||
|
strconv.Itoa(listen.TrackNumber),
|
||||||
|
strconv.Itoa(int(listen.Duration.Seconds())),
|
||||||
|
rating,
|
||||||
|
strconv.Itoa(int(listen.ListenedAt.Unix())),
|
||||||
|
string(listen.RecordingMbid),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
tsvWriter.Flush()
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
func readHeader(reader *bufio.Reader) (client string, err error) {
|
func readHeader(reader *bufio.Reader) (client string, err error) {
|
||||||
// Skip header
|
// Skip header
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
|
@ -130,6 +180,21 @@ func readHeader(reader *bufio.Reader) (client string, err error) {
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeHeader(writer io.Writer) error {
|
||||||
|
headers := []string{
|
||||||
|
"#AUDIOSCROBBLER/1.1\n",
|
||||||
|
"#TZ/UNKNOWN\n",
|
||||||
|
"#CLIENT/Rockbox sansaclipplus $Revision$\n",
|
||||||
|
}
|
||||||
|
for _, line := range headers {
|
||||||
|
_, err := writer.Write([]byte(line))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func rowToListen(row []string, client string) (Listen, error) {
|
func rowToListen(row []string, client string) (Listen, error) {
|
||||||
var listen Listen
|
var listen Listen
|
||||||
trackNumber, err := strconv.Atoi(row[3])
|
trackNumber, err := strconv.Atoi(row[3])
|
||||||
|
@ -153,7 +218,7 @@ func rowToListen(row []string, client string) (Listen, error) {
|
||||||
ReleaseName: row[1],
|
ReleaseName: row[1],
|
||||||
TrackName: row[2],
|
TrackName: row[2],
|
||||||
TrackNumber: trackNumber,
|
TrackNumber: trackNumber,
|
||||||
Duration: time.Duration(duration),
|
Duration: time.Duration(duration * int(time.Second)),
|
||||||
AdditionalInfo: AdditionalInfo{
|
AdditionalInfo: AdditionalInfo{
|
||||||
"rockbox_rating": row[5],
|
"rockbox_rating": row[5],
|
||||||
"media_player": client,
|
"media_player": client,
|
||||||
|
|
Loading…
Add table
Reference in a new issue