Implemented scrobbler.log writer

This commit is contained in:
Philipp Wolfer 2023-11-09 17:31:02 +01:00
parent 0b3b3b768d
commit e9b7aabc0a
No known key found for this signature in database
GPG key ID: 8FDF744D4919943B

View file

@ -60,16 +60,16 @@ func (b ScrobblerLogBackend) ExportListens(oldestTimestamp time.Time) ([]Listen,
return nil, err
}
csvReader := csv.NewReader(reader)
csvReader.Comma = '\t'
tsvReader := csv.NewReader(reader)
tsvReader.Comma = '\t'
// Row length is often flexible
csvReader.FieldsPerRecord = -1
tsvReader.FieldsPerRecord = -1
listens := make([]Listen, 0)
for {
// A row is:
// artistName releaseName trackName trackNumber duration rating timestamp recordingMbid
row, err := csvReader.Read()
row, err := tsvReader.Read()
if err == io.EOF {
break
} 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
if len(row) < 7 {
line, _ := csvReader.FieldPos(0)
line, _ := tsvReader.FieldPos(0)
return nil, errors.New(fmt.Sprintf(
"Invalid record in %s line %v", b.filePath, line))
}
@ -101,6 +101,56 @@ func (b ScrobblerLogBackend) ExportListens(oldestTimestamp time.Time) ([]Listen,
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) {
// Skip header
for i := 0; i < 3; i++ {
@ -130,6 +180,21 @@ func readHeader(reader *bufio.Reader) (client string, err error) {
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) {
var listen Listen
trackNumber, err := strconv.Atoi(row[3])
@ -153,7 +218,7 @@ func rowToListen(row []string, client string) (Listen, error) {
ReleaseName: row[1],
TrackName: row[2],
TrackNumber: trackNumber,
Duration: time.Duration(duration),
Duration: time.Duration(duration * int(time.Second)),
AdditionalInfo: AdditionalInfo{
"rockbox_rating": row[5],
"media_player": client,