Add review workflow

This commit is contained in:
Tim Van Baak 2020-04-10 15:10:09 -07:00
parent a4dc2e496f
commit c9f1f9a44f
7 changed files with 88 additions and 6 deletions

View File

@ -61,6 +61,11 @@ class ConfigDirectoryContext():
raise MissingConfigError(fpath) raise MissingConfigError(fpath)
os.delete(fpath) os.delete(fpath)
def ls(self):
"""Lists all files in this directory."""
filenames = os.listdir(self.path)
return filenames
class ConfigFileMixin(): class ConfigFileMixin():
def config(self, edit=False): def config(self, edit=False):

View File

@ -59,7 +59,7 @@ function update(article) {
} }
function updateEditorStatus() { function updateEditorStatus() {
var ready = !!params.article.status.ready var ready = !!params.article.status.ready || !!params.article.status.approved;
document.getElementById("editor-title").disabled = ready; document.getElementById("editor-title").disabled = ready;
document.getElementById("editor-content").disabled = ready; document.getElementById("editor-content").disabled = ready;
var submitButton = document.getElementById("button-submit"); var submitButton = document.getElementById("button-submit");

View File

@ -1,7 +1,7 @@
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import ( from wtforms import (
StringField, PasswordField, BooleanField, SubmitField, TextAreaField, StringField, PasswordField, BooleanField, SubmitField, TextAreaField,
IntegerField, SelectField) IntegerField, SelectField, RadioField)
from wtforms.validators import DataRequired, ValidationError, Optional from wtforms.validators import DataRequired, ValidationError, Optional
from wtforms.widgets.html5 import NumberInput from wtforms.widgets.html5 import NumberInput
@ -239,3 +239,9 @@ class LexiconCharacterForm(FlaskForm):
char = l.character.get(cid) char = l.character.get(cid)
char.name = self.characterName.data char.name = self.characterName.data
char.signature = self.defaultSignature.data char.signature = self.defaultSignature.data
class LexiconReviewForm(FlaskForm):
"""/lexicon/<name>/session/review/"""
approved = RadioField("Buttons", choices=(("Y", "Approved"), ("N", "Rejected")))
submit = SubmitField("Submit")

View File

@ -11,7 +11,7 @@ from amanuensis.errors import MissingConfigError
from amanuensis.lexicon.manage import valid_add, add_player, add_character from amanuensis.lexicon.manage import valid_add, add_player, add_character
from amanuensis.parser import parse_raw_markdown, PreviewHtmlRenderer, FeatureCounter from amanuensis.parser import parse_raw_markdown, PreviewHtmlRenderer, FeatureCounter
from amanuensis.server.forms import ( from amanuensis.server.forms import (
LexiconConfigForm, LexiconJoinForm,LexiconCharacterForm) LexiconConfigForm, LexiconJoinForm,LexiconCharacterForm, LexiconReviewForm)
from amanuensis.server.helpers import ( from amanuensis.server.helpers import (
lexicon_param, player_required, editor_required, lexicon_param, player_required, editor_required,
player_required_if_not_public) player_required_if_not_public)
@ -66,7 +66,14 @@ def get_bp():
@lexicon_param @lexicon_param
@player_required @player_required
def session(name): def session(name):
return render_template('lexicon/session.html') drafts = []
draft_ctx = g.lexicon.ctx.draft
draft_filenames = draft_ctx.ls()
for draft_filename in draft_filenames:
with draft_ctx.read(draft_filename) as draft:
if draft.status.ready and not draft.status.approved:
drafts.append(draft)
return render_template('lexicon/session.html', ready_articles=drafts)
def edit_character(name, form, cid): def edit_character(name, form, cid):
if form.validate_on_submit(): if form.validate_on_submit():
@ -135,6 +142,41 @@ def get_bp():
flash("Validation error") flash("Validation error")
return render_template("lexicon/settings.html", form=form) return render_template("lexicon/settings.html", form=form)
@bp.route('/session/review/', methods=['GET', 'POST'])
@lexicon_param
@editor_required
def review(name):
aid = request.args.get('aid')
if not aid:
flash("Unknown article id")
return redirect(url_for('lexicon.session', name=name))
draft_ctx = g.lexicon.ctx.draft
# TODO do this not terribly
draft_filename = [fn for fn in draft_ctx.ls() if aid in fn][0]
with draft_ctx.read(draft_filename) as draft:
parsed_draft = parse_raw_markdown(draft.contents)
rendered_html = parsed_draft.render(PreviewHtmlRenderer(
{'Article':'default','Phantom':None}))
form = LexiconReviewForm()
if form.validate_on_submit():
with draft_ctx.edit(draft_filename) as draft:
if not draft.status.ready:
flash("Article was rescinded")
return redirect(url_for('lexicon.session', name=name))
result = (form.approved.data == "Y")
draft.status.ready = result
draft.status.approved = result
return redirect(url_for('lexicon.session', name=name))
return render_template(
"lexicon/review.html",
form=form,
article_html=Markup(rendered_html))
@bp.route('/statistics/', methods=['GET']) @bp.route('/statistics/', methods=['GET'])
@lexicon_param @lexicon_param
@player_required_if_not_public @player_required_if_not_public
@ -239,6 +281,8 @@ def get_bp():
def editor_update(name): def editor_update(name):
article = request.json['article'] article = request.json['article']
# TODO verification # TODO verification
# check if article was previously approved
# check extrinsic constraints for blocking errors
parsed_draft = parse_raw_markdown(article['contents']) parsed_draft = parse_raw_markdown(article['contents'])
rendered_html = parsed_draft.render(PreviewHtmlRenderer( rendered_html = parsed_draft.render(PreviewHtmlRenderer(
{'Article':'default','Phantom':None})) {'Article':'default','Phantom':None}))

View File

@ -68,8 +68,8 @@
</div> </div>
{% endfor %} {% endfor %}
{% if article %} {% if article %}
<input id="editor-title" placeholder="Title" oninput="onContentChange()"> <input id="editor-title" placeholder="Title" oninput="onContentChange()" disabled>
<textarea id="editor-content" class="fullwidth" oninput="onContentChange()"></textarea> <textarea id="editor-content" class="fullwidth" oninput="onContentChange()" disabled></textarea>
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@ -0,0 +1,20 @@
{% extends "lexicon/lexicon.html" %}
{% block title %}Review | {{ lexicon_title }}{% endblock %}
{% block article %}
{{ article_html }}
{% endblock %}
{% block evaluation %}
{% for message in get_flashed_messages() %}
<span style="color: #ff0000">{{ message }}</span><br>
{% endfor %}
<form id="article-review" action="" method="post" novalidate>
{{ form.hidden_tag() }}
{{ form.approved }}
<p>{{ form.submit() }}</p>
</form>
{% endblock %}
{% set template_content_blocks = [self.article(), self.evaluation()] %}

View File

@ -18,6 +18,13 @@
Edit default character Edit default character
</a> </a>
</li> </li>
{% for article in ready_articles %}
<li>
<a href="{{ url_for('lexicon.review', name=g.lexicon.name, aid=article.aid) }}">
Review article by {{ g.lexicon.character[article.character].name }}
</a>
</li>
{% endfor %}
</ul> </ul>
{% endblock %} {% endblock %}
{% set template_content_blocks = template_content_blocks + [self.bl_editor()] %} {% set template_content_blocks = template_content_blocks + [self.bl_editor()] %}