canape/backend/models/episodes.go
Grégoire Delattre d585a59c83 Download movie fanart and better torrent list on mobile
Show the thumb on wide screens and the fanart on small screens.
2021-08-22 11:33:36 -10:00

169 lines
5.1 KiB
Go

package models
import (
"database/sql"
"fmt"
"time"
"github.com/jmoiron/sqlx"
polochon "github.com/odwrtw/polochon/lib"
"github.com/sirupsen/logrus"
)
const (
upsertEpisodeQuery = `
INSERT INTO episodes (show_imdb_id, show_tvdb_id, title, season, episode, tvdb_id, aired, plot, runtime, rating, imdb_id)
VALUES (:show_imdb_id, :show_tvdb_id, :title, :season, :episode, :tvdb_id, :aired, :plot, :runtime, :rating, :imdb_id)
ON CONFLICT (show_imdb_id, season, episode)
DO UPDATE
SET show_imdb_id=:show_imdb_id, show_tvdb_id=:show_tvdb_id, title=:title,
season=:season, episode=:episode, tvdb_id=:tvdb_id, aired=:aired,
plot=:plot, runtime=:runtime, rating=:rating, imdb_id=:imdb_id
RETURNING id;`
getEpisodesQuery = `
SELECT *
FROM episodes WHERE show_imdb_id=$1;`
getEpisodeQuery = `
SELECT s.title show_title, e.*
FROM shows s , episodes e
WHERE s.imdb_id = e.show_imdb_id
AND e.show_imdb_id=$1
AND e.season=$2
AND e.episode=$3;`
)
// episodeDB represents the Episode in the DB
type episodeDB struct {
ID string `db:"id"`
TvdbID int `db:"tvdb_id"`
ImdbID string `db:"imdb_id"`
ShowImdbID string `db:"show_imdb_id"`
ShowTvdbID int `db:"show_tvdb_id"`
ShowTitle string `db:"show_title"`
Season int `db:"season"`
Episode int `db:"episode"`
Title string `db:"title"`
Rating float32 `db:"rating"`
Plot string `db:"plot"`
Thumb string `db:"thumb"`
Runtime int `db:"runtime"`
Aired string `db:"aired"`
Created time.Time `db:"created_at"`
Updated time.Time `db:"updated_at"`
}
// getEpisodeDB returns an episodeDB from a polochon.ShowEpisode
func getEpisodeDB(db *sqlx.DB, episode *polochon.ShowEpisode) (*episodeDB, error) {
var episodeDB episodeDB
err := db.QueryRowx(getEpisodeQuery, episode.ShowImdbID, episode.Season, episode.Episode).StructScan(&episodeDB)
if err != nil {
return &episodeDB, err
}
return &episodeDB, nil
}
// NewEpisodeFromDB returns a new polochon ShowEpisode from an episodeDB
func NewEpisodeFromDB(eDB *episodeDB) *polochon.ShowEpisode {
pEpisode := polochon.ShowEpisode{}
FillEpisodeFromDB(eDB, &pEpisode)
return &pEpisode
}
// FillEpisodeFromDB fills a ShowEpisode from an episodeDB
func FillEpisodeFromDB(eDB *episodeDB, pEpisode *polochon.ShowEpisode) {
// Keep the data that never changes but only if we have it
updateIfNonEmpty(&pEpisode.EpisodeImdbID, eDB.ImdbID)
updateIfNonEmpty(&pEpisode.ShowImdbID, eDB.ShowImdbID)
updateIfNonEmpty(&pEpisode.ShowTitle, eDB.ShowTitle)
updateIfNonZeroInt(&pEpisode.TvdbID, eDB.TvdbID)
updateIfNonZeroInt(&pEpisode.ShowTvdbID, eDB.ShowTvdbID)
pEpisode.Season = eDB.Season
pEpisode.Episode = eDB.Episode
pEpisode.Title = eDB.Title
pEpisode.Rating = eDB.Rating
pEpisode.Plot = eDB.Plot
pEpisode.Runtime = eDB.Runtime
pEpisode.Aired = eDB.Aired
pEpisode.Thumb = imageURL(fmt.Sprintf(
"shows/%s/%d-%d.jpg",
eDB.ShowImdbID,
eDB.Season,
eDB.Episode,
))
}
// GetEpisode gets an episode and fills the polochon episode
func GetEpisode(db *sqlx.DB, pEpisode *polochon.ShowEpisode) error {
episodeDB, err := getEpisodeDB(db, pEpisode)
if err != nil {
return err
}
FillEpisodeFromDB(episodeDB, pEpisode)
return nil
}
// GetEpisodes gets show's episodes and fills the polochon show
func GetEpisodes(db *sqlx.DB, pShow *polochon.Show, log *logrus.Entry) error {
// Get the episodes
var episodesDB = []*episodeDB{}
err := db.Select(&episodesDB, getEpisodesQuery, pShow.ImdbID)
if err != nil {
return err
}
if len(episodesDB) == 0 {
log.Debug("got no episodes")
return nil
}
log.Debugf("got %d episodes", len(episodesDB))
for _, episodeDB := range episodesDB {
episode := NewEpisodeFromDB(episodeDB)
pShow.Episodes = append(pShow.Episodes, episode)
}
return nil
}
// updateFromEpisode will update the episodeDB from a ShowEpisode
// We just make sure to never update the episodeDB with empty value
func (e *episodeDB) updateFromEpisode(showEpisode *polochon.ShowEpisode) {
updateIfNonEmpty(&e.ImdbID, showEpisode.EpisodeImdbID)
updateIfNonEmpty(&e.ShowImdbID, showEpisode.ShowImdbID)
updateIfNonEmpty(&e.Title, showEpisode.Title)
updateIfNonEmpty(&e.Plot, showEpisode.Plot)
updateIfNonEmpty(&e.Thumb, showEpisode.Thumb)
updateIfNonEmpty(&e.Aired, showEpisode.Aired)
updateIfNonZeroInt(&e.TvdbID, showEpisode.TvdbID)
updateIfNonZeroInt(&e.ShowTvdbID, showEpisode.ShowTvdbID)
updateIfNonZeroInt(&e.Season, showEpisode.Season)
updateIfNonZeroInt(&e.Episode, showEpisode.Episode)
updateIfNonZeroInt(&e.Runtime, showEpisode.Runtime)
updateIfNonZeroFloat(&e.Rating, showEpisode.Rating)
}
// UpsertEpisode upserts the episode
func UpsertEpisode(db *sqlx.DB, showEpisode *polochon.ShowEpisode) error {
// Try to get the episode
episodeDB, err := getEpisodeDB(db, showEpisode)
// Return only if the error is != sql.ErrNoRows
if err != nil {
if err != sql.ErrNoRows {
return err
}
}
// Update the episodeDB from the showEpisode we have
episodeDB.updateFromEpisode(showEpisode)
r, err := db.NamedQuery(upsertEpisodeQuery, episodeDB)
if err != nil {
return err
}
defer r.Close()
return nil
}