diff --git a/handler/movie_search.go b/handler/movie_search.go new file mode 100644 index 0000000..bb19b11 --- /dev/null +++ b/handler/movie_search.go @@ -0,0 +1,41 @@ +package handler + +import ( + "net/http" + "projectreshoot/config" + "projectreshoot/tmdb" + "projectreshoot/view/component/search" + "projectreshoot/view/page" + + "github.com/rs/zerolog" +) + +func SearchMovies( + logger *zerolog.Logger, + config *config.Config, +) http.Handler { + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + query := r.FormValue("search") + if query == "" { + w.WriteHeader(http.StatusOK) + return + } + movies, err := tmdb.SearchMovies(config.TMDBToken, query, false, 1) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + search.MovieResults(movies, &config.TMDBConfig.Image).Render(r.Context(), w) + }, + ) +} + +func MoviesPage() http.Handler { + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + page.Movies().Render(r.Context(), w) + }, + ) +} diff --git a/server/routes.go b/server/routes.go index 66b3a05..e99fd46 100644 --- a/server/routes.go +++ b/server/routes.go @@ -61,6 +61,10 @@ func addRoutes( route("POST /change-bio", loggedIn(handler.ChangeBio(logger, conn))) route("POST /change-password", loggedIn(fresh(handler.ChangePassword(logger, conn)))) + // Movies Search + route("GET /movies", handler.MoviesPage()) + route("POST /search-movies", handler.SearchMovies(logger, config)) + // Movie page route("GET /movie/{movie_id}", handler.Movie(logger, config)) } diff --git a/tmdb/movie_functions.go b/tmdb/movie_functions.go index a73f3bf..ebfa679 100644 --- a/tmdb/movie_functions.go +++ b/tmdb/movie_functions.go @@ -23,7 +23,11 @@ func (movie *Movie) GetPoster(image *Image, size string) string { } func (movie *Movie) ReleaseYear() string { - return movie.ReleaseDate[:4] + if movie.ReleaseDate == "" { + return "" + } else { + return "(" + movie.ReleaseDate[:4] + ")" + } } func (movie *Movie) FGenres() string { @@ -31,5 +35,8 @@ func (movie *Movie) FGenres() string { for _, genre := range movie.Genres { genres += genre.Name + ", " } - return genres[:len(genres)-2] + if len(genres) > 2 { + return genres[:len(genres)-2] + } + return genres } diff --git a/tmdb/search.go b/tmdb/search.go index 9ce77bd..701ff04 100644 --- a/tmdb/search.go +++ b/tmdb/search.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/url" + "path" "github.com/pkg/errors" ) @@ -16,23 +17,51 @@ type Result struct { type ResultMovies struct { Result - Results []struct { - Adult bool `json:"adult"` - BackdropPath string `json:"backdrop_path"` - GenreIDs []int `json:"genre_ids"` - ID int32 `json:"id"` - OriginalLanguage string `json:"original_language"` - OriginalTitle string `json:"original_title"` - Overview string `json:"overview"` - Popularity int `json:"popularity"` - PosterPath string `json:"poster_path"` - ReleaseDate string `json:"release_date"` - Title string `json:"title"` - Video bool `json:"video"` - VoteAverage int `json:"vote_average"` - VoteCount int `json:"vote_count"` - } `json:"results"` + Results []ResultMovie `json:"results"` } +type ResultMovie struct { + Adult bool `json:"adult"` + BackdropPath string `json:"backdrop_path"` + GenreIDs []int `json:"genre_ids"` + ID int32 `json:"id"` + OriginalLanguage string `json:"original_language"` + OriginalTitle string `json:"original_title"` + Overview string `json:"overview"` + Popularity int `json:"popularity"` + PosterPath string `json:"poster_path"` + ReleaseDate string `json:"release_date"` + Title string `json:"title"` + Video bool `json:"video"` + VoteAverage int `json:"vote_average"` + VoteCount int `json:"vote_count"` +} + +func (movie *ResultMovie) GetPoster(image *Image, size string) string { + base, err := url.Parse(image.SecureBaseURL) + if err != nil { + return "" + } + fullPath := path.Join(base.Path, size, movie.PosterPath) + base.Path = fullPath + return base.String() +} + +func (movie *ResultMovie) ReleaseYear() string { + if movie.ReleaseDate == "" { + return "" + } else { + return "(" + movie.ReleaseDate[:4] + ")" + } +} + +// TODO: genres list https://developer.themoviedb.org/reference/genre-movie-list +// func (movie *ResultMovie) FGenres() string { +// genres := "" +// for _, genre := range movie.Genres { +// genres += genre.Name + ", " +// } +// return genres[:len(genres)-2] +// } func SearchMovies(token string, query string, adult bool, page int) (*ResultMovies, error) { url := "https://api.themoviedb.org/3/search/movie" + diff --git a/view/component/search/movies_results.templ b/view/component/search/movies_results.templ new file mode 100644 index 0000000..396a6fa --- /dev/null +++ b/view/component/search/movies_results.templ @@ -0,0 +1,44 @@ +package search + +import "projectreshoot/tmdb" +import "fmt" + +templ MovieResults(movies *tmdb.ResultMovies, image *tmdb.Image) { + for _, movie := range movies.Results { +
+ Movie Poster + +
+ { movie.Title } { movie.ReleaseYear() } +

+ Released: + { movie.ReleaseDate } +

+

+ Original Title: + { movie.OriginalTitle } +

+

{ movie.Overview }

+
+
+ } +} diff --git a/view/page/movie_search.templ b/view/page/movie_search.templ new file mode 100644 index 0000000..534a146 --- /dev/null +++ b/view/page/movie_search.templ @@ -0,0 +1,31 @@ +package page + +import "projectreshoot/view/layout" + +templ Movies() { + @layout.Global() { +
+
+
+ + +
+
+
+
+ } +}