feat: ✨ add radarr releases support
This commit is contained in:
parent
fde9190254
commit
cbf25cd129
2 changed files with 117 additions and 4 deletions
|
@ -17,6 +17,12 @@ type SonarrConfig struct {
|
|||
ApiKey string `yaml:"apikey"`
|
||||
}
|
||||
|
||||
type RadarrConfig struct {
|
||||
Enable bool `yaml:"enable"`
|
||||
Endpoint string `yaml:"endpoint"`
|
||||
ApiKey string `yaml:"apikey"`
|
||||
}
|
||||
|
||||
type ArrRelease struct {
|
||||
Title string
|
||||
ImageCoverUrl string
|
||||
|
@ -42,6 +48,18 @@ type SonarrReleaseResponse struct {
|
|||
AirDateUtc string `json:"airDateUtc"`
|
||||
}
|
||||
|
||||
type RadarrReleaseResponse struct {
|
||||
HasFile bool `json:"hasFile"`
|
||||
Title string `json:"title"`
|
||||
Images []struct {
|
||||
CoverType string `json:"coverType"`
|
||||
RemoteUrl string `json:"remoteUrl"`
|
||||
} `json:"images"`
|
||||
InCinemasDate string `json:"inCinemas"`
|
||||
PhysicalReleaseDate string `json:"physicalRelease"`
|
||||
DigitalReleaseDate string `json:"digitalRelease"`
|
||||
}
|
||||
|
||||
func extractHostFromURL(apiEndpoint string) string {
|
||||
u, err := url.Parse(apiEndpoint)
|
||||
if err != nil {
|
||||
|
@ -124,18 +142,108 @@ func FetchReleasesFromSonarr(SonarrEndpoint string, SonarrApiKey string) (ArrRel
|
|||
return releases, nil
|
||||
}
|
||||
|
||||
func FetchReleasesFromArrStack(Sonarr SonarrConfig) (ArrReleases, error) {
|
||||
func FetchReleasesFromRadarr(RadarrEndpoint string, RadarrApiKey string) (ArrReleases, error) {
|
||||
if RadarrEndpoint == "" {
|
||||
return nil, fmt.Errorf("missing radarr-endpoint config")
|
||||
}
|
||||
|
||||
if RadarrApiKey == "" {
|
||||
return nil, fmt.Errorf("missing radarr-apikey config")
|
||||
}
|
||||
|
||||
client := &http.Client{}
|
||||
url := fmt.Sprintf("%s/api/v3/calendar", strings.TrimSuffix(RadarrEndpoint, "/"))
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create request: %v", err)
|
||||
}
|
||||
|
||||
req.Header.Set("X-Api-Key", RadarrApiKey)
|
||||
req.Header.Set("Host", extractHostFromURL(RadarrEndpoint))
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to make request: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("unexpected status code: %v", resp.StatusCode)
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read response body: %v", err)
|
||||
}
|
||||
|
||||
var radarrReleases []RadarrReleaseResponse
|
||||
err = json.Unmarshal(body, &radarrReleases)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal JSON: %v", err)
|
||||
}
|
||||
|
||||
var releases ArrReleases
|
||||
for _, release := range radarrReleases {
|
||||
var imageCover string
|
||||
for _, image := range release.Images {
|
||||
if image.CoverType == "poster" {
|
||||
imageCover = image.RemoteUrl
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Choose the appropriate release date from Radarr's response
|
||||
releaseDate := release.InCinemasDate
|
||||
formattedDate := "In Cinemas: "
|
||||
if release.PhysicalReleaseDate != "" {
|
||||
releaseDate = release.PhysicalReleaseDate
|
||||
formattedDate = "Physical Release: "
|
||||
} else if release.DigitalReleaseDate != "" {
|
||||
releaseDate = release.DigitalReleaseDate
|
||||
formattedDate = "Digital Release: "
|
||||
}
|
||||
|
||||
airDate, err := time.Parse("2006-01-02", releaseDate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse release date: %v", err)
|
||||
}
|
||||
|
||||
// Format the date as YYYY-MM-DD HH:MM:SS
|
||||
formattedDate = formattedDate + airDate.Format("2006-01-02 15:04:05")
|
||||
|
||||
releases = append(releases, ArrRelease{
|
||||
Title: release.Title,
|
||||
ImageCoverUrl: imageCover,
|
||||
AirDateUtc: formattedDate,
|
||||
Grabbed: release.HasFile,
|
||||
})
|
||||
}
|
||||
|
||||
return releases, nil
|
||||
}
|
||||
|
||||
func FetchReleasesFromArrStack(Sonarr SonarrConfig, Radarr RadarrConfig) (ArrReleases, error) {
|
||||
result := ArrReleases{}
|
||||
|
||||
// Call FetchReleasesFromSonarr and handle the result
|
||||
if Sonarr.Enable {
|
||||
sonarrReleases, err := FetchReleasesFromSonarr(Sonarr.Endpoint, Sonarr.ApiKey)
|
||||
if err != nil {
|
||||
slog.Warn("failed to fetch release", "error", err)
|
||||
slog.Warn("failed to fetch release from sonarr", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = sonarrReleases
|
||||
result = append(result, sonarrReleases...)
|
||||
}
|
||||
|
||||
// Call FetchReleasesFromRadarr and handle the result
|
||||
if Radarr.Enable {
|
||||
radarrReleases, err := FetchReleasesFromRadarr(Radarr.Endpoint, Radarr.ApiKey)
|
||||
if err != nil {
|
||||
slog.Warn("failed to fetch release from radarr", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = append(result, radarrReleases...)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
|
|
@ -17,6 +17,11 @@ type ArrReleases struct {
|
|||
Endpoint string `yaml:"endpoint"`
|
||||
ApiKey string `yaml:"apikey"`
|
||||
}
|
||||
Radarr struct {
|
||||
Enable bool `yaml:"enable"`
|
||||
Endpoint string `yaml:"endpoint"`
|
||||
ApiKey string `yaml:"apikey"`
|
||||
}
|
||||
CollapseAfter int `yaml:"collapse-after"`
|
||||
CacheDuration time.Duration `yaml:"cache-duration"`
|
||||
}
|
||||
|
@ -39,7 +44,7 @@ func (widget *ArrReleases) Initialize() error {
|
|||
}
|
||||
|
||||
func (widget *ArrReleases) Update(ctx context.Context) {
|
||||
releases, err := feed.FetchReleasesFromArrStack(widget.Sonarr)
|
||||
releases, err := feed.FetchReleasesFromArrStack(widget.Sonarr, widget.Radarr)
|
||||
if !widget.canContinueUpdateAfterHandlingErr(err) {
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue