231 lines
6.0 KiB
Go
231 lines
6.0 KiB
Go
package shows
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"git.quimbo.fr/odwrtw/canape/backend/backend"
|
|
"git.quimbo.fr/odwrtw/canape/backend/users"
|
|
"git.quimbo.fr/odwrtw/canape/backend/web"
|
|
"github.com/odwrtw/papi"
|
|
polochon "github.com/odwrtw/polochon/lib"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// Show represents a show
|
|
type Show struct {
|
|
client *papi.Client
|
|
pShow *papi.Show
|
|
*polochon.Show
|
|
TrackedSeason *int `json:"tracked_season"`
|
|
TrackedEpisode *int `json:"tracked_episode"`
|
|
publicDir string
|
|
imgURLPrefix string
|
|
}
|
|
|
|
// MarshalJSON implements the Marshal interface
|
|
func (s *Show) MarshalJSON() ([]byte, error) {
|
|
type alias Show
|
|
// Create the structure that we want to marshal
|
|
showToMarshal := &struct {
|
|
*alias
|
|
Episodes []Episode `json:"episodes"`
|
|
BannerURL string `json:"banner_url"`
|
|
FanartURL string `json:"fanart_url"`
|
|
PosterURL string `json:"poster_url"`
|
|
}{
|
|
alias: (*alias)(s),
|
|
BannerURL: s.GetImageURL("banner"),
|
|
FanartURL: s.GetImageURL("fanart"),
|
|
PosterURL: s.GetImageURL("poster"),
|
|
}
|
|
|
|
// Create Episode obj from polochon.Episodes and add them to the object to
|
|
// marshal
|
|
for _, e := range s.Show.Episodes {
|
|
showToMarshal.Episodes = append(showToMarshal.Episodes, Episode{
|
|
ShowEpisode: e,
|
|
client: s.client,
|
|
pShow: s.pShow,
|
|
})
|
|
}
|
|
return json.Marshal(showToMarshal)
|
|
}
|
|
|
|
// New returns a new Show with a polochon ShowConfig
|
|
func New(imdbID string, publicDir, imgURLPrefix string) *Show {
|
|
return &Show{
|
|
Show: &polochon.Show{
|
|
ImdbID: imdbID,
|
|
},
|
|
publicDir: publicDir,
|
|
imgURLPrefix: imgURLPrefix,
|
|
}
|
|
}
|
|
|
|
// NewWithClient returns a new Show with a polochon ShowConfig
|
|
func NewWithClient(imdbID string, client *papi.Client, pShow *papi.Show, wShow *backend.WishedShow, publicDir, imgURLPrefix string) *Show {
|
|
s := &Show{
|
|
Show: &polochon.Show{
|
|
ImdbID: imdbID,
|
|
},
|
|
client: client,
|
|
pShow: pShow,
|
|
publicDir: publicDir,
|
|
imgURLPrefix: imgURLPrefix,
|
|
}
|
|
if wShow != nil {
|
|
s.TrackedSeason = &wShow.Season
|
|
s.TrackedEpisode = &wShow.Episode
|
|
}
|
|
return s
|
|
}
|
|
|
|
// GetDetails retrieves details for the show with the given detailers
|
|
func (s *Show) GetDetails(env *web.Env, detailers []polochon.Detailer) error {
|
|
log := env.Log.WithFields(logrus.Fields{
|
|
"imdb_id": s.ImdbID,
|
|
"function": "shows.GetDetails",
|
|
})
|
|
var detailersName []string
|
|
for _, d := range detailers {
|
|
detailersName = append(detailersName, d.Name())
|
|
}
|
|
log.Debugf("getting details with %s", strings.Join(detailersName, ", "))
|
|
|
|
s.Detailers = detailers
|
|
|
|
// Get the details
|
|
err := polochon.GetDetails(s.Show, env.Log)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Debugf("got details from detailers")
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetAndFetch retrieves details for the show with the given
|
|
// detailers 'before'
|
|
// If found, return
|
|
// If not, retrives details with the detailers 'after' and update them in
|
|
// database
|
|
func (s *Show) GetAndFetch(env *web.Env, before []polochon.Detailer, after []polochon.Detailer) error {
|
|
log := env.Log.WithFields(logrus.Fields{
|
|
"imdb_id": s.ImdbID,
|
|
"function": "shows.GetAndFetch",
|
|
})
|
|
|
|
// Try to get details with the first batch of Detailers
|
|
err := s.GetDetails(env, before)
|
|
if err == nil {
|
|
log.Debug("show found in first try")
|
|
return nil
|
|
}
|
|
log.Debugf("show not found in database: %s", err)
|
|
|
|
// If not found, try the second batch and upsert
|
|
return s.Refresh(env, after)
|
|
}
|
|
|
|
// Refresh retrieves details for the show with the given detailers
|
|
// and update them in database
|
|
func (s *Show) Refresh(env *web.Env, detailers []polochon.Detailer) error {
|
|
// Refresh
|
|
err := s.GetDetails(env, detailers)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Download show images
|
|
s.downloadImages(env)
|
|
|
|
env.Log.Debug("images downloaded")
|
|
|
|
// If found, update in database
|
|
return backend.UpsertShow(env.Database, s.Show)
|
|
}
|
|
|
|
// GetImageURL returns the image URL or the default image if the poster is not yet downloaded
|
|
func (s *Show) GetImageURL(imgType string) string {
|
|
// Check if the show image exists
|
|
if _, err := os.Stat(s.imgFile(imgType)); os.IsNotExist(err) {
|
|
// TODO image in the config ?
|
|
return s.imgURLPrefix + "noimage.png"
|
|
}
|
|
return s.imgURLPrefix + s.imgURL(imgType)
|
|
}
|
|
|
|
// downloadImages will download the show images
|
|
func (s *Show) downloadImages(env *web.Env) {
|
|
// Download the banner
|
|
err := web.Download(s.Show.Banner, s.imgFile("banner"), false)
|
|
if err != nil {
|
|
env.Log.Errorf("failed to dowload banner: %s", err)
|
|
}
|
|
err = web.Download(s.Show.Fanart, s.imgFile("fanart"), false)
|
|
if err != nil {
|
|
env.Log.Errorf("failed to dowload fanart: %s", err)
|
|
}
|
|
err = web.Download(s.Show.Poster, s.imgFile("poster"), true)
|
|
if err != nil {
|
|
env.Log.Errorf("failed to dowload poster: %s", err)
|
|
}
|
|
}
|
|
|
|
// imgURL returns the default image url
|
|
func (s *Show) imgURL(imgType string) string {
|
|
return fmt.Sprintf("shows/%s-%s.jpg", s.ImdbID, imgType)
|
|
}
|
|
|
|
// imgFile returns the image location on disk
|
|
func (s *Show) imgFile(imgType string) string {
|
|
return filepath.Join(s.publicDir, "img", s.imgURL(imgType))
|
|
}
|
|
|
|
// getPolochonShows returns all the Shows from the polochon of a user
|
|
func getPolochonShows(env *web.Env, user *users.User) ([]*Show, error) {
|
|
shows := []*Show{}
|
|
|
|
client, err := user.NewPapiClient()
|
|
if err != nil {
|
|
return shows, err
|
|
}
|
|
|
|
// Get the polochon's shows
|
|
pshows, err := client.GetShows()
|
|
if err != nil {
|
|
return shows, err
|
|
}
|
|
|
|
wShows, err := backend.GetShowWishlist(env.Database, user.ID)
|
|
if err != nil {
|
|
return shows, err
|
|
}
|
|
|
|
// Create Shows objects from the shows retrieved
|
|
for _, pShow := range pshows.List() {
|
|
wShow, _ := wShows.IsShowInWishlist(pShow.ImdbID)
|
|
show := NewWithClient(pShow.ImdbID, client, pShow, wShow, env.Config.PublicDir, env.Config.ImgURLPrefix)
|
|
shows = append(shows, show)
|
|
}
|
|
return shows, nil
|
|
}
|
|
|
|
// LastSeasonEpisodes will return the episodes of the last season of the show
|
|
func (s *Show) LastSeasonEpisodes() []*polochon.ShowEpisode {
|
|
episodes := make(map[int][]*polochon.ShowEpisode)
|
|
lastSeason := 0
|
|
for _, e := range s.Episodes {
|
|
if lastSeason < e.Season {
|
|
lastSeason = e.Season
|
|
}
|
|
episodes[e.Season] = append(episodes[e.Season], e)
|
|
}
|
|
return episodes[lastSeason]
|
|
}
|