Beispiel #1
0
    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
Beispiel #2
0
 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
Beispiel #3
0
 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
Beispiel #4
0
def compute(movieID,
            userID,
            ratings_sum=None,
            review_count=None,
            banned_users=None):
    '''
    This method computes a movie's average rating, free of the influence of banned users.
    If the caller already knows the movie's ratings sum or review count, or the FilmFinders
    banned by the user, these can be passed in to make the computation more efficient.
    '''
    session = Session()
    if ratings_sum is None or review_count is None:
        query = session.query(
            Movie.ratings_sum,
            Movie.review_count).filter(Movie.movieID == movieID).one_or_none()
        ratings_sum, review_count = query if query else (0, 0)
    if banned_users is None:
        banned_users = tuple(
            banned_user
            for banned_user, in session.query(BannedList.bannedUserID).filter(
                BannedList.userID == userID))
    banned_user_ratings = session.query(MovieReview.rating)\
                                 .filter(MovieReview.movieID == movieID,
                                         MovieReview.userID.in_(banned_users)
                                        ).all()
    review_count -= len(banned_user_ratings)
    rating_times_ten = ((ratings_sum - sum(rating for rating, in banned_user_ratings)) / review_count)\
                       * 10\
                           if review_count\
                           else 0
    # This is to ensure multiples of 0.05 are always rounded up,
    # in contrast to the behaviour of Python's round() method.
    # Reference: <https://stackoverflow.com/questions/33019698/how-to-properly-round-up-half-float-numbers-in-python>
    return floor(rating_times_ten) / 10 if rating_times_ten - floor(rating_times_ten) < 0.5\
                                        else ceil(rating_times_ten) / 10
Beispiel #5
0
    def post(self):
        # Get params
        username = request.json.get('username')
        username = cleanString(username)

        yob = request.json.get('yob')

        email = request.json['email']
        email = cleanString(email)
        isValidEmail(email)

        password = request.json['password']

        session = Session()
        if session.query(User).filter(User.email == email).first():
            raise BadRequest

        hashed_password = HashGenerator(password).generate()
        new_user = User(username, email, hashed_password, yob)
        session.add(new_user)
        session.commit()
        session.close()

        response = {'message': 'Registration successful.'}
        return response, 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):
     '''
     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, 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 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 readWriteComputeUserPred():
    session = Session()
    dataset = pd.read_sql('movieReviews', session.bind)
    recoDir = 'RecSystem'
    dataDir = 'RecoData'
    location = path.join(recoDir, dataDir)
    movie_movie = pd.read_csv(path.join(location, 'movie_movie.csv'),
                              header=0)  # load the movie-movie file

    sub_dict = {
        userID: list(map(int, subscribedUserIDs.split(',')))
        for userID, subscribedUserIDs in session.query(
            Subscription.userID,
            func.group_concat(Subscription.subscribedUserID)).group_by(
                Subscription.userID)
    }

    session.close()
    return getPerdictionsOfUsers(dataset, sub_dict, movie_movie)
    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
Beispiel #13
0
    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
Beispiel #14
0
    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
Beispiel #15
0
 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 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