Refactor editor functions into another file
This commit is contained in:
parent
9f785b1f4e
commit
d580949de0
|
@ -1,4 +1,3 @@
|
||||||
import json
|
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from flask import (
|
from flask import (
|
||||||
|
@ -12,10 +11,7 @@ from flask import (
|
||||||
Markup)
|
Markup)
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
from amanuensis.lexicon import (
|
from amanuensis.lexicon import attempt_publish
|
||||||
get_player_characters,
|
|
||||||
get_player_drafts,
|
|
||||||
attempt_publish)
|
|
||||||
from amanuensis.models import LexiconModel
|
from amanuensis.models import LexiconModel
|
||||||
from amanuensis.parser import (
|
from amanuensis.parser import (
|
||||||
parse_raw_markdown,
|
parse_raw_markdown,
|
||||||
|
@ -30,9 +26,7 @@ from amanuensis.server.helpers import (
|
||||||
player_required,
|
player_required,
|
||||||
editor_required)
|
editor_required)
|
||||||
|
|
||||||
|
from .editor import load_editor, new_draft, update_draft
|
||||||
def jsonfmt(obj):
|
|
||||||
return Markup(json.dumps(obj))
|
|
||||||
|
|
||||||
|
|
||||||
bp_session = Blueprint('session', __name__,
|
bp_session = Blueprint('session', __name__,
|
||||||
|
@ -187,89 +181,24 @@ def review(name):
|
||||||
@player_required
|
@player_required
|
||||||
def editor(name):
|
def editor(name):
|
||||||
lexicon: LexiconModel = g.lexicon
|
lexicon: LexiconModel = g.lexicon
|
||||||
aid = request.args.get('aid')
|
aid: str = request.args.get('aid')
|
||||||
if aid:
|
return load_editor(lexicon, aid)
|
||||||
# Article specfied, load editor in edit mode
|
|
||||||
article_fn = None
|
|
||||||
for filename in lexicon.ctx.draft.ls():
|
|
||||||
if filename.endswith(f'{aid}.json'):
|
|
||||||
article_fn = filename
|
|
||||||
break
|
|
||||||
if not article_fn:
|
|
||||||
flash("Draft not found")
|
|
||||||
return redirect(url_for('session.session', name=name))
|
|
||||||
with lexicon.ctx.draft.read(article_fn) as a:
|
|
||||||
article = a
|
|
||||||
# Check that the player owns this article
|
|
||||||
character = lexicon.cfg.character.get(article.character)
|
|
||||||
if character.player != current_user.uid:
|
|
||||||
flash("Access forbidden")
|
|
||||||
return redirect(url_for('session.session', name=name))
|
|
||||||
return render_template(
|
|
||||||
'session.editor.jinja',
|
|
||||||
character=character,
|
|
||||||
article=article,
|
|
||||||
jsonfmt=jsonfmt)
|
|
||||||
|
|
||||||
# Article not specified, load editor in load mode
|
|
||||||
characters = list(get_player_characters(lexicon, current_user.uid))
|
|
||||||
articles = list(get_player_drafts(lexicon, current_user.uid))
|
|
||||||
print(characters)
|
|
||||||
print(articles)
|
|
||||||
return render_template(
|
|
||||||
'session.editor.jinja',
|
|
||||||
characters=characters,
|
|
||||||
articles=articles)
|
|
||||||
|
|
||||||
|
|
||||||
@bp_session.route('/editor/new', methods=['GET'])
|
@bp_session.route('/editor/new', methods=['GET'])
|
||||||
@lexicon_param
|
@lexicon_param
|
||||||
@player_required
|
@player_required
|
||||||
def editor_new(name):
|
def editor_new(name):
|
||||||
new_aid = uuid.uuid4().hex
|
lexicon: LexiconModel = g.lexicon
|
||||||
# TODO harden this
|
cid: str = request.args.get('cid')
|
||||||
cid = request.args.get("cid")
|
return new_draft(lexicon, cid)
|
||||||
character = g.lexicon.cfg.character.get(cid)
|
|
||||||
article = {
|
|
||||||
"version": "0",
|
|
||||||
"aid": new_aid,
|
|
||||||
"lexicon": g.lexicon.lid,
|
|
||||||
"character": cid,
|
|
||||||
"title": "",
|
|
||||||
"turn": 1,
|
|
||||||
"status": {
|
|
||||||
"ready": False,
|
|
||||||
"approved": False
|
|
||||||
},
|
|
||||||
"contents": f"\n\n{character.signature}",
|
|
||||||
}
|
|
||||||
filename = f"{cid}.{new_aid}"
|
|
||||||
with g.lexicon.ctx.draft.new(filename) as j:
|
|
||||||
j.update(article)
|
|
||||||
return redirect(url_for('session.editor', name=name, cid=cid, aid=new_aid))
|
|
||||||
|
|
||||||
|
|
||||||
@bp_session.route('/editor/update', methods=['POST'])
|
@bp_session.route('/editor/update', methods=['POST'])
|
||||||
@lexicon_param
|
@lexicon_param
|
||||||
@player_required
|
@player_required
|
||||||
def editor_update(name):
|
def editor_update(name):
|
||||||
article = request.json['article']
|
lexicon: LexiconModel = g.lexicon
|
||||||
# TODO verification
|
article_json = request.json['article']
|
||||||
# check if article was previously approved
|
return update_draft(lexicon, article_json)
|
||||||
# check extrinsic constraints for blocking errors
|
# only need to be sending around title, status, contents, aid
|
||||||
parsed_draft = parse_raw_markdown(article['contents'])
|
|
||||||
rendered_html = parsed_draft.render(PreviewHtmlRenderer(g.lexicon))
|
|
||||||
features = parsed_draft.render(FeatureCounter())
|
|
||||||
|
|
||||||
filename = f'{article["character"]}.{article["aid"]}'
|
|
||||||
with g.lexicon.ctx.draft.edit(filename) as a:
|
|
||||||
a.update(article)
|
|
||||||
|
|
||||||
# TODO return more info
|
|
||||||
return {
|
|
||||||
'article': article,
|
|
||||||
'info': {
|
|
||||||
'rendered': rendered_html,
|
|
||||||
'word_count': features.word_count,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
"""
|
||||||
|
Handler helper functions pertaining to the article editor
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from flask import (
|
||||||
|
flash, redirect, url_for, render_template, Markup)
|
||||||
|
from flask_login import current_user
|
||||||
|
|
||||||
|
from amanuensis.lexicon import get_player_characters, get_player_drafts
|
||||||
|
from amanuensis.models import LexiconModel
|
||||||
|
from amanuensis.parser import (
|
||||||
|
parse_raw_markdown,
|
||||||
|
PreviewHtmlRenderer,
|
||||||
|
FeatureCounter)
|
||||||
|
|
||||||
|
|
||||||
|
def load_editor(lexicon: LexiconModel, aid: str):
|
||||||
|
"""
|
||||||
|
Load the editor page
|
||||||
|
"""
|
||||||
|
if aid:
|
||||||
|
# Article specfied, load editor in edit mode
|
||||||
|
article_fn = None
|
||||||
|
for filename in lexicon.ctx.draft.ls():
|
||||||
|
if filename.endswith(f'{aid}.json'):
|
||||||
|
article_fn = filename
|
||||||
|
break
|
||||||
|
if not article_fn:
|
||||||
|
flash("Draft not found")
|
||||||
|
return redirect(url_for('session.session', name=lexicon.cfg.name))
|
||||||
|
with lexicon.ctx.draft.read(article_fn) as a:
|
||||||
|
article = a
|
||||||
|
# Check that the player owns this article
|
||||||
|
character = lexicon.cfg.character.get(article.character)
|
||||||
|
if character.player != current_user.uid:
|
||||||
|
flash("Access forbidden")
|
||||||
|
return redirect(url_for('session.session', name=lexicon.cfg.name))
|
||||||
|
return render_template(
|
||||||
|
'session.editor.jinja',
|
||||||
|
character=character,
|
||||||
|
article=article,
|
||||||
|
jsonfmt=lambda obj: Markup(json.dumps(obj)))
|
||||||
|
|
||||||
|
# Article not specified, load editor in load mode
|
||||||
|
characters = list(get_player_characters(lexicon, current_user.uid))
|
||||||
|
articles = list(get_player_drafts(lexicon, current_user.uid))
|
||||||
|
return render_template(
|
||||||
|
'session.editor.jinja',
|
||||||
|
characters=characters,
|
||||||
|
articles=articles)
|
||||||
|
|
||||||
|
|
||||||
|
def new_draft(lexicon: LexiconModel, cid: str):
|
||||||
|
"""
|
||||||
|
Create a new draft and open it in the editor
|
||||||
|
"""
|
||||||
|
if cid:
|
||||||
|
new_aid = uuid.uuid4().hex
|
||||||
|
# TODO harden this
|
||||||
|
character = lexicon.cfg.character.get(cid)
|
||||||
|
article = {
|
||||||
|
"version": "0",
|
||||||
|
"aid": new_aid,
|
||||||
|
"lexicon": lexicon.lid,
|
||||||
|
"character": cid,
|
||||||
|
"title": "",
|
||||||
|
"turn": 1,
|
||||||
|
"status": {
|
||||||
|
"ready": False,
|
||||||
|
"approved": False
|
||||||
|
},
|
||||||
|
"contents": f"\n\n{character.signature}",
|
||||||
|
}
|
||||||
|
filename = f"{cid}.{new_aid}"
|
||||||
|
with lexicon.ctx.draft.new(filename) as j:
|
||||||
|
j.update(article)
|
||||||
|
return redirect(url_for(
|
||||||
|
'session.editor',
|
||||||
|
name=lexicon.cfg.name,
|
||||||
|
cid=cid,
|
||||||
|
aid=new_aid))
|
||||||
|
|
||||||
|
# Character not specified
|
||||||
|
flash('Character not found')
|
||||||
|
return redirect(url_for('session.session', name=lexicon.cfg.name))
|
||||||
|
|
||||||
|
|
||||||
|
def update_draft(lexicon: LexiconModel, article_json):
|
||||||
|
"""
|
||||||
|
Update a draft and perform analysis on it
|
||||||
|
"""
|
||||||
|
aid = article_json.get('aid')
|
||||||
|
# TODO check if article can be updated
|
||||||
|
# article exists
|
||||||
|
# player owns article
|
||||||
|
# article is not already approved
|
||||||
|
|
||||||
|
contents = article_json.get('contents')
|
||||||
|
if contents is not None:
|
||||||
|
parsed = parse_raw_markdown(contents)
|
||||||
|
# HTML parsing
|
||||||
|
rendered_html = parsed.render(PreviewHtmlRenderer(lexicon))
|
||||||
|
# Constraint analysis
|
||||||
|
# features = parsed_draft.render(FeatureCounter()) TODO
|
||||||
|
filename = f'{article_json["character"]}.{article_json["aid"]}'
|
||||||
|
with lexicon.ctx.draft.edit(filename) as article:
|
||||||
|
# TODO
|
||||||
|
article.contents = contents
|
||||||
|
return {
|
||||||
|
'article': article,
|
||||||
|
'info': {
|
||||||
|
'rendered': rendered_html,
|
||||||
|
#'word_count': features.word_count,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {}
|
Loading…
Reference in New Issue