Changelog 0.5.0

This commit is contained in:
Mukhtar Akere
2025-03-05 20:15:10 +01:00
parent 1c06407900
commit a83f3d72ce
30 changed files with 1787 additions and 342 deletions
+47 -11
View File
@@ -2,13 +2,16 @@ package arr
import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"github.com/sirrobot01/debrid-blackhole/internal/config"
"github.com/sirrobot01/debrid-blackhole/internal/request"
"io"
"net/http"
"strings"
"sync"
"time"
)
// Type is a type of arr
@@ -21,51 +24,84 @@ const (
Readarr Type = "readarr"
)
var (
client *request.RLHTTPClient = request.NewRLHTTPClient(nil, nil)
)
type Arr struct {
Name string `json:"name"`
Host string `json:"host"`
Token string `json:"token"`
Type Type `json:"type"`
Cleanup bool `json:"cleanup"`
client *http.Client
}
func New(name, host, token string, cleanup bool) *Arr {
return &Arr{
Name: name,
Host: host,
Token: token,
Token: strings.TrimSpace(token),
Type: InferType(host, name),
Cleanup: cleanup,
client: &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Proxy: http.ProxyFromEnvironment,
},
},
}
}
func (a *Arr) Request(method, endpoint string, payload interface{}) (*http.Response, error) {
if a.Token == "" || a.Host == "" {
return nil, nil
return nil, fmt.Errorf("arr not configured")
}
url, err := request.JoinURL(a.Host, endpoint)
if err != nil {
return nil, err
}
var jsonPayload []byte
var body io.Reader
if payload != nil {
jsonPayload, err = json.Marshal(payload)
b, err := json.Marshal(payload)
if err != nil {
return nil, err
}
body = bytes.NewReader(b)
}
req, err := http.NewRequest(method, url, bytes.NewBuffer(jsonPayload))
req, err := http.NewRequest(method, url, body)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Api-Key", a.Token)
return client.Do(req)
if a.client == nil {
a.client = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Proxy: http.ProxyFromEnvironment,
},
}
}
var resp *http.Response
for attempts := 0; attempts < 5; attempts++ {
resp, err = a.client.Do(req)
if err != nil {
return nil, err
}
// If we got a 401, wait briefly and retry
if resp.StatusCode == http.StatusUnauthorized {
resp.Body.Close() // Don't leak response bodies
if attempts < 4 { // Don't sleep on the last attempt
time.Sleep(time.Duration(attempts+1) * 100 * time.Millisecond)
continue
}
}
return resp, nil
}
return resp, err
}
func (a *Arr) Validate() error {
+31 -11
View File
@@ -7,25 +7,38 @@ import (
"strconv"
)
func (a *Arr) GetMedia(tvId string) ([]Content, error) {
type episode struct {
Id int `json:"id"`
EpisodeFileID int `json:"episodeFileId"`
}
func (a *Arr) GetMedia(mediaId string) ([]Content, error) {
// Get series
resp, err := a.Request(http.MethodGet, fmt.Sprintf("api/v3/series?tvdbId=%s", tvId), nil)
if a.Type == Radarr {
return GetMovies(a, mediaId)
}
// This is likely Sonarr
resp, err := a.Request(http.MethodGet, fmt.Sprintf("api/v3/series?tvdbId=%s", mediaId), nil)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusNotFound {
// This is likely Radarr
return GetMovies(a, tvId)
return GetMovies(a, mediaId)
}
a.Type = Sonarr
defer resp.Body.Close()
type series struct {
Title string `json:"title"`
Id int `json:"id"`
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to get series: %s", resp.Status)
}
var data []series
if err = json.NewDecoder(resp.Body).Decode(&data); err != nil {
return nil, err
return nil, fmt.Errorf("failed to decode series: %v", err)
}
// Get series files
contents := make([]Content, 0)
@@ -43,11 +56,6 @@ func (a *Arr) GetMedia(tvId string) ([]Content, error) {
Title: d.Title,
Id: d.Id,
}
type episode struct {
Id int `json:"id"`
EpisodeFileID int `json:"episodeFileId"`
}
resp, err = a.Request(http.MethodGet, fmt.Sprintf("api/v3/episode?seriesId=%d", d.Id), nil)
if err != nil {
continue
@@ -67,12 +75,20 @@ func (a *Arr) GetMedia(tvId string) ([]Content, error) {
if !ok {
eId = 0
}
if file.Id == 0 || file.Path == "" {
// Skip files without path
continue
}
files = append(files, ContentFile{
FileId: file.Id,
Path: file.Path,
Id: eId,
})
}
if len(files) == 0 {
// Skip series without files
continue
}
ct.Files = files
contents = append(contents, ct)
}
@@ -92,7 +108,7 @@ func GetMovies(a *Arr, tvId string) ([]Content, error) {
defer resp.Body.Close()
var movies []Movie
if err = json.NewDecoder(resp.Body).Decode(&movies); err != nil {
return nil, err
return nil, fmt.Errorf("failed to decode movies: %v", err)
}
contents := make([]Content, 0)
for _, movie := range movies {
@@ -101,6 +117,10 @@ func GetMovies(a *Arr, tvId string) ([]Content, error) {
Id: movie.Id,
}
files := make([]ContentFile, 0)
if movie.MovieFile.Id == 0 || movie.MovieFile.Path == "" {
// Skip movies without files
continue
}
files = append(files, ContentFile{
FileId: movie.MovieFile.Id,
Id: movie.Id,
-1
View File
@@ -8,7 +8,6 @@ type Movie struct {
MovieId int `json:"movieId"`
RelativePath string `json:"relativePath"`
Path string `json:"path"`
Size int `json:"size"`
Id int `json:"id"`
} `json:"movieFile"`
Id int `json:"id"`