Exemple #1
0
def entity(id):
    id = str(id)
    event = musicbrainz.get_event_by_id(id)
    if not event:
        raise NotFound(gettext("Sorry, we couldn't find a event with that MusicBrainz ID."))

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

    if current_user.is_authenticated:
        my_reviews, my_count = Review.list(entity_id=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 = Review.list(entity_id=id, entity_type='event', sort='rating', limit=limit, offset=offset)

    return render_template('event/entity.html', id=id, event=event, reviews=reviews,
                           my_review=my_review, limit=limit, offset=offset, count=count)
Exemple #2
0
def entity(id):
    id = str(id)
    place = musicbrainz.get_place_by_id(id)
    if not place:
        raise NotFound(
            gettext(
                "Sorry, we couldn't find a place with that MusicBrainz ID."))

    if current_user.is_authenticated:
        my_reviews, my_count = Review.list(entity_id=id,
                                           entity_type='place',
                                           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 = Review.list(entity_id=id,
                                 entity_type='place',
                                 sort='rating',
                                 limit=limit,
                                 offset=offset)

    return render_template('place/entity.html',
                           id=id,
                           place=place,
                           reviews=reviews,
                           my_review=my_review,
                           limit=limit,
                           offset=offset,
                           count=count)
Exemple #3
0
def entity(id):
    id = str(id)
    event = musicbrainz.get_event_by_id(id)
    if not event:
        raise NotFound(gettext("Sorry, we couldn't find a event with that MusicBrainz ID."))

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

    if current_user.is_authenticated():
        my_reviews, my_count = Review.list(entity_id=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 = Review.list(entity_id=id, entity_type='event', sort='rating', limit=limit, offset=offset)

    return render_template('event/entity.html', id=id, event=event, reviews=reviews,
                           my_review=my_review, limit=limit, offset=offset, count=count)
Exemple #4
0
    def test_get_popular(self):
        reviews = Review.get_popular()
        self.assertEqual(len(reviews), 0)

        new_review = Review.create(
            user=self.user,
            release_group='e7aad618-fa86-3983-9e77-405e21796eca',
            text=u"Testing!",
            is_draft=False,
            license_id=self.license.id)

        reviews = Review.get_popular()
        self.assertEqual(len(reviews), 1)
def entity(id):
    id = str(id)
    release_group = musicbrainz.get_release_group_by_id(id)
    if not release_group:
        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 len(release_group['release-list']) > 0:
        release = musicbrainz.get_release_by_id(
            release_group['release-list'][0]['id'])
    else:
        release = None
    soundcloud_url = soundcloud.get_url(id)
    if soundcloud_url:
        spotify_mappings = None
    else:
        spotify_mappings = mbspotify.mappings(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 = Review.list(entity_id=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 = Review.list(entity_id=id,
                                 entity_type='release_group',
                                 sort='rating',
                                 limit=limit,
                                 offset=offset)
    return render_template('release_group/entity.html',
                           id=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)
    def test_get_popular(self):
        reviews = Review.get_popular()
        self.assertEqual(len(reviews), 0)

        new_review = Review.create(
            user=self.user,
            release_group='e7aad618-fa86-3983-9e77-405e21796eca',
            text=u"Testing!",
            is_draft=False,
            license_id=self.license.id
        )

        reviews = Review.get_popular()
        self.assertEqual(len(reviews), 1)
Exemple #7
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 = User.query.get_or_404(user_id)
    page = int(request.args.get('page', default=1))
    if page < 1:
        return redirect(url_for('.reviews'))
    limit = 12
    offset = (page - 1) * limit
    reviews, count = Review.list(user_id=user_id,
                                 sort='created',
                                 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)
Exemple #8
0
 def setUp(self):
     super(VoteTestCase, self).setUp()
     author = User(
         db_users.get_or_create('0',
                                new_user_data={
                                    "display_name": "Author",
                                }))
     self.user_1 = User(
         db_users.get_or_create('1',
                                new_user_data={
                                    "display_name": "Tester #1",
                                }))
     self.user_2 = User(
         db_users.get_or_create('2',
                                new_user_data={
                                    "display_name": "Tester #2",
                                }))
     license = License(id='Test', full_name='Test License')
     db.session.add(license)
     db.session.commit()
     self.review = Review.create(
         release_group='e7aad618-fa86-3983-9e77-405e21796eca',
         text="Testing!",
         user_id=author.id,
         is_draft=False,
         license_id=license.id)
    def test_update(self):
        review = Review.create(user=self.user,
                               release_group='e7aad618-fa86-3983-9e77-405e21796eca',
                               text=u"Awesome!",
                               is_draft=True,
                               license_id=self.license.id)
        another_license = License(id=u"License-2", full_name=u"Another license")
        db.session.add(another_license)
        db.session.commit()
        review.update(text=u"Bad...", is_draft=False, license_id=another_license.id, language='es')

        # Checking if contents are updated
        retrieved_review = Review.query.all()[0]
        self.assertEqual(retrieved_review.text, u"Bad...")
        self.assertFalse(retrieved_review.is_draft)
        self.assertEqual(retrieved_review.license_id, another_license.id)
        self.assertEqual(retrieved_review.language, 'es')

        # Updating should create a new revision.
        self.assertEqual(len(retrieved_review.revisions), 2)
        self.assertNotEqual(retrieved_review.revisions[0], retrieved_review.last_revision)

        # Let's try doing some things that shouldn't be allowed!

        with self.assertRaises(BadRequest):  # like changing license...
            review.update(text=u"Sucks!", license_id=self.license.id)

        with self.assertRaises(BadRequest):  # or converting review back to draft...
            review.update(text=u"Sucks!", is_draft=True)
Exemple #10
0
 def setUp(self):
     super(UserTestCase, self).setUp()
     self.user1 = User(
         db_users.get_or_create('tester_1',
                                new_user_data={
                                    "display_name": "test",
                                }))
     self.user2 = User(
         db_users.get_or_create("тестер",
                                new_user_data={
                                    "display_name": "test1",
                                }))
     self.author = User(
         db_users.get_or_create("author1",
                                new_user_data={
                                    "display_name": "Author1",
                                }))
     license = License(id='Test', full_name='Test License')
     db.session.add(license)
     db.session.commit()
     self.review = Review.create(
         release_group='e7aad618-fa86-3983-9e77-405e21796eca',
         text="Testing!",
         user_id=self.author.id,
         is_draft=False,
         license_id=license.id,
     )
     vote = db_vote.submit(self.user1.id, self.review.last_revision.id,
                           True)
     self.review_created = self.review.last_revision.timestamp
     self.review_id = self.review.id
     self.revision_id = self.review.last_revision.id
     self.report = SpamReport.create(self.revision_id, self.user1.id,
                                     "Testing Reason Report")
Exemple #11
0
    def test_user_has_voted(self):
        # Review needs user
        user_1 = User(display_name=u'Tester #1')
        db.session.add(user_1)
        db.session.commit()

        # and license
        license = License(id=u"Test", full_name=u'Test License')
        db.session.add(license)
        db.session.commit()

        review = Review.create(
            user_id=user_1.id,
            release_group='e7aad618-fa86-3983-9e77-405e21796eca',
            text=u"Testing!",
            is_draft=False,
            license_id=license.id)
        db.session.add(review)
        db.session.commit()

        user_2 = User(display_name=u'Tester #2')
        db.session.add(user_2)
        db.session.commit()

        self.assertFalse(user_2.has_voted(review))
        Vote.create(user_2.id, review, True)
        self.assertTrue(user_2.has_voted(review))
Exemple #12
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).
    """
    artist = musicbrainz.get_artist_by_id(id)
    if not artist:
        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
    count, release_groups = musicbrainz.browse_release_groups(artist_id=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 = Review.list(entity_id=release_group['id'], entity_type='release_group', sort='created', limit=1)
        release_group['review_count'] = review_count

    return render_template(
            'artist.html', id=id, artist=artist, release_type=release_type, release_groups=release_groups,
            page=page, limit=limit, count=count, band_members=band_members
    )
    def test_user_has_voted(self):
        # Review needs user
        user_1 = User(display_name=u'Tester #1')
        db.session.add(user_1)
        db.session.commit()

        # and license
        license = License(id=u"Test", full_name=u'Test License')
        db.session.add(license)
        db.session.commit()

        review = Review.create(user=user_1,
                               release_group='e7aad618-fa86-3983-9e77-405e21796eca',
                               text=u"Testing!",
                               is_draft=False,
                               license_id=license.id)
        db.session.add(review)
        db.session.commit()

        user_2 = User(display_name=u'Tester #2')
        db.session.add(user_2)
        db.session.commit()

        self.assertFalse(user_2.has_voted(review))
        Vote.create(user_2, review, True)
        self.assertTrue(user_2.has_voted(review))
Exemple #14
0
    def test_vote_create(self):
        # Preparing test data
        author = User.get_or_create(u'Author', musicbrainz_id=u'0')
        user_1 = User.get_or_create(u'Tester #1', musicbrainz_id=u'1')
        user_2 = User.get_or_create(u'Tester #2', musicbrainz_id=u'2')
        license = License(id=u'Test', full_name=u'Test License')
        db.session.add(license)
        db.session.commit()
        review = Review.create(
            release_group='e7aad618-fa86-3983-9e77-405e21796eca',
            text=u"Testing!",
            user=author,
            is_draft=False,
            license_id=license.id)

        vote_u1_positive = Vote.create(user_1, review, True)

        votes = db.session.query(Vote).all()
        self.assertEqual(len(votes), 1)
        self.assertIn(vote_u1_positive, votes)

        vote_u2_negative = Vote.create(user_2, review, False)

        votes = db.session.query(Vote).all()
        self.assertEqual(len(votes), 2)
        self.assertIn(vote_u1_positive, votes)
        self.assertIn(vote_u2_negative, votes)
 def test_created_property(self):
     review = Review.create(user=self.user,
                            release_group='e7aad618-fa86-3983-9e77-405e21796eca',
                            text=u"Testing!",
                            is_draft=False,
                            license_id=self.license.id)
     self.assertEqual(review.created, review.revisions[0].timestamp)
    def test_vote_create(self):
        # Preparing test data
        author = User.get_or_create(u'Author', musicbrainz_id=u'0')
        user_1 = User.get_or_create(u'Tester #1', musicbrainz_id=u'1')
        user_2 = User.get_or_create(u'Tester #2', musicbrainz_id=u'2')
        license = License(id=u'Test', full_name=u'Test License')
        db.session.add(license)
        db.session.commit()
        review = Review.create(release_group='e7aad618-fa86-3983-9e77-405e21796eca',
                               text=u"Testing!",
                               user=author,
                               is_draft=False,
                               license_id=license.id)

        vote_u1_positive = Vote.create(user_1, review, True)

        votes = db.session.query(Vote).all()
        self.assertEqual(len(votes), 1)
        self.assertIn(vote_u1_positive, votes)

        vote_u2_negative = Vote.create(user_2, review, False)

        votes = db.session.query(Vote).all()
        self.assertEqual(len(votes), 2)
        self.assertIn(vote_u1_positive, votes)
        self.assertIn(vote_u2_negative, votes)
Exemple #17
0
def browse():
    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 = Review.list(sort='created', limit=limit, offset=offset)

    if not reviews:
        if page - 1 > count / limit:
            return redirect(
                url_for('review.browse', page=int(ceil(count / limit))))
        else:
            raise NotFound(gettext("No reviews to display."))

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

    return render_template('review/browse.html',
                           reviews=reviews,
                           entities=entities_info,
                           page=page,
                           limit=limit,
                           count=count)
def json(location=os.path.join(os.getcwd(), 'export', 'json'), 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 License.query.all():
        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 release groups that have reviews with current license
            query = db.session.query(Review.entity_id).group_by(
                Review.entity_id)
            for entity in query.all():
                entity = entity[0]
                # Creating directory structure and dumping reviews
                dir_part = os.path.join(entity[0:1], entity[0:2])
                reviews = Review.list(entity_id=entity,
                                      license_id=license.id)[0]
                if len(reviews) > 0:
                    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=[r.to_dict() for r in reviews]).data)
                    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=lambda x: os.path.getmtime(x))

    print("Done!")
Exemple #19
0
def index():
    # Popular reviews
    popular_reviews = 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, _ = Review.list(sort='created', limit=9)

    # Statistics
    review_count = format_number(Review.get_count(is_draft = False))
    user_count = format_number(User.get_count())

    return render_template('index/index.html', popular_reviews=popular_reviews, recent_reviews=recent_reviews,
                           reviews_total=review_count, users_total=user_count)
Exemple #20
0
 def test_created_property(self):
     review = Review.create(
         user=self.user,
         release_group='e7aad618-fa86-3983-9e77-405e21796eca',
         text=u"Testing!",
         is_draft=False,
         license_id=self.license.id)
     self.assertEqual(review.created, review.revisions[0].timestamp)
def index():
    # Popular reviews
    popular_reviews = 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).findAll(text=True))

    # Recent reviews
    recent_reviews, _ = Review.list(sort='created', limit=9)

    # Statistics
    # TODO(roman): Move these into models:
    review_count = format_number(Review.query.filter(Review.is_draft == False).count())
    user_count = format_number(User.query.count())

    return render_template('index.html', popular_reviews=popular_reviews, recent_reviews=recent_reviews,
                           reviews_total=review_count, users_total=user_count)
Exemple #22
0
 def create_dummy_review(self, is_draft=False):
     review = Review.create(
         release_group="6b3cd75d-7453-39f3-86c4-1441f360e121",
         user_id=self.user.id,
         text=self.review_text,
         is_draft=is_draft,
         license_id=self.license.id,
     )
     return review
Exemple #23
0
def create():
    for entity_type in ENTITY_TYPES:
        entity_id = request.args.get(entity_type)
        if entity_id:
            break

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

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

    # Checking if the user already wrote a review for this entity
    review = Review.query.filter_by(user=current_user,
                                    entity_id=entity_id).first()
    if review:
        flash(gettext("You have already published a review for this entity!"),
              'error')
        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(gettext("You have exceeded your limit of reviews per day."),
                  'error')
            return redirect(url_for('user.reviews', user_id=current_user.id))

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

    entity = musicbrainz.get_entity_by_id(entity_id, entity_type)
    if not entity:
        flash(
            gettext(
                "You can only write a review for an entity that exists on MusicBrainz!"
            ), 'error')
        return redirect(url_for('search.selector', next=url_for('.create')))
    return render_template('review/write.html',
                           form=form,
                           entity_type=entity_type,
                           entity=entity)
 def create_dummy_review(self, is_draft=False):
     review = Review.create(
         release_group="6b3cd75d-7453-39f3-86c4-1441f360e121",
         user=self.user,
         text=self.review_text,
         is_draft=is_draft,
         license_id=self.license.id,
     )
     return review
    def test_review_deletion(self):
        review = Review.create(user=self.user,
                               release_group='e7aad618-fa86-3983-9e77-405e21796eca',
                               text=u"Testing!",
                               is_draft=False,
                               license_id=self.license.id)
        self.assertEqual(Review.query.count(), 1)

        review.delete()
        self.assertEqual(Review.query.count(), 0)
Exemple #26
0
def review_list_handler():
    """Get list of reviews.

    :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: ``rating`` or ``created`` **(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=['rating', 'created'], optional=True)
    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 = Review.list(
            entity_id=entity_id,
            entity_type=entity_type,
            user_id=user_id,
            sort=sort,
            limit=limit,
            offset=offset,
            language=language,
        )
        reviews = [p.to_dict() 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)
def review_list_handler():
    """Get list of reviews.

    :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: ``rating`` or ``created`` **(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=['rating', 'created'], optional=True)
    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 = Review.list(
            entity_id=entity_id,
            entity_type=entity_type,
            user_id=user_id,
            sort=sort,
            limit=limit,
            offset=offset,
            language=language,
        )
        reviews = [p.to_dict() 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)
Exemple #28
0
    def test_review_deletion(self):
        review = Review.create(
            user=self.user,
            release_group='e7aad618-fa86-3983-9e77-405e21796eca',
            text=u"Testing!",
            is_draft=False,
            license_id=self.license.id)
        self.assertEqual(Review.query.count(), 1)

        review.delete()
        self.assertEqual(Review.query.count(), 0)
    def test_languages(self):
        review_en = Review.create(user=self.user,
                                  release_group='e7aad618-fa86-3983-9e77-405e21796eca',
                                  text=u"Testing!",
                                  is_draft=False,
                                  license_id=self.license.id,
                                  language='en')
        review_de = Review.create(user=self.user,
                                  release_group='e7aad618-fa86-3983-9e77-405e21796ece',
                                  text=u"Testing!",
                                  is_draft=False,
                                  license_id=self.license.id,
                                  language='de')

        reviews, count = Review.list(language='de')
        self.assertEqual(len(reviews), 1)
        self.assertEqual(count, 1)

        reviews, count = Review.list(language='ru')
        self.assertEqual(len(reviews), 0)
        self.assertEqual(count, 0)
Exemple #30
0
def entity(id):
    id = str(id)
    place = musicbrainz.get_place_by_id(id)
    if not place:
        raise NotFound(gettext("Sorry, we couldn't find a place with that MusicBrainz ID."))

    if current_user.is_authenticated():
        my_reviews, my_count = Review.list(entity_id=id, entity_type='place', 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 = Review.list(entity_id=id, entity_type='place', sort='rating', limit=limit, offset=offset)

    return render_template('place/entity.html', id=id, place=place, reviews=reviews,
                           my_review=my_review, limit=limit, offset=offset, count=count)
Exemple #31
0
    def test_list(self):
        reviews, count = Review.list()
        self.assertEqual(count, 0)
        self.assertEqual(len(reviews), 0)

        review = Review.create(
            user=self.user,
            release_group='e7aad618-fa86-3983-9e77-405e21796eca',
            text=u"Awesome!",
            is_draft=False,
            license_id=self.license.id)
        reviews, count = Review.list()
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)
        self.assertEqual(reviews[0].text, u"Awesome!")

        review.update(text=u"Beautiful!", )
        reviews, count = Review.list()
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)
        self.assertEqual(reviews[0].text, u"Beautiful!")

        reviews, count = Review.list(sort='rating')
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)

        reviews, count = Review.list(sort='created')
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)
    def test_list(self):
        reviews, count = Review.list()
        self.assertEqual(count, 0)
        self.assertEqual(len(reviews), 0)

        review = Review.create(
            user=self.user,
            release_group='e7aad618-fa86-3983-9e77-405e21796eca',
            text=u"Awesome!",
            is_draft=False,
            license_id=self.license.id
        )
        reviews, count = Review.list()
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)
        self.assertEqual(reviews[0].text, u"Awesome!")

        review.update(
            text=u"Beautiful!",
        )
        reviews, count = Review.list()
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)
        self.assertEqual(reviews[0].text, u"Beautiful!")

        reviews, count = Review.list(sort='rating')
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)

        reviews, count = Review.list(sort='created')
        self.assertEqual(count, 1)
        self.assertEqual(len(reviews), 1)
Exemple #33
0
def entity(id, rev=None):
    review = Review.query.get_or_404(str(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(review.entity_id)
        soundcloud_url = soundcloud.get_url(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
    review.text_html = markdown(revision['text'], safe_mode="escape")

    user_all_reviews, review_count = Review.list(user_id=review.user_id,
                                                 sort="random",
                                                 exclude=[review.id])
    other_reviews = user_all_reviews[:3]
    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)
    def test_revisions(self):
        review = Review.create(user=self.user,
                               release_group='e7aad618-fa86-3983-9e77-405e21796eca',
                               text=u"Awesome!",
                               is_draft=False,
                               license_id=self.license.id)
        self.assertEqual(len(review.revisions), 1)
        self.assertEqual(review.revisions[0], review.last_revision)

        # Updating should create a new revision.
        review.update(text=u"The worst!")
        self.assertEqual(len(review.revisions), 2)
        self.assertNotEqual(review.revisions[0], review.last_revision)
    def test_review_creation(self):
        self.assertEqual(Review.query.count(), 0)

        review = Review.create(user=self.user,
                               release_group='e7aad618-fa86-3983-9e77-405e21796eca',
                               text=u"Testing!",
                               is_draft=False,
                               license_id=self.license.id)

        reviews = Review.query.all()
        self.assertEqual(len(reviews), 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)
Exemple #36
0
    def test_languages(self):
        review_en = Review.create(
            user=self.user,
            release_group='e7aad618-fa86-3983-9e77-405e21796eca',
            text=u"Testing!",
            is_draft=False,
            license_id=self.license.id,
            language='en')
        review_de = Review.create(
            user=self.user,
            release_group='e7aad618-fa86-3983-9e77-405e21796ece',
            text=u"Testing!",
            is_draft=False,
            license_id=self.license.id,
            language='de')

        reviews, count = Review.list(language='de')
        self.assertEqual(len(reviews), 1)
        self.assertEqual(count, 1)

        reviews, count = Review.list(language='ru')
        self.assertEqual(len(reviews), 0)
        self.assertEqual(count, 0)
def review_post_handler(user):
    """Publish a review.

    **OAuth scope:** review

    :reqheader Content-Type: *application/json*

    :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.
    :json string text: review contents, min length is 25, max is 5000
    :json string license_choice: license ID
    :json string lang: language code (ISO 639-1), default is ``en`` **(optional)**
    :json boolean is_draft: whether the review should be saved as a draft or not, default is ``False`` **(optional)**

    :resheader Content-Type: *application/json*
    """
    def fetch_params():
        is_draft = Parser.bool('json', 'is_draft', optional=True) or False
        if is_draft:
            REVIEW_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_MIN_LENGTH,
                             max=REVIEW_MAX_LENGTH)
        license_choice = Parser.string('json', 'license_choice')
        language = Parser.string(
            'json', 'language', min=2, max=3, optional=True) or 'en'
        if language and language not in supported_languages:
            raise InvalidRequest(desc='Unsupported language')
        if Review.query.filter_by(user=user, entity_id=entity_id).count():
            raise InvalidRequest(
                desc='You have already published a review for this album')
        return entity_id, entity_type, text, license_choice, language, is_draft

    if user.is_review_limit_exceeded:
        raise LimitExceeded('You have exceeded your limit of reviews per day.')
    entity_id, entity_type, text, license_choice, language, is_draft = fetch_params(
    )
    review = Review.create(user=user,
                           entity_id=entity_id,
                           entity_type=entity_type,
                           text=text,
                           license_id=license_choice,
                           language=language,
                           is_draft=is_draft)
    return jsonify(message='Request processed successfully', id=review.id)
Exemple #38
0
 def setUp(self):
     super(VoteTestCase, self).setUp()
     author = User.get_or_create('Author', musicbrainz_id='0')
     self.user_1 = User.get_or_create('Tester #1', musicbrainz_id='1')
     self.user_2 = User.get_or_create('Tester #2', musicbrainz_id='2')
     license = License(id='Test', full_name='Test License')
     db.session.add(license)
     db.session.commit()
     self.review = Review.create(
         release_group='e7aad618-fa86-3983-9e77-405e21796eca',
         text="Testing!",
         user=author,
         is_draft=False,
         license_id=license.id)
Exemple #39
0
    def test_revisions(self):
        review = Review.create(
            user=self.user,
            release_group='e7aad618-fa86-3983-9e77-405e21796eca',
            text=u"Awesome!",
            is_draft=False,
            license_id=self.license.id)
        self.assertEqual(len(review.revisions), 1)
        self.assertEqual(review.revisions[0], review.last_revision)

        # Updating should create a new revision.
        review.update(text=u"The worst!")
        self.assertEqual(len(review.revisions), 2)
        self.assertNotEqual(review.revisions[0], review.last_revision)
Exemple #40
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).
    """
    artist = musicbrainz.get_artist_by_id(mbid)
    if not artist:
        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
    count, release_groups = musicbrainz.browse_release_groups(
        artist_id=mbid,
        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 = Review.list(entity_id=release_group['id'],
                                            entity_type='release_group',
                                            sort='created',
                                            limit=1)
        release_group['review_count'] = review_count

    return render_template(
        'artist/entity.html',
        id=mbid,
        artist=artist,
        release_type=release_type,
        release_groups=release_groups,
        page=page,
        limit=limit,
        count=count,
        band_members=band_members,
    )
Exemple #41
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).
    """
    artist = musicbrainz.get_artist_by_id(id)
    if not artist:
        raise NotFound(
            gettext(
                "Sorry, we couldn't find an artist with that MusicBrainz ID."))

    # Preparing artist-rels
    if 'band-members' in artist:
        artist['current_members'] = []
        artist['former_members'] = []
        for member in artist['band-members']:
            if 'ended' in member and member['ended'] == 'true':
                artist['former_members'].append(member)
            else:
                artist['current_members'].append(member)

    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
    count, release_groups = musicbrainz.browse_release_groups(
        artist_id=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 = Review.list(entity_id=release_group['id'],
                                            entity_type='release_group',
                                            sort='created',
                                            limit=1)
        release_group['review_count'] = review_count
    return render_template('artist.html',
                           id=id,
                           artist=artist,
                           release_type=release_type,
                           release_groups=release_groups,
                           page=page,
                           limit=limit,
                           count=count)
Exemple #42
0
    def setUp(self):
        super(RevisionTestCase, self).setUp()
        self.author = User.get_or_create('Author', musicbrainz_id='0')
        self.user_1 = User.get_or_create('Tester #1', musicbrainz_id='1')
        self.user_2 = User.get_or_create('Tester #2', musicbrainz_id='2')
        self.license = License(id=u'TEST', full_name=u"Test License")
        db.session.add(self.license)
        db.session.commit()

        self.review = Review.create(
            user_id=self.author.id,
            release_group='e7aad618-fa86-3983-9e77-405e21796eca',
            text=u"Testing!",
            is_draft=False,
            license_id=self.license.id)
def entity(id):
    id = str(id)
    release_group = musicbrainz.get_release_group_by_id(id)
    if not release_group:
        raise NotFound(gettext("Sorry, we couldn't find a release group with that MusicBrainz ID."))
    if len(release_group['release-list']) > 0:
        release = musicbrainz.get_release_by_id(release_group['release-list'][0]['id'])
    else:
        release = None
    spotify_mappings = mbspotify.mappings(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 = Review.list(entity_id=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 = Review.list(entity_id=id, entity_type='release_group', sort='rating', limit=limit, offset=offset)
    return render_template('release_group/entity.html', id=id, release_group=release_group, reviews=reviews,
                           release=release, my_review=my_review, spotify_mappings=spotify_mappings,
                           limit=limit, offset=offset, count=count)
Exemple #44
0
    def test_review_creation(self):
        self.assertEqual(Review.query.count(), 0)

        review = Review.create(
            user=self.user,
            release_group='e7aad618-fa86-3983-9e77-405e21796eca',
            text=u"Testing!",
            is_draft=False,
            license_id=self.license.id)

        reviews = Review.query.all()
        self.assertEqual(len(reviews), 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)
def json(location=os.path.join(os.getcwd(), 'export', 'json'), 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 License.query.all():
        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 release groups that have reviews with current license
            query = db.session.query(Review.entity_id).group_by(Review.entity_id)
            for entity in query.all():
                entity = entity[0]
                # Creating directory structure and dumping reviews
                dir_part = os.path.join(entity[0:1], entity[0:2])
                reviews = Review.list(entity_id=entity, license_id=license.id)[0]
                if len(reviews) > 0:
                    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=[r.to_dict() for r in reviews]).data)
                    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=lambda x: os.path.getmtime(x))

    print("Done!")
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 = User.query.get_or_404(user_id)
    page = int(request.args.get('page', default=1))
    if page < 1:
        return redirect(url_for('.reviews'))
    limit = 12
    offset = (page - 1) * limit
    reviews, count = Review.list(user_id=user_id, sort='created', 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)
    def setUp(self):
        super(RevisionTestCase, self).setUp()

        self.user = User(display_name=u'Tester')
        db.session.add(self.user)
        db.session.commit()

        self.license = License(id=u'TEST', full_name=u"Test License")
        db.session.add(self.license)
        db.session.commit()

        self.review = Review.create(user=self.user,
                                    release_group='e7aad618-fa86-3983-9e77-405e21796eca',
                                    text=u"Testing!",
                                    is_draft=False,
                                    license_id=self.license.id)
Exemple #48
0
def create():
    for entity_type in ENTITY_TYPES:
        entity_id = request.args.get(entity_type)
        if entity_id:
            break

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

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

    # Checking if the user already wrote a review for this entity
    review = Review.query.filter_by(user=current_user, entity_id=entity_id).first()
    if review:
        flash(gettext("You have already published a review for this entity!"), 'error')
        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(gettext("You have exceeded your limit of reviews per day."), 'error')
            return redirect(url_for('user.reviews', user_id=current_user.id))

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

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

    if entity_type == 'release_group':
        spotify_mappings = mbspotify.mappings(entity_id)
        return render_template('review/modify/write.html', form=form, entity_type=entity_type, entity=entity, spotify_mappings = spotify_mappings)
    return render_template('review/modify/write.html', form=form, entity_type=entity_type, entity=entity)
    def setUp(self):
        super(SpamReportTestCase, self).setUp()

        # We need review and a couple of users to work with.

        self.reporter = User(display_name=u'Reporter')
        db.session.add(self.reporter)

        self.author = User(display_name=u'Author')
        db.session.add(self.author)
        self.license = License(id=u'Test', full_name=u'Test License')
        db.session.add(self.license)
        db.session.flush()

        self.review = Review.create(user=self.author, release_group='e7aad618-fa86-3983-9e77-405e21796eca',
                                    text=u"It's... beautiful!", is_draft=False, license_id=self.license.id,
                                    language='en')
    def setUp(self):
        super(ModerationLogCase, self).setUp()

        self.admin = User(display_name=u'Admin')
        db.session.add(self.admin)

        self.user = User(display_name=u'User')
        db.session.add(self.user)

        self.reason = "Testing Reason"

        self.license = License(id=u'Test', full_name=u'Test License')
        db.session.add(self.license)
        db.session.flush()

        self.review = Review.create(user=self.user, release_group='e7aad618-fa86-3983-9e77-405e21796eca',
                                    text=u"It's... beautiful!", is_draft=False, license_id=self.license.id,
                                    language='en')
Exemple #51
0
    def setUp(self):
        super(ModerationLogCase, self).setUp()

        self.admin = User(display_name=u'Admin')
        db.session.add(self.admin)

        self.user = User(display_name=u'User')
        db.session.add(self.user)

        self.reason = "Testing Reason"

        self.license = License(id=u'Test', full_name=u'Test License')
        db.session.add(self.license)
        db.session.flush()

        self.review = Review.create(user_id=self.user.id, release_group='e7aad618-fa86-3983-9e77-405e21796eca',
                                    text=u"It's... beautiful!", is_draft=False, license_id=self.license.id,
                                    language='en')
Exemple #52
0
def browse():
    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 = Review.list(sort='created', limit=limit, offset=offset)

    if not reviews:
        if page - 1 > count / limit:
            return redirect(url_for('review.browse', page=int(ceil(count/limit))))
        else:
            raise NotFound(gettext("No reviews to display."))

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

    return render_template('review/browse.html', reviews=reviews, entities=entities_info,
                           page=page, limit=limit, count=count)
    def test_reviews_property(self):
        user = User(display_name=u'Tester')
        db.session.add(user)
        db.session.commit()

        self.assertEqual(len(user.reviews), 0)

        license = License(id=u"Test", full_name=u'Test License')
        db.session.add(license)
        db.session.flush()
        review = Review.create(user=user,
                               release_group='e7aad618-fa86-3983-9e77-405e21796eca',
                               text=u"Testing!",
                               is_draft=False,
                               license_id=license.id)
        db.session.add(review)
        db.session.commit()
        self.assertEqual(len(user.reviews), 1)

        review.delete()
        self.assertEqual(len(user.reviews), 0)
def review_post_handler(user):
    """Publish a review.

    **OAuth scope:** review

    :reqheader Content-Type: *application/json*

    :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.
    :json string text: review contents, min length is 25, max is 5000
    :json string license_choice: license ID
    :json string lang: language code (ISO 639-1), default is ``en`` **(optional)**
    :json boolean is_draft: whether the review should be saved as a draft or not, default is ``False`` **(optional)**

    :resheader Content-Type: *application/json*
    """

    def fetch_params():
        is_draft = Parser.bool('json', 'is_draft', optional=True) or False
        if is_draft:
            REVIEW_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_MIN_LENGTH, max=REVIEW_MAX_LENGTH)
        license_choice = Parser.string('json', 'license_choice')
        language = Parser.string('json', 'language', min=2, max=3, optional=True) or 'en'
        if language and language not in supported_languages:
            raise InvalidRequest(desc='Unsupported language')
        if Review.query.filter_by(user=user, entity_id=entity_id).count():
            raise InvalidRequest(desc='You have already published a review for this album')
        return entity_id, entity_type, text, license_choice, language, is_draft

    if user.is_review_limit_exceeded:
        raise LimitExceeded('You have exceeded your limit of reviews per day.')
    entity_id, entity_type, text, license_choice, language, is_draft = fetch_params()
    review = Review.create(user=user, entity_id=entity_id, entity_type=entity_type, text=text,
                           license_id=license_choice, language=language, is_draft=is_draft)
    return jsonify(message='Request processed successfully', id=review.id)
 def create_dummy_review(self):
     return Review.create(**self.review)
 def review(self):
     return Review.get(id=self.review_id)