def post(self, userID): TokenAuthenticator(request.headers.get('Authorization')).authenticate() session = Session() is_valid_integer(userID) # User not Found if not session.query(User).filter(User.userID == userID).first(): raise NotFound cID = g.userID # Can't subscribe to oneself. if cID == userID: raise BadRequest new = set(session.query(Wishlist.movieID).filter(Wishlist.userID == userID)) cur = set(session.query(Wishlist.movieID).filter(Wishlist.userID == cID)) # Add only absent movies toAdd = new.difference(cur) if toAdd: for movie in toAdd: for m in movie: wl = Wishlist(m, cID) session.add(wl) session.commit() session.close() response = {'message': 'Wishlisted Movies imported'} return response, 201 else: response = {'message': 'No Movies were imported'} return response, 200
def post(self, id): ''' Leave a movie review ''' TokenAuthenticator(request.headers.get('Authorization')).authenticate() is_valid_integer(id) validate_rating(request.json['rating']) validate_review(request.json['review']) session = Session() movie = session.query(Movie).filter(Movie.movieID == id).one_or_none() if not movie: raise NotFound query = session.query(MovieReview).filter( MovieReview.movieID == id, MovieReview.userID == g.userID).one_or_none() if query: # We disallow a user from leaving more than one review for the same movie. raise Forbidden query = session.query(Watchlist).filter( Watchlist.movieID == id, Watchlist.userID == g.userID).one_or_none() if not query: # When a user leaves a review for a film, we add that # film to his Watchlist if it isn't there already. session.add(Watchlist(id, g.userID)) request.json['rating'] = float(request.json['rating']) session.add( MovieReview(id, g.userID, request.json['rating'], request.json['review'])) movie.ratings_sum += request.json['rating'] movie.review_count += 1 session.commit() session.close() return {'message': 'Review saved.'}, 201
def post(self): ''' Add a FilmFinder to your Banned List. ''' TokenAuthenticator(request.headers.get('Authorization')).authenticate() is_valid_integer(request.json['userID']) session = Session() query = session.query(User).filter( User.userID == request.json['userID']).one_or_none() if not query: raise NotFound query = session.query(BannedList).filter( BannedList.userID == g.userID, BannedList.bannedUserID == request.json['userID']).one_or_none() if query or g.userID == request.json['userID']: # If the FilmFinder being banned is already in the user's Banned List, # or if a user is attempting to ban himself, raise an Exception. raise Forbidden # Remove a user's subscription to a FilmFinder when banning that FilmFinder. session.query(Subscription).filter( Subscription.userID == g.userID, Subscription.subscribedUserID == request.json['userID']).delete() session.add(BannedList(g.userID, request.json['userID'])) session.commit() session.close() return {'message': 'Reviewer banned.'}, 201
def get(self): ''' View list of movies in user's Watchlist :return: ''' TokenAuthenticator(request.headers.get('Authorization')).authenticate() session = Session() userID = g.userID is_valid_integer(userID) results = session.query(Movie.movieID, Movie.title, Movie.year, Movie.ratings_sum, \ Movie.review_count).filter(Watchlist.userID == userID) \ .filter(Watchlist.movieID == Movie.movieID) movies = list() for movieID, title, year, ratings_sum, review_count in results: movies.append({ 'movieID': movieID, 'title': title, 'year': year, 'rating': str(compute(movieID, userID, ratings_sum, review_count)) }) response = {'watchlist': movies} return response, 200
def get(self): ''' View your Banned List. ''' TokenAuthenticator(request.headers.get('Authorization')).authenticate() banned_list = Session().query(User.userID, User.username)\ .join(BannedList, User.userID == BannedList.bannedUserID)\ .filter(BannedList.userID == g.userID) return [{ 'userID': userID, 'username': username } for userID, username in banned_list], 200
def delete(self, id): ''' Remove a FilmFinder from your Banned List. ''' TokenAuthenticator(request.headers.get('Authorization')).authenticate() is_valid_integer(id) session = Session() if not session.query(BannedList).filter(BannedList.userID == g.userID, BannedList.bannedUserID == id).delete(): # If the FilmFinder being unbanned is not in # the user's Banned List, raise an Exception. session.commit() raise NotFound session.commit() session.close() return {'message': 'Reviewer unbanned.'}, 200
def delete(self, movieID): ''' Removes said movie from current user's Wishlist. ''' TokenAuthenticator(request.headers.get('Authorization')).authenticate() session = Session() is_valid_integer(movieID) affectedRows = session.query(Wishlist).filter(Wishlist.movieID == movieID)\ .filter(Wishlist.userID == g.userID).delete() # When 0, it means either of movieID or userID are not present in database. if affectedRows == 0: raise NotFound else: session.commit() session.close() return 204
def get(self): ''' Search for movies by name, description, mood, genre or director. ''' TokenAuthenticator(request.headers.get('Authorization')).authenticate() args = parser.parse_args() page_size = args.get('page_size') is_valid_integer(page_size) page_index = args.get('page_index') is_valid_integer(page_index) name_keywords = validate_search_keywords(args.get('name')) description_keywords = validate_search_keywords(args.get('description')) director = validate_search_keywords(args.get('director')) genre = args.get('genre') mood = args.get('mood') if mood: genres = mood_mappings[mood] | {genre} if genre else mood_mappings[mood] else: genres = {genre} if genre else None session = Session() query = session.query(Movie.movieID, Movie.title, Movie.year, Movie.ratings_sum, Movie.review_count ).filter(Movie.title.ilike(f'%{name_keywords}%'), Movie.description.ilike(f'%{description_keywords}%') ).order_by(desc(Movie.average_rating(g.userID)), Movie.title) count = session.query(Movie.movieID).filter(Movie.title.ilike(f'%{name_keywords}%'), Movie.description.ilike(f'%{description_keywords}%') ) if director: query = query.join(FilmDirector).join(Person).filter(Person.name.ilike(f'%{director}%')).distinct() count = count.join(FilmDirector).join(Person).filter(Person.name.ilike(f'%{director}%')).distinct() if genres: query = query.join(GenreOfFilm).join(Genres).filter(Genres.genre.in_(genres)).distinct() count = count.join(GenreOfFilm).join(Genres).filter(Genres.genre.in_(genres)).distinct() banned_users = tuple(banned_user for banned_user, in session.query(BannedList.bannedUserID) .filter(BannedList.userID == g.userID) ) search_results = [{'movieID': movieID, 'title': title, 'year': year, 'rating': str(compute(movieID, g.userID, ratings_sum, review_count, banned_users)) } for movieID, title, year, ratings_sum, review_count in query.limit(page_size).offset(page_size * page_index) ] return {'data': search_results, 'count': count.count()}, 200
def get(self): ''' Show list of subscribed users ''' TokenAuthenticator(request.headers.get('Authorization')).authenticate() session = Session() results = session.query(Subscription.subscribedUserID, User.username) \ .filter(Subscription.userID == g.userID) \ .filter(User.userID == Subscription.subscribedUserID) users = list() for id, username in results: users.append({'userID': id, 'username': username}) response = {'subscribedUsers': users} return response, 200
def get(self, id): ''' View a movie's full details. ''' TokenAuthenticator(request.headers.get('Authorization')).authenticate() is_valid_integer(id) session = Session() movie = session.query(Movie.movieID, Movie.title, Movie.year, Movie.description, Movie.ratings_sum, Movie.review_count ).filter(Movie.movieID == id).one_or_none() if not movie: raise NotFound genres = [genre for genre, in session.query(Genres.genre).join(GenreOfFilm) .filter(GenreOfFilm.movieID == id) ] directors = [director for director, in session.query(Person.name) .join(FilmDirector) .filter(FilmDirector.movieID == id) ] cast = [member for member, in session.query(Person.name).join(FilmCast) .filter(FilmCast.movieID == id) ] banned_users = tuple(banned_user for banned_user, in session.query(BannedList.bannedUserID) .filter(BannedList.userID == g.userID) ) reviews = session.query(User.userID, User.username, MovieReview.rating, MovieReview.review ).join(MovieReview).filter(MovieReview.movieID == id, User.userID.notin_(banned_users) ) reviews = [{'userID': userID, 'username': username, 'rating': str(rating), 'review': review } for userID, username, rating, review in reviews ] return {'movieID': id, 'title': movie.title, 'year': movie.year, 'description': movie.description, 'genre': genres, 'director': directors, 'cast': cast, 'rating': str(compute(id, g.userID, movie.ratings_sum, movie.review_count, banned_users)), 'reviews': reviews }, 200
def post(self): ''' Adds a movie to the users' Watchlist. ''' TokenAuthenticator(request.headers.get('Authorization')).authenticate() movieID = request.json.get('movieID') is_valid_integer(movieID) new_watchlist = Watchlist(movieID, g.userID) session = Session() session.add(new_watchlist) try: session.commit() session.close() except IntegrityError: #If Watchlist already present session.rollback() raise BadRequest response = {'message': 'Movie added to Watchlist.'} return response, 201
def get(self): TokenAuthenticator(request.headers.get('Authorization')).authenticate() session = Session() cid = g.userID results = session.query(User.username, Movie.title, User.userID)\ .select_from(Subscription)\ .join(Wishlist, Wishlist.userID == Subscription.subscribedUserID)\ .join(Movie, Movie.movieID == Wishlist.movieID)\ .join(User, User.userID == Subscription.subscribedUserID)\ .filter(Subscription.userID == cid) movies = list() for username, title, userID in results: movies.append({ 'userID': userID, 'username': username, 'title': title }) response = {'movies': movies} return response, 200
def delete(self, userID): ''' Unsubscribe to said user. ''' TokenAuthenticator(request.headers.get('Authorization')).authenticate() session = Session() curUserID = g.userID # Can't subscribe to oneself. if curUserID == int(userID): raise BadRequest affectedRows = session.query(Subscription).filter(Subscription.userID == curUserID) \ .filter(Subscription.subscribedUserID == userID).delete() # When 0, it means userIDs are not present in database. if affectedRows == 0: raise NotFound else: session.commit() return 204
def post(self): ''' Subscribe to the user. ''' TokenAuthenticator(request.headers.get('Authorization')).authenticate() subscribedUserID = request.json.get('userID') curUserID = g.userID # Can't subscribe to oneself. if curUserID == int(subscribedUserID): raise BadRequest subscribe = Subscription(curUserID, subscribedUserID) session = Session() session.add(subscribe) try: session.commit() except IntegrityError: #If subscription already present session.rollback() raise BadRequest response = {'message': 'Subscribed to User'} return response, 201
def get(self, userID): ''' View said user's Wishlist of movies. ''' TokenAuthenticator(request.headers.get('Authorization')).authenticate() session = Session() is_valid_integer(userID) results = session.query(Movie.movieID, Movie.title, Movie.year, Movie.ratings_sum, \ Movie.review_count).filter(Wishlist.userID == userID)\ .filter(Wishlist.movieID == Movie.movieID) username = session.query(User.username).filter(User.userID == userID).first() if not username: raise NotFound movies = list() for movieID, title, year, ratings_sum, review_count in results: movies.append({'movieID': movieID, 'title': title, 'year': year, 'rating': str(compute(movieID, g.userID, ratings_sum, review_count)) }) # Check if current user is subscribed to said user res = session.query(Subscription).filter(Subscription.userID == g.userID) \ .filter(Subscription.subscribedUserID == userID).first() session.close() isSubscribed = False if res: isSubscribed = True response = {'username': username, 'wishlist': movies, 'isSubscribed': isSubscribed} return response, 200
def get(self, movieID): TokenAuthenticator(request.headers.get('Authorization')).authenticate() is_valid_integer(movieID) userID = g.userID args = parser.parse_args() use_genre = args.get('use_genre') use_director = args.get('use_director') topMovieIds = list() movies = list() # Need this try/except block to catch errors when calling # recommendations if dataframes haven't loaded yet. try: movie = current_app.movieDf director = current_app.dirDf genre = current_app.genDf user = current_app.userDf topMovieIds = movie_similarity_calc(movieID=movieID, userID=userID, movie=movie, director=director, genre=genre, user=user, use_genre=use_genre, use_director=use_director) session = Session() result = session.query(Movie.movieID, Movie.title, Movie.year, Movie.ratings_sum, Movie.review_count).filter( Movie.movieID.in_(topMovieIds)).all() banned_users = tuple(banned_user for banned_user, in session.query(BannedList.bannedUserID)\ .filter(BannedList.userID == userID)) for id, title, year, ratings_sum, review_count in result: movies.append({ 'movieID': id, 'title': title, 'year': year, 'rating': compute(movieID, g.userID, ratings_sum, review_count, banned_users) }) movies.sort(key=lambda film: (-film['rating'], film['title'])) except ProgrammingError as pe: print("Df hasn't loaded yet.") except Exception as e: print("Df hasn't loaded yet.") response = {'movies': movies} return response, 200