From 916d5c2eb5632bfcd159a0c8a795bf19610d4687 Mon Sep 17 00:00:00 2001
From: Tim Van Baak
Date: Mon, 27 Apr 2020 23:24:16 -0700
Subject: [PATCH] Fix character edit form
---
amanuensis/lexicon/setup.py | 4 +-
amanuensis/server/session/__init__.py | 94 ++++++++++++-------
amanuensis/server/session/forms.py | 24 +----
.../server/session/session.character.jinja | 3 +
4 files changed, 71 insertions(+), 54 deletions(-)
diff --git a/amanuensis/lexicon/setup.py b/amanuensis/lexicon/setup.py
index 06d3b8c..22c738b 100644
--- a/amanuensis/lexicon/setup.py
+++ b/amanuensis/lexicon/setup.py
@@ -95,7 +95,7 @@ def player_can_create_character(
def create_character_in_lexicon(
player: UserModel,
lexicon: LexiconModel,
- name: str) -> None:
+ name: str) -> str:
"""
Unconditionally creates a character for a player
"""
@@ -129,3 +129,5 @@ def create_character_in_lexicon(
# Log addition
lexicon.log(f'Character "{name}" created ({character.cid})')
+
+ return character.cid
diff --git a/amanuensis/server/session/__init__.py b/amanuensis/server/session/__init__.py
index 1dfc029..f9e873a 100644
--- a/amanuensis/server/session/__init__.py
+++ b/amanuensis/server/session/__init__.py
@@ -9,7 +9,10 @@ from flask import (
Markup)
from flask_login import current_user
-from amanuensis.lexicon import attempt_publish
+from amanuensis.lexicon import (
+ attempt_publish,
+ get_player_characters,
+ create_character_in_lexicon)
from amanuensis.models import LexiconModel
from amanuensis.parser import (
parse_raw_markdown,
@@ -57,34 +60,52 @@ def session(name):
characters=characters)
-def edit_character(name, form, cid):
- if form.validate_on_submit():
- # Update character
- form.update_character(g.lexicon, cid)
- flash('Character updated')
+def edit_character(name, form, character):
+ if not form.is_submitted():
+ # GET, populate with values
+ return render_template(
+ 'session.character.jinja', form=form.for_character(character))
+
+ if not form.validate():
+ # POST with invalid data, return unchanged
+ return render_template('session.character.jinja', form=form)
+
+ # POST with valid data, update character
+ with g.lexicon.ctx.edit_config() as cfg:
+ char = cfg.character[character.cid]
+ char.name = form.characterName.data
+ char.signature = form.defaultSignature.data
+ flash('Character updated')
+ return redirect(url_for('session.session', name=name))
+
+
+def create_character(name: str, form: LexiconCharacterForm):
+ # Characters can't be created if the game has already started
+ if g.lexicon.status != LexiconModel.PREGAME:
+ flash("Characters can't be added after the game has started")
+ return redirect(url_for('session.session', name=name))
+ # Characters can't be created beyond the per-player limit
+ player_characters = get_player_characters(g.lexicon, current_user.uid)
+ if len(list(player_characters)) >= g.lexicon.cfg.join.chars_per_player:
+ flash("Can't create more characters")
return redirect(url_for('session.session', name=name))
if not form.is_submitted():
- # On GET, populate with the character
- form.for_character(g.lexicon, cid)
- return render_template('session.character.jinja', form=form, action='edit')
+ # GET, populate with default values
+ return render_template(
+ 'session.character.jinja', form=form.for_new())
+ if not form.validate():
+ # POST with invalid data, return unchanged
+ return render_template('session.character.jinja', form=form)
-def create_character(name, form):
- if form.validate_on_submit():
- # On POST, verify character can be added
- if not g.lexicon.can_add_character(current_user.uid):
- flash('Operation not permitted')
- return redirect(url_for('session.session', name=name))
- # Add the character
- form.add_character(g.lexicon, current_user)
- flash('Character created')
- return redirect(url_for('session.session', name=name))
-
- if not form.is_submitted():
- # On GET, populate form for new character
- form.for_new()
- return render_template('session.character.jinja', form=form, action='create')
+ # POST with valid data, create character
+ char_name = form.characterName.data
+ cid = create_character_in_lexicon(current_user, g.lexicon, char_name)
+ with g.lexicon.ctx.edit_config() as cfg:
+ cfg.character[cid].signature = form.defaultSignature.data
+ flash('Character created')
+ return redirect(url_for('session.session', name=name))
@bp_session.route('/character/', methods=['GET', 'POST'])
@@ -93,16 +114,21 @@ def create_character(name, form):
def character(name):
form = LexiconCharacterForm()
cid = request.args.get('cid')
- if cid:
- if cid not in g.lexicon.cfg.character:
- flash('Character not found')
- return redirect(url_for('session.session', name=name))
- if (g.lexicon.cfg.character.get(cid).player != current_user.uid
- and g.lexicon.cfg.editor != current_user.uid):
- flash('Access denied')
- return redirect(url_for('session.session', name=name))
- return edit_character(name, form, cid)
- return create_character(name, form)
+ if not cid:
+ # No character specified, creating a new character
+ return create_character(name, form)
+
+ character = g.lexicon.cfg.character.get(cid)
+ if not character:
+ # Bad character id, abort
+ flash('Character not found')
+ return redirect(url_for('session.session', name=name))
+ if current_user.uid not in (character.player, g.lexicon.cfg.editor):
+ # Only its owner and the editor can edit a character
+ flash('Access denied')
+ return redirect(url_for('session.session', name=name))
+ # Edit allowed
+ return edit_character(name, form, character)
@bp_session.route('/settings/', methods=['GET', 'POST'])
diff --git a/amanuensis/server/session/forms.py b/amanuensis/server/session/forms.py
index 46a7b55..9dee59c 100644
--- a/amanuensis/server/session/forms.py
+++ b/amanuensis/server/session/forms.py
@@ -3,8 +3,6 @@ from wtforms import (
StringField, SubmitField, TextAreaField, RadioField)
from wtforms.validators import DataRequired
-from amanuensis.lexicon import create_character_in_lexicon
-
class LexiconCharacterForm(FlaskForm):
"""/lexicon//session/character/"""
@@ -17,24 +15,12 @@ class LexiconCharacterForm(FlaskForm):
def for_new(self):
self.characterName.data = ""
self.defaultSignature.data = "~"
+ return self
- def for_character(self, lexicon, cid):
- char = lexicon.cfg.character.get(cid)
- self.characterName.data = char.name
- self.defaultSignature.data = char.signature
-
- def add_character(self, lexicon, user):
- create_character_in_lexicon(user, lexicon, self.characterName.data)
- # add_character(lexicon, user, {
- # 'name': self.characterName.data,
- # 'signature': self.defaultSignature.data,
- # })
-
- def update_character(self, lexicon, cid):
- with lexicon.ctx.edit_config() as cfg:
- char = cfg.character.get(cid)
- char.name = self.characterName.data
- char.signature = self.defaultSignature.data
+ def for_character(self, character):
+ self.characterName.data = character.name
+ self.defaultSignature.data = character.signature
+ return self
class LexiconReviewForm(FlaskForm):
diff --git a/amanuensis/server/session/session.character.jinja b/amanuensis/server/session/session.character.jinja
index f96946d..81b3036 100644
--- a/amanuensis/server/session/session.character.jinja
+++ b/amanuensis/server/session/session.character.jinja
@@ -9,6 +9,9 @@
{{ form.characterName.label }}
{{ form.characterName(size=32) }}
+ {% for error in form.characterName.errors %}
+ {{ error }}
+ {% endfor %}
{{ form.defaultSignature.label }}
{{ form.defaultSignature(class_='fullwidth') }}