canape/backend/shows/episodes.go
Grégoire Delattre 7be65b6a9a Get the video images from the models
Return the video details embedded in the torrents

This requires the eventers to have the app env
2020-04-13 17:38:47 +02:00

225 lines
6.0 KiB
Go

package shows
import (
"encoding/json"
"fmt"
"time"
"git.quimbo.fr/odwrtw/canape/backend/models"
"git.quimbo.fr/odwrtw/canape/backend/subtitles"
"git.quimbo.fr/odwrtw/canape/backend/web"
"github.com/odwrtw/errors"
"github.com/odwrtw/papi"
polochon "github.com/odwrtw/polochon/lib"
"github.com/sirupsen/logrus"
)
// Episode represents an episode
type Episode struct {
show *Show
*polochon.ShowEpisode
}
// MarshalJSON implements the Marshal interface
func (e *Episode) MarshalJSON() ([]byte, error) {
type alias Episode
var downloadURL string
var subs []subtitles.Subtitle
var dateAdded time.Time
var quality string
var audioCodec string
var videoCodec string
var container string
// If the episode is present, fill the downloadURL
if e.show.pShow != nil {
pEpisode := e.show.pShow.GetEpisode(e.Season, e.Episode)
if pEpisode != nil {
// Get the DownloadURL
downloadURL, _ = e.show.client.DownloadURL(
&papi.Episode{
ShowImdbID: e.ShowImdbID,
Episode: e.Episode,
Season: e.Season,
},
)
dateAdded = pEpisode.DateAdded
quality = pEpisode.Quality
audioCodec = pEpisode.AudioCodec
videoCodec = pEpisode.VideoCodec
container = pEpisode.Container
// Append the Subtitles
for _, l := range pEpisode.Subtitles {
subtitleURL, _ := e.show.client.SubtitleURL(pEpisode, l)
subs = append(subs, subtitles.Subtitle{
Language: l,
URL: subtitleURL,
VVTFile: fmt.Sprintf("/shows/%s/seasons/%d/episodes/%d/subtitles/%s", e.ShowImdbID, e.Season, e.Episode, l),
})
}
}
}
// Marshal the episode with its polochon_url
episodeToMarshal := &struct {
*alias
PolochonURL string `json:"polochon_url"`
Subtitles []subtitles.Subtitle `json:"subtitles"`
DateAdded time.Time `json:"date_added"`
Quality string `json:"quality"`
AudioCodec string `json:"audio_codec"`
VideoCodec string `json:"video_codec"`
Container string `json:"container"`
Thumb string `json:"thumb"`
}{
alias: (*alias)(e),
PolochonURL: downloadURL,
Subtitles: subs,
DateAdded: dateAdded,
Quality: quality,
AudioCodec: audioCodec,
VideoCodec: videoCodec,
Container: container,
Thumb: e.Thumb,
}
return json.Marshal(episodeToMarshal)
}
// NewEpisode returns an Episode
func NewEpisode(show *Show, season, episode int) *Episode {
return &Episode{
show: show,
ShowEpisode: &polochon.ShowEpisode{
ShowImdbID: show.ImdbID,
Season: season,
Episode: episode,
},
}
}
// GetAndFetchTorrents retrieves torrents for the episode with the given
// torrenters 'before'
// If found, return
// If not, retrives torrents with the torrenters 'after' and update them in
// database
func (e *Episode) GetAndFetchTorrents(env *web.Env, before []polochon.Torrenter, after []polochon.Torrenter) error {
log := env.Log.WithFields(logrus.Fields{
"imdb_id": e.ShowImdbID,
"season": e.Season,
"episode": e.Episode,
"function": "episodes.GetAndFetchTorrents",
})
// Try to get details with the first batch of Detailers
err := e.GetTorrents(env, before)
if err == nil {
log.Debug("episode torrents found in first try")
return nil
}
log.Debugf("episode torrent not found in database: %s", err)
// If not found, try the second batch and upsert
return e.RefreshTorrents(env, after)
}
// GetTorrents retrieves torrents for the episode with the given torrenters
func (e *Episode) GetTorrents(env *web.Env, torrenters []polochon.Torrenter) error {
return GetTorrents(env, e.ShowEpisode, torrenters)
}
// GetTorrents retrieves torrents for the episode with the given torrenters
func GetTorrents(env *web.Env, showEpisode *polochon.ShowEpisode, torrenters []polochon.Torrenter) error {
log := env.Log.WithFields(logrus.Fields{
"imdb_id": showEpisode.ShowImdbID,
"season": showEpisode.Season,
"episode": showEpisode.Episode,
"function": "episodes.GetTorrents",
})
log.Debugf("getting torrents")
showEpisode.Torrenters = torrenters
err := polochon.GetTorrents(showEpisode, env.Log)
if err != nil {
return err
}
log.Debugf("got %d torrents from torrenters", len(showEpisode.Torrents))
return nil
}
// RefreshTorrents refresh the episode torrents
func (e *Episode) RefreshTorrents(env *web.Env, torrenters []polochon.Torrenter) error {
return RefreshTorrents(env, e.ShowEpisode, torrenters)
}
// RefreshTorrents refresh the episode torrents
func RefreshTorrents(env *web.Env, showEpisode *polochon.ShowEpisode, torrenters []polochon.Torrenter) error {
log := env.Log.WithFields(logrus.Fields{
"imdb_id": showEpisode.ShowImdbID,
"season": showEpisode.Season,
"episode": showEpisode.Episode,
"function": "episodes.RefreshTorrents",
})
log.Debugf("refreshing torrents")
// Refresh
err := GetTorrents(env, showEpisode, torrenters)
if err != nil {
return err
}
// Upsert all the torrents we got
for _, t := range showEpisode.Torrents {
t.ImdbID = showEpisode.ShowImdbID
t.Season = showEpisode.Season
t.Episode = showEpisode.Episode
err = models.UpsertEpisodeTorrent(env.Database, t)
if err != nil {
log.Errorf("error while adding torrent : %s", err)
continue
}
}
return nil
}
// Refresh retrieves details for the episode with the given detailers
// and update them in database
func (e *Episode) Refresh(env *web.Env, detailers []polochon.Detailer) error {
// Refresh
err := e.GetEpisodeDetails(env, detailers)
if err != nil {
return err
}
return models.UpsertEpisode(env.Database, e.ShowEpisode)
}
// GetEpisodeDetails retrieves details for the episode with the given detailers
func (e *Episode) GetEpisodeDetails(env *web.Env, detailers []polochon.Detailer) error {
log := env.Log.WithFields(logrus.Fields{
"imdb_id": e.ShowImdbID,
"function": "episodes.GetDetails",
})
log.Debugf("getting details")
e.ShowEpisode.Detailers = detailers
// Get the details
err := polochon.GetDetails(e.ShowEpisode, log)
if err != nil {
if errors.IsFatal(err) {
return err
}
}
log.Debug("got details from detailers")
return nil
}