227 lines
6.1 KiB
Go
227 lines
6.1 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"
|
|
polochon "github.com/odwrtw/polochon/lib"
|
|
"github.com/odwrtw/polochon/lib/papi"
|
|
"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{
|
|
ShowEpisode: &polochon.ShowEpisode{
|
|
ShowImdbID: e.ShowImdbID,
|
|
Episode: e.Episode,
|
|
Season: e.Season,
|
|
},
|
|
},
|
|
)
|
|
dateAdded = pEpisode.DateAdded
|
|
quality = string(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
|
|
}
|