package arr import ( "encoding/json" "io" "net/http" gourl "net/url" "strconv" "strings" ) type HistorySchema struct { Page int `json:"page"` PageSize int `json:"pageSize"` SortKey string `json:"sortKey"` SortDirection string `json:"sortDirection"` TotalRecords int `json:"totalRecords"` Records []struct { ID int `json:"id"` DownloadID string `json:"downloadId"` } `json:"records"` } type QueueResponseScheme struct { Page int `json:"page"` PageSize int `json:"pageSize"` SortKey string `json:"sortKey"` SortDirection string `json:"sortDirection"` TotalRecords int `json:"totalRecords"` Records []QueueSchema `json:"records"` } type QueueSchema struct { SeriesId int `json:"seriesId"` EpisodeId int `json:"episodeId"` SeasonNumber int `json:"seasonNumber"` Title string `json:"title"` Status string `json:"status"` TrackedDownloadStatus string `json:"trackedDownloadStatus"` TrackedDownloadState string `json:"trackedDownloadState"` StatusMessages []struct { Title string `json:"title"` Messages []string `json:"messages"` } `json:"statusMessages"` DownloadId string `json:"downloadId"` Protocol string `json:"protocol"` DownloadClient string `json:"downloadClient"` DownloadClientHasPostImportCategory bool `json:"downloadClientHasPostImportCategory"` Indexer string `json:"indexer"` OutputPath string `json:"outputPath"` EpisodeHasFile bool `json:"episodeHasFile"` Id int `json:"id"` } func (a *Arr) GetHistory(downloadId, eventType string) *HistorySchema { query := gourl.Values{} if downloadId != "" { query.Add("downloadId", downloadId) } query.Add("eventType", eventType) query.Add("pageSize", "100") url := "api/v3/history" + "?" + query.Encode() resp, err := a.Request(http.MethodGet, url, nil) if err != nil { return nil } defer resp.Body.Close() var data *HistorySchema if err = json.NewDecoder(resp.Body).Decode(&data); err != nil { return nil } return data } func (a *Arr) GetQueue() []QueueSchema { query := gourl.Values{} query.Add("page", "1") query.Add("pageSize", "200") results := make([]QueueSchema, 0) for { url := "api/v3/queue" + "?" + query.Encode() resp, err := a.Request(http.MethodGet, url, nil) if err != nil { break } func() { defer func(Body io.ReadCloser) { err := Body.Close() if err != nil { return } }(resp.Body) var data QueueResponseScheme if err = json.NewDecoder(resp.Body).Decode(&data); err != nil { return } results = append(results, data.Records...) if len(results) >= data.TotalRecords { // We've fetched all records err = io.EOF // Signal to exit the loop return } query.Set("page", strconv.Itoa(data.Page+1)) }() if err != nil { break } } return results } func (a *Arr) CleanupQueue() error { queue := a.GetQueue() type messedUp struct { id int episodeId int seasonNum int } cleanups := make(map[int][]messedUp) for _, q := range queue { isMessedUp := false if q.Protocol == "torrent" && q.Status == "completed" && q.TrackedDownloadStatus == "warning" && q.TrackedDownloadState == "importPending" { messages := q.StatusMessages if len(messages) > 0 { for _, m := range messages { if strings.Contains(strings.Join(m.Messages, " "), "No files found are eligible for import in") { isMessedUp = true break } if strings.Contains(m.Title, "One or more episodes expected in this release were not imported or missing from the release") { isMessedUp = true break } } } } if isMessedUp { cleanups[q.SeriesId] = append(cleanups[q.SeriesId], messedUp{ id: q.Id, episodeId: q.EpisodeId, seasonNum: q.SeasonNumber, }) } } if len(cleanups) == 0 { return nil } queueIds := make([]int, 0) for _, c := range cleanups { // Delete the messed up episodes from queue for _, m := range c { queueIds = append(queueIds, m.id) } } // Delete the messed up episodes from queue payload := struct { Ids []int `json:"ids"` }{ Ids: queueIds, } // Blocklist that hash(it's typically not complete, then research the episode) query := gourl.Values{} query.Add("removeFromClient", "true") query.Add("blocklist", "true") query.Add("skipRedownload", "false") query.Add("changeCategory", "false") url := "api/v3/queue/bulk" + "?" + query.Encode() _, err := a.Request(http.MethodDelete, url, payload) if err != nil { return err } return nil }