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`) ) }