From 351552d049b889d704c0779aa1e0a63b7e09823b Mon Sep 17 00:00:00 2001 From: Lucas BEE Date: Tue, 31 Jan 2017 13:39:58 +0000 Subject: [PATCH 1/2] Normalize when to fetch data from external service --- src/internal/movies/movies.go | 26 +++++++++++++------------- src/internal/shows/episodes.go | 5 +++-- src/internal/shows/handlers.go | 2 +- src/internal/shows/shows.go | 9 +++++---- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/internal/movies/movies.go b/src/internal/movies/movies.go index 0af223f..8d69cb8 100644 --- a/src/internal/movies/movies.go +++ b/src/internal/movies/movies.go @@ -209,16 +209,17 @@ func (m *Movie) GetDetails(env *web.Env, user *users.User, force bool) error { switch err { case nil: log.Debug("movie found in database") - if !force { - log.Debug("returning movie from db") - return nil - } case sql.ErrNoRows: log.Debug("movie not found in database") default: // Unexpected error return err } + // If force is not specified, don't go further + if !force { + // Will return ErrNoRows if the movie wasn't found + return err + } // GetDetail err = m.Movie.GetDetails(env.Log) @@ -271,21 +272,20 @@ func (m *Movie) GetTorrents(env *web.Env, force bool) error { switch err { case nil: log.Debug("torrents found in database") - if !force { - log.Debugf("returning %d torrents from db", len(movieTorrents)) - // Add the torrents to the movie - for _, t := range movieTorrents { - m.Torrents = append(m.Torrents, t.Torrent) - } - return nil - } case sql.ErrNoRows: log.Debug("torrent not found in database") - // We'll need to GetTorrents from torrenters default: // Unexpected error return err } + if !force { + log.Debugf("returning %d torrents from db", len(movieTorrents)) + // Add the torrents to the movie + for _, t := range movieTorrents { + m.Torrents = append(m.Torrents, t.Torrent) + } + return nil + } err = m.Movie.GetTorrents(env.Log) if err != nil { diff --git a/src/internal/shows/episodes.go b/src/internal/shows/episodes.go index addbba3..338e368 100644 --- a/src/internal/shows/episodes.go +++ b/src/internal/shows/episodes.go @@ -147,18 +147,19 @@ func (e *Episode) GetTorrents(env *web.Env, force bool) error { log.Debug("torrents found in database") case sql.ErrNoRows: log.Debug("torrent not found in database") - // We'll need to GetTorrents from torrenters default: // Unexpected error return err } + // If force is not specified, don't go further if !force { log.Debugf("returning %d torrents from db", len(episodeTorrents)) // Add the torrents to the episode for _, t := range episodeTorrents { e.Torrents = append(e.Torrents, t.Torrent) } - return nil + // Will return ErrNoRows if the torrent wasn't found + return err } err = e.ShowEpisode.GetTorrents(env.Log) diff --git a/src/internal/shows/handlers.go b/src/internal/shows/handlers.go index 156e92c..9fbb45a 100644 --- a/src/internal/shows/handlers.go +++ b/src/internal/shows/handlers.go @@ -31,7 +31,7 @@ func RefreshDetailsHandler(env *web.Env, w http.ResponseWriter, r *http.Request) return DetailsHandler(env, w, r, true) } -// DetailsHandler handles details of a show +// DetailsHandler handles details of an episode func DetailsHandler(env *web.Env, w http.ResponseWriter, r *http.Request, force bool) error { vars := mux.Vars(r) id := vars["id"] diff --git a/src/internal/shows/shows.go b/src/internal/shows/shows.go index 75c3b36..b3473da 100644 --- a/src/internal/shows/shows.go +++ b/src/internal/shows/shows.go @@ -190,16 +190,17 @@ func (s *Show) GetDetails(env *web.Env, user *users.User, force bool) error { switch err { case nil: log.Debug("show found in database") - if !force { - log.Debug("returning show from db") - return nil - } case sql.ErrNoRows: log.Debug("show not found in database") default: // Unexpected error return err } + // If force is not specified, don't go further + if !force { + // Will return ErrNoRows if the show wasn't found + return err + } // GetDetail err = s.Show.GetDetails(env.Log) From 91c32cf2d400634c7f9ce8a3330cdc65d2c6f64c Mon Sep 17 00:00:00 2001 From: Lucas BEE Date: Tue, 31 Jan 2017 13:40:35 +0000 Subject: [PATCH 2/2] Add a handler to refresh episode info Update movies/refresh route while we're here --- src/internal/shows/episodes.go | 17 ++++++++ src/internal/shows/handlers.go | 49 ++++++++++++++++++++++ src/internal/shows/shows.go | 54 +++++++++++++++++++++++++ src/main.go | 3 +- src/public/js/actions/actionCreators.js | 2 +- 5 files changed, 123 insertions(+), 2 deletions(-) diff --git a/src/internal/shows/episodes.go b/src/internal/shows/episodes.go index 338e368..29f79f6 100644 --- a/src/internal/shows/episodes.go +++ b/src/internal/shows/episodes.go @@ -26,6 +26,10 @@ const ( getEpisodesQuery = ` SELECT * FROM episodes WHERE show_imdb_id=$1;` + + getEpisodeQuery = ` + SELECT * + FROM episodes WHERE show_imdb_id=$1 AND season=$2 AND episode=$3;` ) // Episode represents an episode @@ -180,3 +184,16 @@ func (e *Episode) GetTorrents(env *web.Env, force bool) error { return nil } + +// Get returns an episode +func (e *Episode) Get(env *web.Env) error { + var episodeDB EpisodeDB + err := env.Database.QueryRowx(getEpisodeQuery, e.ShowImdbID, e.Season, e.Episode).StructScan(&episodeDB) + if err != nil { + return err + } + + e.FillFromDB(&episodeDB) + + return nil +} diff --git a/src/internal/shows/handlers.go b/src/internal/shows/handlers.go index 9fbb45a..df156c9 100644 --- a/src/internal/shows/handlers.go +++ b/src/internal/shows/handlers.go @@ -7,6 +7,7 @@ import ( "net" "net/http" "net/url" + "strconv" "github.com/gorilla/mux" "github.com/odwrtw/papi" @@ -282,3 +283,51 @@ func FromPolochon(env *web.Env, w http.ResponseWriter, r *http.Request) error { return env.RenderJSON(w, shows) } + +// RefreshEpisodeHandler refresh details of an episode +func RefreshEpisodeHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error { + return EpisodeDetailsHandler(env, w, r, true) +} + +// EpisodeDetailsHandler handles details of a show +func EpisodeDetailsHandler(env *web.Env, w http.ResponseWriter, r *http.Request, force bool) error { + vars := mux.Vars(r) + id := vars["id"] + + // No need to check errors here as the router is making sure that season + // and episode are numbers + season, _ := strconv.Atoi(vars["season"]) + episode, _ := strconv.Atoi(vars["episode"]) + + v := auth.GetCurrentUser(r, env.Log) + user, ok := v.(*users.User) + if !ok { + return env.RenderError(w, errors.New("invalid user type")) + } + + s := New(id) + e, err := s.GetEpisodeDetails(env, season, episode, force) + if err != nil { + return env.RenderError(w, err) + } + + if err := e.GetTorrents(env, force); err != nil { + return env.RenderError(w, err) + } + + // Get the show from the polochon of the user + pShow, err := getPolochonShow(user, id) + if err != nil { + env.Log.Warnf("error while getting polochon episode %s S%02dE%02d : %s", id, season, episode, err) + } + // Find if the user has a the episode in its polochon to add the + // DownloadURL + for _, pEpisode := range pShow.Episodes { + if e.Season == pEpisode.Season && e.Episode == pEpisode.Episode { + e.PolochonURL = pEpisode.PolochonURL + break + } + } + + return env.RenderJSON(w, e) +} diff --git a/src/internal/shows/shows.go b/src/internal/shows/shows.go index b3473da..681d77b 100644 --- a/src/internal/shows/shows.go +++ b/src/internal/shows/shows.go @@ -332,6 +332,60 @@ func (s *Show) GetEpisodes(env *web.Env, force bool) error { return nil } +// GetEpisode from database +func (s *Show) GetEpisodeDetails(env *web.Env, seasonNb, episodeNb int, force bool) (*Episode, error) { + log := env.Log.WithFields(logrus.Fields{ + "imdb_id": s.ImdbID, + "season": seasonNb, + "episode": episodeNb, + "function": "show.GetEpisodeDetails", + }) + log.Debugf("getting episode details") + + e := NewEpisode() + e.ShowImdbID = s.ImdbID + e.Season = seasonNb + e.Episode = episodeNb + + if len(e.Detailers) == 0 { + e.Detailers = env.Config.ShowDetailers + } + + var err error + err = e.Get(env) + switch err { + case nil: + log.Debug("episode found in database") + case sql.ErrNoRows: + log.Debug("episode not found in database") + default: + // Unexpected error + return nil, err + } + // If force is not specified, don't go further + if !force { + // Will return ErrNoRows if the episode wasn't found + return e, err + } + + // GetDetail of the episode + err = e.ShowEpisode.GetDetails(env.Log) + if err != nil { + return nil, err + } + + // Upsert the episode + err = e.Upsert(env.Database) + if err != nil { + log.Debug("error while doing episode upsert func", err) + return nil, err + } + + log.Debug("episode inserted/updated in database") + + return e, nil +} + // GetTorrents from the database or fetch them if needed func (s *Show) GetTorrents(env *web.Env, force bool) error { for _, e := range s.Episodes { diff --git a/src/main.go b/src/main.go index 7106210..313a0f2 100644 --- a/src/main.go +++ b/src/main.go @@ -77,7 +77,7 @@ func main() { env.Handle("/users/edit", users.EditHandler).WithRole(users.UserRole).Methods("POST") env.Handle("/movies/polochon", movies.FromPolochon).WithRole(users.UserRole).Methods("GET") - env.Handle("/movies/{id:tt[0-9]+}/get_details", movies.GetDetailsHandler).WithRole(users.UserRole).Methods("GET") + env.Handle("/movies/{id:tt[0-9]+}/refresh", movies.GetDetailsHandler).WithRole(users.UserRole).Methods("POST") env.Handle("/movies/{id:tt[0-9]+}", movies.DeleteHandler).WithRole(users.AdminRole).Methods("DELETE") env.Handle("/movies/explore", extmedias.Explore).WithRole(users.UserRole).Methods("GET") env.Handle("/movies/refresh", extmedias.Refresh).WithRole(users.UserRole).Methods("POST") @@ -85,6 +85,7 @@ func main() { env.Handle("/shows/polochon", shows.FromPolochon).WithRole(users.UserRole).Methods("GET") env.Handle("/shows/{id:tt[0-9]+}", shows.GetDetailsHandler).WithRole(users.UserRole).Methods("GET") + env.Handle("/shows/{id:tt[0-9]+}/seasons/{season:[0-9]+}/episodes/{episode:[0-9]+}", shows.RefreshEpisodeHandler).WithRole(users.UserRole).Methods("POST") env.Handle("/shows/{id:tt[0-9]+}/refresh", shows.RefreshDetailsHandler).WithRole(users.UserRole).Methods("POST") env.Handle("/shows/refresh", extmedias.RefreshShows).WithRole(users.UserRole).Methods("POST") env.Handle("/shows/explore", extmedias.ExploreShows).WithRole(users.UserRole).Methods("GET") diff --git a/src/public/js/actions/actionCreators.js b/src/public/js/actions/actionCreators.js index 8fe7a77..1f4591d 100644 --- a/src/public/js/actions/actionCreators.js +++ b/src/public/js/actions/actionCreators.js @@ -109,7 +109,7 @@ export function searchMovies(search) { export function getMovieDetails(imdbId) { return request( 'MOVIE_GET_DETAILS', - configureAxios().get(`/movies/${imdbId}/get_details`) + configureAxios().post(`/movies/${imdbId}/refresh`) ) }