golift.io/starr@v1.0.0/readarr/queue.go (about) 1 package readarr 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "fmt" 8 "path" 9 "time" 10 11 "golift.io/starr" 12 ) 13 14 const bpQueue = APIver + "/queue" 15 16 // Queue is the /api/v1/queue endpoint. 17 type Queue struct { 18 Page int `json:"page"` 19 PageSize int `json:"pageSize"` 20 SortKey string `json:"sortKey"` 21 SortDirection string `json:"sortDirection"` 22 TotalRecords int `json:"totalRecords"` 23 Records []*QueueRecord `json:"records"` 24 } 25 26 // QueueRecord is a book from the queue API path. 27 type QueueRecord struct { 28 AuthorID int64 `json:"authorId"` 29 BookID int64 `json:"bookId"` 30 Quality *starr.Quality `json:"quality"` 31 Size float64 `json:"size"` 32 Title string `json:"title"` 33 Sizeleft float64 `json:"sizeleft"` 34 Timeleft string `json:"timeleft"` 35 EstimatedCompletionTime time.Time `json:"estimatedCompletionTime"` 36 Status string `json:"status"` 37 TrackedDownloadStatus string `json:"trackedDownloadStatus,omitempty"` 38 TrackedDownloadState string `json:"trackedDownloadState,omitempty"` 39 StatusMessages []*starr.StatusMessage `json:"statusMessages,omitempty"` 40 DownloadID string `json:"downloadId,omitempty"` 41 Protocol string `json:"protocol"` 42 DownloadClient string `json:"downloadClient,omitempty"` 43 Indexer string `json:"indexer"` 44 OutputPath string `json:"outputPath,omitempty"` 45 DownloadForced bool `json:"downloadForced"` 46 ID int64 `json:"id"` 47 ErrorMessage string `json:"errorMessage"` 48 } 49 50 // GetQueue returns a single page from the Readarr Queue (processing, but not yet imported). 51 // If you need control over the page, use readarr.GetQueuePage(). 52 // This function simply returns the number of queue records desired, 53 // up to the number of records present in the application. 54 // It grabs records in (paginated) batches of perPage, and concatenates 55 // them into one list. Passing zero for records will return all of them. 56 func (r *Readarr) GetQueue(records, perPage int) (*Queue, error) { 57 return r.GetQueueContext(context.Background(), records, perPage) 58 } 59 60 // GetQueueContext returns a single page from the Readarr Queue (processing, but not yet imported). 61 // If you need control over the page, use readarr.GetQueuePageContext(). 62 func (r *Readarr) GetQueueContext(ctx context.Context, records, perPage int) (*Queue, error) { 63 queue := &Queue{Records: []*QueueRecord{}} 64 perPage = starr.SetPerPage(records, perPage) 65 66 for page := 1; ; page++ { 67 curr, err := r.GetQueuePageContext(ctx, &starr.PageReq{PageSize: perPage, Page: page}) 68 if err != nil { 69 return nil, err 70 } 71 72 queue.Records = append(queue.Records, curr.Records...) 73 74 if len(queue.Records) >= curr.TotalRecords || 75 (len(queue.Records) >= records && records != 0) || 76 len(curr.Records) == 0 { 77 queue.PageSize = curr.TotalRecords 78 queue.TotalRecords = curr.TotalRecords 79 queue.SortDirection = curr.SortDirection 80 queue.SortKey = curr.SortKey 81 82 break 83 } 84 85 perPage = starr.AdjustPerPage(records, curr.TotalRecords, len(queue.Records), perPage) 86 } 87 88 return queue, nil 89 } 90 91 // GetQueuePage returns a single page from the Readarr Queue. 92 // The page size and number is configurable with the input request parameters. 93 func (r *Readarr) GetQueuePage(params *starr.PageReq) (*Queue, error) { 94 return r.GetQueuePageContext(context.Background(), params) 95 } 96 97 // GetQueuePageContext returns a single page from the Readarr Queue. 98 // The page size and number is configurable with the input request parameters. 99 func (r *Readarr) GetQueuePageContext(ctx context.Context, params *starr.PageReq) (*Queue, error) { 100 var output Queue 101 102 params.CheckSet("sortKey", "timeleft") 103 params.CheckSet("includeUnknownAuthorItems", "true") 104 105 req := starr.Request{URI: bpQueue, Query: params.Params()} 106 if err := r.GetInto(ctx, req, &output); err != nil { 107 return nil, fmt.Errorf("api.Get(%s): %w", &req, err) 108 } 109 110 return &output, nil 111 } 112 113 // DeleteQueue deletes an item from the Activity Queue. 114 func (r *Readarr) DeleteQueue(queueID int64, opts *starr.QueueDeleteOpts) error { 115 return r.DeleteQueueContext(context.Background(), queueID, opts) 116 } 117 118 // DeleteQueueContext deletes an item from the Activity Queue. 119 func (r *Readarr) DeleteQueueContext(ctx context.Context, queueID int64, opts *starr.QueueDeleteOpts) error { 120 req := starr.Request{URI: path.Join(bpQueue, fmt.Sprint(queueID)), Query: opts.Values()} 121 if err := r.DeleteAny(ctx, req); err != nil { 122 return fmt.Errorf("api.Delete(%s): %w", &req, err) 123 } 124 125 return nil 126 } 127 128 // QueueGrab tells the app to grab an item that's in queue. 129 // Most often used on items with a delay set from a delay profile. 130 func (r *Readarr) QueueGrab(ids ...int64) error { 131 return r.QueueGrabContext(context.Background(), ids...) 132 } 133 134 // QueueGrabContext tells the app to grab an item that's in queue, probably set to a delay. 135 // Most often used on items with a delay set from a delay profile. 136 func (r *Readarr) QueueGrabContext(ctx context.Context, ids ...int64) error { 137 idList := struct { 138 IDs []int64 `json:"ids"` 139 }{IDs: ids} 140 141 var body bytes.Buffer 142 if err := json.NewEncoder(&body).Encode(idList); err != nil { 143 return fmt.Errorf("json.Marshal(%s): %w", bpQueue, err) 144 } 145 146 var output interface{} // any ok 147 148 req := starr.Request{URI: path.Join(bpQueue, "grab", "bulk"), Body: &body} 149 if err := r.PostInto(ctx, req, &output); err != nil { 150 return fmt.Errorf("api.Post(%s): %w", &req, err) 151 } 152 153 return nil 154 }