mirror of
https://github.com/FJurmanovic/sugarr.git
synced 2026-11-12 00:01:09 +00:00
init
This commit is contained in:
133
internal/client/jellyfin.go
Normal file
133
internal/client/jellyfin.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/fjurmanovic/sugarr/internal/model"
|
||||
"github.com/fjurmanovic/sugarr/internal/utl/configs"
|
||||
)
|
||||
|
||||
type JellyfinClient struct {
|
||||
url string
|
||||
apiKey string
|
||||
userID string
|
||||
http *http.Client
|
||||
}
|
||||
|
||||
func NewJellyfinClient(cfg *configs.Config) *JellyfinClient {
|
||||
return &JellyfinClient{
|
||||
url: cfg.JellyfinURL,
|
||||
apiKey: cfg.JellyfinAPIKey,
|
||||
userID: cfg.JellyfinUserID,
|
||||
http: &http.Client{},
|
||||
}
|
||||
}
|
||||
|
||||
type jellyfinItemsResponse struct {
|
||||
Items []jellyfinItem `json:"Items"`
|
||||
}
|
||||
|
||||
type jellyfinItem struct {
|
||||
Name string `json:"Name"`
|
||||
ProductionYear int `json:"ProductionYear"`
|
||||
ProviderIds map[string]string `json:"ProviderIds"`
|
||||
Genres []string `json:"Genres"`
|
||||
CommunityRating float64 `json:"CommunityRating"`
|
||||
UserData jellyfinUserData `json:"UserData"`
|
||||
}
|
||||
|
||||
type jellyfinUserData struct {
|
||||
IsFavorite bool `json:"IsFavorite"`
|
||||
PlayCount int `json:"PlayCount"`
|
||||
}
|
||||
|
||||
func (c *JellyfinClient) get(path string, params url.Values) (*jellyfinItemsResponse, error) {
|
||||
u := fmt.Sprintf("%s%s?%s", c.url, path, params.Encode())
|
||||
req, err := http.NewRequest(http.MethodGet, u, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Authorization", fmt.Sprintf("MediaBrowser Token=%q", c.apiKey))
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
resp, err := c.http.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("jellyfin request failed: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("jellyfin returned status %d for %s", resp.StatusCode, path)
|
||||
}
|
||||
|
||||
var result jellyfinItemsResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
return nil, fmt.Errorf("decoding jellyfin response: %w", err)
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func toMovies(items []jellyfinItem) []model.Movie {
|
||||
movies := make([]model.Movie, 0, len(items))
|
||||
for _, item := range items {
|
||||
movies = append(movies, model.Movie{
|
||||
Name: item.Name,
|
||||
Year: item.ProductionYear,
|
||||
IMDbID: item.ProviderIds["Imdb"],
|
||||
TMDbID: item.ProviderIds["Tmdb"],
|
||||
Genres: item.Genres,
|
||||
CommunityRating: item.CommunityRating,
|
||||
IsFavorite: item.UserData.IsFavorite,
|
||||
PlayCount: item.UserData.PlayCount,
|
||||
})
|
||||
}
|
||||
return movies
|
||||
}
|
||||
|
||||
func (c *JellyfinClient) GetFavoriteMovies() ([]model.Movie, error) {
|
||||
params := url.Values{
|
||||
"IncludeItemTypes": {"Movie"},
|
||||
"Recursive": {"true"},
|
||||
"IsFavorite": {"true"},
|
||||
"Fields": {"ProviderIds,Genres,CommunityRating,UserData"},
|
||||
}
|
||||
resp, err := c.get(fmt.Sprintf("/Users/%s/Items", c.userID), params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toMovies(resp.Items), nil
|
||||
}
|
||||
|
||||
func (c *JellyfinClient) GetRecentlyWatched() ([]model.Movie, error) {
|
||||
params := url.Values{
|
||||
"IncludeItemTypes": {"Movie"},
|
||||
"Recursive": {"true"},
|
||||
"Filters": {"IsPlayed"},
|
||||
"SortBy": {"DatePlayed"},
|
||||
"SortOrder": {"Descending"},
|
||||
"Limit": {"50"},
|
||||
"Fields": {"ProviderIds,Genres,CommunityRating,UserData"},
|
||||
}
|
||||
resp, err := c.get(fmt.Sprintf("/Users/%s/Items", c.userID), params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toMovies(resp.Items), nil
|
||||
}
|
||||
|
||||
func (c *JellyfinClient) GetAllMovies() ([]model.Movie, error) {
|
||||
params := url.Values{
|
||||
"IncludeItemTypes": {"Movie"},
|
||||
"Recursive": {"true"},
|
||||
"Fields": {"ProviderIds"},
|
||||
"Limit": {"10000"},
|
||||
}
|
||||
resp, err := c.get(fmt.Sprintf("/Users/%s/Items", c.userID), params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toMovies(resp.Items), nil
|
||||
}
|
||||
Reference in New Issue
Block a user