canape/src/internal/movies/handlers.go

194 lines
4.5 KiB
Go

package movies
import (
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
"net/url"
"github.com/gorilla/mux"
"github.com/odwrtw/papi"
polochon "github.com/odwrtw/polochon/lib"
"github.com/odwrtw/polochon/modules/pam"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/auth"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/config"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/users"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/web"
)
// ErrPolochonUnavailable is an error returned if the polochon server is not available
var ErrPolochonUnavailable = fmt.Errorf("Invalid polochon address")
func getPolochonMovies(user *users.User) ([]*Movie, error) {
movies := []*Movie{}
var polochonConfig config.UserPolochon
err := user.GetConfig("polochon", &polochonConfig)
if err != nil {
return movies, err
}
client, err := papi.New(polochonConfig.URL)
if err != nil {
return movies, err
}
if polochonConfig.Token != "" {
client.SetToken(polochonConfig.Token)
}
pmovies, err := client.GetMovies()
if err != nil {
// Catch network error for accessing specified polochon address
if uerr, ok := err.(*url.Error); ok {
if nerr, ok := uerr.Err.(*net.OpError); ok {
if nerr.Op == "dial" {
return movies, ErrPolochonUnavailable
}
}
}
return movies, err
}
for _, pmovie := range pmovies {
movie := New(pmovie.ImdbID)
movie.PolochonURL, err = client.DownloadURL(&papi.Movie{ImdbID: movie.ImdbID})
if err != nil {
return nil, err
}
movies = append(movies, movie)
}
return movies, nil
}
// GetPolochonMoviesURLs returns the polochon urls associated with an imdb id
func GetPolochonMoviesURLs(user *users.User) (map[string]string, error) {
movies, err := getPolochonMovies(user)
if err != nil {
return nil, err
}
urls := make(map[string]string, len(movies))
for _, movie := range movies {
urls[movie.ImdbID] = movie.PolochonURL
}
return urls, nil
}
// FromPolochon will returns movies from Polochon
func FromPolochon(env *web.Env, w http.ResponseWriter, r *http.Request) error {
v := auth.GetCurrentUser(r, env.Log)
user, ok := v.(*users.User)
if !ok {
return fmt.Errorf("invalid user type")
}
movies, err := getPolochonMovies(user)
if err != nil {
return env.RenderError(w, err)
}
var polochonConfig config.UserPolochon
err = user.GetConfig("polochon", &polochonConfig)
if err != nil {
return err
}
detailer, err := pam.New(&pam.Params{
Endpoint: polochonConfig.URL,
Token: polochonConfig.Token,
})
for _, m := range movies {
m.Detailers = []polochon.Detailer{detailer}
err := m.GetDetails(env, false)
if err != nil {
env.Log.Error(err)
}
}
return env.RenderJSON(w, movies)
}
// GetDetailsHandler retrieves details for a movie
func GetDetailsHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
id := vars["id"]
m := New(id)
if err := m.GetDetails(env, true); err != nil {
return err
}
return env.RenderJSON(w, m)
}
// SearchMovie will search movie
func SearchMovie(env *web.Env, w http.ResponseWriter, r *http.Request) error {
var data struct {
Key string `json:"key"`
}
err := json.NewDecoder(r.Body).Decode(&data)
if err != nil {
return env.RenderError(w, errors.New("failed to get the search key"))
}
if data.Key == "" {
return env.RenderError(w, errors.New("no given key"))
}
v := auth.GetCurrentUser(r, env.Log)
user, ok := v.(*users.User)
if !ok {
return env.RenderError(w, errors.New("invalid user"))
}
var movies []*polochon.Movie
searchers := env.Config.MovieSearchers
for _, searcher := range searchers {
result, err := searcher.SearchMovie(data.Key, env.Log)
if err != nil {
env.Log.Errorf("error while searching movie : %s", err)
continue
}
movies = append(movies, result...)
}
// Get the URLs from polochon, we don't really care if it fails for now
var urls map[string]string
urls, err = GetPolochonMoviesURLs(user)
if err != nil {
env.Log.Errorf("error while getting polochon movies url: %s", err)
}
env.Log.Debugf("got %d movies doing search %q", len(movies), data.Key)
movieList := []*Movie{}
for _, m := range movies {
movie := New(m.ImdbID)
err := movie.GetDetails(env, false)
if err != nil {
env.Log.Errorf("error while getting movie details : %s", err)
continue
}
err = movie.GetTorrents(env, false)
if err != nil {
env.Log.Errorf("error while getting movie torrents : %s", err)
continue
}
if urls != nil {
if url, ok := urls[m.ImdbID]; ok {
movie.PolochonURL = url
}
}
movieList = append(movieList, movie)
}
return env.RenderJSON(w, movieList)
}