Example #1
0
 def entry_point():
     """
     Returns Mason with the controls:
     - revmusic:reviews-all
     - revmusic:albums-all
     - revmusic:users-all
     """
     body = RevMusicBuilder()
     body.add_namespace('revmusic', LINK_RELATIONS_URL)
     body.add_control_reviews_all()
     body.add_control_albums_all()
     body.add_control_users_all()
     return Response(json.dumps(body), 200, mimetype=MASON)
Example #2
0
    def get(self, user):
        """
        Responds to GET request with the representation of the requested user item (JSON document with added hypermedia controls (MASON))
        If the requested user does not exist in the API, 404 error code returned.
        : param str user: the username of the requested user, provided in the request URL
        """
        # Fetch the requested user from the database and check that it exists
        db_user = User.query.filter_by(username=user).first()
        if not db_user:
            return create_error_response(404, 'User not found')

        body = RevMusicBuilder(username=db_user.username, email=db_user.email)
        body.add_namespace('revmusic', LINK_RELATIONS_URL)
        body.add_control('self', url_for('api.useritem',
                                         user=db_user.username))
        body.add_control('profile', USER_PROFILE)
        body.add_control_users_all('collection')
        body.add_control_reviews_by(user)
        body.add_control_edit_user(user)
        body.add_control_delete_user(user)
        return Response(json.dumps(body), 200, mimetype=MASON)
Example #3
0
    def get(self):
        """
        Responds to GET request with a listing of all user items known to the API (JSON document with added hypermedia controls (MASON))
        """
        body = RevMusicBuilder()
        body.add_namespace('revmusic', LINK_RELATIONS_URL)
        body.add_control_users_all('self')
        body.add_control_reviews_all()
        body.add_control_albums_all()
        body.add_control_add_user()

        body['items'] = []
        for user in User.query.all():
            item = RevMusicBuilder(username=user.username)
            item.add_control('self', url_for('api.useritem',
                                             user=user.username))
            item.add_control('profile', USER_PROFILE)
            body['items'].append(item)

        return Response(json.dumps(body), 200, mimetype=MASON)
Example #4
0
    def get(self):
        """
        Responds to GET request with a listing of all album items known to the API (JSON document with added hypermedia controls (MASON))
        """
        body = RevMusicBuilder()
        body.add_namespace('revmusic', LINK_RELATIONS_URL)
        body.add_control('self', url_for('api.albumcollection'))
        body.add_control_users_all()
        body.add_control_reviews_all()
        body.add_control_add_album()

        body['items'] = []
        for album in Album.query.all():
            item = RevMusicBuilder(unique_name=album.unique_name,
                                   title=album.title,
                                   artist=album.artist,
                                   genre=album.genre)
            item.add_control('self',
                             url_for('api.albumitem', album=album.unique_name))
            item.add_control('profile', ALBUM_PROFILE)
            body['items'].append(item)

        return Response(json.dumps(body), 200, mimetype=MASON)
Example #5
0
    def get(self, album):
        """
        Responds to GET request with the information of the requested album item (JSON document with added hypermedia controls (MASON))
        If requested album does not exist in the API, 404 error code returned.
        : param str album: the unique name of the requested album, provided in the request URL
        """
        # Fetch requested album item from database and check that it exists
        album_item = Album.query.filter_by(unique_name=album).first()
        if not album_item:
            return create_error_response(404, 'Album not found')

        # Handle optional data (date and time objects to string, if exists)
        release = album_item.publication_date
        duration = album_item.duration
        if release:
            release = release.strftime('%Y-%m-%d')
        if duration:
            duration = duration.strftime('%H:%M:%S')

        body = RevMusicBuilder(unique_name=album,
                               title=album_item.title,
                               artist=album_item.artist,
                               release=release,
                               duration=duration,
                               genre=album_item.genre)
        body.add_namespace('revmusic', LINK_RELATIONS_URL)
        body.add_control('self', url_for('api.albumitem', album=album))
        body.add_control('profile', ALBUM_PROFILE)
        body.add_control('collection',
                         url_for('api.albumcollection'),
                         title='All albums')
        body.add_control_reviews_for(album)
        body.add_control_edit_album(album)
        body.add_control_delete_album(album)

        return Response(json.dumps(body), 200, mimetype=MASON)
Example #6
0
    def get(self, album, review):
        """
        Responds to GET request with the representation of the requested review item (JSON document with added hypermedia controls (MASON))
        If the requested review or the album for which the review should have been submitted does not exist in the API, 404 error code returned.
        : param str album: the unique name of the album for which the requested review have been submitted, provided in the request URL
        : param str review: the identifier of the requested review, provided in the request URL
        """
        # Fetch the album and review items from the database and check if they exist
        album_item = Album.query.filter_by(unique_name=album).first()
        if not album_item:
            return create_error_response(404, 'Album not found')
        review_item = Review.query.filter(Review.identifier == review).filter(
            Review.album == album_item).first()
        if not review_item:
            return create_error_response(404, 'Review not found')

        # Create response
        user = review_item.user.username
        body = RevMusicBuilder(identifier=review,
                               user=user,
                               album=album_item.title,
                               artist=album_item.artist,
                               title=review_item.title,
                               content=review_item.content,
                               star_rating=review_item.star_rating,
                               submission_date=datetime.datetime.strftime(
                                   review_item.submission_date,
                                   '%Y-%m-%d %H:%M:%S'))
        body.add_namespace('revmusic', LINK_RELATIONS_URL)
        body.add_control('self',
                         url_for('api.reviewitem', album=album, review=review))
        body.add_control('profile', REVIEW_PROFILE)
        body.add_control('author',
                         url_for('api.useritem', user=user),
                         title='The user who has submitted the review')
        body.add_control(
            'about',
            url_for('api.albumitem', album=album),
            title='The album for which the review has been written')
        body.add_control_reviews_by(user)
        body.add_control_reviews_for(album)
        body.add_control_reviews_all()
        body.add_control_edit_review(album, review)
        body.add_control_delete_review(album, review)

        return Response(json.dumps(body), 200, mimetype=MASON)
Example #7
0
    def get(self):
        """
        Responds to GET request with a listing of review items known to the API (JSON document with added hypermedia controls (MASON))
        Query parameters in the request URL can be used to filter the returned reviews.
        """
        body = RevMusicBuilder()
        body.add_namespace('revmusic', LINK_RELATIONS_URL)
        body.add_control_reviews_all('self')
        body.add_control_users_all()
        body.add_control_albums_all()

        # Obtain query parameters sent by user
        args = self.parse.parse_args()
        reviews = []
        foreign_keys = []
        timeframe = []
        nlatest = args['nlatest']  # None or int

        if args['timeframe'] is not None:
            try:
                temp = args['timeframe'].split('_')
                if not temp[0][4:].isnumeric() or not temp[0][2:4].isnumeric(
                ) or not temp[0][0:2].isnumeric():
                    return create_error_response(415,
                                                 'Incorrect timeframe format')
                try:
                    datetime.date(int(temp[0][4:]), int(temp[0][2:4]),
                                  int(temp[0][0:2]))
                except ValueError:
                    return create_error_response(415,
                                                 'Incorrect timeframe format')
                timeframe.append('{}-{}-{}'.format(temp[0][4:], temp[0][2:4],
                                                   temp[0][0:2]))
                # Check for possible second time
                if len(temp) is 2:
                    if not temp[1][4:].isnumeric() or not temp[1][
                            2:4].isnumeric() or not temp[1][0:2].isnumeric():
                        return create_error_response(
                            415, 'Incorrect timeframe format')
                    try:
                        datetime.date(int(temp[1][4:]), int(temp[1][2:4]),
                                      int(temp[1][0:2]))
                    except ValueError:
                        return create_error_response(
                            415, 'Incorrect timeframe format')
                    timeframe.append('{}-{}-{}'.format(temp[1][4:],
                                                       temp[1][2:4],
                                                       temp[1][0:2]))
                # Make sure no more than 2 timeframes were provided
                if len(temp) > 2:
                    raise Exception('More than two timeframe parameters')
            except Exception as e:
                # Return an error if an exception occurred
                return create_error_response(
                    415, 'Incorrect timeframe format',
                    'You provided an incorrect timeframe format. Please fix that >:( {}'
                    .format(e))

        # Error handling for nlatest is implemented by flask, since the type has been set to int

        # Handle filtering
        if not args['searchword']:
            # No searchword
            if len(timeframe) < 1:
                # No timeframe provided, return all or nlatest
                reviews = Review.query.order_by(
                    Review.submission_date.desc()).limit(nlatest).all()
            elif len(timeframe) == 1:
                # One time provided, return all or nlatest after that
                reviews = Review.query.filter(func.date(Review.submission_date) >= timeframe[0])\
                    .order_by(Review.submission_date.desc()).limit(nlatest).all()
            else:
                # Two times provided, return all or nlatest between them
                reviews = Review.query.filter(func.date(Review.submission_date) >= timeframe[0])\
                    .filter(func.date(Review.submission_date) <= timeframe[1]).order_by(Review.submission_date.desc()).limit(nlatest).all()

        else:
            # Handle filtering
            if args['filterby'] == 'album':
                foreign_keys = Album.query.filter(
                    Album.title.contains(args['searchword'])).all()
            elif args['filterby'] == 'artist':
                foreign_keys = Album.query.filter(
                    Album.artist.contains(args['searchword'])).all()
            elif args['filterby'] == 'genre':
                foreign_keys = Album.query.filter(
                    Album.genre.contains(args['searchword'])).all()
            else:  # Filter by users
                foreign_keys = User.query.filter(
                    User.username.contains(args['searchword'])).all()

            if len(timeframe) < 1:
                reviews = Review.query.filter(
                    Review.album_id.in_([
                        fk.id for fk in foreign_keys
                    ])).order_by(
                        Review.submission_date.desc()).limit(nlatest).all()
            elif len(timeframe) == 1:
                reviews = Review.query.filter(Review.album_id.in_([fk.id for fk in foreign_keys])).filter(func.date(Review.submission_date) >= timeframe[0])\
                    .order_by(Review.submission_date.desc()).limit(nlatest).all()
            else:
                reviews = Review.query.filter(Review.album_id.in_([fk.id for fk in foreign_keys])).filter(func.date(Review.submission_date) >= timeframe[0])\
                    .filter(func.date(Review.submission_date) <= timeframe[1]).order_by(Review.submission_date.desc()).limit(nlatest).all()

        body['items'] = []
        for review in reviews:
            item = RevMusicBuilder(identifier=review.identifier,
                                   user=review.user.username,
                                   album=review.album.title,
                                   title=review.title,
                                   star_rating=review.star_rating,
                                   submission_date=datetime.datetime.strftime(
                                       review.submission_date,
                                       '%Y-%m-%d %H:%M:%S'))
            item.add_control(
                'self',
                url_for('api.reviewitem',
                        album=review.album.unique_name,
                        review=review.identifier))
            item.add_control('profile', REVIEW_PROFILE)
            body['items'].append(item)
        return Response(json.dumps(body), 200, mimetype=MASON)
Example #8
0
    def get(self, user):
        """
        Responds to GET request with a listing of all reviews submitted by the specified user (JSON document with added hypermedia controls (MASON))
        If the specified user does not exist in the API, 404 error code returned.
        : param str user: the username of the user whose reviews are requested, provided in the request URL
        """
        # Fetch the user item from the database and check if it exists
        user_item = User.query.filter_by(username=user).first()
        if not user_item:
            return create_error_response(404, 'User not found')

        body = RevMusicBuilder()
        body.add_namespace('revmusic', LINK_RELATIONS_URL)
        body.add_control('self', url_for('api.reviewsbyuser', user=user))
        body.add_control('up',
                         url_for('api.useritem', user=user),
                         title='User by whom the reviews have been submitted')
        body.add_control_reviews_all()

        # Fetch the reviews from the database submitted by the specified user
        reviews = Review.query.filter(Review.user == user_item).order_by(
            Review.submission_date.desc()).all()
        body['items'] = []
        for review in reviews:
            item = RevMusicBuilder(identifier=review.identifier,
                                   album=review.album.title,
                                   title=review.title,
                                   star_rating=review.star_rating,
                                   submission_date=datetime.datetime.strftime(
                                       review.submission_date,
                                       '%Y-%m-%d %H:%M:%S'))
            item.add_control(
                'self',
                url_for('api.reviewitem',
                        album=review.album.unique_name,
                        review=review.identifier))
            item.add_control('profile', REVIEW_PROFILE)
            body['items'].append(item)

        return Response(json.dumps(body), 200, mimetype=MASON)