Documentation
¶
Overview ¶
Package streamstore keeps the plays and stream health events the stream recorder sees, one SQLite database per profile, and answers history, report, and export queries over them.
Index ¶
- type Gap
- type HealthEvent
- type Play
- type ReportRow
- type Store
- func (s *Store) AccountStreams() ([]int, error)
- func (s *Store) AddHealth(h HealthEvent) error
- func (s *Store) AddPlay(p Play) (inserted bool, err error)
- func (s *Store) Close() error
- func (s *Store) CountPlays() (int, error)
- func (s *Store) Cover(from, to time.Time, radioIDs ...int) error
- func (s *Store) Earliest() (time.Time, error)
- func (s *Store) Gaps(since time.Time, radioIDs ...int) ([]Gap, error)
- func (s *Store) HasStreams() (bool, error)
- func (s *Store) Heartbeat(at time.Time, radioIDs ...int) error
- func (s *Store) History(radioID *int, since time.Time, limit int) ([]Play, error)
- func (s *Store) LastHeartbeat(radioIDs ...int) (time.Time, error)
- func (s *Store) Latest(radioID int) (*Play, error)
- func (s *Store) LatestHealth(radioID int) (*HealthEvent, error)
- func (s *Store) Meta(key string) (string, error)
- func (s *Store) Path() string
- func (s *Store) Report(by string, since time.Time) ([]ReportRow, error)
- func (s *Store) SetAccountStreams(radioIDs []int, at time.Time) error
- func (s *Store) SetMeta(key, value string) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type HealthEvent ¶
type HealthEvent struct {
RadioID int `json:"radio_id"`
At time.Time `json:"at"`
Code int `json:"code"` // AudD notification code, e.g. 650 can't connect, 651 no music; 0 for running-state changes
Message string `json:"message"`
Running bool `json:"running"`
}
HealthEvent is a stream status change (AudD notification or a change in the stream_running flag).
type Play ¶
type Play struct {
RadioID int `json:"radio_id"`
Timestamp time.Time `json:"timestamp"`
PlayLength int `json:"play_length"` // seconds; 0 when unknown
Artist string `json:"artist"`
Title string `json:"title"`
Album string `json:"album"`
Label string `json:"label"`
ReleaseDate string `json:"release_date"`
ISRC string `json:"isrc"`
UPC string `json:"upc"`
SongLink string `json:"song_link"`
Score int `json:"score"`
Raw json.RawMessage `json:"-"` // the song object as AudD sent it
}
Play is one recognized song on a stream.
func (Play) MarshalJSON ¶
MarshalJSON writes the typed fields, then every other field of the song object as AudD sent it (provider blocks such as apple_music or spotify, and fields this version does not know), under their API names.
type Store ¶
type Store struct {
// Now is the clock used for gap detection.
Now func() time.Time
// contains filtered or unexported fields
}
Store is a stream store database. It is safe for concurrent use, and several processes may write the same file.
func (*Store) AccountStreams ¶
AccountStreams returns the streams the account had when it was last listed, in radio ID order (empty when it was never listed).
func (*Store) AddHealth ¶
func (s *Store) AddHealth(h HealthEvent) error
AddHealth stores a health event.
func (*Store) AddPlay ¶
AddPlay stores a play unless one with the same stream and timestamp (to the second) exists. inserted reports whether it was new.
func (*Store) CountPlays ¶
CountPlays returns the number of stored plays.
func (*Store) Cover ¶
Cover records that the store is complete for a period for the given streams (for example after a backfill from the recent-results endpoint reached back that far). Without IDs it covers every stream.
func (*Store) Earliest ¶
Earliest returns the oldest point the store knows about: the start of the first recorded period or the first play, whichever is older (zero when the store is empty).
func (*Store) Gaps ¶
Gaps returns the periods since a time (up to now) that no recorder heartbeat or backfill covers, for the given streams; a period missing for any one of them is a gap. Without IDs it checks the streams the account had when last listed (or, if it was never listed, every stream the store knows). Gaps shorter than two minutes are left out. A zero since means all time: gaps then start at Earliest, and an empty store has none. A stream first seen on the account after the store began recording has no gap before it was seen.
func (*Store) HasStreams ¶
HasStreams reports whether the account has streams or the store has plays or coverage for any.
func (*Store) Heartbeat ¶
Heartbeat records that a recorder was running and connected at a time for the given streams. Without IDs it records it for every stream.
func (*Store) History ¶
History returns plays newest first. radioID nil means all streams; a zero since means all time; limit 0 means no limit.
func (*Store) LastHeartbeat ¶
LastHeartbeat returns the end of the newest recorded period (zero if none). With IDs it is the oldest of those streams' newest periods: the time up to which all of them were recorded (zero when any has none).
func (*Store) LatestHealth ¶
func (s *Store) LatestHealth(radioID int) (*HealthEvent, error)
LatestHealth returns the last health event stored for a stream, or nil.
func (*Store) Report ¶
Report groups plays since a time. by is song, artist, label, or station. Rows are ordered by plays, then airtime, then key.
func (*Store) SetAccountStreams ¶
SetAccountStreams records the streams the account has now. A stream seen for the first time is remembered with the time it was first seen, so a stream added later does not show the time before it existed as a gap.