package movies import ( "fmt" "log" "net/http" "git.quimbo.fr/odwrtw/canape/backend/auth" "git.quimbo.fr/odwrtw/canape/backend/models" "git.quimbo.fr/odwrtw/canape/backend/subtitles" "git.quimbo.fr/odwrtw/canape/backend/web" "github.com/gorilla/mux" polochon "github.com/odwrtw/polochon/lib" "github.com/odwrtw/polochon/lib/papi" "github.com/sirupsen/logrus" ) // PolochonMoviesHandler will returns movies from Polochon func PolochonMoviesHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error { // Get the user from the request user := auth.GetCurrentUser(r, env.Log) // Get the polochon movies of the user movies, err := getPolochonMovies(user, env) if err != nil { return env.RenderError(w, err) } // Get details with the polochon Detailer for each polochon.Movies we have for _, m := range movies { // First try from the db first := []polochon.Detailer{env.Backend.Detailer} // Then try from the polochon detailer detailers := env.Config.Movie.Detailers err := m.GetAndFetch(env, first, detailers) if err != nil { env.Log.Error(err) } // Look only for torrents in db torrenters := []polochon.Torrenter{env.Backend.Torrenter} err = m.GetTorrents(env, torrenters) if err != nil { env.Log.Errorf("error while getting movie torrents : %s", err) continue } } return env.RenderJSON(w, movies) } // GetMovieHandler will return a single movie func GetMovieHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error { vars := mux.Vars(r) id := vars["id"] user := auth.GetCurrentUser(r, env.Log) client, err := user.NewPapiClient(env.Database) if err != nil { return env.RenderError(w, err) } movies, err := client.GetMovies() if err != nil { return env.RenderError(w, err) } moviesWishlist, err := models.GetMovieWishlist(env.Database, user.ID) if err != nil { return env.RenderError(w, err) } pMovie, _ := movies.Has(id) movie := New( id, client, pMovie, moviesWishlist.IsMovieInWishlist(id), ) detailers := []polochon.Detailer{env.Backend.Detailer} err = movie.GetDetails(env, detailers) if err != nil { return env.RenderError(w, err) } torrenters := []polochon.Torrenter{env.Backend.Torrenter} err = movie.GetTorrents(env, torrenters) if err != nil { env.Log.Errorf("error while getting movie torrents : %s", err) } return env.RenderJSON(w, movie) } // RefreshMovieHandler refreshes details for a movie func RefreshMovieHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error { vars := mux.Vars(r) id := vars["id"] // Get the user user := auth.GetCurrentUser(r, env.Log) // Create a new papi client client, err := user.NewPapiClient(env.Database) if err != nil { return env.RenderError(w, err) } // Get the polochon movie pMovie, err := client.GetMovie(id) if err != nil && err != papi.ErrResourceNotFound { log.Println("Error getting movie ", err) } // Check if the movie is wishlisted isWishlisted, err := models.IsMovieWishlisted(env.Database, user.ID, id) if err != nil { log.Println("Error getting wishlisted movie ", err) } // Create a new movie m := New(id, client, pMovie, isWishlisted) // Refresh the movie's infos if err := m.Refresh(env, env.Config.Movie.Detailers); err != nil { env.Log.Error(err) } // Refresh the movie's torrents if err := m.RefreshTorrents(env, env.Config.Movie.Torrenters); err != nil { env.Log.Error(err) } // Get everything from DB again detailers := []polochon.Detailer{env.Backend.Detailer} err = m.GetDetails(env, detailers) if err != nil { return env.RenderError(w, err) } return env.RenderJSON(w, m) } // SearchMovie will search movie func SearchMovie(env *web.Env, w http.ResponseWriter, r *http.Request) error { vars := mux.Vars(r) search := vars["search"] user := auth.GetCurrentUser(r, env.Log) // Create a new papi client client, err := user.NewPapiClient(env.Database) if err != nil { return env.RenderError(w, err) } // Get the user's polochon movies pMovies, err := client.GetMovies() if err != nil { return env.RenderError(w, err) } // Get the user's wishlisted movies moviesWishlist, err := models.GetMovieWishlist(env.Database, user.ID) if err != nil { return env.RenderError(w, err) } var movies []*polochon.Movie searchers := env.Config.Movie.Searchers // Search for the movie with all the Searchers for _, searcher := range searchers { result, err := searcher.SearchMovie(search, env.Log) if err != nil { env.Log.Errorf("error while searching movie : %s", err) continue } movies = append(movies, result...) } env.Log.Debugf("got %d movies doing search %q", len(movies), search) movieList := []*Movie{} // For each movie found, fill the details for _, m := range movies { pMovie, _ := pMovies.Has(m.ImdbID) movie := New( m.ImdbID, client, pMovie, moviesWishlist.IsMovieInWishlist(m.ImdbID), ) // First check in the DB before := []polochon.Detailer{env.Backend.Detailer} // Then with the default detailers after := env.Config.Movie.Detailers err := movie.GetAndFetch(env, before, after) if err != nil { env.Log.Errorf("error while getting movie details : %s", err) continue } // Look only for torrents in db torrenters := []polochon.Torrenter{env.Backend.Torrenter} err = movie.GetTorrents(env, torrenters) if err != nil { env.Log.Errorf("error while getting movie torrents : %s", err) continue } movieList = append(movieList, movie) } return env.RenderJSON(w, movieList) } // PolochonDeleteHandler deletes the movie from polochon func PolochonDeleteHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error { vars := mux.Vars(r) id := vars["id"] log := env.Log.WithFields(logrus.Fields{ "imdb_id": id, "function": "movies.DeleteHandler", }) log.Debugf("deleting movie") // Get the user user := auth.GetCurrentUser(r, env.Log) // Create a new papi client client, err := user.NewPapiClient(env.Database) if err != nil { return env.RenderError(w, err) } // Delete the movie return client.Delete(&papi.Movie{Movie: &polochon.Movie{ImdbID: id}}) } // AddToWishlist adds a movie to the user's wishlist func AddToWishlist(env *web.Env, w http.ResponseWriter, r *http.Request) error { vars := mux.Vars(r) id := vars["id"] user := auth.GetCurrentUser(r, env.Log) if err := models.AddMovieToWishlist(env.Database, user.ID, id); err != nil { return env.RenderError(w, err) } return env.RenderOK(w, "Movie added to wishlist") } // DeleteFromWishlist deletes a movie from the user's wishlist func DeleteFromWishlist(env *web.Env, w http.ResponseWriter, r *http.Request) error { vars := mux.Vars(r) id := vars["id"] user := auth.GetCurrentUser(r, env.Log) if err := models.DeleteMovieFromWishlist(env.Database, user.ID, id); err != nil { return env.RenderError(w, err) } return env.RenderOK(w, "Movie deleted from wishlist") } // GetWishlistHandler returns the wishlisted movies of a user func GetWishlistHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error { user := auth.GetCurrentUser(r, env.Log) // Create a new papi client client, err := user.NewPapiClient(env.Database) if err != nil { return env.RenderError(w, err) } // Get the user's polochon movies pMovies, err := client.GetMovies() if err != nil { return env.RenderError(w, err) } // Get the user's wishlisted movies moviesWishlist, err := models.GetMovieWishlist(env.Database, user.ID) if err != nil { return env.RenderError(w, err) } movieList := []*Movie{} // For each movie found, fill the details for _, imdbID := range moviesWishlist.List() { pMovie, _ := pMovies.Has(imdbID) movie := New( imdbID, client, pMovie, moviesWishlist.IsMovieInWishlist(imdbID), ) // First check in the DB before := []polochon.Detailer{env.Backend.Detailer} // Then with the default detailers after := env.Config.Movie.Detailers err := movie.GetAndFetch(env, before, after) if err != nil { env.Log.Errorf("error while getting movie details : %s", err) continue } // Look only for torrents in db torrenters := []polochon.Torrenter{env.Backend.Torrenter} err = movie.GetTorrents(env, torrenters) if err != nil { env.Log.Errorf("error while getting movie torrents : %s", err) continue } movieList = append(movieList, movie) } return env.RenderJSON(w, movieList) } // RefreshMovieSubtitlesHandler refreshes details for a movie func RefreshMovieSubtitlesHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error { vars := mux.Vars(r) id := vars["id"] lang := polochon.Language(vars["lang"]) // Get the user user := auth.GetCurrentUser(r, env.Log) // Create a new papi client client, err := user.NewPapiClient(env.Database) if err != nil { return env.RenderError(w, err) } movie := &papi.Movie{Movie: &polochon.Movie{ImdbID: id}} sub, err := client.UpdateSubtitle(movie, lang) if err != nil { return env.RenderError(w, err) } // TODO: handle this with a better error if sub == nil { return env.RenderJSON(w, nil) } url, err := client.DownloadURLWithToken(sub) if err != nil { return env.RenderError(w, err) } s := &subtitles.Subtitle{ Subtitle: sub.Subtitle, URL: url, VVTFile: fmt.Sprintf("/movies/%s/subtitles/%s", id, sub.Lang), } return env.RenderJSON(w, s) } // DownloadVVTSubtitle returns a vvt subtitle for the movie func DownloadVVTSubtitle(env *web.Env, w http.ResponseWriter, r *http.Request) error { vars := mux.Vars(r) id := vars["id"] lang := polochon.Language(vars["lang"]) // Get the user user := auth.GetCurrentUser(r, env.Log) // Create a new papi client client, err := user.NewPapiClient(env.Database) if err != nil { return env.RenderError(w, err) } s := &papi.Subtitle{ Subtitle: &polochon.Subtitle{ Video: &papi.Movie{Movie: &polochon.Movie{ImdbID: id}}, Lang: lang, }, } url, err := client.DownloadURLWithToken(s) if err != nil { return env.RenderError(w, err) } return subtitles.ConvertSubtitle(url, w) }