Пример #1
0
    def get(self, album):
        """
        Responds to GET request with a listing of all reviews for the specified album (JSON document with added hypermedia controls (MASON))
        If the specified album does not exist in the API, 404 error code returned.
        : param str album: the unique name of the album the reviews of which are requested, provided in the request URL
        """
        # Fetch the album item from the database and check whether it exists
        album_item = Album.query.filter_by(unique_name=album).first()
        if not album_item:
            return create_error_response(404, 'Album not found')

        body = RevMusicBuilder()
        body.add_namespace('revmusic', LINK_RELATIONS_URL)
        body.add_control('self', url_for('api.reviewsbyalbum', album=album))
        body.add_control(
            'up',
            url_for('api.albumitem', album=album),
            title='Album item for which the reviews have been submitted')
        body.add_control_reviews_all()
        body.add_control_add_review(album)

        # Fetch all the reviews from the database for the specified album
        reviews = Review.query.filter(Review.album == album_item).order_by(
            Review.submission_date.desc()).all()
        body['items'] = []
        for review in reviews:
            item = RevMusicBuilder(identifier=review.identifier,
                                   user=review.user.username,
                                   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=album,
                        review=review.identifier))
            item.add_control('profile', REVIEW_PROFILE)
            body['items'].append(item)

        return Response(json.dumps(body), 200, mimetype=MASON)
Пример #2
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)
Пример #3
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)
Пример #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)
Пример #5
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)
Пример #6
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)
Пример #7
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)
Пример #8
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)