canape/backend/movies/handlers.go
Grégoire Delattre b6be9488c9
Some checks failed
continuous-integration/drone/push Build is failing
Add a page to display a movie
2021-08-22 11:33:36 -10:00

396 lines
9.8 KiB
Go

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