def annotation(annotation_id): """Main view route for an annotation.""" annotation = Annotation.query.get_or_404(annotation_id) if not annotation.active: current_user.authorize('view_deactivated_annotations') return render_template('view/annotation.html', title=f"Annotation [{annotation.id}]", annotation=annotation)
def flag_annotation(flag_id, annotation_id): """Flag an annotation.""" annotation = Annotation.query.get_or_404(annotation_id) redirect_url = generate_next(annotation.url) if not annotation.active: current_user.authorize('view_deactivated_annotations') flag = AnnotationFlag.enum_cls.query.get_or_404(flag_id) AnnotationFlag.flag(annotation, flag, current_user) db.session.commit() flash(f"Annotation {annotation.id} flagged \"{flag.enum}\"") return redirect(redirect_url)
def mark_all_annotation_flags(annotation_id): """Resolve all flags for a given annotation. This route will be deprecated after the annotation flag democratization overhaul.""" annotation = Annotation.query.get_or_404(annotation_id) if not annotation.active: current_user.authorize('resolve_deactivated_annotation_flags') redirect_url = generate_next( url_for('admin.annotation_flags', annotation_id=annotation_id)) for flag in annotation.active_flags: flag.resolve(current_user) db.session.commit() flash("All flags marked resolved.") return redirect(redirect_url)
def annotation_flags(annotation_id): """View all flags for a given annotation.""" default = 'unresolved' page = request.args.get('page', 1, type=int) sort = request.args.get('sort', default, type=str) annotation = Annotation.query.get_or_404(annotation_id) if not annotation.active: current_user.authorize('resolve_deactivated_annotation_flags') sorts = { 'unresolved': (annotation.flags.order_by(AnnotationFlag.time_resolved.asc())), 'flag': (annotation.flags.outerjoin(AnnotationFlag.enum_cls).order_by( AnnotationFlag.enum_cls.enum.asc())), 'time-thrown': (annotation.flags.order_by(AnnotationFlag.time_thrown.desc())), 'time-resolved': (annotation.flags.order_by(AnnotationFlag.time_resolved.desc())), } sort = sort if sort in sorts else default flags = sorts[sort].paginate(page, current_app.config['NOTIFICATIONS_PER_PAGE'], False) if not flags.items and page > 1: abort(404) sorturls = { key: url_for('admin.annotation_flags', annotation_id=annotation_id, sort=key) for key in sorts.keys() } next_page = (url_for('admin.annotation_flags', annotation_id=annotation.id, page=flags.next_num, sort=sort) if flags.has_next else None) prev_page = (url_for('admin.annotation_flags', annotation_id=annotation.id, page=flags.prev_num, sort=sort) if flags.has_prev else None) return render_template('indexes/annotation_flags.html', title=f"Annotation {annotation.id} flags", next_page=next_page, prev_page=prev_page, sort=sort, sorts=sorturls, flags=flags.items, annotation=annotation)
def delete_tag_request(request_id): form = AreYouSureForm() tag_request = TagRequest.query.get_or_404(request_id) if not current_user == tag_request.requester: current_user.authorize('delete_tag_requests') redirect_url = url_for('requests.tag_request_index') if form.validate_on_submit(): db.session.delete(tag_request) db.session.commit() flash(f"Tag Request for {tag_request.tag} deleted.") return redirect(redirect_url) text = """If you click submit the text request and all of it's votes will be deleted permanently.""" return render_template('forms/delete_check.html', title=f"Delete Tag Request", form=form, text=text)
def request_tag(): """Request a tag.""" current_user.authorize('request_tags') form = TagRequestForm() if form.validate_on_submit(): tag_request = TagRequest(tag=form.tag.data, description=form.description.data, weight=0, requester=current_user) db.session.add(tag_request) current_user.followed_tagrequests.append(tag_request) db.session.commit() flash("Tag request created.") flash(f"You are now follow the request for {tag_request.tag}") return redirect(url_for('requests.tag_request_index')) return render_template('forms/tag_request.html', title="Request Tag", form=form)
def request_text(): current_user.authorize('request_texts') form = TextRequestForm() if form.validate_on_submit(): text_request = TextRequest(title=form.title.data, authors=form.authors.data, description=form.description.data, requester=current_user, weight=0) db.session.add(text_request) current_user.followed_textrequests.append(text_request) db.session.commit() flash("Text request created.") flash(f"You are now following the request for {text_request.title}.") return redirect(url_for('requests.text_request_index')) return render_template('forms/text_request.html', title="Request Text", form=form)
def edit_history(annotation_id): default = 'number' page = request.args.get('page', 1, type=int) sort = request.args.get('sort', 'num_invert', type=str) annotation = Annotation.query.get_or_404(annotation_id) if not annotation.active: current_user.authorize('view_deactivated_annotations') sorts = { 'number': annotation.history.order_by(Edit.num.desc()), 'editor': (annotation.history.join(User).order_by(User.displayname.asc())), 'time': annotation.history.order_by(Edit.timestamp.asc()), } sort = sort if sort in sorts else default edits = sorts[sort]\ .paginate(page, current_app.config['NOTIFICATIONS_PER_PAGE'], False) sorturls = { key: url_for('main.edit_history', annotation_id=annotation_id, sort=key) for key in sorts.keys() } next_page = (url_for('main.edit_history', annotation_id=annotation_id, page=edits.next_num, sort=sort) if edits.has_next else None) prev_page = (url_for('main.edit_history', annotation_id=annotation_id, page=edits.prev_num, sort=sort) if edits.has_prev else None) return render_template('indexes/edit_history.html', title="Edit History", next_page=next_page, prev_page=prev_page, sort=sort, sorts=sorturls, edits=edits.items, annotation=annotation)
def review_edit(annotation_id, edit_id): """Review an edit. This, with the queue, are the chief moderation routes.""" edit = Edit.query.get_or_404(edit_id) if edit.approved == True: return redirect(edit.url) if not edit.annotation.active: current_user.authorize('review_deactivated_annotation_edits') # we have to replace single returns with spaces because markdown only # recognizes paragraph separation based on two returns. We also have to be # careful to do this for both unix and windows return variants (i.e. be # careful of \r's). diff1 = re.sub(r'(?<!\n)\r?\n(?![\r\n])', ' ', edit.previous.body) diff2 = re.sub(r'(?<!\n)\r?\n(?![\r\n])', ' ', edit.body) diff = list(difflib.Differ().compare(diff1.splitlines(), diff2.splitlines())) tags = [tag for tag in edit.tags] for tag in edit.previous.tags: if tag not in tags: tags.append(tag) if edit.first_line_num > edit.previous.first_line_num: context = [line for line in edit.previous.context] for line in edit.context: if line not in context: context.append(line) else: context = [line for line in edit.context] for line in edit.previous.context: if line not in context: context.append(line) return render_template('view/edit.html', title=f"[{edit.annotation.id}] Edit #{edit.num}", diff=diff, edit=edit, tags=tags, context=context)
def edit(annotation_id): annotation = Annotation.query.get_or_404(annotation_id) form = AnnotationForm() redirect_url = generate_next( url_for('main.annotation', annotation_id=annotation_id)) if (annotation.locked and not current_user.is_authorized('edit_locked_annotations')): flash("That annotation is locked from editing.") return redirect(redirect_url) elif annotation.edit_pending: flash("There is an edit still pending peer review.") return redirect(redirect_url) elif not annotation.active: current_user.authorize('edit_deactivated_annotations') lines = annotation.HEAD.lines context = annotation.HEAD.context if form.validate_on_submit(): fl, ll = line_check(form.first_line.data, form.last_line.data) tagsuccess, tags = process_tags(form.tags.data) try: editsuccess = annotation.edit(editor=current_user, reason=form.reason.data, fl=fl, ll=ll, fc=form.first_char_idx.data, lc=form.last_char_idx.data, body=form.annotation.data, tags=tags) except Exception as e: print(e) editsuccess = False # rerender the template with the work already filled if not (editsuccess and tagsuccess): db.session.rollback() return render_template('forms/annotation.html', form=form, title=annotation.text.title, lines=lines, text=annotation.text, edition=annotation.edition, annotation=annotation, context=context) else: db.session.commit() return redirect(redirect_url) elif not annotation.edit_pending: tag_strings = [] for t in annotation.HEAD.tags: tag_strings.append(t.tag) form.first_line.data = annotation.HEAD.first_line_num form.last_line.data = annotation.HEAD.last_line_num form.first_char_idx.data = annotation.HEAD.first_char_idx form.last_char_idx.data = annotation.HEAD.last_char_idx form.annotation.data = annotation.HEAD.body form.tags.data = ' '.join(tag_strings) return render_template('forms/annotation.html', form=form, title=f"Edit Annotation {annotation.id}", edition=annotation.edition, lines=lines, annotation=annotation, context=context)
def wrapper(*args, **kwargs): current_user.authorize(string) return f(*args, **kwargs)