From 4f4635dd33226f21fb7bf74af24dc29c2d9d4bba Mon Sep 17 00:00:00 2001 From: David Newhall II Date: Thu, 17 Aug 2023 12:16:47 -0700 Subject: [PATCH] add moviefile for radarr --- .github/workflows/codetests.yml | 4 +- radarr/movie.go | 38 --------- radarr/movieeditor.go | 2 +- radarr/moviefile.go | 139 ++++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+), 41 deletions(-) create mode 100644 radarr/moviefile.go diff --git a/.github/workflows/codetests.yml b/.github/workflows/codetests.yml index 8430046..bf6904d 100644 --- a/.github/workflows/codetests.yml +++ b/.github/workflows/codetests.yml @@ -49,7 +49,7 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: - version: 'v1.53' + version: 'v1.54' # Runs golangci-lint on linux against linux and windows. golangci-linux: strategy: @@ -67,4 +67,4 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: - version: 'v1.53' + version: 'v1.54' diff --git a/radarr/movie.go b/radarr/movie.go index d26a1e8..863ed11 100644 --- a/radarr/movie.go +++ b/radarr/movie.go @@ -64,44 +64,6 @@ type Collection struct { Images []*starr.Image `json:"images"` } -// MovieFile is part of a Movie. -type MovieFile struct { - ID int64 `json:"id"` - MovieID int64 `json:"movieId"` - RelativePath string `json:"relativePath"` - Path string `json:"path"` - Size int64 `json:"size"` - DateAdded time.Time `json:"dateAdded"` - SceneName string `json:"sceneName"` - IndexerFlags int64 `json:"indexerFlags"` - Quality *starr.Quality `json:"quality"` - MediaInfo *MediaInfo `json:"mediaInfo"` - QualityCutoffNotMet bool `json:"qualityCutoffNotMet"` - Languages []*starr.Value `json:"languages"` - ReleaseGroup string `json:"releaseGroup"` - Edition string `json:"edition"` - OriginalFilePath string `json:"originalFilePath"` -} - -// MediaInfo is part of a MovieFile. -type MediaInfo struct { - AudioAdditionalFeatures string `json:"audioAdditionalFeatures"` - AudioBitrate int `json:"audioBitrate"` - AudioChannels float64 `json:"audioChannels"` - AudioCodec string `json:"audioCodec"` - AudioLanguages string `json:"audioLanguages"` - AudioStreamCount int `json:"audioStreamCount"` - VideoBitDepth int `json:"videoBitDepth"` - VideoBitrate int `json:"videoBitrate"` - VideoCodec string `json:"videoCodec"` - VideoFps float64 `json:"videoFps"` - VideoDynamicRangeType string `json:"videoDynamicRangeType"` - Resolution string `json:"resolution"` - RunTime string `json:"runTime"` - ScanType string `json:"scanType"` - Subtitles string `json:"subtitles"` -} - // AddMovieInput is the input for a new movie. type AddMovieInput struct { Title string `json:"title,omitempty"` diff --git a/radarr/movieeditor.go b/radarr/movieeditor.go index 142c08f..f3a3d44 100644 --- a/radarr/movieeditor.go +++ b/radarr/movieeditor.go @@ -72,7 +72,7 @@ func (r *Radarr) DeleteMovies(deleteMovies *BulkEdit) error { return r.DeleteMoviesContext(context.Background(), deleteMovies) } -// DeleteDeleteMoviesContextMovies bulk deletes movies. Can also mark them as excluded, and delete their files. +// DeleteMoviesContext bulk deletes movies. Can also mark them as excluded, and delete their files. func (r *Radarr) DeleteMoviesContext(ctx context.Context, deleteMovies *BulkEdit) error { var body bytes.Buffer if err := json.NewEncoder(&body).Encode(deleteMovies); err != nil { diff --git a/radarr/moviefile.go b/radarr/moviefile.go new file mode 100644 index 0000000..d15dfb0 --- /dev/null +++ b/radarr/moviefile.go @@ -0,0 +1,139 @@ +package radarr + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/url" + "path" + "time" + + "golift.io/starr" +) + +const bpMovieFile = APIver + "/moviefile" + +// MovieFile is part of a Movie. +type MovieFile struct { + ID int64 `json:"id"` + MovieID int64 `json:"movieId"` + RelativePath string `json:"relativePath"` + Path string `json:"path"` + Size int64 `json:"size"` + DateAdded time.Time `json:"dateAdded"` + SceneName string `json:"sceneName"` + IndexerFlags int64 `json:"indexerFlags"` + Quality *starr.Quality `json:"quality,omitempty"` + CustomFormats []*CustomFormatOutput `json:"customFormats,omitempty"` + CustomFormatScore int `json:"customFormatScore"` + MediaInfo *MediaInfo `json:"mediaInfo,omitempty"` + OriginalFilePath string `json:"originalFilePath"` + QualityCutoffNotMet bool `json:"qualityCutoffNotMet"` + Languages []*starr.Value `json:"languages"` + ReleaseGroup string `json:"releaseGroup"` + Edition string `json:"edition"` +} + +// MediaInfo is part of a MovieFile. +type MediaInfo struct { + ID int64 `json:"id"` + AudioBitrate int `json:"audioBitrate"` + AudioChannels float64 `json:"audioChannels"` + AudioCodec string `json:"audioCodec"` + AudioLanguages string `json:"audioLanguages"` + AudioStreamCount int `json:"audioStreamCount"` + VideoBitDepth int `json:"videoBitDepth"` + VideoBitrate int `json:"videoBitrate"` + VideoCodec string `json:"videoCodec"` + VideoDynamicRangeType string `json:"videoDynamicRangeType"` + VideoFps float64 `json:"videoFps"` + Resolution string `json:"resolution"` + RunTime string `json:"runTime"` + ScanType string `json:"scanType"` + Subtitles string `json:"subtitles"` +} + +// GetMovieFile returns the movie file(s) for a movie. +func (r *Radarr) GetMovieFile(movieID int64) ([]*MovieFile, error) { + return r.GetMovieFileContext(context.Background(), movieID) +} + +// GetMovieFileContext returns the movie file(s) for a movie. +func (r *Radarr) GetMovieFileContext(ctx context.Context, movieID int64) ([]*MovieFile, error) { + req := starr.Request{URI: bpMovieFile, Query: make(url.Values)} + req.Query.Add("movieID", fmt.Sprint(movieID)) + + var output []*MovieFile + if err := r.GetInto(ctx, req, &output); err != nil { + return nil, fmt.Errorf("api.Get(%s): %w", &req, err) + } + + return output, nil +} + +// GetMovieFiles returns the movie file(s) requested. +func (r *Radarr) GetMovieFiles(movieFileIDs []int64) ([]*MovieFile, error) { + return r.GetMovieFilesContext(context.Background(), movieFileIDs) +} + +// GetMovieFilesContext returns the movie file(s) requested. +func (r *Radarr) GetMovieFilesContext(ctx context.Context, movieFileIDs []int64) ([]*MovieFile, error) { + req := starr.Request{URI: bpMovieFile, Query: make(url.Values)} + for _, id := range movieFileIDs { + req.Query.Add("movieFileIds", fmt.Sprint(id)) + } + + var output []*MovieFile + if err := r.GetInto(ctx, req, &output); err != nil { + return nil, fmt.Errorf("api.Get(%s): %w", &req, err) + } + + return output, nil +} + +// UpdateMovieFile updates the movie file provided. +func (r *Radarr) UpdateMovieFile(movieFile *MovieFile) (*MovieFile, error) { + return r.UpdateMovieFileContext(context.Background(), movieFile) +} + +// UpdateMovieFileContext updates the movie file provided. +func (r *Radarr) UpdateMovieFileContext(ctx context.Context, movieFile *MovieFile) (*MovieFile, error) { + var body bytes.Buffer + if err := json.NewEncoder(&body).Encode(movieFile); err != nil { + return nil, fmt.Errorf("json.Marshal(%s): %w", bpMovieFile, err) + } + + var output *MovieFile + + req := starr.Request{URI: path.Join(bpMovieFile, fmt.Sprint(movieFile.ID)), Body: &body} + if err := r.PutInto(ctx, req, &output); err != nil { + return nil, fmt.Errorf("api.Put(%s): %w", &req, err) + } + + return output, nil +} + +// DeleteMovieFile deletes movie files by their IDs. +func (r *Radarr) DeleteMovieFiles(movieFileIDs ...int64) error { + return r.DeleteMovieFilesContext(context.Background(), movieFileIDs...) +} + +// DeleteMovieFileContext deletes movie files by their IDs. +func (r *Radarr) DeleteMovieFilesContext(ctx context.Context, movieFileIDs ...int64) error { + postData := struct { + T []int64 `json:"movieFileIds"` + }{movieFileIDs} + + var body bytes.Buffer + if err := json.NewEncoder(&body).Encode(&postData); err != nil { + return fmt.Errorf("json.Marshal(%s): %w", bpMovieFile, err) + } + + req := starr.Request{URI: path.Join(bpMovieFile, "bulk"), Body: &body} + if err := r.DeleteAny(ctx, req); err != nil { + return fmt.Errorf("api.Delete(%s): %w", &req, err) + } + + return nil +}