Documentation
¶
Index ¶
- Variables
- func Enqueue(ctx context.Context, db *sql.DB, ev state.Event) error
- func Handler(d HandlerDeps) http.Handler
- func HistoryPayload(key core.RatingKey, at time.Time) (map[string]any, error)
- func ParseHistory(user int64, data []byte) ([]state.ImportRecord, int, error)
- func RunDelivery(ctx context.Context, service func() Service, enabled func() bool, ...)
- type Client
- type Grant
- type HTTPError
- type HandlerDeps
- type Service
- type SyncResult
- type TokenStore
- func (s TokenStore) AcquireLease(ctx context.Context, user int64, now time.Time) (string, error)
- func (s TokenStore) Delete(ctx context.Context, user int64) error
- func (s TokenStore) Load(ctx context.Context, user int64) (Grant, error)
- func (s TokenStore) Pop(ctx context.Context, user int64) (Grant, error)
- func (s TokenStore) ReleaseLease(ctx context.Context, user int64, id string) error
- func (s TokenStore) Save(ctx context.Context, user int64, key string, now time.Time) error
Constants ¶
This section is empty.
Variables ¶
var ErrBusy = errors.New("mdblist: account is busy")
var ErrUnsupported = errors.New("mdblist: history identity unsupported")
ErrUnsupported marks a history identity MDBList cannot resolve or store.
Functions ¶
func Enqueue ¶
Enqueue records local completions only for linked viewers. Imports do not echo back to their source, and an unwatch never deletes remote history.
func Handler ¶
func Handler(d HandlerDeps) http.Handler
func HistoryPayload ¶
HistoryPayload uses only identities represented unambiguously by Ether's native movie and episode keys. Show and season keys are skipped. Episodes are sent in TMDb numbering (nested, by season/episode number), which is what MDBList's sync documents as the canonical form. https://api.mdblist.com/docs/ (POST /sync/watched)
func ParseHistory ¶
ParseHistory accepts only actual timestamps and TMDB identities. Movies are read from `movies[]`; watched episodes from the flat `episodes[]`, which carry the parent show's TMDb id and TMDb season/episode numbers, exactly the grain Ether stores. Shows and seasons are skipped: their watched state is already implied by their episodes. https://api.mdblist.com/docs/ (GET /sync/watched)
Types ¶
type Client ¶
Client talks to MDBList's account API using a viewer's personal API key. The key travels as MDBList's documented `apikey` query parameter.
func (Client) PullHistory ¶
func (c Client) PullHistory(ctx context.Context, user int64, apiKey, cursor string) ([]state.ImportRecord, string, int, error)
PullHistory reads the watched snapshot with cursor pagination. Movies and episodes are returned by default; the returned cursor must only be saved after all imported records commit. A first pull (empty cursor) reads from the beginning; later pulls pass the cursor to continue. https://api.mdblist.com/docs/ (GET /sync/watched)
func (Client) PushHistory ¶
func (c Client) PushHistory(ctx context.Context, apiKey string, key core.RatingKey, at time.Time) error
PushHistory sends one completion. MDBList records a play per request and treats a re-sent already-watched item without a date as a no-op, so a retry after an uncertain response is idempotent. A 4xx that means the item cannot be written is reported as ErrUnsupported so the caller can drop it.
type Grant ¶
type Grant struct {
APIKey string
}
Grant is one viewer's MDBList credential together with its lease state.
type HTTPError ¶
HTTPError exposes status and Retry-After without copying upstream bodies into logs. Callers must honour Retry-After before retrying a rate limit.
type HandlerDeps ¶
type HandlerDeps struct {
Tokens *TokenStore
Service func() Service
Viewer func(context.Context, int64) bool
Enabled func() bool
}
HandlerDeps are explicitly provided by the owner-authenticated admin API. Viewer validates that an ID identifies a current viewer, never a caller- supplied arbitrary account. Authentication is enforced by the mounting API.
type Service ¶
type Service struct {
Client Client
Tokens TokenStore
State *state.State
}
Service is supplied explicit state and credential dependencies. Manual sync uses a lease and a deadline shorter than the lease; it never advances the snapshot after a partial pull.
func (Service) FlushOne ¶
FlushOne delivers at most one queued event under the per-viewer lease. The caller runs it only on the cluster leader. MDBList's watched write is idempotent for already-watched items, including retries after an uncertain response, so a re-sent completion cannot create a duplicate play.
type SyncResult ¶
type TokenStore ¶
type TokenStore struct {
DB *sql.DB
Sealer config.FieldSealer
}
TokenStore keeps one API key per viewer, sealed and bound to its row. A working field sealer is mandatory: keys are never stored in cleartext, including during the legacy credential upgrade.
func (TokenStore) AcquireLease ¶
AcquireLease reserves a viewer account across nodes for bounded remote work. Operations must end before the deadline; every update also checks the lease id, since a paused process may wake after losing its reservation.
func (TokenStore) Delete ¶
func (s TokenStore) Delete(ctx context.Context, user int64) error
Delete removes a viewer's key and queue under the viewer lock. It is a no-op when nothing is stored, and refuses while a lease is held.
func (TokenStore) Load ¶
Load returns the viewer's key. A row that carries no longer opens (wrong key or moved to another viewer) is an error, never a silent empty key.
func (TokenStore) Pop ¶
Pop removes a viewer's key and queue, returning the key only when it actually removed the row. Used by merge/lifecycle bookkeeping.