def spotify(): release_group_id = request.args.get('release_group_id') if not release_group_id: return redirect(url_for('frontend.index')) release_group = musicbrainz.get_release_group_by_id(release_group_id) if not release_group: flash.error( gettext("Only existing release groups can be mapped to Spotify!")) return redirect(url_for('search.index')) page = int(request.args.get('page', default=1)) if page < 1: return redirect(url_for('.spotify')) limit = 16 offset = (page - 1) * limit # Removing punctuation from the string punctuation_map = dict((ord(char), None) for char in string.punctuation) query = release_group['title'].translate(punctuation_map) # Searching... response = spotify_api.search(query, 'album', limit, offset).get('albums') albums_ids = [x['id'] for x in response['items']] full_response = spotify_api.get_multiple_albums(albums_ids) return render_template('mapping/spotify.html', release_group=release_group, search_results=[ full_response[id] for id in albums_ids if id in full_response ], page=page, limit=limit, count=response.get('total'))
def spotify_confirm(): """Confirmation page for adding new Spotify mapping.""" release_group_id = request.args.get('release_group_id') if not release_group_id: raise BadRequest("Didn't provide `release_group_id`!") try: release_group = mb_release_group.get_release_group_by_id( release_group_id) except mb_exceptions.NoDataFoundException: flash.error( gettext("Only existing release groups can be mapped to Spotify!")) return redirect(url_for('search.index')) spotify_ref = request.args.get('spotify_ref', default=None) if not spotify_ref: flash.error(gettext("You need to select an album from Spotify!")) return redirect( url_for('.spotify_add', release_group_id=release_group_id)) try: spotify_id = parse_spotify_id(spotify_ref) except UnsupportedSpotifyReferenceTypeException: flash.error( gettext( "You need to specify a correct link to this album on Spotify!") ) return redirect( url_for('.spotify_add', release_group_id=release_group_id)) except Exception: raise BadRequest("Could not parse Spotify ID!") try: album = spotify_api.get_album(spotify_id) except ExternalServiceException: flash.error( gettext("You need to specify existing album from Spotify!")) return redirect( url_for('.spotify_add', release_group_id=release_group_id)) if request.method == 'POST': # TODO(roman): Check values that are returned by add_mapping (also take a look at related JS). res, error = mbspotify.add_mapping(release_group_id, 'spotify:album:%s' % spotify_id, current_user.id) if res: flash.success(gettext("Spotify mapping has been added!")) else: flash.error(gettext("Could not add Spotify mapping!")) current_app.logger.error( "Failed to create new Spotify mapping! Error: {}".format( error)) return redirect( url_for('.spotify_list', release_group_id=release_group_id)) return render_template('mapping/confirm.html', release_group=release_group, spotify_album=album)
def musicbrainz_post(): """Callback endpoint.""" if mb_auth.validate_post_login(): login_user(mb_auth.get_user()) next = session.get('next') if next: return redirect(next) else: flash.error(gettext("Login failed.")) return redirect(url_for('frontend.index'))
def musicbrainz_post(): """Callback endpoint.""" if mb_auth.validate_post_login(): login_user(mb_auth.get_user()) next = session.get('next') if next: return redirect(next) else: flash.error(gettext("Login failed.")) return redirect(url_for('frontend.index'))
def vote_delete(id): review = get_review_or_404(id) if review["is_hidden"] and not current_user.is_admin(): raise NotFound(gettext("Review has been hidden.")) try: vote = db_vote.get(user_id=current_user.id, revision_id=review["last_revision"]["id"]) flash.success(gettext("You have deleted your vote for this review!")) db_vote.delete(user_id=vote["user_id"], revision_id=vote["revision_id"]) except db_exceptions.NoDataFoundException: flash.error(gettext("This review is not rated yet.")) return redirect(url_for('.entity', id=id))
def create(): form = CommentEditForm() if form.validate_on_submit(): db_comment.create( review_id=form.review_id.data, user_id=current_user.id, text=form.text.data, ) flash.success('Comment has been saved!') else: flash.error('Comment must not be empty!') return redirect(url_for('review.entity', id=form.review_id.data))
def spotify_add(): release_group_id = request.args.get('release_group_id') if not release_group_id: return redirect(url_for('frontend.index')) try: release_group = mb_release_group.get_release_group_by_id( release_group_id) except mb_exceptions.NoDataFoundException: flash.error( gettext("Only existing release groups can be mapped to Spotify!")) return redirect(url_for('search.index')) page = int(request.args.get('page', default=1)) if page < 1: return redirect(url_for('.spotify_add')) limit = 16 offset = (page - 1) * limit # Removing punctuation from the string punctuation_map = dict((ord(char), None) for char in string.punctuation) query = release_group['title'].translate(punctuation_map) # Searching... try: response = spotify_api.search(query, item_types='album', limit=limit, offset=offset).get('albums') except ExternalServiceException as e: current_app.logger.error("Error while searching Spotify API: %s", str(e), exc_info=True) raise ServiceUnavailable(e) albums_ids = [x['id'] for x in response['items']] try: full_response = spotify_api.get_multiple_albums(albums_ids) except ExternalServiceException as e: current_app.logger.error("Error while getting albums from Spotify: %s", str(e), exc_info=True) raise ServiceUnavailable(e) search_results = [ full_response[id] for id in albums_ids if id in full_response ] return render_template('mapping/spotify.html', release_group=release_group, search_results=search_results, page=page, limit=limit, count=response.get('total'))
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))
def create(): # TODO (code-master5): comment limit, revision and drafts, edit functionality form = CommentEditForm() if form.validate_on_submit(): get_review_or_404(form.review_id.data) if current_user.is_blocked: flash.error(gettext("You are not allowed to write new comments because your " "account has been blocked by a moderator.")) return redirect(url_for('review.entity', id=form.review_id.data)) # should be able to comment only if review exists db_comment.create( review_id=form.review_id.data, user_id=current_user.id, text=form.text.data, ) flash.success(gettext("Comment has been saved!")) elif not form.text.data: # comment must have some text flash.error(gettext("Comment must not be empty!")) return redirect(url_for('review.entity', id=form.review_id.data))
def spotify_confirm(): """Confirmation page for adding new Spotify mapping.""" release_group_id = request.args.get('release_group_id') if not release_group_id: raise BadRequest("Didn't provide `release_group_id`!") try: release_group = mb_release_group.get_release_group_by_id(release_group_id) except mb_exceptions.NoDataFoundException: flash.error(gettext("Only existing release groups can be mapped to Spotify!")) return redirect(url_for('search.index')) spotify_ref = request.args.get('spotify_ref', default=None) if not spotify_ref: flash.error(gettext("You need to select an album from Spotify!")) return redirect(url_for('.spotify_add', release_group_id=release_group_id)) try: spotify_id = parse_spotify_id(spotify_ref) except UnsupportedSpotifyReferenceTypeException: flash.error(gettext("You need to specify a correct link to this album on Spotify!")) return redirect(url_for('.spotify_add', release_group_id=release_group_id)) except Exception: raise BadRequest("Could not parse Spotify ID!") try: album = spotify_api.get_album(spotify_id) except ExternalServiceException: flash.error(gettext("You need to specify existing album from Spotify!")) return redirect(url_for('.spotify_add', release_group_id=release_group_id)) if request.method == 'POST': # TODO(roman): Check values that are returned by add_mapping (also take a look at related JS). res, error = mbspotify.add_mapping(release_group_id, 'spotify:album:%s' % spotify_id, current_user.id) if res: flash.success(gettext("Spotify mapping has been added!")) else: flash.error(gettext("Could not add Spotify mapping!")) current_app.logger.error("Failed to create new Spotify mapping! Error: {}".format(error)) return redirect(url_for('.spotify_list', release_group_id=release_group_id)) return render_template('mapping/confirm.html', release_group=release_group, spotify_album=album)
def spotify_report(): """Endpoint for reporting incorrect Spotify mappings. Shows confirmation page before submitting report to mbspotify. """ release_group_id = request.args.get('release_group_id') spotify_id = request.args.get('spotify_id') spotify_uri = "spotify:album:" + spotify_id # Checking if release group exists try: release_group = mb_release_group.get_release_group_by_id( release_group_id) except mb_exceptions.NoDataFoundException: flash.error(gettext("Can't find release group with that ID!")) return redirect( url_for('.spotify_list', release_group_id=release_group_id)) # Checking if release group is mapped to Spotify spotify_mappings = mbspotify.mappings(str(release_group_id)) if spotify_uri not in spotify_mappings: flash.error(gettext("This album is not mapped to Spotify yet!")) return redirect( url_for('.spotify_list', release_group_id=release_group_id)) if request.method == 'POST': res, error = mbspotify.vote(release_group_id, spotify_uri, current_user.id) if res: flash.success( gettext( "Incorrect Spotify mapping has been reported. Thank you!")) else: flash.error(gettext("Could not report incorrect Spotify mapping!")) current_app.logger.error( "Failed to report incorrect Spotify mapping! Error: {}".format( error)) return redirect( url_for('.spotify_list', release_group_id=release_group_id)) try: album = spotify_api.get_album(spotify_id) except ExternalServiceException: flash.error( gettext("You need to specify existing album from Spotify!")) return redirect( url_for('.spotify_list', release_group_id=release_group_id)) return render_template('mapping/report.html', release_group=release_group, spotify_album=album)
def report(id): review = get_review_or_404(id) if review["is_hidden"] and not current_user.is_admin(): raise NotFound(gettext("Review has been hidden.")) if review["user"] == current_user: flash.error(gettext("You cannot report your own review.")) return redirect(url_for('.entity', id=id)) if current_user.is_blocked: flash.error( gettext("You are not allowed to report this review because " "your account has been blocked by a moderator.")) return redirect(url_for('.entity', id=id)) last_revision_id = review["last_revision"]["id"] report = db_spam_report.get(current_user.id, last_revision_id) if report: flash.error(gettext("You have already reported this review.")) return redirect(url_for('.entity', id=id)) form = ReviewReportForm() if form.validate_on_submit(): db_spam_report.create(last_revision_id, current_user.id, form.reason.data) flash.success(gettext("Review has been reported.")) return redirect(url_for('.entity', id=id)) return render_template('review/report.html', review=review, form=form)
def vote_submit(review_id): review_id = str(review_id) if 'yes' in request.form: vote = True elif 'no' in request.form: vote = False else: vote = None review = get_review_or_404(review_id) if review["is_hidden"] and not current_user.is_admin(): raise NotFound(gettext("Review has been hidden.")) if review["user"] == current_user: flash.error(gettext("You cannot rate your own review.")) return redirect(url_for('.entity', id=review_id)) if current_user.is_vote_limit_exceeded is True and current_user.has_voted( review) is False: flash.error(gettext("You have exceeded your limit of votes per day.")) return redirect(url_for('.entity', id=review_id)) if current_user.is_blocked: flash.error( gettext("You are not allowed to rate this review because " "your account has been blocked by a moderator.")) return redirect(url_for('.entity', id=review_id)) db_vote.submit( user_id=current_user.id, revision_id=review["last_revision"]["id"], vote=vote, # overwrites an existing vote, if needed ) flash.success(gettext("You have rated this review!")) return redirect(url_for('.entity', id=review_id))
def create(): # TODO (code-master5): comment limit, revision and drafts, edit functionality form = CommentEditForm() if form.validate_on_submit(): get_review_or_404(form.review_id.data) if current_user.is_blocked: flash.error( gettext( "You are not allowed to write new comments because your " "account has been blocked by a moderator.")) return redirect(url_for('review.entity', id=form.review_id.data)) # should be able to comment only if review exists db_comment.create( review_id=form.review_id.data, user_id=current_user.id, text=form.text.data, ) flash.success(gettext("Comment has been saved!")) elif not form.text.data: # comment must have some text flash.error(gettext("Comment must not be empty!")) return redirect(url_for('review.entity', id=form.review_id.data))
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))
def spotify_add(): release_group_id = request.args.get('release_group_id') if not release_group_id: return redirect(url_for('frontend.index')) try: release_group = mb_release_group.get_release_group_by_id(release_group_id) except mb_exceptions.NoDataFoundException: flash.error(gettext("Only existing release groups can be mapped to Spotify!")) return redirect(url_for('search.index')) page = int(request.args.get('page', default=1)) if page < 1: return redirect(url_for('.spotify_add')) limit = 16 offset = (page - 1) * limit # Removing punctuation from the string punctuation_map = dict((ord(char), None) for char in string.punctuation) query = release_group['title'].translate(punctuation_map) # Searching... try: response = spotify_api.search(query, item_types='album', limit=limit, offset=offset).get('albums') except ExternalServiceException as e: current_app.logger.error("Error while searching Spotify API: %s", str(e), exc_info=True) raise ServiceUnavailable(e) albums_ids = [x['id'] for x in response['items']] try: full_response = spotify_api.get_multiple_albums(albums_ids) except ExternalServiceException as e: current_app.logger.error("Error while getting albums from Spotify: %s", str(e), exc_info=True) raise ServiceUnavailable(e) search_results = [full_response[id] for id in albums_ids if id in full_response] return render_template('mapping/spotify.html', release_group=release_group, search_results=search_results, page=page, limit=limit, count=response.get('total'))
def spotify_confirm(): """Confirmation page for adding new Spotify mapping.""" release_group_id = request.args.get('release_group_id') if not release_group_id: raise BadRequest("Didn't provide `release_group_id`!") release_group = musicbrainz.get_release_group_by_id(release_group_id) if not release_group: flash.error( gettext("Only existing release groups can be mapped to Spotify!")) return redirect(url_for('search.index')) spotify_ref = request.args.get('spotify_ref', default=None) if not spotify_ref: flash.error(gettext("You need to select an album from Spotify!")) return redirect(url_for('.spotify', release_group_id=release_group_id)) spotify_id = parse_spotify_id(spotify_ref) if not spotify_id: flash.error( gettext( "You need to specify a correct link to this album on Spotify!") ) return redirect(url_for('.spotify', release_group_id=release_group_id)) try: album = spotify_api.get_album(spotify_id) except ExternalServiceException: flash.error( gettext("You need to specify existing album from Spotify!")) return redirect(url_for('.spotify', release_group_id=release_group_id)) if request.method == 'POST': # TODO(roman): Check values that are returned by add_mapping (also take a look at related JS). mbspotify.add_mapping(release_group_id, 'spotify:album:%s' % spotify_id, current_user.id) flash.success(gettext("Spotify mapping has been added!")) return redirect( url_for('.spotify_list', release_group_id=release_group_id)) return render_template('mapping/confirm.html', release_group=release_group, spotify_album=album)
def spotify_report(): """Endpoint for reporting incorrect Spotify mappings. Shows confirmation page before submitting report to mbspotify. """ release_group_id = request.args.get('release_group_id') if not release_group_id: raise BadRequest("Didn't provide `release_group_id`!") spotify_id = request.args.get('spotify_id') if not spotify_id: raise BadRequest("Didn't provide `spotify_id`!") spotify_uri = "spotify:album:" + spotify_id # Checking if release group exists try: release_group = mb_release_group.get_release_group_by_id(release_group_id) except mb_exceptions.NoDataFoundException: raise NotFound("Can't find release group with a specified ID.") # Checking if release group is mapped to Spotify spotify_mappings = mbspotify.mappings(str(release_group_id)) if spotify_uri not in spotify_mappings: flash.error(gettext("This album is not mapped to Spotify yet!")) return redirect(url_for('.spotify_list', release_group_id=release_group_id)) if request.method == 'POST': res, error = mbspotify.vote(release_group_id, spotify_uri, current_user.id) if res: flash.success(gettext("Incorrect Spotify mapping has been reported. Thank you!")) else: flash.error(gettext("Could not report incorrect Spotify mapping!")) current_app.logger.error("Failed to report incorrect Spotify mapping! Error: {}".format(error)) return redirect(url_for('.spotify_list', release_group_id=release_group_id)) try: album = spotify_api.get_album(spotify_id) except ExternalServiceException: flash.error(gettext("You need to specify existing album from Spotify!")) return redirect(url_for('.spotify_list', release_group_id=release_group_id)) return render_template('mapping/report.html', release_group=release_group, spotify_album=album)
def spotify_report(): """Endpoint for reporting incorrect Spotify mappings. Shows confirmation page before submitting report to mbspotify. """ release_group_id = request.args.get('release_group_id') spotify_id = request.args.get('spotify_id') spotify_uri = "spotify:album:" + spotify_id # Checking if release group exists release_group = musicbrainz.get_release_group_by_id(release_group_id) if not release_group: flash.error(gettext("Can't find release group with that ID!")) return redirect( url_for('.spotify_list', release_group_id=release_group_id)) # Checking if release group is mapped to Spotify spotify_mappings = mbspotify.mappings(str(release_group_id)) if not (spotify_uri in spotify_mappings): flash.error(gettext("This album is not mapped to Spotify yet!")) return redirect( url_for('.spotify_list', release_group_id=release_group_id)) if request.method == 'POST': mbspotify.vote(release_group_id, spotify_uri, current_user.id) flash.success( gettext("Incorrect Spotify mapping has been reported. Thank you!")) return redirect( url_for('.spotify_list', release_group_id=release_group_id)) else: album = spotify_api.get_album(spotify_id) if not album or album.get('error'): flash.error( gettext("You need to specify existing album from Spotify!")) return redirect( url_for('.spotify_list', release_group_id=release_group_id)) return render_template('mapping/report.html', release_group=release_group, spotify_album=album)
def edit(id): comment = get_comment_or_404(id) if comment["user"] != current_user: raise Unauthorized(gettext("Only the author can edit this comment.")) if current_user.is_blocked: flash.error( gettext("You are not allowed to edit comments because your " "account has been blocked by a moderator.")) return redirect(url_for('review.entity', id=comment["review_id"])) form = CommentEditForm() if form.validate_on_submit(): if form.text.data != comment["last_revision"]["text"]: db_comment.update(comment_id=comment["id"], text=form.text.data) flash.success(gettext("Comment has been updated.")) else: flash.error( gettext( "You must change some content of the comment to update it!" )) elif not form.text.data: # comment must have some text flash.error(gettext("Comment must not be empty!")) return redirect(url_for('review.entity', id=comment["review_id"]))
if entity_type: return redirect( url_for('.create', entity_type=entity_type, entity_id=entity_id)) 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']))
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)