Esempio n. 1
0
    def test_languages(self):
        db_review.create(
            user_id=self.user.id,
            entity_id="e7aad618-fa86-3983-9e77-405e21796ece",
            entity_type="release_group",
            text="Testing",
            is_draft=False,
            license_id=self.license["id"],
            language="en",
        )

        db_review.create(
            user_id=self.user.id,
            entity_id="e7aad618-fa86-3983-9e77-405e21796eca",
            entity_type="release_group",
            text="Testing",
            is_draft=False,
            license_id=self.license["id"],
            language="de",
        )
        reviews, count = db_review.list_reviews(language="de")
        self.assertEqual(len(reviews), 1)
        self.assertEqual(count, 1)

        reviews, count = db_review.list_reviews(language="ru")
        self.assertEqual(count, 0)
Esempio n. 2
0
def entity(id):
    id = str(id)
    try:
        release_group = mb_release_group.get_release_group_by_id(id)
    except mb_exceptions.NoDataFoundException:
        raise NotFound(
            gettext(
                "Sorry, we couldn't find a release group with that MusicBrainz ID."
            ))

    if 'tag-list' in release_group:
        tags = release_group['tag-list']
    else:
        tags = None
    if 'release-list' in release_group and release_group['release-list']:
        release = mb_release.get_release_by_id(
            release_group['release-list'][0]['id'])
    else:
        release = None
    soundcloud_url = soundcloud.get_url(release_group['id'])
    if soundcloud_url:
        spotify_mappings = None
    else:
        spotify_mappings = mbspotify.mappings(release_group['id'])
    limit = int(request.args.get('limit', default=10))
    offset = int(request.args.get('offset', default=0))
    if current_user.is_authenticated:
        my_reviews, my_count = db_review.list_reviews(
            entity_id=release_group['id'],
            entity_type='release_group',
            user_id=current_user.id,
        )
        if my_count != 0:
            my_review = my_reviews[0]
        else:
            my_review = None
    else:
        my_review = None
    reviews, count = db_review.list_reviews(
        entity_id=release_group['id'],
        entity_type='release_group',
        sort='popularity',
        limit=limit,
        offset=offset,
    )
    avg_rating = get_avg_rating(release_group['id'], "release_group")

    return render_template('release_group/entity.html',
                           id=release_group['id'],
                           release_group=release_group,
                           reviews=reviews,
                           release=release,
                           my_review=my_review,
                           spotify_mappings=spotify_mappings,
                           tags=tags,
                           soundcloud_url=soundcloud_url,
                           limit=limit,
                           offset=offset,
                           count=count,
                           avg_rating=avg_rating)
Esempio n. 3
0
    def test_languages(self):
        db_review.create(
            user_id=self.user.id,
            entity_id="e7aad618-fa86-3983-9e77-405e21796ece",
            entity_type="release_group",
            text="Testing",
            is_draft=False,
            license_id=self.license["id"],
            language="en",
        )

        db_review.create(
            user_id=self.user.id,
            entity_id="e7aad618-fa86-3983-9e77-405e21796eca",
            entity_type="release_group",
            text="Testing",
            is_draft=False,
            license_id=self.license["id"],
            language="de",
        )
        reviews, count = db_review.list_reviews(language="de")
        self.assertEqual(len(reviews), 1)
        self.assertEqual(count, 1)

        reviews, count = db_review.list_reviews(language="ru")
        self.assertEqual(count, 0)
Esempio n. 4
0
def entity(id):
    id = str(id)
    try:
        place = mb_place.get_place_by_id(id)
    except mb_exceptions.NoDataFoundException:
        raise NotFound(gettext("Sorry, we couldn't find a place with that MusicBrainz ID."))

    if current_user.is_authenticated:
        my_reviews, _ = db_review.list_reviews(
            entity_id=place['id'],
            entity_type='place',
            user_id=current_user.id
        )
        my_review = my_reviews[0] if my_reviews else None
    else:
        my_review = None

    rating_form = RatingEditForm(entity_id=id, entity_type='place')
    rating_form.rating.data = my_review['rating'] if my_review else None

    limit = int(request.args.get('limit', default=10))
    offset = int(request.args.get('offset', default=0))
    reviews, count = db_review.list_reviews(
        entity_id=place['id'],
        entity_type='place',
        sort='popularity',
        limit=limit,
        offset=offset,
    )
    avg_rating = get_avg_rating(place['id'], "place")

    return render_template('place/entity.html', id=place['id'], place=place, reviews=reviews,
                           rating_form=rating_form, my_review=my_review, limit=limit, offset=offset,
                           count=count, avg_rating=avg_rating, current_user=current_user)
Esempio n. 5
0
def entity(id):
    id = str(id)
    try:
        event = mb_event.get_event_by_id(id)
    except mb_exceptions.NoDataFoundException:
        raise NotFound(
            gettext(
                "Sorry, we couldn't find an event with that MusicBrainz ID."))

    if 'url-rels' in event:
        external_reviews = list(
            filter(lambda rel: rel['type'] == 'review', event['url-rels']))
    else:
        external_reviews = []

    if 'artist-rels' in event and event['artist-rels']:
        artists_unique = []
        for artist in event['artist-rels']:
            if artist not in artists_unique:
                artists_unique.append(artist)
        artists_sorted = sorted(artists_unique, key=itemgetter('type'))
        event['artists_grouped'] = groupby(artists_sorted, itemgetter('type'))

    if current_user.is_authenticated:
        my_reviews, _ = db_review.list_reviews(entity_id=event['id'],
                                               entity_type='event',
                                               user_id=current_user.id)
        my_review = my_reviews[0] if my_reviews else None
    else:
        my_review = None

    rating_form = RatingEditForm(entity_id=id, entity_type='event')
    rating_form.rating.data = my_review['rating'] if my_review else None

    limit = int(request.args.get('limit', default=10))
    offset = int(request.args.get('offset', default=0))
    reviews, count = db_review.list_reviews(entity_id=event['id'],
                                            entity_type='event',
                                            sort='popularity',
                                            limit=limit,
                                            offset=offset)
    avg_rating = get_avg_rating(event['id'], "event")

    return render_template('event/entity.html',
                           id=event['id'],
                           event=event,
                           reviews=reviews,
                           rating_form=rating_form,
                           my_review=my_review,
                           external_reviews=external_reviews,
                           limit=limit,
                           offset=offset,
                           count=count,
                           avg_rating=avg_rating,
                           current_user=current_user)
Esempio n. 6
0
 def test_review_deletion(self):
     review = db_review.create(
         user_id=self.user.id,
         entity_id="e7aad618-fa86-3983-9e77-405e21796eca",
         entity_type="release_group",
         text="Testing",
         is_draft=False,
         license_id=self.license["id"],
     )
     self.assertEqual(db_review.list_reviews()[1], 1)
     db_review.delete(review["id"])
     self.assertEqual(db_review.list_reviews()[1], 0)
Esempio n. 7
0
 def test_review_deletion(self):
     review = db_review.create(
         user_id=self.user.id,
         entity_id="e7aad618-fa86-3983-9e77-405e21796eca",
         entity_type="release_group",
         text="Testing",
         is_draft=False,
         license_id=self.license["id"],
     )
     self.assertEqual(db_review.list_reviews()[1], 1)
     db_review.delete(review["id"])
     self.assertEqual(db_review.list_reviews()[1], 0)
Esempio n. 8
0
def entity(id):
    id = str(id)
    try:
        release_group = mb_release_group.get_release_group_by_id(id)
    except mb_exceptions.NoDataFoundException:
        raise NotFound(gettext("Sorry, we couldn't find a release group with that MusicBrainz ID."))

    if 'url-rels' in release_group:
        external_reviews = list(filter(lambda rel: rel['type'] == 'review', release_group['url-rels']))
    else:
        external_reviews = []
    if 'tag-list' in release_group:
        tags = release_group['tag-list']
    else:
        tags = None
    if 'release-list' in release_group and release_group['release-list']:
        release = mb_release.get_release_by_id(release_group['release-list'][0]['id'])
    else:
        release = None
    soundcloud_url = soundcloud.get_url(release_group['id'])
    if soundcloud_url:
        spotify_mappings = None
    else:
        spotify_mappings = mbspotify.mappings(release_group['id'])

    limit = int(request.args.get('limit', default=10))
    offset = int(request.args.get('offset', default=0))
    if current_user.is_authenticated:
        my_reviews, my_count = db_review.list_reviews(
            entity_id=release_group['id'],
            entity_type='release_group',
            user_id=current_user.id,
        )
        my_review = my_reviews[0] if my_count else None
    else:
        my_review = None
    reviews, count = db_review.list_reviews(
        entity_id=release_group['id'],
        entity_type='release_group',
        sort='popularity',
        limit=limit,
        offset=offset,
    )
    avg_rating = get_avg_rating(release_group['id'], "release_group")

    rating_form = RatingEditForm(entity_id=id, entity_type='release_group')
    rating_form.rating.data = my_review['rating'] if my_review else None

    return render_template('release_group/entity.html', id=release_group['id'], release_group=release_group, reviews=reviews,
                           release=release, my_review=my_review, spotify_mappings=spotify_mappings, tags=tags,
                           soundcloud_url=soundcloud_url, external_reviews=external_reviews, limit=limit, offset=offset,
                           count=count, avg_rating=avg_rating, rating_form=rating_form, current_user=current_user)
Esempio n. 9
0
def entity(id):
    id = str(id)
    try:
        recording = mb_recording.get_recording_by_id(id)
    except mb_exceptions.NoDataFoundException:
        raise NotFound(
            gettext(
                "Sorry, we couldn't find a recording with that MusicBrainz ID."
            ))

    if 'url-rels' in recording:
        external_reviews = list(
            filter(lambda rel: rel['type'] == 'review', recording['url-rels']))
    else:
        external_reviews = []

    limit = int(request.args.get('limit', default=RECORDING_REVIEWS_LIMIT))
    offset = int(request.args.get('offset', default=0))
    if current_user.is_authenticated:
        my_reviews, my_count = db_review.list_reviews(
            entity_id=recording['id'],
            entity_type='recording',
            user_id=current_user.id,
        )
        my_review = my_reviews[0] if my_count else None
    else:
        my_review = None
    reviews, count = db_review.list_reviews(
        entity_id=recording['id'],
        entity_type='recording',
        sort='popularity',
        limit=limit,
        offset=offset,
    )
    avg_rating = get_avg_rating(recording['id'], "recording")

    rating_form = RatingEditForm(entity_id=id, entity_type='recording')
    rating_form.rating.data = my_review['rating'] if my_review else None

    return render_template('recording/entity.html',
                           id=recording['id'],
                           recording=recording,
                           reviews=reviews,
                           my_review=my_review,
                           external_reviews=external_reviews,
                           limit=limit,
                           offset=offset,
                           count=count,
                           avg_rating=avg_rating,
                           rating_form=rating_form,
                           current_user=current_user)
Esempio n. 10
0
def entity(id):
    id = str(id)
    try:
        work = mb_work.get_work_by_id(id)
    except mb_exceptions.NoDataFoundException:
        raise NotFound(gettext("Sorry, we couldn't find a work with that MusicBrainz ID."))

    work_reviews_limit = WORK_REVIEWS_LIMIT
    if request.args.get('reviews') == "all":
        work_reviews_limit = None

    if current_user.is_authenticated:
        my_reviews, _ = db_review.list_reviews(
            entity_id=work['id'],
            entity_type='work',
            user_id=current_user.id,
        )
        my_review = my_reviews[0] if my_reviews else None
    else:
        my_review = None

    reviews_offset = 0
    reviews, reviews_count = db_review.list_reviews(
        entity_id=work['id'],
        entity_type='work',
        sort='popularity',
        limit=work_reviews_limit,
        offset=reviews_offset,
    )

    page = int(request.args.get('page', default=1))
    if page < 1:
        return redirect(url_for('.reviews'))

    recording_rels = work['recording-rels']
    recording_count = len(recording_rels)

    recording_offset = (page - 1) * BROWSE_RECORDING_LIMIT
    recording_rels = recording_rels[recording_offset:recording_offset + BROWSE_RECORDING_LIMIT]

    avg_rating = get_avg_rating(work['id'], "work")

    rating_form = RatingEditForm(entity_id=id, entity_type='work')
    rating_form.rating.data = my_review['rating'] if my_review else None

    return render_template('work/entity.html', id=work['id'], work=work, page=page,
                           reviews=reviews, my_review=my_review, reviews_limit=work_reviews_limit,
                           reviews_count=reviews_count, avg_rating=avg_rating, rating_form=rating_form,
                           recording_limit=BROWSE_RECORDING_LIMIT, recording_rels=recording_rels,
                           recording_count=recording_count, current_user=current_user)
Esempio n. 11
0
 def fetch_params():
     is_draft = Parser.bool('json', 'is_draft', optional=True) or False
     if is_draft:
         REVIEW_TEXT_MIN_LENGTH = None
     entity_id = Parser.uuid('json', 'entity_id')
     entity_type = Parser.string('json',
                                 'entity_type',
                                 valid_values=ENTITY_TYPES)
     text = Parser.string('json',
                          'text',
                          min=REVIEW_TEXT_MIN_LENGTH,
                          max=REVIEW_TEXT_MAX_LENGTH,
                          optional=True)
     rating = Parser.int('json',
                         'rating',
                         min=REVIEW_RATING_MIN,
                         max=REVIEW_RATING_MAX,
                         optional=True)
     license_choice = Parser.string('json', 'license_choice')
     language = Parser.string(
         'json', 'language', min=2, max=3, optional=True) or 'en'
     if text is None and rating is None:
         raise InvalidRequest(desc='Review must have either text or rating')
     if language and language not in supported_languages:
         raise InvalidRequest(desc='Unsupported language')
     if db_review.list_reviews(user_id=user.id, entity_id=entity_id)[1]:
         raise InvalidRequest(
             desc='You have already published a review for this album')
     return entity_id, entity_type, text, rating, license_choice, language, is_draft
Esempio n. 12
0
def entity(id, rev=None):
    review = get_review_or_404(id)
    # Not showing review if it isn't published yet and not viewed by author.
    if review["is_draft"] and not (current_user.is_authenticated
                                   and current_user == review["user"]):
        raise NotFound(gettext("Can't find a review with the specified ID."))
    if review["is_hidden"]:
        if not current_user.is_admin():
            raise Forbidden(
                gettext("Review has been hidden. "
                        "You need to be an administrator to view it."))
        else:
            flash.warn(gettext("Review has been hidden."))

    spotify_mappings = None
    soundcloud_url = None
    if review["entity_type"] == 'release_group':
        spotify_mappings = mbspotify.mappings(str(review["entity_id"]))
        soundcloud_url = soundcloud.get_url(str(review["entity_id"]))
    count = db_revision.get_count(id)
    if not rev:
        rev = count
    if rev < count:
        flash.info(
            gettext(
                'You are viewing an old revision, the review has been updated since then.'
            ))
    elif rev > count:
        raise NotFound(
            gettext("The revision you are looking for does not exist."))

    revision = db_revision.get(id, offset=count - rev)[0]
    if not review[
            "is_draft"] and current_user.is_authenticated:  # if user is logged in, get their vote for this review
        try:
            vote = db_vote.get(user_id=current_user.id,
                               revision_id=revision['id'])
        except db_exceptions.NoDataFoundException:
            vote = None
    else:  # otherwise set vote to None, its value will not be used
        vote = None
    if revision["text"] is None:
        review["text_html"] = None
    else:
        review["text_html"] = markdown(revision['text'], safe_mode="escape")

    user_all_reviews, review_count = db_review.list_reviews(  # pylint: disable=unused-variable
        user_id=review["user_id"],
        sort="random",
        exclude=[review["id"]],
    )
    other_reviews = user_all_reviews[:3]
    avg_rating = get_avg_rating(review["entity_id"], review["entity_type"])
    return render_template('review/entity/%s.html' % review["entity_type"],
                           review=review,
                           spotify_mappings=spotify_mappings,
                           soundcloud_url=soundcloud_url,
                           vote=vote,
                           other_reviews=other_reviews,
                           avg_rating=avg_rating)
Esempio n. 13
0
def reviews(user_id):
    user_id = str(user_id)
    if current_user.is_authenticated and current_user.id == user_id:
        user = current_user
    else:
        user = db_users.get_by_id(user_id)
        if not user:
            raise NotFound(
                "Can't find a user with ID: {user_id}".format(user_id=user_id))
        user = User(user)
    page = int(request.args.get('page', default=1))
    if page < 1:
        return redirect(url_for('.reviews'))
    limit = 12
    offset = (page - 1) * limit
    reviews, count = db_review.list_reviews(
        user_id=user_id,
        sort='published_on',
        limit=limit,
        offset=offset,
        inc_hidden=current_user.is_admin(),
        inc_drafts=current_user.is_authenticated
        and current_user.id == user_id)
    return render_template('user/reviews.html',
                           section='reviews',
                           user=user,
                           reviews=reviews,
                           page=page,
                           limit=limit,
                           count=count)
Esempio n. 14
0
    def test_review_creation(self):
        review = db_review.create(
            user_id=self.user.id,
            entity_id="e7aad618-fa86-3983-9e77-405e21796eca",
            entity_type="release_group",
            text="Testing",
            rating=5,
            is_draft=False,
            license_id=self.license["id"],
        )
        reviews, count = db_review.list_reviews()
        self.assertEqual(count, 1)
        self.assertEqual(reviews[0]["id"], review["id"])
        self.assertEqual(reviews[0]["entity_id"], review["entity_id"])
        self.assertEqual(reviews[0]["license_id"], review["license_id"])
        self.assertEqual(reviews[0]["rating"], review["rating"])

        with self.assertRaises(db_exceptions.BadDataException):
            db_review.create(
                user_id=self.user_2.id,
                entity_id="e7aad618-fa86-3983-9e77-405e21796eca",
                entity_type="release_group",
                is_draft=False,
                license_id=self.license["id"],
            )
Esempio n. 15
0
def browse():
    entity_type = request.args.get('entity_type', default=None)
    if entity_type == 'all':
        entity_type = None
    page = int(request.args.get('page', default=1))
    if page < 1:
        return redirect(url_for('.browse'))
    limit = 3 * 9  # 9 rows
    offset = (page - 1) * limit
    reviews, count = db_review.list_reviews(sort='created',
                                            limit=limit,
                                            offset=offset,
                                            entity_type=entity_type)
    if not reviews:
        if page - 1 > count / limit:
            return redirect(
                url_for('review.browse', page=int(ceil(count / limit))))
        else:
            if not entity_type:
                raise NotFound(gettext("No reviews to display."))

    # Loading info about entities for reviews
    entities = [(str(review["entity_id"]), review["entity_type"])
                for review in reviews]
    entities_info = get_multiple_entities(entities)

    return render_template('review/browse.html',
                           reviews=reviews,
                           entities=entities_info,
                           page=page,
                           limit=limit,
                           count=count,
                           entity_type=entity_type)
Esempio n. 16
0
    def test_review_creation(self):
        review = db_review.create(
            user_id=self.user.id,
            entity_id="e7aad618-fa86-3983-9e77-405e21796eca",
            entity_type="release_group",
            text="Testing",
            rating=5,
            is_draft=False,
            license_id=self.license["id"],
        )
        reviews, count = db_review.list_reviews()
        self.assertEqual(count, 1)
        self.assertEqual(reviews[0]["id"], review["id"])
        self.assertEqual(reviews[0]["entity_id"], review["entity_id"])
        self.assertEqual(reviews[0]["license_id"], review["license_id"])
        self.assertEqual(reviews[0]["rating"], review["rating"])

        with self.assertRaises(db_exceptions.BadDataException):
            db_review.create(
                user_id=self.user_2.id,
                entity_id="e7aad618-fa86-3983-9e77-405e21796eca",
                entity_type="release_group",
                is_draft=False,
                license_id=self.license["id"],
            )
Esempio n. 17
0
def entity(id):
    id = str(id)
    try:
        label = mb_label.get_label_by_id(id)
    except mb_exceptions.NoDataFoundException:
        raise NotFound(
            gettext(
                "Sorry, we couldn't find a label with that MusicBrainz ID."))

    label_reviews_limit = LABEL_REVIEWS_LIMIT
    if request.args.get('reviews') == "all":
        label_reviews_limit = None

    if current_user.is_authenticated:
        my_reviews, my_count = db_review.list_reviews(
            entity_id=label['id'],
            entity_type='label',
            user_id=current_user.id,
        )
        my_review = my_reviews[0] if my_count else None
    else:
        my_review = None

    reviews_offset = 0
    reviews, reviews_count = db_review.list_reviews(
        entity_id=label['id'],
        entity_type='label',
        sort='popularity',
        limit=label_reviews_limit,
        offset=reviews_offset,
    )

    avg_rating = get_avg_rating(label['id'], "label")

    rating_form = RatingEditForm(entity_id=id, entity_type='label')
    rating_form.rating.data = my_review['rating'] if my_review else None

    return render_template('label/entity.html',
                           id=label['id'],
                           label=label,
                           reviews=reviews,
                           my_review=my_review,
                           reviews_limit=label_reviews_limit,
                           reviews_count=reviews_count,
                           avg_rating=avg_rating,
                           rating_form=rating_form,
                           current_user=current_user)
Esempio n. 18
0
def entity(id):
    id = str(id)
    try:
        event = mb_event.get_event_by_id(id)
    except mb_exceptions.NoDataFoundException:
        raise NotFound(gettext("Sorry, we couldn't find an event with that MusicBrainz ID."))

    if 'url-rels' in event:
        external_reviews = list(filter(lambda rel: rel['type'] == 'review', event['url-rels']))
    else:
        external_reviews = []

    if 'artist-rels' in event and event['artist-rels']:
        artists_sorted = sorted(event['artist-rels'], key=itemgetter('type'))
        event['artists_grouped'] = groupby(artists_sorted, itemgetter('type'))

    if current_user.is_authenticated:
        my_reviews, my_count = db_review.list_reviews(
            entity_id=event['id'],
            entity_type='event',
            user_id=current_user.id
        )
        my_review = my_reviews[0] if my_count else None
    else:
        my_review = None

    rating_form = RatingEditForm(entity_id=id, entity_type='event')
    rating_form.rating.data = my_review['rating'] if my_review else None

    limit = int(request.args.get('limit', default=10))
    offset = int(request.args.get('offset', default=0))
    reviews, count = db_review.list_reviews(
        entity_id=event['id'],
        entity_type='event',
        sort='popularity',
        limit=limit,
        offset=offset
    )
    avg_rating = get_avg_rating(event['id'], "event")

    return render_template('event/entity.html', id=event['id'], event=event, reviews=reviews,
                           rating_form=rating_form, my_review=my_review, external_reviews=external_reviews,
                           limit=limit, offset=offset, count=count, avg_rating=avg_rating, current_user=current_user)
Esempio n. 19
0
def entity(id):
    id = str(id)
    try:
        event = mb_event.get_event_by_id(id)
    except mb_exceptions.NoDataFoundException:
        raise NotFound(
            gettext(
                "Sorry, we couldn't find a event with that MusicBrainz ID."))

    if 'artist-rels' in event and event['artist-rels']:
        artists_sorted = sorted(event['artist-rels'], key=itemgetter('type'))
        event['artists_grouped'] = groupby(artists_sorted, itemgetter('type'))

    if current_user.is_authenticated:
        my_reviews, my_count = db_review.list_reviews(entity_id=event['id'],
                                                      entity_type='event',
                                                      user_id=current_user.id)
        if my_count != 0:
            my_review = my_reviews[0]
        else:
            my_review = None
    else:
        my_review = None

    limit = int(request.args.get('limit', default=10))
    offset = int(request.args.get('offset', default=0))
    reviews, count = db_review.list_reviews(entity_id=event['id'],
                                            entity_type='event',
                                            sort='popularity',
                                            limit=limit,
                                            offset=offset)
    avg_rating = get_avg_rating(event['id'], "event")

    return render_template('event/entity.html',
                           id=event['id'],
                           event=event,
                           reviews=reviews,
                           my_review=my_review,
                           limit=limit,
                           offset=offset,
                           count=count,
                           avg_rating=avg_rating)
Esempio n. 20
0
def entity(mbid):
    """Artist page.

    Displays release groups (split up into several sections depending on their
    type), artist information (type, members/member of, external links).
    """
    try:
        artist = mb_artist.get_artist_by_id(str(mbid))
    except mb_exceptions.NoDataFoundException:
        raise NotFound(
            gettext(
                "Sorry, we couldn't find an artist with that MusicBrainz ID."))

    # Note that some artists might not have a list of members because they are not a band
    band_members = _get_band_members(artist)

    release_type = request.args.get('release_type', default='album')
    if release_type not in ['album', 'single', 'ep', 'broadcast',
                            'other']:  # supported release types
        raise BadRequest("Unsupported release type.")

    page = int(request.args.get('page', default=1))
    if page < 1:
        return redirect(url_for('.reviews'))
    limit = 20
    offset = (page - 1) * limit
    release_groups, count = mb_release_group.browse_release_groups(
        artist_id=artist['id'],
        release_types=[release_type],
        limit=limit,
        offset=offset,
    )
    for release_group in release_groups:
        # TODO(roman): Count reviews instead of fetching them.
        reviews, review_count = db_review.list_reviews(  # pylint: disable=unused-variable
            entity_id=release_group['id'],
            entity_type='release_group',
            sort='published_on',
            limit=1,
        )
        release_group['review_count'] = review_count

    return render_template(
        'artist/entity.html',
        id=artist['id'],
        artist=artist,
        release_type=release_type,
        release_groups=release_groups,
        page=page,
        limit=limit,
        count=count,
        band_members=band_members,
    )
Esempio n. 21
0
def entity(mbid):
    """Artist page.

    Displays release groups (split up into several sections depending on their
    type), artist information (type, members/member of, external links).
    """
    try:
        artist = mb_artist.get_artist_by_id(str(mbid))
    except mb_exceptions.NoDataFoundException:
        raise NotFound(gettext("Sorry, we couldn't find an artist with that MusicBrainz ID."))

    # Note that some artists might not have a list of members because they are not a band
    band_members = _get_band_members(artist)

    release_type = request.args.get('release_type', default='album')
    if release_type not in ['album', 'single', 'ep', 'broadcast', 'other']:  # supported release types
        raise BadRequest("Unsupported release type.")

    page = int(request.args.get('page', default=1))
    if page < 1:
        return redirect(url_for('.reviews'))
    limit = 20
    offset = (page - 1) * limit
    release_groups, count = mb_release_group.browse_release_groups(
        artist_id=artist['id'],
        release_types=[release_type],
        limit=limit,
        offset=offset,
    )
    for release_group in release_groups:
        # TODO(roman): Count reviews instead of fetching them.
        reviews, review_count = db_review.list_reviews(  # pylint: disable=unused-variable
            entity_id=release_group['id'],
            entity_type='release_group',
            sort='published_on', limit=1,
        )
        release_group['review_count'] = review_count

    return render_template(
        'artist/entity.html',
        id=artist['id'],
        artist=artist,
        release_type=release_type,
        release_groups=release_groups,
        page=page,
        limit=limit,
        count=count,
        band_members=band_members,
    )
Esempio n. 22
0
def json(location, rotate=False):
    """Create JSON dumps with all reviews.

    This command will create an archive for each license available on CB.
    Archives will be put into a specified directory (default is *dump*).
    """
    create_path(location)

    current_app.json_encoder = DumpJSONEncoder

    print("Creating new archives...")
    for license in db_license.list_licenses():
        safe_name = slugify(license["id"])
        with tarfile.open(os.path.join(location, "critiquebrainz-%s-%s-json.tar.bz2" %
                                       (datetime.today().strftime('%Y%m%d'), safe_name)), "w:bz2") as tar:
            temp_dir = tempfile.mkdtemp()
            license_dir = os.path.join(temp_dir, safe_name)
            create_path(license_dir)

            # Finding entities that have reviews with current license
            entities = db_review.distinct_entities()
            for entity in entities:
                entity = str(entity)
                # Creating directory structure and dumping reviews
                dir_part = os.path.join(entity[0:1], entity[0:2])
                reviews = db_review.list_reviews(entity_id=entity, license_id=license["id"], limit=None)[0]
                if reviews:
                    rg_dir = '%s/%s' % (license_dir, dir_part)
                    create_path(rg_dir)
                    f = open('%s/%s.json' % (rg_dir, entity), 'w+')
                    f.write(jsonify(reviews=[db_review.to_dict(r) for r in reviews]).data.decode("utf-8"))
                    f.close()

            tar.add(license_dir, arcname='reviews')

            # Copying legal text
            tar.add(os.path.join("critiquebrainz", "data", "licenses", safe_name + ".txt"), arcname='COPYING')

            print(" + %s/critiquebrainz-%s-%s-json.tar.bz2" % (location, datetime.today().strftime('%Y%m%d'), safe_name))

            shutil.rmtree(temp_dir)  # Cleanup

    if rotate:
        print("Removing old sets of archives (except two latest)...")
        remove_old_archives(location, "critiquebrainz-[0-9]+-[-\w]+-json.tar.bz2",
                            is_dir=False, sort_key=os.path.getmtime)

    print("Done!")
Esempio n. 23
0
def index():
    # Popular reviews
    popular_reviews = db_review.get_popular(6)
    for review in popular_reviews:
        # Preparing text for preview
        preview = markdown(review['text'], safe_mode="escape")
        review['preview'] = ''.join(BeautifulSoup(preview, "html.parser").findAll(text=True))

    # Recent reviews
    recent_reviews, _ = db_review.list_reviews(sort='created', limit=9)

    # Statistics
    review_count = format_number(db_review.get_count(is_draft=False))
    user_count = format_number(db_users.total_count())

    return render_template('index/index.html', popular_reviews=popular_reviews, recent_reviews=recent_reviews,
                           reviews_total=review_count, users_total=user_count)
Esempio n. 24
0
def index():
    # Popular reviews
    popular_reviews = db_review.get_popular(6)
    for review in popular_reviews:
        # Preparing text for preview
        preview = markdown(review['text'], safe_mode="escape")
        review['preview'] = ''.join(BeautifulSoup(preview, "html.parser").findAll(text=True))

    # Recent reviews
    recent_reviews, _ = db_review.list_reviews(sort='published_on', limit=9)

    # Statistics
    review_count = format_number(db_review.get_count(is_draft=False))
    user_count = format_number(db_users.total_count())

    return render_template('index/index.html', popular_reviews=popular_reviews, recent_reviews=recent_reviews,
                           reviews_total=review_count, users_total=user_count)
Esempio n. 25
0
 def fetch_params():
     is_draft = Parser.bool('json', 'is_draft', optional=True) or False
     if is_draft:
         REVIEW_TEXT_MIN_LENGTH = None
     entity_id = Parser.uuid('json', 'entity_id')
     entity_type = Parser.string('json', 'entity_type', valid_values=ENTITY_TYPES)
     text = Parser.string('json', 'text', min=REVIEW_TEXT_MIN_LENGTH, max=REVIEW_TEXT_MAX_LENGTH, optional=True)
     rating = Parser.int('json', 'rating', min=REVIEW_RATING_MIN, max=REVIEW_RATING_MAX, optional=True)
     license_choice = Parser.string('json', 'license_choice')
     language = Parser.string('json', 'language', min=2, max=3, optional=True) or 'en'
     if text is None and rating is None:
         raise InvalidRequest(desc='Review must have either text or rating')
     if language and language not in supported_languages:
         raise InvalidRequest(desc='Unsupported language')
     if db_review.list_reviews(user_id=user.id, entity_id=entity_id)[1]:
         raise InvalidRequest(desc='You have already published a review for this album')
     return entity_id, entity_type, text, rating, license_choice, language, is_draft
Esempio n. 26
0
def rate():
    form = RatingEditForm()
    if form.validate_on_submit():
        if current_user.is_blocked:
            flash.error(
                gettext("You are not allowed to rate any entity because your "
                        "account has been blocked by a moderator."))
            return redirect(
                url_for('{}.entity'.format(form.entity_type.data),
                        id=form.entity_id.data))
        reviews, review_count = db_review.list_reviews(
            entity_id=form.entity_id.data,
            entity_type=form.entity_type.data,
            user_id=current_user.id,
        )
        review = reviews[0] if review_count else None

        if not review and form.rating.data is None:
            raise BadRequest(
                "Cannot create a review with no rating and no text!")

        if not review and form.rating.data is not None:
            db_review.create(
                user_id=current_user.id,
                entity_id=form.entity_id.data,
                entity_type=form.entity_type.data,
                rating=form.rating.data,
                is_draft=False,
            )
        elif review and review['text'] is None and form.rating.data is None:
            db_review.delete(review['id'])
        elif review and review['rating'] != form.rating.data:
            db_review.update(
                review_id=review['id'],
                drafted=review['is_draft'],
                text=review['text'],
                rating=form.rating.data,
            )
        # TODO(code-master5): Make this message specify the entity
        flash.success("We have updated your rating for this entity!")
    else:
        flash.error("Error! Could not update the rating...")
    return redirect(
        url_for('{}.entity'.format(form.entity_type.data),
                id=form.entity_id.data))
Esempio n. 27
0
def reviews(user_id):
    user_id = str(user_id)
    if current_user.is_authenticated and current_user.id == user_id:
        user = current_user
    else:
        user = db_users.get_by_id(user_id)
        if not user:
            raise NotFound("Can't find a user with ID: {user_id}".format(user_id=user_id))
        user = User(user)
    page = int(request.args.get('page', default=1))
    if page < 1:
        return redirect(url_for('.reviews'))
    limit = 12
    offset = (page - 1) * limit
    reviews, count = db_review.list_reviews(user_id=user_id, sort='published_on', limit=limit, offset=offset,
                                            inc_hidden=current_user.is_admin(),
                                            inc_drafts=current_user.is_authenticated and current_user.id == user_id)
    return render_template('user/reviews.html', section='reviews', user=user,
                           reviews=reviews, page=page, limit=limit, count=count)
Esempio n. 28
0
def rate():
    form = RatingEditForm()
    if form.validate_on_submit():
        if current_user.is_blocked:
            flash.error(gettext("You are not allowed to rate any entity because your "
                                "account has been blocked by a moderator."))
            return redirect(url_for('{}.entity'.format(form.entity_type.data), id=form.entity_id.data))
        reviews, review_count = db_review.list_reviews(
            entity_id=form.entity_id.data,
            entity_type=form.entity_type.data,
            user_id=current_user.id,
        )
        review = reviews[0] if review_count else None

        if not review and form.rating.data is None:
            raise BadRequest("Cannot create a review with no rating and no text!")

        if not review and form.rating.data is not None:
            db_review.create(
                user_id=current_user.id,
                entity_id=form.entity_id.data,
                entity_type=form.entity_type.data,
                rating=form.rating.data,
                is_draft=False,
            )
        elif review and review['text'] is None and form.rating.data is None:
            db_review.delete(review['id'])
        elif review and review['rating'] != form.rating.data:
            db_review.update(
                review_id=review['id'],
                drafted=review['is_draft'],
                text=review['text'],
                rating=form.rating.data,
            )
        # TODO(code-master5): Make this message specify the entity
        flash.success("We have updated your rating for this entity!")
    else:
        flash.error("Error! Could not update the rating...")
    return redirect(url_for('{}.entity'.format(form.entity_type.data), id=form.entity_id.data))
Esempio n. 29
0
    def test_artist_rating(self):
        self.temporary_login(self.reviewer)
        test_entity_id = 'f59c5520-5f46-4d2c-b2c4-822eabf53419'
        payload = {
            'entity_id': test_entity_id,
            'entity_type': 'artist',
            'rating': 4
        }

        response = self.client.post(url_for('rate.rate'), data=payload)
        self.assertRedirects(response, '/artist/{}'.format(test_entity_id))
        reviews, review_count = db_review.list_reviews(
            entity_id=test_entity_id,
            entity_type='artist',
            user_id=self.reviewer.id)

        self.assertEqual(review_count, 1)
        self.assertEqual(reviews[0]['rating'], 4)

        response = self.client.get('/artist/{}'.format(test_entity_id))
        self.assert200(response)
        self.assertIn('We have updated your rating for this entity!',
                      str(response.data))
Esempio n. 30
0
    def test_list_reviews(self):
        reviews, count = db_review.list_reviews()
        self.assertEqual(count, 0)
        self.assertEqual(len(reviews), 0)

        review = db_review.create(
            user_id=self.user.id,
            entity_id="e7aad618-fa86-3983-9e77-405e21796eca",
            entity_type="release_group",
            text="Awesome",
            rating=5,
            is_draft=False,
            license_id=self.license["id"],
        )
        reviews, count = db_review.list_reviews()
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)
        self.assertEqual(reviews[0]["text"], "Awesome")
        self.assertEqual(reviews[0]["rating"], 5)

        db_review.update(
            review_id=review["id"],
            drafted=review["is_draft"],
            text="Beautiful!",
            rating=4,
        )
        reviews, count = db_review.list_reviews()
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)
        self.assertEqual(reviews[0]["text"], "Beautiful!")
        self.assertEqual(reviews[0]["rating"], 4)

        reviews, count = db_review.list_reviews(sort="popularity")
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)

        reviews, count = db_review.list_reviews(sort="published_on")
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)

        reviews, count = db_review.list_reviews(sort="random")
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)
Esempio n. 31
0
    def test_list_reviews(self):
        reviews, count = db_review.list_reviews()
        self.assertEqual(count, 0)
        self.assertEqual(len(reviews), 0)

        review = db_review.create(
            user_id=self.user.id,
            entity_id="e7aad618-fa86-3983-9e77-405e21796eca",
            entity_type="release_group",
            text="Awesome",
            rating=5,
            is_draft=False,
            license_id=self.license["id"],
        )
        reviews, count = db_review.list_reviews()
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)
        self.assertEqual(reviews[0]["text"], "Awesome")
        self.assertEqual(reviews[0]["rating"], 5)

        db_review.update(
            review_id=review["id"],
            drafted=review["is_draft"],
            text="Beautiful!",
            rating=4,
        )
        reviews, count = db_review.list_reviews()
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)
        self.assertEqual(reviews[0]["text"], "Beautiful!")
        self.assertEqual(reviews[0]["rating"], 4)

        reviews, count = db_review.list_reviews(sort="popularity")
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)

        reviews, count = db_review.list_reviews(sort="published_on")
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)

        reviews, count = db_review.list_reviews(sort="random")
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)
Esempio n. 32
0
    def test_rate(self):
        self.temporary_login(self.reviewer)

        # Test for first time rating (no review exists)
        payload = {
            'entity_id': self.test_entity['id'],
            'entity_type': 'release_group',
            'rating': 4
        }
        response = self.client.post(
            url_for('rate.rate'),
            data=payload
        )

        self.assertRedirects(response, '/release-group/{}'.format(self.test_entity['id']))

        reviews, review_count = db_review.list_reviews(
            entity_id=self.test_entity['id'],
            entity_type='release_group',
            user_id=self.reviewer.id
        )
        # Test that the rate request created a review
        self.assertEqual(review_count, 1)
        review = reviews[0]
        self.assertEqual(review['text'], None)
        self.assertEqual(review['rating'], 4)

        response = self.client.get('/release-group/{}'.format(self.test_entity['id']))
        self.assert200(response)
        self.assertIn('We have updated your rating for this entity!', str(response.data))

        # Test after rating is cleared for review with NO text
        payload = {
            'entity_id': self.test_entity['id'],
            'entity_type': 'release_group',
            'rating': None
        }
        response = self.client.post(
            url_for('rate.rate'),
            data=payload
        )

        reviews, review_count = db_review.list_reviews(
            entity_id=self.test_entity['id'],
            entity_type='release_group',
            user_id=self.reviewer.id
        )
        # Test that the clear rating request results in deletion of review (because review-text was None)
        self.assertEqual(review_count, 0)

        # Test after rating is cleared for review with some text
        self.review = db_review.create(
            user_id=self.reviewer.id,
            entity_id=self.test_entity['id'],
            entity_type="release_group",
            text="Test Review.",
            rating=4,
            is_draft=False,
            license_id=self.license["id"],
        )

        payload = {
            'entity_id': self.test_entity['id'],
            'entity_type': 'release_group',
            'rating': None
        }
        response = self.client.post(
            url_for('rate.rate'),
            data=payload
        )

        reviews, review_count = db_review.list_reviews(
            entity_id=self.test_entity['id'],
            entity_type='release_group',
            user_id=self.reviewer.id
        )
        # Test that the clear rating request doesn't delete review (because review-text was not None)
        self.assertEqual(review_count, 1)
        review = reviews[0]
        self.assertEqual(review['rating'], None)
Esempio n. 33
0
    def test_update(self):
        review = db_review.create(
            user_id=self.user.id,
            entity_id="e7aad618-fa86-3983-9e77-405e21796eca",
            entity_type="release_group",
            text="Testing",
            rating=5,
            is_draft=True,
            license_id=self.license["id"],
        )
        another_license = db_license.create(
            id="License-2",
            full_name="Another License",
        )
        # Update review to only rating
        db_review.update(
            review_id=review["id"],
            drafted=review["is_draft"],
            rating=4,
            is_draft=False,
            license_id=another_license["id"],
            language="es",
        )
        # Checking if contents are updated
        retrieved_review = db_review.list_reviews()[0][0]
        self.assertEqual(retrieved_review["text"], None)
        self.assertEqual(retrieved_review["rating"], 4)
        self.assertFalse(retrieved_review["is_draft"])
        self.assertEqual(retrieved_review["license_id"], another_license["id"])
        self.assertEqual(retrieved_review["language"], "es")
        # Update review to only text
        db_review.update(
            review_id=review["id"],
            drafted=review["is_draft"],
            text="Testing update",
            is_draft=False,
            license_id=another_license["id"],
            language="es",
        )
        # Checking if contents are updated
        retrieved_review = db_review.list_reviews()[0][0]
        self.assertEqual(retrieved_review["text"], "Testing update")
        self.assertEqual(retrieved_review["rating"], None)

        # Updating should create a new revision.
        revisions = db_revision.get(retrieved_review["id"], limit=None)
        self.assertEqual(len(revisions), 3)
        self.assertEqual(revisions[0]["timestamp"], retrieved_review["last_revision"]["timestamp"])
        self.assertEqual(revisions[0]["text"], retrieved_review["text"])
        self.assertEqual(revisions[0]["rating"], retrieved_review["rating"])

        # Checking things that shouldn't be allowed
        with self.assertRaises(db_exceptions.BadDataException):
            db_review.update(
                review_id=retrieved_review["id"],
                drafted=retrieved_review["is_draft"],
                text="Sucks!",
                license_id=self.license["id"],
            )
        review = db_review.get_by_id(review["id"])
        with self.assertRaises(db_exceptions.BadDataException):
            db_review.update(
                review_id=review["id"],
                drafted=review["is_draft"],
                text="Sucks!",
                is_draft=True,
            )
Esempio n. 34
0
def review_list_handler():
    """Get list of reviews.

    **Request Example:**

    .. code-block:: bash

        $ curl "https://critiquebrainz.org/ws/1/review/?limit=1&offset=50" \\
                -X GET

    **Response Example:**

    .. code-block:: json

        {
          "count": 9197,
          "limit": 1,
          "offset": 50,
          "reviews": [
            {
              "created": "Fri, 16 May 2008 00:00:00 GMT",
              "edits": 0,
              "entity_id": "09259937-6477-3959-8b10-af1cbaea8e6e",
              "entity_type": "release_group",
              "id": "c807d0b4-0dd0-43fe-a7c4-d29bb61f389e",
              "language": "en",
              "last_updated": "Fri, 16 May 2008 00:00:00 GMT",
              "license": {
                "full_name": "Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported",
                "id": "CC BY-NC-SA 3.0",
                "info_url": "https://creativecommons.org/licenses/by-nc-sa/3.0/"
              },
              "popularity": 0,
              "source": "BBC",
              "source_url": "http://www.bbc.co.uk/music/reviews/vh54",
              "text": "TEXT CONTENT OF REVIEW",
              "rating": 5,
              "user": {
                "created": "Wed, 07 May 2014 16:20:47 GMT",
                "display_name": "Jenny Nelson",
                "id": "3bf3fe0c-6db2-4746-bcf1-f39912113852",
                "karma": 0,
                "user_type": "Noob"
              },
              "votes": {
                "positive": 0,
                "negative": 0
              }
            }
          ]
        }

    :json uuid entity_id: UUID of the release group that is being reviewed
    :json string entity_type: One of the supported reviewable entities. 'release_group' or 'event' etc. **(optional)**
    :query user_id: user's UUID **(optional)**
    :query sort: ``popularity`` or ``published_on`` **(optional)**
    :query limit: results limit, min is 0, max is 50, default is 50 **(optional)**
    :query offset: result offset, default is 0 **(optional)**
    :query language: language code (ISO 639-1) **(optional)**

    :resheader Content-Type: *application/json*
    """
    # TODO: This checking is added to keep old clients working and needs to be removed.
    release_group = Parser.uuid('uri', 'release_group', optional=True)
    if release_group:
        entity_id = release_group
        entity_type = 'release_group'
    else:
        entity_id = Parser.uuid('uri', 'entity_id', optional=True)
        entity_type = Parser.string('uri',
                                    'entity_type',
                                    valid_values=ENTITY_TYPES,
                                    optional=True)

    user_id = Parser.uuid('uri', 'user_id', optional=True)
    sort = Parser.string(
        'uri',
        'sort',
        valid_values=['popularity', 'published_on', 'rating', 'created'],
        optional=True)

    # "rating" and "created" sort values are deprecated and but allowed here for backward compatibility
    if sort == 'created':
        sort = 'published_on'
    if sort == 'rating':
        sort = 'popularity'

    limit = Parser.int('uri', 'limit', min=1, max=50, optional=True) or 50
    offset = Parser.int('uri', 'offset', optional=True) or 0
    language = Parser.string('uri', 'language', min=2, max=3, optional=True)
    if language and language not in supported_languages:
        raise InvalidRequest(desc='Unsupported language')

    # TODO(roman): Ideally caching logic should live inside the model. Otherwise it
    # becomes hard to track all this stuff.
    cache_key = cache.gen_key('list', entity_id, user_id, sort, limit, offset,
                              language)
    cached_result = cache.get(cache_key, REVIEW_CACHE_NAMESPACE)
    if cached_result:
        reviews = cached_result['reviews']
        count = cached_result['count']

    else:
        reviews, count = db_review.list_reviews(
            entity_id=entity_id,
            entity_type=entity_type,
            user_id=user_id,
            sort=sort,
            limit=limit,
            offset=offset,
            language=language,
        )
        reviews = [db_review.to_dict(p) for p in reviews]
        cache.set(cache_key, {
            'reviews': reviews,
            'count': count,
        },
                  namespace=REVIEW_CACHE_NAMESPACE)

    return jsonify(limit=limit, offset=offset, count=count, reviews=reviews)
Esempio n. 35
0
    def test_update(self):
        review = db_review.create(
            user_id=self.user.id,
            entity_id="e7aad618-fa86-3983-9e77-405e21796eca",
            entity_type="release_group",
            text="Testing",
            rating=5,
            is_draft=True,
            license_id=self.license["id"],
        )
        another_license = db_license.create(
            id="License-2",
            full_name="Another License",
        )
        # Update review to only rating
        db_review.update(
            review_id=review["id"],
            drafted=review["is_draft"],
            rating=4,
            is_draft=False,
            license_id=another_license["id"],
            language="es",
        )
        # Checking if contents are updated
        retrieved_review = db_review.list_reviews()[0][0]
        self.assertEqual(retrieved_review["text"], None)
        self.assertEqual(retrieved_review["rating"], 4)
        self.assertFalse(retrieved_review["is_draft"])
        self.assertEqual(retrieved_review["license_id"], another_license["id"])
        self.assertEqual(retrieved_review["language"], "es")
        # Update review to only text
        db_review.update(
            review_id=review["id"],
            drafted=review["is_draft"],
            text="Testing update",
            is_draft=False,
            license_id=another_license["id"],
            language="es",
        )
        # Checking if contents are updated
        retrieved_review = db_review.list_reviews()[0][0]
        self.assertEqual(retrieved_review["text"], "Testing update")
        self.assertEqual(retrieved_review["rating"], None)

        # Updating should create a new revision.
        revisions = db_revision.get(retrieved_review["id"], limit=None)
        self.assertEqual(len(revisions), 3)
        self.assertEqual(revisions[0]["timestamp"],
                         retrieved_review["last_revision"]["timestamp"])
        self.assertEqual(revisions[0]["text"], retrieved_review["text"])
        self.assertEqual(revisions[0]["rating"], retrieved_review["rating"])

        # Checking things that shouldn't be allowed
        with self.assertRaises(db_exceptions.BadDataException):
            db_review.update(
                review_id=retrieved_review["id"],
                drafted=retrieved_review["is_draft"],
                text="Sucks!",
                license_id=self.license["id"],
            )
        review = db_review.get_by_id(review["id"])
        with self.assertRaises(db_exceptions.BadDataException):
            db_review.update(
                review_id=review["id"],
                drafted=review["is_draft"],
                text="Sucks!",
                is_draft=True,
            )
Esempio n. 36
0
        flash.info(gettext("Please choose an entity to review."))
        return redirect(url_for('search.selector', next=url_for('.create')))

    if entity_type not in ENTITY_TYPES:
        raise BadRequest("You can't write reviews about this type of entity.")

    if current_user.is_blocked:
        flash.error(
            gettext("You are not allowed to write new reviews because your "
                    "account has been blocked by a moderator."))
        return redirect(url_for('user.reviews', user_id=current_user.id))

    # Checking if the user already wrote a review for this entity
    reviews, count = db_review.list_reviews(user_id=current_user.id,
                                            entity_id=entity_id,
                                            inc_drafts=True,
                                            inc_hidden=True)
    review = reviews[0] if count != 0 else None

    if review:
        if review['is_draft']:
            return redirect(url_for('review.edit', id=review['id']))
        elif review['is_hidden']:
            return redirect(url_for('review.entity', id=review['id']))
        else:
            flash.error(
                gettext("You have already published a review for this entity"))
            return redirect(url_for('review.entity', id=review["id"]))

    if current_user.is_review_limit_exceeded:
        flash.error(
Esempio n. 37
0
def review_list_handler():
    """Get list of reviews.

    **Request Example:**

    .. code-block:: bash

        $ curl "https://critiquebrainz.org/ws/1/review/?limit=1&offset=50" \\
                -X GET

    **Response Example:**

    .. code-block:: json

        {
          "count": 9197,
          "limit": 1,
          "offset": 50,
          "reviews": [
            {
              "created": "Fri, 16 May 2008 00:00:00 GMT",
              "edits": 0,
              "entity_id": "09259937-6477-3959-8b10-af1cbaea8e6e",
              "entity_type": "release_group",
              "id": "c807d0b4-0dd0-43fe-a7c4-d29bb61f389e",
              "language": "en",
              "last_updated": "Fri, 16 May 2008 00:00:00 GMT",
              "license": {
                "full_name": "Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported",
                "id": "CC BY-NC-SA 3.0",
                "info_url": "https://creativecommons.org/licenses/by-nc-sa/3.0/"
              },
              "popularity": 0,
              "source": "BBC",
              "source_url": "http://www.bbc.co.uk/music/reviews/vh54",
              "text": "TEXT CONTENT OF REVIEW",
              "rating": 5,
              "user": {
                "created": "Wed, 07 May 2014 16:20:47 GMT",
                "display_name": "Jenny Nelson",
                "id": "3bf3fe0c-6db2-4746-bcf1-f39912113852",
                "karma": 0,
                "user_type": "Noob"
              },
              "votes": {
                "positive": 0,
                "negative": 0
              }
            }
          ]
        }

    :json uuid entity_id: UUID of the release group that is being reviewed
    :json string entity_type: One of the supported reviewable entities. 'release_group' or 'event' etc. **(optional)**
    :query user_id: user's UUID **(optional)**
    :query sort: ``popularity`` or ``published_on`` **(optional)**
    :query limit: results limit, min is 0, max is 50, default is 50 **(optional)**
    :query offset: result offset, default is 0 **(optional)**
    :query language: language code (ISO 639-1) **(optional)**

    :resheader Content-Type: *application/json*
    """
    # TODO: This checking is added to keep old clients working and needs to be removed.
    release_group = Parser.uuid('uri', 'release_group', optional=True)
    if release_group:
        entity_id = release_group
        entity_type = 'release_group'
    else:
        entity_id = Parser.uuid('uri', 'entity_id', optional=True)
        entity_type = Parser.string('uri', 'entity_type', valid_values=ENTITY_TYPES, optional=True)

    user_id = Parser.uuid('uri', 'user_id', optional=True)
    # TODO: "rating" sort value is deprecated and needs to be removed.
    sort = Parser.string('uri', 'sort', valid_values=['popularity', 'published_on', 'rating'], optional=True)
    if sort == 'rating':
        sort = 'popularity'
    limit = Parser.int('uri', 'limit', min=1, max=50, optional=True) or 50
    offset = Parser.int('uri', 'offset', optional=True) or 0
    language = Parser.string('uri', 'language', min=2, max=3, optional=True)
    if language and language not in supported_languages:
        raise InvalidRequest(desc='Unsupported language')

    # TODO(roman): Ideally caching logic should live inside the model. Otherwise it
    # becomes hard to track all this stuff.
    cache_key = cache.gen_key('list', entity_id, user_id, sort, limit, offset, language)
    cached_result = cache.get(cache_key, REVIEW_CACHE_NAMESPACE)
    if cached_result:
        reviews = cached_result['reviews']
        count = cached_result['count']

    else:
        reviews, count = db_review.list_reviews(
            entity_id=entity_id,
            entity_type=entity_type,
            user_id=user_id,
            sort=sort,
            limit=limit,
            offset=offset,
            language=language,
        )
        reviews = [db_review.to_dict(p) for p in reviews]
        cache.set(cache_key, {
            'reviews': reviews,
            'count': count,
        }, namespace=REVIEW_CACHE_NAMESPACE)

    return jsonify(limit=limit, offset=offset, count=count, reviews=reviews)
Esempio n. 38
0
    def test_rate(self):
        self.temporary_login(self.reviewer)

        # Test for first time rating (no review exists)
        payload = {
            'entity_id': self.test_entity['id'],
            'entity_type': 'release_group',
            'rating': 4
        }
        response = self.client.post(url_for('rate.rate'), data=payload)

        self.assertRedirects(
            response, '/release-group/{}'.format(self.test_entity['id']))

        reviews, review_count = db_review.list_reviews(
            entity_id=self.test_entity['id'],
            entity_type='release_group',
            user_id=self.reviewer.id)
        # Test that the rate request created a review
        self.assertEqual(review_count, 1)
        review = reviews[0]
        self.assertEqual(review['text'], None)
        self.assertEqual(review['rating'], 4)

        response = self.client.get('/release-group/{}'.format(
            self.test_entity['id']))
        self.assert200(response)
        self.assertIn('We have updated your rating for this entity!',
                      str(response.data))

        # Test after rating is cleared for review with NO text
        payload = {
            'entity_id': self.test_entity['id'],
            'entity_type': 'release_group',
            'rating': None
        }
        response = self.client.post(url_for('rate.rate'), data=payload)

        reviews, review_count = db_review.list_reviews(
            entity_id=self.test_entity['id'],
            entity_type='release_group',
            user_id=self.reviewer.id)
        # Test that the clear rating request results in deletion of review (because review-text was None)
        self.assertEqual(review_count, 0)

        # Test after rating is cleared for review with some text
        self.review = db_review.create(
            user_id=self.reviewer.id,
            entity_id=self.test_entity['id'],
            entity_type="release_group",
            text="Test Review.",
            rating=4,
            is_draft=False,
            license_id=self.license["id"],
        )

        payload = {
            'entity_id': self.test_entity['id'],
            'entity_type': 'release_group',
            'rating': None
        }
        response = self.client.post(url_for('rate.rate'), data=payload)

        reviews, review_count = db_review.list_reviews(
            entity_id=self.test_entity['id'],
            entity_type='release_group',
            user_id=self.reviewer.id)
        # Test that the clear rating request doesn't delete review (because review-text was not None)
        self.assertEqual(review_count, 1)
        review = reviews[0]
        self.assertEqual(review['rating'], None)
Esempio n. 39
0
def entity(id):
    """Artist page.

    Displays release groups (split up into several sections depending on their
    type), artist information (type, members/member of, external links).
    """
    try:
        artist = mb_artist.get_artist_by_id(str(id))
    except mb_exceptions.NoDataFoundException:
        raise NotFound(
            gettext(
                "Sorry, we couldn't find an artist with that MusicBrainz ID."))

    # Note that some artists might not have a list of members because they are not a band
    band_members = _get_band_members(artist)

    artist_reviews_limit = ARTIST_REVIEWS_LIMIT
    if request.args.get('reviews') == "all":
        artist_reviews_limit = None

    my_review = None
    if current_user.is_authenticated:
        my_reviews, my_count = db_review.list_reviews(
            entity_id=artist['id'],
            entity_type='artist',
            user_id=current_user.id,
        )
        my_review = my_reviews[0] if my_count else None

    reviews_offset = 0
    reviews, reviews_count = db_review.list_reviews(
        entity_id=artist['id'],
        entity_type='artist',
        sort='popularity',
        limit=artist_reviews_limit,
        offset=reviews_offset,
    )

    avg_rating = get_avg_rating(artist['id'], "artist")

    rating_form = RatingEditForm(entity_id=id, entity_type='artist')
    rating_form.rating.data = my_review['rating'] if my_review else None

    release_type = request.args.get('release_type', default='album')
    if release_type not in ['album', 'single', 'ep', 'broadcast',
                            'other']:  # supported release types
        raise BadRequest("Unsupported release type.")

    page = int(request.args.get('page', default=1))
    if page < 1:
        return redirect(url_for('.reviews'))
    release_groups_offset = (page - 1) * BROWSE_RELEASE_GROUPS_LIMIT
    release_groups, release_group_count = mb_release_group.browse_release_groups(
        artist_id=artist['id'],
        release_types=[release_type],
        limit=BROWSE_RELEASE_GROUPS_LIMIT,
        offset=release_groups_offset,
    )
    for release_group in release_groups:
        # TODO(roman): Count reviews instead of fetching them.
        _, release_group_review_count = db_review.list_reviews(  # pylint: disable=unused-variable
            entity_id=release_group['id'],
            entity_type='release_group',
            sort='published_on',
            limit=1,
        )
        release_group['review_count'] = release_group_review_count

    return render_template(
        'artist/entity.html',
        id=artist['id'],
        artist=artist,
        release_type=release_type,
        release_groups=release_groups,
        page=page,
        reviews=reviews,
        reviews_limit=artist_reviews_limit,
        reviews_count=reviews_count,
        avg_rating=avg_rating,
        rating_form=rating_form,
        release_groups_limit=BROWSE_RELEASE_GROUPS_LIMIT,
        release_group_count=release_group_count,
        band_members=band_members,
    )
Esempio n. 40
0
def create():
    entity_id, entity_type = None, None
    for entity_type in ENTITY_TYPES:
        entity_id = request.args.get(entity_type)
        if entity_id:
            entity_type = entity_type
            break

    if not (entity_id or entity_type):
        logging.warning("Unsupported entity type")
        raise BadRequest("Unsupported entity type")

    if not entity_id:
        flash.info(gettext("Please choose an entity to review."))
        return redirect(url_for('search.selector', next=url_for('.create')))

    if current_user.is_blocked:
        flash.error(
            gettext("You are not allowed to write new reviews because your "
                    "account has been blocked by a moderator."))
        return redirect(url_for('user.reviews', user_id=current_user.id))

    # Checking if the user already wrote a review for this entity
    review = db_review.list_reviews(user_id=current_user.id,
                                    entity_id=entity_id)[0]
    if review:
        flash.error(
            gettext("You have already published a review for this entity!"))
        return redirect(url_for('review.entity', id=review["id"]))

    form = ReviewCreateForm(default_language=get_locale())

    if form.validate_on_submit():
        if current_user.is_review_limit_exceeded:
            flash.error(
                gettext("You have exceeded your limit of reviews per day."))
            return redirect(url_for('user.reviews', user_id=current_user.id))

        is_draft = form.state.data == 'draft'
        if form.text.data == '':
            form.text.data = None
        review = db_review.create(user_id=current_user.id,
                                  entity_id=entity_id,
                                  entity_type=entity_type,
                                  text=form.text.data,
                                  rating=form.rating.data,
                                  license_id=form.license_choice.data,
                                  language=form.language.data,
                                  is_draft=is_draft)
        if is_draft:
            flash.success(gettext("Review has been saved!"))
        else:
            flash.success(gettext("Review has been published!"))
        return redirect(url_for('.entity', id=review['id']))

    entity = get_entity_by_id(entity_id, entity_type)
    if not entity:
        flash.error(
            gettext(
                "You can only write a review for an entity that exists on MusicBrainz!"
            ))
        return redirect(url_for('search.selector', next=url_for('.create')))

    if entity_type == 'release_group':
        spotify_mappings = mbspotify.mappings(entity_id)
        soundcloud_url = soundcloud.get_url(entity_id)
        if not form.errors:
            flash.info(
                gettext(
                    "Please provide some text or a rating for this review."))
        return render_template('review/modify/write.html',
                               form=form,
                               entity_type=entity_type,
                               entity=entity,
                               spotify_mappings=spotify_mappings,
                               soundcloud_url=soundcloud_url)
    if not form.errors:
        flash.info(
            gettext("Please provide some text or a rating for this review."))
    return render_template('review/modify/write.html',
                           form=form,
                           entity_type=entity_type,
                           entity=entity)