Build and publish / Test and build (darwin) (pull_request) Successful in 1m54s
Build and publish / Test and build (linux) (pull_request) Successful in 2m14s
Build and publish / Test and build (windows) (pull_request) Successful in 3m6s
Build and publish / Build and publish Docker image (pull_request) Successful in 1m54s
Build and publish / Test and build (darwin) (push) Successful in 1m44s
Build and publish / Test and build (windows) (push) Successful in 3m4s
Build and publish / Test and build (linux) (push) Successful in 2m4s
Build and publish / Build and publish Docker image (push) Successful in 1m58s
270 lines
8.9 KiB
Go
270 lines
8.9 KiB
Go
package ombi
|
|
|
|
import "encoding/json"
|
|
|
|
// Wire types for upstream request bodies and small typed responses.
|
|
// Field names match the RAML wire spellings exactly — including
|
|
// upstream quirks such as is4kRequest vs is4K. Optional fields use
|
|
// pointers/omitempty so omitted values are never sent.
|
|
|
|
// --- Request creation bodies ---
|
|
|
|
// MovieRequestViewModel — POST /api/v1/Request/movie
|
|
type MovieRequestViewModel struct {
|
|
TheMovieDbID int `json:"theMovieDbId"`
|
|
LanguageCode string `json:"languageCode,omitempty"`
|
|
Is4KRequest bool `json:"is4kRequest"`
|
|
RequestOnBehalf string `json:"requestOnBehalf,omitempty"`
|
|
RootFolderOverride *int `json:"rootFolderOverride,omitempty"`
|
|
QualityPathOverride *int `json:"qualityPathOverride,omitempty"`
|
|
}
|
|
|
|
// TvRequestViewModel — POST /api/v1/Request/tv (TVDB provider)
|
|
type TvRequestViewModel struct {
|
|
TvDbID int `json:"tvDbId"`
|
|
RequestAll bool `json:"requestAll"`
|
|
LatestSeason bool `json:"latestSeason"`
|
|
FirstSeason bool `json:"firstSeason"`
|
|
Seasons []SeasonsViewModel `json:"seasons,omitempty"`
|
|
LanguageProfile *int `json:"languageProfile,omitempty"`
|
|
RequestOnBehalf string `json:"requestOnBehalf,omitempty"`
|
|
RootFolderOverride *int `json:"rootFolderOverride,omitempty"`
|
|
QualityPathOverride *int `json:"qualityPathOverride,omitempty"`
|
|
}
|
|
|
|
// TvRequestViewModelV2 — POST /api/v2/Requests/tv (TMDB provider)
|
|
type TvRequestViewModelV2 struct {
|
|
TheMovieDbID int `json:"theMovieDbId"`
|
|
LanguageCode string `json:"languageCode,omitempty"`
|
|
RequestAll bool `json:"requestAll"`
|
|
LatestSeason bool `json:"latestSeason"`
|
|
FirstSeason bool `json:"firstSeason"`
|
|
Seasons []SeasonsViewModel `json:"seasons,omitempty"`
|
|
LanguageProfile *int `json:"languageProfile,omitempty"`
|
|
RequestOnBehalf string `json:"requestOnBehalf,omitempty"`
|
|
RootFolderOverride *int `json:"rootFolderOverride,omitempty"`
|
|
QualityPathOverride *int `json:"qualityPathOverride,omitempty"`
|
|
}
|
|
|
|
type SeasonsViewModel struct {
|
|
SeasonNumber int `json:"seasonNumber"`
|
|
Episodes []EpisodesViewModel `json:"episodes"`
|
|
}
|
|
|
|
type EpisodesViewModel struct {
|
|
EpisodeNumber int `json:"episodeNumber"`
|
|
}
|
|
|
|
// MusicAlbumRequestViewModel — POST /api/v1/request/music
|
|
type MusicAlbumRequestViewModel struct {
|
|
ForeignAlbumID string `json:"foreignAlbumId"`
|
|
RequestedByAlias string `json:"requestedByAlias,omitempty"`
|
|
}
|
|
|
|
// --- Moderation bodies ---
|
|
|
|
// MovieUpdateModel — POST Request/movie/{approve|available|unavailable}
|
|
type MovieUpdateModel struct {
|
|
ID int `json:"id"`
|
|
Is4K bool `json:"is4K"`
|
|
}
|
|
|
|
// TvUpdateModel / AlbumUpdateModel — POST Request/tv|request/music/*
|
|
type UpdateModelID struct {
|
|
ID int `json:"id"`
|
|
}
|
|
|
|
// DenyMovieModel — PUT Request/movie/deny
|
|
type DenyMovieModel struct {
|
|
Reason string `json:"reason"`
|
|
ID int `json:"id"`
|
|
Is4K bool `json:"is4K"`
|
|
}
|
|
|
|
// DenyTvModel / DenyAlbumModel — PUT Request/tv|request/music/deny
|
|
type DenyModel struct {
|
|
Reason string `json:"reason"`
|
|
ID int `json:"id"`
|
|
}
|
|
|
|
// MediaAdvancedOptions — POST /api/v2/Requests/{movie|tv}/advancedoptions
|
|
type MediaAdvancedOptions struct {
|
|
RequestID int `json:"requestId"`
|
|
RootPathOverride *int `json:"rootPathOverride,omitempty"`
|
|
QualityOverride *int `json:"qualityOverride,omitempty"`
|
|
LanguageProfile *int `json:"languageProfile,omitempty"`
|
|
}
|
|
|
|
// --- Issue bodies ---
|
|
|
|
// IssueCreateBody — POST /api/v1/Issues (minimal editable projection)
|
|
type IssueCreateBody struct {
|
|
Title string `json:"title"`
|
|
Subject string `json:"subject,omitempty"`
|
|
Description string `json:"description"`
|
|
IssueCategoryID int `json:"issueCategoryId"`
|
|
RequestType int `json:"requestType"`
|
|
RequestID *int `json:"requestId,omitempty"`
|
|
ProviderID string `json:"providerId,omitempty"`
|
|
}
|
|
|
|
// NewIssueCommentViewModel — POST /api/v1/Issues/comments
|
|
type NewIssueCommentViewModel struct {
|
|
Comment string `json:"comment"`
|
|
IssueID int `json:"issueId"`
|
|
}
|
|
|
|
// IssueStateViewModel — POST /api/v1/Issues/status
|
|
type IssueStateViewModel struct {
|
|
IssueID int `json:"issueId"`
|
|
Status int `json:"status"`
|
|
}
|
|
|
|
// IssueCategoryBody — POST /api/v1/Issues/categories
|
|
type IssueCategoryBody struct {
|
|
Value string `json:"value"`
|
|
}
|
|
|
|
// --- Search / discovery bodies ---
|
|
|
|
// MultiSearchFilter — POST /api/v2/Search/multi/{searchTerm}
|
|
type MultiSearchFilter struct {
|
|
Movies bool `json:"movies"`
|
|
TvShows bool `json:"tvShows"`
|
|
Music bool `json:"music"`
|
|
People bool `json:"people"`
|
|
}
|
|
|
|
// SearchMovieRefineModel — POST /api/v1/Search/movie
|
|
type SearchMovieRefineModel struct {
|
|
SearchTerm string `json:"searchTerm"`
|
|
Year *int `json:"year,omitempty"`
|
|
LanguageCode string `json:"languageCode,omitempty"`
|
|
}
|
|
|
|
// SearchActorModel — POST /api/v1/Search/movie/actor
|
|
type SearchActorModel struct {
|
|
SearchTerm string `json:"searchTerm"`
|
|
LanguageCode string `json:"languageCode,omitempty"`
|
|
}
|
|
|
|
// SimilarMoviesRefineModel — POST /api/v2/Search/movie/similar
|
|
type SimilarMoviesRefineModel struct {
|
|
TheMovieDbID int `json:"theMovieDbId"`
|
|
LanguageCode string `json:"languageCode,omitempty"`
|
|
}
|
|
|
|
// SearchMovieExtraInfoRefineModel — POST /api/v1/Search/movie/info
|
|
type SearchMovieExtraInfoRefineModel struct {
|
|
TheMovieDbID int `json:"theMovieDbId"`
|
|
LanguageCode string `json:"languageCode"`
|
|
}
|
|
|
|
// DiscoverModel — POST /api/v2/Search/advancedSearch/movie/{pos}/{amt}.
|
|
// Ombi uses Type to choose its downstream TMDB discover route; omitting it
|
|
// produces an empty result set.
|
|
type DiscoverModel struct {
|
|
Type string `json:"type"`
|
|
ReleaseYear *int `json:"releaseYear,omitempty"`
|
|
Decade *int `json:"decade,omitempty"`
|
|
GenreIDs []int `json:"genreIds,omitempty"`
|
|
KeywordIDs []int `json:"keywordIds,omitempty"`
|
|
WatchProviders []int `json:"watchProviders,omitempty"`
|
|
}
|
|
|
|
// --- User / admin bodies ---
|
|
|
|
// UserLanguage — POST /api/v1/Identity/language
|
|
type UserLanguage struct {
|
|
Lang string `json:"lang"`
|
|
}
|
|
|
|
// CountryStreamingPreference — POST /api/v1/Identity/streamingcountry
|
|
type CountryStreamingPreference struct {
|
|
Code string `json:"code"`
|
|
}
|
|
|
|
// CronViewModelBody — POST /api/v1/Settings/testcron
|
|
type CronViewModelBody struct {
|
|
Expression string `json:"expression"`
|
|
}
|
|
|
|
// FeatureEnablement — POST /api/v2/Features/{enable|disable}
|
|
type FeatureEnablement struct {
|
|
Name string `json:"name"`
|
|
Enabled bool `json:"enabled"`
|
|
}
|
|
|
|
// MassEmailModel — POST /api/v1/Notifications/massemail
|
|
type MassEmailModel struct {
|
|
Subject string `json:"subject"`
|
|
Body string `json:"body"`
|
|
Bcc bool `json:"bcc"`
|
|
Users []MassEmailUser `json:"users"`
|
|
}
|
|
|
|
// MassEmailUser is the minimal verified recipient entity resolved
|
|
// internally from a saved user record — never model-supplied JSON.
|
|
type MassEmailUser struct {
|
|
ID string `json:"id"`
|
|
UserName string `json:"userName,omitempty"`
|
|
Email string `json:"email,omitempty"`
|
|
}
|
|
|
|
// --- Typed small responses ---
|
|
|
|
// EngineResult is the shared shape of RequestEngineResult and
|
|
// VoteEngineResult upstream responses.
|
|
type EngineResult struct {
|
|
Result *bool `json:"result"`
|
|
Message string `json:"message"`
|
|
IsError *bool `json:"isError"`
|
|
ErrorMessage string `json:"errorMessage"`
|
|
ErrorCode json.RawMessage `json:"errorCode"`
|
|
RequestID *int `json:"requestId"`
|
|
}
|
|
|
|
// ErrorCodeValue returns the upstream errorCode as an int when it is
|
|
// numeric and as a string otherwise. Ombi versions disagree on the
|
|
// wire shape: some emit the enum as a number, others as a name.
|
|
func (e *EngineResult) ErrorCodeValue() (*int, string) {
|
|
if len(e.ErrorCode) == 0 || string(e.ErrorCode) == "null" {
|
|
return nil, ""
|
|
}
|
|
var n int
|
|
if json.Unmarshal(e.ErrorCode, &n) == nil {
|
|
return &n, ""
|
|
}
|
|
var s string
|
|
if json.Unmarshal(e.ErrorCode, &s) == nil {
|
|
return nil, s
|
|
}
|
|
return nil, ""
|
|
}
|
|
|
|
// IdentityResult — DELETE Identity/{userId} and other identity writes
|
|
type IdentityResult struct {
|
|
Errors []string `json:"errors"`
|
|
Successful *bool `json:"successful"`
|
|
}
|
|
|
|
// TesterResultModel — Tester/{radarr|sonarr|lidarr} responses
|
|
type TesterResultModel struct {
|
|
IsValid *bool `json:"isValid"`
|
|
Version string `json:"version"`
|
|
ExpectedSubDir string `json:"expectedSubDir"`
|
|
AdditionalInformation string `json:"additionalInformation"`
|
|
}
|
|
|
|
// CronTestModel — Settings/testcron response
|
|
type CronTestModel struct {
|
|
Success *bool `json:"success"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
// JobSettingsViewModel — Settings/jobs POST response
|
|
type JobSettingsViewModel struct {
|
|
Result *bool `json:"result"`
|
|
Message string `json:"message"`
|
|
}
|