diff --git a/src/internal/shows/episodes.go b/src/internal/shows/episodes.go index f02e223..addbba3 100644 --- a/src/internal/shows/episodes.go +++ b/src/internal/shows/episodes.go @@ -32,6 +32,7 @@ const ( type Episode struct { sqly.BaseModel polochon.ShowEpisode + PolochonURL string `json:"polochon_url"` } // EpisodeDB represents the Episode in the DB diff --git a/src/internal/shows/handlers.go b/src/internal/shows/handlers.go index 3381b5e..156e92c 100644 --- a/src/internal/shows/handlers.go +++ b/src/internal/shows/handlers.go @@ -3,15 +3,24 @@ package shows import ( "encoding/json" "errors" + "fmt" + "net" "net/http" + "net/url" "github.com/gorilla/mux" + "github.com/odwrtw/papi" polochon "github.com/odwrtw/polochon/lib" + "github.com/odwrtw/polochon/modules/pam" "gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/auth" + "gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/config" "gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/users" "gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/web" ) +// ErrPolochonUnavailable is an error returned if the polochon server is not available +var ErrPolochonUnavailable = fmt.Errorf("Invalid polochon address") + // GetDetailsHandler retrieves details of a show func GetDetailsHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error { return DetailsHandler(env, w, r, false) @@ -40,6 +49,20 @@ func DetailsHandler(env *web.Env, w http.ResponseWriter, r *http.Request, force if err := s.GetEpisodes(env, force); err != nil { return env.RenderError(w, err) } + // Get the show from the polochon of the user + pShow, err := getPolochonShow(user, s.ImdbID) + if err != nil { + env.Log.Warnf("error while getting polochon show %s : %s", s.ImdbID, err) + } + // For each of the user's polochon episodes, add a direct link to it + for _, pEpisode := range pShow.Episodes { + for _, e := range s.Episodes { + if e.Season != pEpisode.Season || e.Episode != pEpisode.Episode { + continue + } + e.PolochonURL = pEpisode.PolochonURL + } + } return env.RenderJSON(w, s) } @@ -154,3 +177,108 @@ func GetWishlistHandler(env *web.Env, w http.ResponseWriter, r *http.Request) er return env.RenderJSON(w, shows) } + +// getPolochonShows returns all the Shows from the polochon of a user +func getPolochonShows(user *users.User) ([]*Show, error) { + shows := []*Show{} + + var polochonConfig config.UserPolochon + err := user.GetConfig("polochon", &polochonConfig) + if err != nil { + return shows, err + } + + client, err := papi.New(polochonConfig.URL) + if err != nil { + return shows, err + } + + if polochonConfig.Token != "" { + client.SetToken(polochonConfig.Token) + } + + pshows, err := client.GetShows() + if err != nil { + // Catch network error for accessing specified polochon address + if uerr, ok := err.(*url.Error); ok { + if nerr, ok := uerr.Err.(*net.OpError); ok { + if nerr.Op == "dial" { + return shows, ErrPolochonUnavailable + } + + } + } + return shows, err + } + for _, pshow := range pshows { + show := New(pshow.ImdbID) + for _, season := range pshow.Seasons { + for _, episode := range season.Episodes { + e := NewEpisode() + e.Season = episode.Season + e.Episode = episode.Episode + e.ShowImdbID = episode.ShowImdbID + e.PolochonURL, _ = client.DownloadURL( + &papi.Episode{ + ShowImdbID: show.ImdbID, + Episode: e.Episode, + Season: e.Season, + }, + ) + + show.Episodes = append(show.Episodes, e) + } + } + shows = append(shows, show) + } + return shows, nil +} + +// getPolochonShow returns a Show with its epidodes from the polochon of a user +func getPolochonShow(user *users.User, imdbID string) (Show, error) { + shows, err := getPolochonShows(user) + if err != nil { + return Show{}, err + } + for _, s := range shows { + if s.ImdbID == imdbID { + return *s, nil + } + } + return Show{}, nil +} + +// FromPolochon will returns shows from Polochon +func FromPolochon(env *web.Env, w http.ResponseWriter, r *http.Request) error { + v := auth.GetCurrentUser(r, env.Log) + user, ok := v.(*users.User) + if !ok { + return env.RenderError(w, errors.New("invalid user type")) + } + + shows, err := getPolochonShows(user) + if err != nil { + return env.RenderError(w, err) + } + + var polochonConfig config.UserPolochon + err = user.GetConfig("polochon", &polochonConfig) + if err != nil { + return env.RenderError(w, err) + } + + detailer, err := pam.New(&pam.Params{ + Endpoint: polochonConfig.URL, + Token: polochonConfig.Token, + }) + + for _, s := range shows { + s.Detailers = []polochon.Detailer{detailer} + err := s.GetDetails(env, user, false) + if err != nil { + env.Log.Error(err) + } + } + + return env.RenderJSON(w, shows) +} diff --git a/src/internal/shows/shows.go b/src/internal/shows/shows.go index 5123f28..75c3b36 100644 --- a/src/internal/shows/shows.go +++ b/src/internal/shows/shows.go @@ -108,18 +108,21 @@ type ShowDB struct { // NewShowDB returns a Show ready to be put in DB from a // Show func NewShowDB(s *Show) ShowDB { - return ShowDB{ - ID: s.ID, - ImdbID: s.ImdbID, - Title: s.Title, - Rating: s.Rating, - Plot: s.Plot, - TvdbID: s.TvdbID, - Year: s.Year, - FirstAired: *s.FirstAired, - Created: s.Created, - Updated: s.Updated, + sDB := ShowDB{ + ID: s.ID, + ImdbID: s.ImdbID, + Title: s.Title, + Rating: s.Rating, + Plot: s.Plot, + TvdbID: s.TvdbID, + Year: s.Year, + Created: s.Created, + Updated: s.Updated, } + if s.FirstAired != nil { + sDB.FirstAired = *s.FirstAired + } + return sDB } // FillFromDB returns a Show from a ShowDB extracted from the DB @@ -231,7 +234,7 @@ func (s *Show) GetDetails(env *web.Env, user *users.User, force bool) error { // GetPosterURL returns the image URL or the default image if the poster is not yet downloaded func (s *Show) GetPosterURL(env *web.Env) string { - // Check if the movie image exists + // Check if the show image exists if _, err := os.Stat(s.imgFile(env, "poster")); os.IsNotExist(err) { // TODO image in the config ? return "img/noimage.png" diff --git a/src/main.go b/src/main.go index 8685491..7106210 100644 --- a/src/main.go +++ b/src/main.go @@ -83,7 +83,7 @@ func main() { env.Handle("/movies/refresh", extmedias.Refresh).WithRole(users.UserRole).Methods("POST") env.Handle("/movies/search", movies.SearchMovie).WithRole(users.UserRole).Methods("POST") - // env.Handle("/shows/polochon", shows.FromPolochon).WithRole(users.UserRole) + env.Handle("/shows/polochon", shows.FromPolochon).WithRole(users.UserRole).Methods("GET") env.Handle("/shows/{id:tt[0-9]+}", shows.GetDetailsHandler).WithRole(users.UserRole).Methods("GET") env.Handle("/shows/{id:tt[0-9]+}/refresh", shows.RefreshDetailsHandler).WithRole(users.UserRole).Methods("POST") env.Handle("/shows/refresh", extmedias.RefreshShows).WithRole(users.UserRole).Methods("POST")