Documentation
¶
Overview ¶
Package stats records owner analytics from observed playback and provider data. It never reconstructs device or bandwidth information from watch counts.
Index ¶
- type AccountRef
- type BandwidthRow
- type Bucket
- type Cost
- type Dashboard
- func (d *Dashboard) Bandwidth(q Query) Page
- func (d *Dashboard) Device(id int64) (Device, bool)
- func (d *Dashboard) Devices() []Device
- func (d *Dashboard) Media(q Query) Page
- func (d *Dashboard) RecordBytes(accountID int64, accountName, clientID, deviceName, platform string, lan bool, ...)
- func (d *Dashboard) RecordPlay(accountID int64, accountName, clientID string, metadataType int, ...)
- func (d *Dashboard) SeeDevice(clientID, name, platform string) Device
- type DashboardOptions
- type Device
- type IndexerUsage
- type MediaRow
- type NewsletterSettings
- type Options
- type Page
- type Play
- type Query
- type Service
- func (s *Service) Close(ctx context.Context) error
- func (s *Service) Dashboard() *Dashboard
- func (s *Service) Handler() http.Handler
- func (s *Service) History(ctx context.Context, since, until time.Time, user int64, limit int) ([]Play, error)
- func (s *Service) IndexerMonth(ctx context.Context) ([]IndexerUsage, error)
- func (s *Service) MaybeNewsletter(ctx context.Context) error
- func (s *Service) NewsletterSettings(ctx context.Context) (NewsletterSettings, error)
- func (s *Service) ObserveIndexer(e newznab.Event)
- func (s *Service) ObservePlayback(ev playback.Event)
- func (s *Service) ObserveState(ev state.Event)
- func (s *Service) OutboxStatus() (st store.OutboxStatus, ok bool)
- func (s *Service) Prune(ctx context.Context) (int64, error)
- func (s *Service) Record(ctx context.Context, p *core.PlaySession, ended bool, problem string) error
- func (s *Service) RecordIndexer(ctx context.Context, e newznab.Event) error
- func (s *Service) RenderNewsletter(ctx context.Context, userID int64) (string, error)
- func (s *Service) Run(ctx context.Context)
- func (s *Service) Sample(ctx context.Context)
- func (s *Service) SaveNewsletter(ctx context.Context, v NewsletterSettings) error
- func (s *Service) SetCost(ctx context.Context, c Cost) error
- func (s *Service) SnapshotProviders(ctx context.Context, ps []usenet.ProviderStats) error
- func (s *Service) Summary(ctx context.Context, since, until time.Time, user int64) (Summary, error)
- type Summary
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AccountRef ¶ added in v0.3.0
AccountRef labels an account id on a statistics page.
type BandwidthRow ¶ added in v0.3.0
type BandwidthRow struct {
AccountID int64
DeviceID int64
Timespan int
At int64
Lan int
Bytes int64
}
BandwidthRow is one StatisticsBandwidth series point.
type Dashboard ¶ added in v0.3.0
type Dashboard struct {
// contains filtered or unexported fields
}
Dashboard is this node's in-memory Plex Dashboard store: devices, per-second bandwidth, and completed-play counts. Clustered nodes each keep their own rings; there is no request pin, so a client reads the node it connected to. Request paths only walk the requested buckets.
func NewDashboard ¶ added in v0.3.0
func NewDashboard(opts DashboardOptions) *Dashboard
NewDashboard creates the anonymous device (id 1) the way a PMS does at start.
func (*Dashboard) Bandwidth ¶ added in v0.3.0
Bandwidth returns the filtered, paged bandwidth series.
func (*Dashboard) Devices ¶ added in v0.3.0
Devices lists every device this process has seen, id order.
func (*Dashboard) RecordBytes ¶ added in v0.3.0
func (d *Dashboard) RecordBytes(accountID int64, accountName, clientID, deviceName, platform string, lan bool, n int64)
RecordBytes adds client-facing playback bytes to the per-second series.
func (*Dashboard) RecordPlay ¶ added in v0.3.0
func (d *Dashboard) RecordPlay(accountID int64, accountName, clientID string, metadataType int, durationSec int64)
RecordPlay counts one completed play into the media series. durationSec is the item's length in seconds (PMS StatisticsMedia duration), summed per bucket.
type DashboardOptions ¶ added in v0.3.0
DashboardOptions configure the clock (tests).
type IndexerUsage ¶
type IndexerUsage struct {
Indexer string `json:"indexer"`
Searches int64 `json:"searches"`
Successes int64 `json:"successes"`
Grabs int64 `json:"grabs"`
GrabSuccess int64 `json:"grabSuccess"`
Budgets int64 `json:"budgets"`
LatencyMS int64 `json:"latencyMs"`
AgeSeconds int64 `json:"ageSeconds"`
AgeSamples int64 `json:"ageSamples"`
}
type MediaRow ¶ added in v0.3.0
type MediaRow struct {
AccountID int64
DeviceID int64
Timespan int
At int64
MetadataType int
Count int64
Duration int64 // sum of item lengths in seconds
}
MediaRow is one StatisticsMedia series point.
type NewsletterSettings ¶
type Options ¶
type Options struct {
Newsletter func(context.Context, string) error
StopSession func(string) error
SessionExists func(string) bool
Playback core.Playback
Providers func() []usenet.ProviderStats
Indexers func(context.Context) ([]newznab.Remaining, error)
Logger *slog.Logger
Now func() time.Time
// NodeID identifies this node in a cluster. Plays are tagged with it and
// New closes only this node's unfinished plays. Empty for a standalone
// server, which therefore closes every unfinished play as before.
NodeID string
// Availability, when set (clustered nodes), holds play records the
// database cannot take through an outage (the latest per play) and
// skips periodic provider snapshots while the database is down; their
// counters are cumulative, so nothing is lost. Nil writes synchronously.
Availability *store.Availability
// MetadataType maps a rating key to a Plex metadata type number for
// Dashboard media rows. Zero or nil skips the play.
MetadataType func(core.RatingKey) int
// AccountName labels a user on Dashboard media rows.
AccountName func(int64) string
}
type Page ¶ added in v0.3.0
type Page struct {
Rows []BandwidthRow
Media []MediaRow
Devices []Device
Accounts []AccountRef
TotalSize int
}
Page is one statistics answer: the series window and the Device/Account lookup for ids that window names.
type Play ¶
type Play struct {
ID string `json:"id"`
UserID int64 `json:"userId"`
Key int64 `json:"ratingKey"`
Username string `json:"username"`
Title string `json:"title"`
Platform string `json:"platform"`
Device string `json:"device"`
Decision string `json:"decision"`
Started int64 `json:"started"`
Updated int64 `json:"updated"`
Ended int64 `json:"ended"`
Bytes int64 `json:"bytes"`
WatchedMS int64 `json:"watchedMs"`
DurationMS int64 `json:"durationMs"`
Completed bool `json:"completed"`
Failovers int `json:"failovers"`
Error string `json:"error"`
}
type Query ¶ added in v0.3.0
type Query struct {
Timespans []int
AccountID int64
DeviceID int64
HasAccount, HasDevice, HasLan bool
Lan int
AtMin, AtMax int64
ExactAt int64
HasExact, HasAtMin, HasAtMax bool
Offset int
Limit int
HasLimit bool
Sort string
Desc bool
}
Query is the parsed Dashboard filter. Timespans empty means "every kept rollup except per-second" for bandwidth/media (0..4).
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func (*Service) Close ¶
Close writes play records still held from a database outage (bounded by ctx); a no-op on a standalone server.
func (*Service) Dashboard ¶ added in v0.3.0
Dashboard is the in-memory Plex Dashboard store for this node.
func (*Service) IndexerMonth ¶
func (s *Service) IndexerMonth(ctx context.Context) ([]IndexerUsage, error)
func (*Service) MaybeNewsletter ¶
MaybeNewsletter claims each weekly slot in a durable ledger before enqueueing. Queue errors remain visible and are not retried automatically, preventing duplicates after an ambiguous process interruption.
func (*Service) NewsletterSettings ¶
func (s *Service) NewsletterSettings(ctx context.Context) (NewsletterSettings, error)
func (*Service) ObserveIndexer ¶
func (*Service) ObservePlayback ¶
ObservePlayback is suitable for playback.Manager.Subscribe.
func (*Service) ObserveState ¶
ObserveState correlates timeline data only when exactly one active session matches the user/title. Plex state events do not identify the client.
func (*Service) OutboxStatus ¶
func (s *Service) OutboxStatus() (st store.OutboxStatus, ok bool)
OutboxStatus reports play records held through a database outage; ok is false on a standalone server.
func (*Service) Prune ¶
Prune deletes per-day indexer/provider counters older than dailyRetentionDays. It is meant to be called periodically.
func (*Service) Record ¶
func (s *Service) Record(ctx context.Context, p *core.PlaySession, ended bool, problem string) error
Record upserts a play. On a clustered node a record the database cannot take is held and written when it is back.
func (*Service) RecordIndexer ¶
func (*Service) RenderNewsletter ¶
func (*Service) SaveNewsletter ¶
func (s *Service) SaveNewsletter(ctx context.Context, v NewsletterSettings) error
func (*Service) SnapshotProviders ¶
type Summary ¶
type Summary struct {
Plays int64 `json:"plays"`
WatchedMS int64 `json:"watchedMs"`
Bytes int64 `json:"bytes"`
Completed int64 `json:"completed"`
Daily []Bucket `json:"daily"`
Hourly []Bucket `json:"hourly"`
Platforms []Bucket `json:"platforms"`
Titles []Bucket `json:"titles"`
Users []Bucket `json:"users"`
Since time.Time `json:"since"`
Until time.Time `json:"until"`
}