Add movie search

This commit is contained in:
Grégoire Delattre 2017-01-06 22:01:04 +01:00
parent 9d55743720
commit 74b2f351bd
7 changed files with 72 additions and 7 deletions

View File

@ -1,6 +1,7 @@
package movies
import (
"encoding/json"
"errors"
"fmt"
"net"
@ -113,15 +114,21 @@ func GetDetailsHandler(env *web.Env, w http.ResponseWriter, r *http.Request) err
// SearchMovie will search movie
func SearchMovie(env *web.Env, w http.ResponseWriter, r *http.Request) error {
key := r.FormValue("key")
if key == "" {
var data struct {
Key string `json:"key"`
}
if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
return err
}
if data.Key == "" {
return env.RenderError(w, errors.New("no given key"))
}
var movies []*polochon.Movie
searchers := env.Config.MovieSearchers
for _, searcher := range searchers {
result, err := searcher.SearchMovie(key, env.Log)
result, err := searcher.SearchMovie(data.Key, env.Log)
if err != nil {
env.Log.Errorf("error while searching movie : %s", err)
continue
@ -129,7 +136,7 @@ func SearchMovie(env *web.Env, w http.ResponseWriter, r *http.Request) error {
movies = append(movies, result...)
}
env.Log.Debugf("got %d movies doing search %q", len(movies), key)
env.Log.Debugf("got %d movies doing search %q", len(movies), data.Key)
movieList := []*Movie{}
for _, m := range movies {
movie := New(m.ImdbID)

View File

@ -80,7 +80,7 @@ func main() {
env.Handle("/movies/{id:tt[0-9]+}/get_details", movies.GetDetailsHandler).WithRole(users.UserRole)
env.Handle("/movies/explore", extmedias.Explore)
env.Handle("/movies/refresh", extmedias.Refresh)
env.Handle("/movies/search", movies.SearchMovie)
env.Handle("/movies/search", movies.SearchMovie).Methods("POST")
// env.Handle("/shows/polochon", shows.FromPolochon).WithRole(users.UserRole)
env.Handle("/shows/{id:tt[0-9]+}", shows.GetDetailsHandler)

View File

@ -80,6 +80,13 @@ export function selectMovie(imdbId) {
}
}
export function searchMovies(search) {
return request(
'SEARCH_MOVIES',
configureAxios().post('/movies/search', search)
)
}
export function getMovieDetails(imdbId) {
return request(
'MOVIE_GET_DETAILS',

View File

@ -83,6 +83,9 @@ const MovieListPopular = (props) => (
const MovieListPolochon = (props) => (
<MovieList {...props} moviesUrl='/movies/polochon'/>
)
const MovieListSearch = (props) => (
<MovieList {...props} />
)
const ShowListPopular = (props) => (
<ShowList {...props} showsUrl='/shows/explore'/>
@ -100,6 +103,7 @@ ReactDOM.render((
<Route path="/users/login" component={UserLoginForm} />
<Route path="/users/signup" component={UserSignUp} />
<Route path="/users/edit" component={UserIsAuthenticated(UserEdit)} />
<Route path="/movies/search/:search" component={UserIsAuthenticated(MovieListSearch)} />
<Route path="/movies/popular" component={UserIsAuthenticated(MovieListPopular)} />
<Route path="/movies/polochon(/:page)" component={UserIsAuthenticated(MovieListPolochon)} />
<Route path="/shows/popular" component={UserIsAuthenticated(ShowListPopular)} />

View File

@ -53,7 +53,24 @@ class MovieButtons extends React.Component {
export default class MovieList extends React.Component {
componentWillMount() {
this.props.fetchMovies(this.props.moviesUrl);
if (this.props.moviesUrl) {
this.props.fetchMovies(this.props.moviesUrl);
} else if (this.props.params && this.props.params.search != "") {
this.props.searchMovies({
key: this.props.params.search
});
}
}
componentWillUpdate(nextProps, nextState) {
if (!nextProps.params || nextProps.params.search === "") {
return
}
if (this.props.params.search === nextProps.params.search) {
return
}
this.props.searchMovies({
key: nextProps.params.search
});
}
render() {
const movies = this.props.movieStore.movies;

View File

@ -1,15 +1,28 @@
import React from 'react'
import { Link } from 'react-router'
import { store } from '../store'
import { isUserLoggedIn } from '../actions/actionCreators'
import { Nav, Navbar, NavItem, NavDropdown, MenuItem } from 'react-bootstrap'
import { LinkContainer } from 'react-router-bootstrap'
import { Control, Form } from 'react-redux-form';
export default class NavBar extends React.Component {
constructor(props) {
super(props);
this.handleMovieSearch = this.handleMovieSearch.bind(this);
}
handleMovieSearch() {
this.props.router.push(`/movies/search/${encodeURI(this.props.movieStore.search)}`)
}
render() {
const username = this.props.userStore.username;
const isLoggedIn = username !== "" ? true : false;
const location = this.props.router.getCurrentLocation().pathname;
let displayMovieSearch = false;
if (isLoggedIn && location.indexOf("movies") > -1)
{
displayMovieSearch = true;
}
return (
<div>
<Navbar fluid fixedTop collapseOnSelect>
@ -53,6 +66,18 @@ export default class NavBar extends React.Component {
</NavDropdown>
}
</Nav>
{displayMovieSearch &&
<Navbar.Form pullRight>
<Form model="movieStore" className="input-group" onSubmit={() => this.handleMovieSearch()}>
<Control.text
model="movieStore.search"
className="form-control"
placeholder="Search"
updateOn="change"
/>
</Form>
</Navbar.Form>
}
</Navbar.Collapse>
</Navbar>
</div>

View File

@ -4,6 +4,7 @@ const defaultState = {
perPage: 30,
selectedImdbId: "",
fetchingDetails: false,
search: "",
};
export default function movieStore(state = defaultState, action) {
@ -18,6 +19,10 @@ export default function movieStore(state = defaultState, action) {
movies: action.payload.data,
selectedImdbId: selectedImdbId,
})
case 'SEARCH_MOVIES_FULFILLED':
return Object.assign({}, state, {
movies: action.payload.data,
})
case 'MOVIE_GET_DETAILS_PENDING':
return Object.assign({}, state, {
fetchingDetails: true,