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

     1  package sonarr
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"path"
     7  	"time"
     8  
     9  	"golift.io/starr"
    10  )
    11  
    12  const bpHistory = APIver + "/history"
    13  
    14  // History is the data from the /api/v3/history endpoint.
    15  type History struct {
    16  	Page          int              `json:"page"`
    17  	PageSize      int              `json:"pageSize"`
    18  	SortKey       string           `json:"sortKey"`
    19  	SortDirection string           `json:"sortDirection"`
    20  	TotalRecords  int              `json:"totalRecords"`
    21  	Records       []*HistoryRecord `json:"records"`
    22  }
    23  
    24  // HistoryRecord is part of the History data.
    25  // Not all items have all Data members. Check EventType for what you need.
    26  type HistoryRecord struct {
    27  	ID                   int64          `json:"id"`
    28  	EpisodeID            int64          `json:"episodeId"`
    29  	SeriesID             int64          `json:"seriesId"`
    30  	SourceTitle          string         `json:"sourceTitle"`
    31  	Language             Language       `json:"language"`
    32  	Quality              *starr.Quality `json:"quality"`
    33  	QualityCutoffNotMet  bool           `json:"qualityCutoffNotMet"`
    34  	LanguageCutoffNotMet bool           `json:"languageCutoffNotMet"`
    35  	Date                 time.Time      `json:"date"`
    36  	DownloadID           string         `json:"downloadId,omitempty"`
    37  	EventType            string         `json:"eventType"`
    38  	Data                 struct {
    39  		Age                string    `json:"age"`
    40  		AgeHours           string    `json:"ageHours"`
    41  		AgeMinutes         string    `json:"ageMinutes"`
    42  		DownloadClient     string    `json:"downloadClient"`
    43  		DownloadClientName string    `json:"downloadClientName"`
    44  		DownloadURL        string    `json:"downloadUrl"`
    45  		DroppedPath        string    `json:"droppedPath"`
    46  		FileID             string    `json:"fileId"`
    47  		GUID               string    `json:"guid"`
    48  		ImportedPath       string    `json:"importedPath"`
    49  		Indexer            string    `json:"indexer"`
    50  		Message            string    `json:"message"`
    51  		NzbInfoURL         string    `json:"nzbInfoUrl"`
    52  		PreferredWordScore string    `json:"preferredWordScore"`
    53  		Protocol           string    `json:"protocol"`
    54  		PublishedDate      time.Time `json:"publishedDate"`
    55  		Reason             string    `json:"reason"`
    56  		ReleaseGroup       string    `json:"releaseGroup"`
    57  		Size               string    `json:"size"`
    58  		TorrentInfoHash    string    `json:"torrentInfoHash"`
    59  		TvRageID           string    `json:"tvRageId"`
    60  		TvdbID             string    `json:"tvdbId"`
    61  	} `json:"data"`
    62  }
    63  
    64  // GetHistory returns the Sonarr History (grabs/failures/completed).
    65  // If you need control over the page, use sonarr.GetHistoryPage().
    66  // This function simply returns the number of history records desired,
    67  // up to the number of records present in the application.
    68  // It grabs records in (paginated) batches of perPage, and concatenates
    69  // them into one list.  Passing zero for records will return all of them.
    70  func (s *Sonarr) GetHistory(records, perPage int) (*History, error) {
    71  	return s.GetHistoryContext(context.Background(), records, perPage)
    72  }
    73  
    74  // GetHistoryContext returns the Sonarr History (grabs/failures/completed). See GetHistory for more.
    75  func (s *Sonarr) GetHistoryContext(ctx context.Context, records, perPage int) (*History, error) {
    76  	hist := &History{Records: []*HistoryRecord{}}
    77  	perPage = starr.SetPerPage(records, perPage)
    78  
    79  	for page := 1; ; page++ {
    80  		curr, err := s.GetHistoryPageContext(ctx, &starr.PageReq{PageSize: perPage, Page: page})
    81  		if err != nil {
    82  			return nil, err
    83  		}
    84  
    85  		hist.Records = append(hist.Records, curr.Records...)
    86  
    87  		if len(hist.Records) >= curr.TotalRecords ||
    88  			(len(hist.Records) >= records && records != 0) ||
    89  			len(curr.Records) == 0 {
    90  			hist.PageSize = curr.TotalRecords
    91  			hist.TotalRecords = curr.TotalRecords
    92  			hist.SortDirection = curr.SortDirection
    93  			hist.SortKey = curr.SortKey
    94  
    95  			break
    96  		}
    97  
    98  		perPage = starr.AdjustPerPage(records, curr.TotalRecords, len(hist.Records), perPage)
    99  	}
   100  
   101  	return hist, nil
   102  }
   103  
   104  // GetHistoryPage returns a single page from the Sonarr History (grabs/failures/completed).
   105  // The page size and number is configurable with the input request parameters.
   106  func (s *Sonarr) GetHistoryPage(params *starr.PageReq) (*History, error) {
   107  	return s.GetHistoryPageContext(context.Background(), params)
   108  }
   109  
   110  // GetHistoryPageContext returns a single page from the Sonarr History (grabs/failures/completed).
   111  // The page size and number is configurable with the input request parameters.
   112  func (s *Sonarr) GetHistoryPageContext(ctx context.Context, params *starr.PageReq) (*History, error) {
   113  	var output History
   114  
   115  	req := starr.Request{URI: bpHistory, Query: params.Params()}
   116  	if err := s.GetInto(ctx, req, &output); err != nil {
   117  		return nil, fmt.Errorf("api.Get(%s): %w", &req, err)
   118  	}
   119  
   120  	return &output, nil
   121  }
   122  
   123  // Fail marks the given history item as failed by id.
   124  func (s *Sonarr) Fail(historyID int64) error {
   125  	return s.FailContext(context.Background(), historyID)
   126  }
   127  
   128  // FailContext marks the given history item as failed by id.
   129  func (s *Sonarr) FailContext(ctx context.Context, historyID int64) error {
   130  	if historyID < 1 {
   131  		return fmt.Errorf("%w: invalid history ID: %d", starr.ErrRequestError, historyID)
   132  	}
   133  
   134  	var output interface{} // any ok
   135  
   136  	// Strangely uses a POST without a payload.
   137  	req := starr.Request{URI: path.Join(bpHistory, "failed", fmt.Sprint(historyID))}
   138  	if err := s.PostInto(ctx, req, &output); err != nil {
   139  		return fmt.Errorf("api.Post(%s): %w", &req, err)
   140  	}
   141  
   142  	return nil
   143  }