golift.io/starr@v1.0.0/sonarr/episodefile.go (about)

     1  package sonarr
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"encoding/json"
     7  	"fmt"
     8  	"net/url"
     9  	"path"
    10  	"time"
    11  
    12  	"golift.io/starr"
    13  )
    14  
    15  const bpEpisodeFile = APIver + "/episodeFile"
    16  
    17  // EpisodeFile is the output from the /api/v3/episodeFile endpoint.
    18  type EpisodeFile struct {
    19  	ID                   int64                 `json:"id"`
    20  	SeriesID             int64                 `json:"seriesId"`
    21  	SeasonNumber         int                   `json:"seasonNumber"`
    22  	RelativePath         string                `json:"relativePath"`
    23  	Path                 string                `json:"path"`
    24  	Size                 int64                 `json:"size"`
    25  	DateAdded            time.Time             `json:"dateAdded"`
    26  	SceneName            string                `json:"sceneName"`
    27  	ReleaseGroup         string                `json:"releaseGroup"`
    28  	Language             *starr.Value          `json:"language"`
    29  	Quality              *starr.Quality        `json:"quality"`
    30  	MediaInfo            *MediaInfo            `json:"mediaInfo"`
    31  	QualityCutoffNotMet  bool                  `json:"qualityCutoffNotMet"`
    32  	LanguageCutoffNotMet bool                  `json:"languageCutoffNotMet"`
    33  	CustomFormats        []*CustomFormatOutput `json:"customFormats"` // v4 only
    34  }
    35  
    36  // MediaInfo is part of an EpisodeFile.
    37  type MediaInfo struct {
    38  	AudioBitrate     int            `json:"audioBitrate"`
    39  	AudioChannels    float64        `json:"audioChannels"`
    40  	AudioCodec       string         `json:"audioCodec"`
    41  	AudioLanguages   string         `json:"audioLanguages"`
    42  	AudioStreamCount int            `json:"audioStreamCount"`
    43  	VideoBitDepth    int            `json:"videoBitDepth"`
    44  	VideoBitrate     int            `json:"videoBitrate"`
    45  	VideoCodec       string         `json:"videoCodec"`
    46  	VideoFPS         float64        `json:"videoFps"`
    47  	Resolution       string         `json:"resolution"`
    48  	RunTime          starr.PlayTime `json:"runTime"`
    49  	ScanType         string         `json:"scanType"`
    50  	Subtitles        string         `json:"subtitles"`
    51  }
    52  
    53  // GetEpisodeFiles returns information about episode files by episode file IDs.
    54  func (s *Sonarr) GetEpisodeFiles(episodeFileIDs ...int64) ([]*EpisodeFile, error) {
    55  	return s.GetEpisodeFilesContext(context.Background(), episodeFileIDs...)
    56  }
    57  
    58  // GetEpisodeFilesContext returns information about episode files by episode file IDs.
    59  func (s *Sonarr) GetEpisodeFilesContext(ctx context.Context, episodeFileIDs ...int64) ([]*EpisodeFile, error) {
    60  	var ids string
    61  	for _, efID := range episodeFileIDs {
    62  		ids += fmt.Sprintf("%d,", efID) // the extra comma is ok.
    63  	}
    64  
    65  	req := starr.Request{URI: bpEpisodeFile, Query: make(url.Values)}
    66  	req.Query.Add("episodeFileIds", ids)
    67  
    68  	var output []*EpisodeFile
    69  	if err := s.GetInto(ctx, req, &output); err != nil {
    70  		return nil, fmt.Errorf("api.Get(%s): %w", &req, err)
    71  	}
    72  
    73  	return output, nil
    74  }
    75  
    76  // GetSeriesEpisodeFile returns information about all episode files in a series.
    77  func (s *Sonarr) GetSeriesEpisodeFiles(seriesID int64) ([]*EpisodeFile, error) {
    78  	return s.GetSeriesEpisodeFilesContext(context.Background(), seriesID)
    79  }
    80  
    81  // GetSeriesEpisodeFilesContext returns information about episode files by episode file ID.
    82  func (s *Sonarr) GetSeriesEpisodeFilesContext(ctx context.Context, seriesID int64) ([]*EpisodeFile, error) {
    83  	var output []*EpisodeFile
    84  
    85  	req := starr.Request{URI: bpEpisodeFile, Query: make(url.Values)}
    86  	req.Query.Add("seriesId", fmt.Sprint(seriesID))
    87  
    88  	if err := s.GetInto(ctx, req, &output); err != nil {
    89  		return nil, fmt.Errorf("api.Get(%s): %w", &req, err)
    90  	}
    91  
    92  	return output, nil
    93  }
    94  
    95  // UpdateEpisodeFile updates an episode file's quality. Use GetQualityProfiles() to find the available IDs.
    96  func (s *Sonarr) UpdateEpisodeFileQuality(episodeFileID, qualityID int64) (*EpisodeFile, error) {
    97  	return s.UpdateEpisodeFileQualityContext(context.Background(), episodeFileID, qualityID)
    98  }
    99  
   100  // UpdateEpisodeFileQualityContext updates an episode file, and takes a context.
   101  func (s *Sonarr) UpdateEpisodeFileQualityContext(
   102  	ctx context.Context,
   103  	episodeFileID int64,
   104  	qualityID int64,
   105  ) (*EpisodeFile, error) {
   106  	var body bytes.Buffer
   107  
   108  	err := json.NewEncoder(&body).Encode(&EpisodeFile{
   109  		ID:      episodeFileID,
   110  		Quality: &starr.Quality{Quality: &starr.BaseQuality{ID: qualityID}},
   111  	})
   112  	if err != nil {
   113  		return nil, fmt.Errorf("json.Marshal(%s): %w", bpEpisodeFile, err)
   114  	}
   115  
   116  	var output EpisodeFile
   117  
   118  	req := starr.Request{URI: path.Join(bpEpisodeFile, fmt.Sprint(episodeFileID)), Body: &body}
   119  	if err := s.PutInto(ctx, req, &output); err != nil {
   120  		return nil, fmt.Errorf("api.Put(%s): %w", &req, err)
   121  	}
   122  
   123  	return &output, nil
   124  }
   125  
   126  // DeleteEpisodeFile deletes an episode file.
   127  func (s *Sonarr) DeleteEpisodeFile(episodeFileID int64) error {
   128  	return s.DeleteEpisodeFileContext(context.Background(), episodeFileID)
   129  }
   130  
   131  // DeleteEpisodeFileContext deletes an episode file, and takes a context.
   132  func (s *Sonarr) DeleteEpisodeFileContext(ctx context.Context, episodeFileID int64) error {
   133  	req := starr.Request{URI: path.Join(bpEpisodeFile, fmt.Sprint(episodeFileID))}
   134  	if err := s.DeleteAny(ctx, req); err != nil {
   135  		return fmt.Errorf("api.Delete(%s): %w", &req, err)
   136  	}
   137  
   138  	return nil
   139  }