Implemented listenrbainz.ExportArchive.IterFeedback

This commit is contained in:
Philipp Wolfer 2025-05-24 01:23:12 +02:00
parent cf5319309a
commit 0231331209
No known key found for this signature in database
GPG key ID: 8FDF744D4919943B

View file

@ -23,6 +23,7 @@ package listenbrainz
import (
"encoding/json"
"errors"
"io"
"iter"
"regexp"
@ -54,6 +55,9 @@ func OpenExportArchive(path string) (*ExportArchive, error) {
// Close the archive and release any resources.
func (a *ExportArchive) Close() error {
if a.backend == nil {
return nil
}
return a.backend.Close()
}
@ -126,8 +130,8 @@ func (a *ExportArchive) IterListens(minTimestamp time.Time) iter.Seq2[Listen, er
continue
}
f := NewExportFile(file.f)
for l, err := range f.IterListens() {
f := JSONLFile[Listen]{file: file.f}
for l, err := range f.IterItems() {
if err != nil {
yield(Listen{}, err)
return
@ -144,6 +148,36 @@ func (a *ExportArchive) IterListens(minTimestamp time.Time) iter.Seq2[Listen, er
}
}
// Yields all feedbacks from the archive that are newer than the given timestamp.
// The feedbacks are yielded in ascending order of their Created timestamp.
func (a *ExportArchive) IterFeedback(minTimestamp time.Time) iter.Seq2[Feedback, error] {
return func(yield func(Feedback, error) bool) {
files, err := a.backend.Glob("feedback.jsonl")
if err != nil {
yield(Feedback{}, err)
return
} else if len(files) == 0 {
yield(Feedback{}, errors.New("no feedback.jsonl file found in archive"))
return
}
j := JSONLFile[Feedback]{file: files[0].File}
for l, err := range j.IterItems() {
if err != nil {
yield(Feedback{}, err)
return
}
if !time.Unix(l.Created, 0).After(minTimestamp) {
continue
}
if !yield(l, nil) {
break
}
}
}
}
type UserInfo struct {
ID string `json:"user_id"`
Name string `json:"username"`
@ -160,15 +194,11 @@ type ListenExportFileInfo struct {
f archive.OpenableFile
}
type ListenExportFile struct {
type JSONLFile[T any] struct {
file archive.OpenableFile
}
func NewExportFile(f archive.OpenableFile) ListenExportFile {
return ListenExportFile{file: f}
}
func (f *ListenExportFile) openReader() (*jsonl.Reader, error) {
func (f *JSONLFile[T]) openReader() (*jsonl.Reader, error) {
fio, err := f.file.Open()
if err != nil {
return nil, err
@ -177,17 +207,18 @@ func (f *ListenExportFile) openReader() (*jsonl.Reader, error) {
return &reader, nil
}
func (f *ListenExportFile) IterListens() iter.Seq2[Listen, error] {
return func(yield func(Listen, error) bool) {
func (f *JSONLFile[T]) IterItems() iter.Seq2[T, error] {
return func(yield func(T, error) bool) {
reader, err := f.openReader()
if err != nil {
yield(Listen{}, err)
var listen T
yield(listen, err)
return
}
defer reader.Close()
for {
listen := Listen{}
var listen T
err := reader.ReadSingleLine(&listen)
if err != nil {
break