diff --git a/CHANGES.md b/CHANGES.md index 7324f77..5ac83ab 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,14 @@ # Scotty Changelog +## 0.5.2 - 2025-05-01 +- ListenBrainz: fixed loves export not considering latest timestamp + + +## 0.5.1 - 2025-05-01 +- scrobblerlog: fixed timezone offset calculation +- if system locale detection fails don't abort but fall back to English + + ## 0.5.0 - 2025-04-29 - ListenBrainz: handle missing loves metadata in case of merged recordings - ListenBrainz: fix loves import loading all existing loves diff --git a/internal/backends/deezer/deezer.go b/internal/backends/deezer/deezer.go index 7b6e1ad..756e271 100644 --- a/internal/backends/deezer/deezer.go +++ b/internal/backends/deezer/deezer.go @@ -117,7 +117,7 @@ out: listens := make(models.ListensList, 0, perPage) for _, track := range result.Tracks { listen := track.AsListen() - if listen.ListenedAt.Unix() > oldestTimestamp.Unix() { + if listen.ListenedAt.After(oldestTimestamp) { listens = append(listens, listen) } else { break @@ -186,7 +186,7 @@ out: loves := make(models.LovesList, 0, perPage) for _, track := range result.Tracks { love := track.AsLove() - if love.Created.Unix() > oldestTimestamp.Unix() { + if love.Created.After(oldestTimestamp) { loves = append(loves, love) } else { totalCount -= 1 diff --git a/internal/backends/funkwhale/funkwhale.go b/internal/backends/funkwhale/funkwhale.go index 99bf43d..3e296c1 100644 --- a/internal/backends/funkwhale/funkwhale.go +++ b/internal/backends/funkwhale/funkwhale.go @@ -84,7 +84,7 @@ out: for _, fwListen := range result.Results { listen := fwListen.AsListen() - if listen.ListenedAt.Unix() > oldestTimestamp.Unix() { + if listen.ListenedAt.After(oldestTimestamp) { p.Elapsed += 1 listens = append(listens, listen) } else { @@ -135,7 +135,7 @@ out: for _, favorite := range result.Results { love := favorite.AsLove() - if love.Created.Unix() > oldestTimestamp.Unix() { + if love.Created.After(oldestTimestamp) { p.Elapsed += 1 loves = append(loves, love) } else { diff --git a/internal/backends/listenbrainz/listenbrainz.go b/internal/backends/listenbrainz/listenbrainz.go index d0074b1..6c7b747 100644 --- a/internal/backends/listenbrainz/listenbrainz.go +++ b/internal/backends/listenbrainz/listenbrainz.go @@ -199,7 +199,7 @@ func (b *ListenBrainzApiBackend) ExportLoves(oldestTimestamp time.Time, results exportChan := make(chan models.LovesResult) p := models.Progress{} - go b.exportLoves(time.Unix(0, 0), exportChan) + go b.exportLoves(oldestTimestamp, exportChan) for existingLoves := range exportChan { if existingLoves.Error != nil { progress <- p.Complete() @@ -219,7 +219,6 @@ func (b *ListenBrainzApiBackend) exportLoves(oldestTimestamp time.Time, results offset := 0 defer close(results) loves := make(models.LovesList, 0, 2*MaxItemsPerGet) - p := models.Progress{} out: for { @@ -246,17 +245,13 @@ out: } love := feedback.AsLove() - if love.Created.Unix() > oldestTimestamp.Unix() { + if love.Created.After(oldestTimestamp) { loves = append(loves, love) - p.Elapsed += 1 } else { break out } } - p.Total = int64(result.TotalCount) - p.Elapsed += int64(count) - offset += MaxItemsPerGet } diff --git a/internal/backends/spotify/spotify.go b/internal/backends/spotify/spotify.go index 1827769..8c17903 100644 --- a/internal/backends/spotify/spotify.go +++ b/internal/backends/spotify/spotify.go @@ -139,7 +139,7 @@ func (b *SpotifyApiBackend) ExportListens(oldestTimestamp time.Time, results cha for _, listen := range result.Items { l := listen.AsListen() - if l.ListenedAt.Unix() > oldestTimestamp.Unix() { + if l.ListenedAt.After(oldestTimestamp) { listens = append(listens, l) } else { // result contains listens older then oldestTimestamp @@ -195,7 +195,7 @@ out: loves := make(models.LovesList, 0, perPage) for _, track := range result.Items { love := track.AsLove() - if love.Created.Unix() > oldestTimestamp.Unix() { + if love.Created.After(oldestTimestamp) { loves = append(loves, love) } else { continue diff --git a/internal/backends/subsonic/subsonic.go b/internal/backends/subsonic/subsonic.go index 1c26bfd..d605324 100644 --- a/internal/backends/subsonic/subsonic.go +++ b/internal/backends/subsonic/subsonic.go @@ -90,7 +90,7 @@ func (b *SubsonicApiBackend) filterSongs(songs []*subsonic.Child, oldestTimestam loves := make(models.LovesList, 0, len(songs)) for _, song := range songs { love := SongAsLove(*song, b.client.User) - if love.Created.Unix() > oldestTimestamp.Unix() { + if love.Created.After(oldestTimestamp) { loves = append(loves, love) } } diff --git a/internal/cli/transfer.go b/internal/cli/transfer.go index ade7ece..0ba04b9 100644 --- a/internal/cli/transfer.go +++ b/internal/cli/transfer.go @@ -123,7 +123,7 @@ func (c *TransferCmd[E, I, R]) Transfer(exp backends.ExportProcessor[R], imp bac resultChan := make(chan models.ImportResult) go imp.Process(exportChan, resultChan, importProgress) result := <-resultChan - if result.LastTimestamp.Unix() < timestamp.Unix() { + if timestamp.After(result.LastTimestamp) { result.LastTimestamp = timestamp } wg.Wait() @@ -180,7 +180,7 @@ func (c *TransferCmd[E, I, R]) timestamp() (time.Time, error) { } func (c *TransferCmd[E, I, R]) updateTimestamp(result models.ImportResult, oldTimestamp time.Time) error { - if result.LastTimestamp.Unix() < oldTimestamp.Unix() { + if oldTimestamp.After(result.LastTimestamp) { result.LastTimestamp = oldTimestamp } printTimestamp("Latest timestamp: %v (%v)", result.LastTimestamp) diff --git a/internal/models/models.go b/internal/models/models.go index 18e3b44..f2dd71d 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -121,7 +121,7 @@ type ListensList []Listen func (l ListensList) NewerThan(t time.Time) ListensList { result := make(ListensList, 0, len(l)) for _, item := range l { - if item.ListenedAt.Unix() > t.Unix() { + if item.ListenedAt.After(t) { result = append(result, item) } } @@ -133,7 +133,7 @@ func (l ListensList) Len() int { } func (l ListensList) Less(i, j int) bool { - return l[i].ListenedAt.Unix() < l[j].ListenedAt.Unix() + return l[j].ListenedAt.After(l[i].ListenedAt) } func (l ListensList) Swap(i, j int) { @@ -147,7 +147,7 @@ func (l LovesList) Len() int { } func (l LovesList) Less(i, j int) bool { - return l[i].Created.Unix() < l[j].Created.Unix() + return l[j].Created.After(l[i].Created) } func (l LovesList) Swap(i, j int) { @@ -190,7 +190,7 @@ type ImportResult struct { // Sets LastTimestamp to newTime, if newTime is newer than LastTimestamp func (i *ImportResult) UpdateTimestamp(newTime time.Time) { - if newTime.Unix() > i.LastTimestamp.Unix() { + if newTime.After(i.LastTimestamp) { i.LastTimestamp = newTime } } diff --git a/internal/version/version.go b/internal/version/version.go index 07d1569..b38a40f 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -17,7 +17,7 @@ package version const ( AppName = "scotty" - AppVersion = "0.5.0" + AppVersion = "0.5.2" AppURL = "https://git.sr.ht/~phw/scotty/" ) diff --git a/pkg/scrobblerlog/parser.go b/pkg/scrobblerlog/parser.go index 9c6471c..d355c62 100644 --- a/pkg/scrobblerlog/parser.go +++ b/pkg/scrobblerlog/parser.go @@ -247,7 +247,8 @@ func (l ScrobblerLog) rowToRecord(row []string) (Record, error) { // Convert a Unix timestamp to a [time.Time] object, but treat the timestamp // as being in the given location's timezone instead of UTC. -// If location is nil, the timestamp is returned as UTC. +// If location is nil, the timestamp is returned assumed to already be in UTC +// and returned unchanged. func timeFromLocalTimestamp(timestamp int64, location *time.Location) time.Time { t := time.Unix(timestamp, 0) @@ -256,7 +257,7 @@ func timeFromLocalTimestamp(timestamp int64, location *time.Location) time.Time if location != nil { _, offset := t.In(location).Zone() if offset != 0 { - t = t.Add(time.Duration(offset) * time.Second) + t = t.Add(-time.Duration(offset) * time.Second) } } diff --git a/pkg/scrobblerlog/parser_test.go b/pkg/scrobblerlog/parser_test.go index f4527cc..8dc30e5 100644 --- a/pkg/scrobblerlog/parser_test.go +++ b/pkg/scrobblerlog/parser_test.go @@ -91,7 +91,7 @@ func TestParserFallbackTimezone(t *testing.T) { require.NoError(t, err) record1 := result.Records[0] assert.Equal( - time.Unix(1260342084, 0).Add(2*time.Hour), + time.Unix(1260342084, 0).Add(-2*time.Hour), record1.Timestamp, ) }