From 588a6cf96f41a31e427396eb885e80b20bfd0e65 Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Thu, 1 May 2025 13:22:20 +0200 Subject: [PATCH] Document the scrobblerlog package --- pkg/scrobblerlog/parser.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/pkg/scrobblerlog/parser.go b/pkg/scrobblerlog/parser.go index d355c62..6b9d1ba 100644 --- a/pkg/scrobblerlog/parser.go +++ b/pkg/scrobblerlog/parser.go @@ -20,11 +20,18 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -// Package to parse and writer .scrobbler.log files as written by Rockbox. +// Package to parse and write .scrobbler.log files as written by Rockbox. +// +// The parser supports reading version 1.1 and 1.0 of the scrobbler log file +// format. The latter is only supported if encoded in UTF-8. +// +// When written it always writes version 1.1 of the scrobbler log file format, +// which includes the MusicBrainz recording ID as the last field of each row. // // See // - https://www.rockbox.org/wiki/LastFMLog // - https://git.rockbox.org/cgit/rockbox.git/tree/apps/plugins/lastfm_scrobbler.c +// - https://web.archive.org/web/20110110053056/http://www.audioscrobbler.net/wiki/Portable_Player_Logging package scrobblerlog import ( @@ -79,6 +86,10 @@ type ScrobblerLog struct { FallbackTimezone *time.Location } +// Parses a scrobbler log file from the given reader. +// +// The reader must provide a valid scrobbler log file with a valid header. +// This function implicitly calls [ScrobblerLog.ReadHeader]. func (l *ScrobblerLog) Parse(data io.Reader, ignoreSkipped bool) error { l.Records = make([]Record, 0) @@ -106,6 +117,7 @@ func (l *ScrobblerLog) Parse(data io.Reader, ignoreSkipped bool) error { // fmt.Printf("row: %v\n", row) // We consider only the last field (recording MBID) optional + // This was added in the 1.1 file format. if len(row) < 7 { line, _ := tsvReader.FieldPos(0) return fmt.Errorf("invalid record in scrobblerlog line %v", line) @@ -126,6 +138,11 @@ func (l *ScrobblerLog) Parse(data io.Reader, ignoreSkipped bool) error { return nil } +// Append writes the given records to the writer. +// +// The writer should be for an existing scrobbler log file or +// [ScrobblerLog.WriteHeader] should be called before this function. +// Returns the last timestamp of the records written. func (l *ScrobblerLog) Append(data io.Writer, records []Record) (lastTimestamp time.Time, err error) { tsvWriter := csv.NewWriter(data) tsvWriter.Comma = '\t' @@ -153,6 +170,9 @@ func (l *ScrobblerLog) Append(data io.Writer, records []Record) (lastTimestamp t return } +// Parses just the header of a scrobbler log file from the given reader. +// +// This function sets [ScrobblerLog.TZ] and [ScrobblerLog.Client]. func (l *ScrobblerLog) ReadHeader(reader *bufio.Reader) error { // Skip header for i := 0; i < 3; i++ { @@ -191,6 +211,7 @@ func (l *ScrobblerLog) ReadHeader(reader *bufio.Reader) error { return nil } +// Writes the header of a scrobbler log file to the given writer. func (l *ScrobblerLog) WriteHeader(writer io.Writer) error { headers := []string{ "#AUDIOSCROBBLER/1.1\n",