canape/backend/shows/episodes.go
Lucas BEE 4206d09954
Some checks reported errors
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build was killed
Fix upsert of torrents
We're missing some infos from the Torrents
We ensure that we set them for now, we'll need to edit the polochon
torrenters so that they put this info
And add a DB constraint, a torrent shouldn't be able to be created
without an imdbID
2020-04-10 17:48:34 +02:00

229 lines
6.2 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.getThumbURL(),
}
return json.Marshal(episodeToMarshal)
}
func (e *Episode) getThumbURL() string {
return e.show.GetImageURL(fmt.Sprintf("%d-%d", e.Season, e.Episode))
}
// 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
}