Documentation
¶
Index ¶
- Constants
- Variables
- func NormalizeTitle(value string) string
- type Artifact
- type ArtifactDescriptor
- type ArtifactInput
- type ArtifactKind
- type CatalogProjector
- type CreateResult
- type Event
- type FederationBackend
- type FederationPublication
- type FederationService
- func (s *FederationService) EligiblePools(ctx context.Context) ([]string, error)
- func (s *FederationService) List(ctx context.Context, submissionID string) ([]FederationPublication, error)
- func (s *FederationService) Request(ctx context.Context, submissionID string, poolIDs []string, actor string) ([]FederationPublication, error)
- func (s *FederationService) RetryDue(ctx context.Context, limit int) (int, error)
- func (s *FederationService) Run(ctx context.Context, interval time.Duration)
- func (s *FederationService) Withdraw(ctx context.Context, submissionID, poolID, actor, reason string) (*FederationPublication, error)
- type InboxLogger
- type InboxOptions
- type InboxScanner
- type IntakeKind
- type IntakeLimits
- type ListFilter
- type Metadata
- type PublicationOutcome
- type PublicationState
- type ScanResult
- type Service
- func (s *Service) Events(ctx context.Context, id string) ([]Event, error)
- func (s *Service) Get(ctx context.Context, id string, revealPassword bool) (*Submission, error)
- func (s *Service) List(ctx context.Context, filter ListFilter) ([]Submission, error)
- func (s *Service) OpenArtifact(ctx context.Context, submissionID, artifactID string) (*Artifact, io.ReadCloser, error)
- func (s *Service) OpenNZB(ctx context.Context, id string, requireApproved bool) (io.ReadCloser, error)
- func (s *Service) ReconcileCatalog(ctx context.Context) error
- func (s *Service) SetCatalogProjector(projector CatalogProjector)
- func (s *Service) Store() Store
- func (s *Service) Submit(ctx context.Context, in SubmitInput) (CreateResult, error)
- func (s *Service) Transition(ctx context.Context, id string, next State, actor, note string, ...) (*Submission, error)
- func (s *Service) Update(ctx context.Context, id string, update Update, revealPassword bool) (*Submission, error)
- type State
- type Store
- type Submission
- type SubmitInput
- type Update
Constants ¶
View Source
const SourceName = "uploader"
Variables ¶
Functions ¶
func NormalizeTitle ¶
Types ¶
type Artifact ¶
type Artifact struct {
ID string `json:"id"`
SubmissionID string `json:"submission_id"`
Kind ArtifactKind `json:"kind"`
OriginalFilename string `json:"original_filename"`
Label string `json:"label,omitempty"`
DeclaredMediaType string `json:"declared_media_type,omitempty"`
DetectedMediaType string `json:"detected_media_type"`
SizeBytes int64 `json:"size_bytes"`
SHA256 string `json:"sha256"`
DisplayOrder int `json:"display_order"`
BlobKey string `json:"-"`
Payload []byte `json:"-"`
CreatedAt time.Time `json:"created_at"`
}
type ArtifactDescriptor ¶
type ArtifactDescriptor struct {
Filename string `json:"filename"`
Kind ArtifactKind `json:"kind"`
Label string `json:"label,omitempty"`
}
type ArtifactInput ¶
type ArtifactKind ¶
type ArtifactKind string
const ( ArtifactNFO ArtifactKind = "nfo" ArtifactScreenshot ArtifactKind = "screenshot" ArtifactSample ArtifactKind = "sample" ArtifactSubtitle ArtifactKind = "subtitle" ArtifactMetadata ArtifactKind = "metadata" ArtifactOther ArtifactKind = "other" )
type CatalogProjector ¶
type CatalogProjector interface {
PublishUploaderSubmission(ctx context.Context, submission Submission) error
WithdrawUploaderSubmission(ctx context.Context, releaseID string) error
ReconcileUploaderSubmissions(ctx context.Context, submissions []Submission) error
}
CatalogProjector mirrors approved submissions into a deployment's terminal release catalog. The uploader store remains authoritative for review state; implementations must not fabricate scrape, binary, or formation records.
type CreateResult ¶
type CreateResult struct {
Submission *Submission
Created bool
}
type Event ¶
type Event struct {
ID int64 `json:"id"`
SubmissionID string `json:"submission_id"`
EventType string `json:"event_type"`
Actor string `json:"actor"`
PriorState State `json:"prior_state,omitempty"`
NextState State `json:"next_state,omitempty"`
Note string `json:"note,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
type FederationBackend ¶
type FederationBackend interface {
EligiblePools(context.Context) ([]string, error)
Publish(context.Context, string, releasecard.LocalRelease, FederationPublication) (PublicationOutcome, error)
PublishState(context.Context, string, FederationPublication, string, string) (PublicationOutcome, error)
}
type FederationPublication ¶
type FederationPublication struct {
SubmissionID string `json:"submission_id"`
PoolID string `json:"pool_id"`
State PublicationState `json:"state"`
ReleaseID string `json:"release_id,omitempty"`
ManifestID string `json:"manifest_id,omitempty"`
CardEventID string `json:"card_event_id,omitempty"`
ManifestEventID string `json:"manifest_event_id,omitempty"`
PublicationStateEventID string `json:"publication_state_event_id,omitempty"`
AttemptCount int `json:"attempt_count"`
LastError string `json:"last_error,omitempty"`
NextAttemptAt *time.Time `json:"next_attempt_at,omitempty"`
RequestedBy string `json:"requested_by,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type FederationService ¶
type FederationService struct {
// contains filtered or unexported fields
}
func NewFederationService ¶
func NewFederationService(service *Service, backend FederationBackend) *FederationService
func (*FederationService) EligiblePools ¶
func (s *FederationService) EligiblePools(ctx context.Context) ([]string, error)
func (*FederationService) List ¶
func (s *FederationService) List(ctx context.Context, submissionID string) ([]FederationPublication, error)
func (*FederationService) Request ¶
func (s *FederationService) Request(ctx context.Context, submissionID string, poolIDs []string, actor string) ([]FederationPublication, error)
func (*FederationService) Run ¶
func (s *FederationService) Run(ctx context.Context, interval time.Duration)
func (*FederationService) Withdraw ¶
func (s *FederationService) Withdraw(ctx context.Context, submissionID, poolID, actor, reason string) (*FederationPublication, error)
type InboxLogger ¶
type InboxOptions ¶
type InboxScanner ¶
type InboxScanner struct {
// contains filtered or unexported fields
}
func NewInboxScanner ¶
func NewInboxScanner(service *Service, opts InboxOptions) *InboxScanner
func (*InboxScanner) Check ¶
func (s *InboxScanner) Check() error
func (*InboxScanner) ScanOnce ¶
func (s *InboxScanner) ScanOnce(ctx context.Context) (ScanResult, error)
type IntakeKind ¶
type IntakeKind string
const ( IntakeHTTP IntakeKind = "http" IntakeInbox IntakeKind = "inbox" IntakeManual IntakeKind = "manual" )
type IntakeLimits ¶
type ListFilter ¶
type Metadata ¶
type Metadata struct {
Title string `json:"title,omitempty"`
CategoryID int `json:"category_id,omitempty"`
PostedAt string `json:"posted_at,omitempty"`
Password string `json:"password,omitempty"`
ExternalIDs struct {
IMDBID string `json:"imdb_id,omitempty"`
TMDBID int64 `json:"tmdb_id,omitempty"`
TVDBID int64 `json:"tvdb_id,omitempty"`
} `json:"external_ids,omitempty"`
Media struct {
Year int `json:"year,omitempty"`
Resolution string `json:"resolution,omitempty"`
Source string `json:"source,omitempty"`
VideoCodec string `json:"video_codec,omitempty"`
AudioCodec string `json:"audio_codec,omitempty"`
} `json:"media,omitempty"`
Flags struct {
ObfuscatedSubjects bool `json:"obfuscated_subjects,omitempty"`
EncryptedNames bool `json:"encrypted_names,omitempty"`
HasPAR2 bool `json:"has_par2,omitempty"`
} `json:"flags,omitempty"`
Provenance struct {
Tool string `json:"tool,omitempty"`
Version string `json:"version,omitempty"`
ExternalID string `json:"external_id,omitempty"`
} `json:"provenance,omitempty"`
Artifacts []ArtifactDescriptor `json:"artifacts,omitempty"`
}
type PublicationOutcome ¶
type PublicationState ¶
type PublicationState string
const ( PublicationRequested PublicationState = "requested" PublicationPublished PublicationState = "published" PublicationWithdrawalRequested PublicationState = "withdrawal_requested" PublicationWithdrawn PublicationState = "withdrawn" PublicationFailed PublicationState = "failed" )
type ScanResult ¶
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func NewService ¶
func NewService(store Store, limits nzb.Limits, intake ...IntakeLimits) *Service
func (*Service) List ¶
func (s *Service) List(ctx context.Context, filter ListFilter) ([]Submission, error)
func (*Service) OpenArtifact ¶
func (*Service) ReconcileCatalog ¶
ReconcileCatalog repairs the terminal catalog projection from the uploader store's authoritative approved state. It is safe to run repeatedly.
func (*Service) SetCatalogProjector ¶
func (s *Service) SetCatalogProjector(projector CatalogProjector)
SetCatalogProjector enables the optional indexer-catalog projection. It is wired only when both uploader and PostgreSQL indexer storage are available.
func (*Service) Submit ¶
func (s *Service) Submit(ctx context.Context, in SubmitInput) (CreateResult, error)
func (*Service) Transition ¶
type Store ¶
type Store interface {
CreateSubmission(ctx context.Context, submission Submission, nzbBytes []byte, artifacts []Artifact) (CreateResult, error)
GetSubmission(ctx context.Context, id string) (*Submission, error)
GetSubmissionByReleaseID(ctx context.Context, releaseID string) (*Submission, error)
GetSubmissionBySHA256(ctx context.Context, sha256 string) (*Submission, error)
ListSubmissions(ctx context.Context, filter ListFilter) ([]Submission, error)
UpdateSubmission(ctx context.Context, id string, update Update) (*Submission, error)
TransitionSubmission(ctx context.Context, id string, next State, actor, note string) (*Submission, error)
ListEvents(ctx context.Context, submissionID string) ([]Event, error)
ListFederationPublications(ctx context.Context, submissionID string) ([]FederationPublication, error)
ListDueFederationPublications(ctx context.Context, limit int) ([]FederationPublication, error)
RequestFederationPublication(ctx context.Context, submissionID, poolID, actor string) (*FederationPublication, error)
RequestFederationWithdrawal(ctx context.Context, submissionID, poolID, actor, note string) (*FederationPublication, error)
RequestSubmissionWithdrawals(ctx context.Context, submissionID, actor, note string) error
CompleteFederationPublication(ctx context.Context, submissionID, poolID string, state PublicationState, outcome PublicationOutcome) (*FederationPublication, error)
FailFederationPublication(ctx context.Context, submissionID, poolID string, cause error) (*FederationPublication, error)
OpenNZB(ctx context.Context, id string) (io.ReadCloser, error)
OpenArtifact(ctx context.Context, submissionID, artifactID string) (*Artifact, io.ReadCloser, error)
Ping(ctx context.Context) error
ValidateSchema(ctx context.Context) error
Close() error
}
type Submission ¶
type Submission struct {
ID string `json:"id"`
State State `json:"state"`
ReleaseID string `json:"release_id"`
Title string `json:"title"`
NormalizedTitle string `json:"normalized_title"`
CategoryID int `json:"category_id"`
Category string `json:"category"`
SizeBytes int64 `json:"size_bytes"`
PostedAt time.Time `json:"posted_at"`
Poster string `json:"poster"`
Groups []string `json:"groups"`
FileCount int `json:"file_count"`
SegmentCount int `json:"segment_count"`
HasPassword bool `json:"has_password"`
Password string `json:"password,omitempty"`
HasPAR2 bool `json:"has_par2"`
HasNFO bool `json:"has_nfo"`
ObfuscatedSubjects bool `json:"obfuscated_subjects"`
EncryptedNames bool `json:"encrypted_names"`
IMDBID string `json:"imdb_id,omitempty"`
TMDBID int64 `json:"tmdb_id,omitempty"`
TVDBID int64 `json:"tvdb_id,omitempty"`
Year int `json:"year,omitempty"`
Resolution string `json:"resolution,omitempty"`
MediaSource string `json:"media_source,omitempty"`
VideoCodec string `json:"video_codec,omitempty"`
AudioCodec string `json:"audio_codec,omitempty"`
NZBSHA256 string `json:"nzb_sha256"`
NZBBlobKey string `json:"-"`
IdempotencyKey string `json:"-"`
IntakeKind IntakeKind `json:"intake_kind"`
ProvenanceTool string `json:"provenance_tool,omitempty"`
ProvenanceVersion string `json:"provenance_version,omitempty"`
ProvenanceExternalID string `json:"provenance_external_id,omitempty"`
OriginalFilename string `json:"original_filename"`
SubmittedBy string `json:"submitted_by"`
Reviewer string `json:"reviewer,omitempty"`
ReviewNote string `json:"review_note,omitempty"`
Files []nzb.FileFacts `json:"files,omitempty"`
Artifacts []Artifact `json:"artifacts,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ReviewedAt *time.Time `json:"reviewed_at,omitempty"`
ApprovedAt *time.Time `json:"approved_at,omitempty"`
RejectedAt *time.Time `json:"rejected_at,omitempty"`
}
type SubmitInput ¶
type SubmitInput struct {
NZBBytes []byte
OriginalFilename string
Metadata Metadata
IntakeKind IntakeKind
SubmittedBy string
IdempotencyKey string
Artifacts []ArtifactInput
}
Click to show internal directories.
Click to hide internal directories.