diff --git a/amanuensis/lexicon/__init__.py b/amanuensis/lexicon/__init__.py index acf44e5..7342c5e 100644 --- a/amanuensis/lexicon/__init__.py +++ b/amanuensis/lexicon/__init__.py @@ -66,3 +66,16 @@ class LexiconModel(): if self.turn.current > self.turn.max: return "completed" return "ongoing" + + def can_add_character(self, uid): + return ( + # Players can't add more characters than chars_per_player + (len(self.get_characters_for_player(uid)) + < self.join.chars_per_player) + # Characters can only be added before the game starts + and not self.turn.current) + + def get_characters_for_player(self, uid=None): + return [ + char for char in self.character.values() + if uid is None or char.player == uid] diff --git a/amanuensis/server/forms.py b/amanuensis/server/forms.py index df7f2be..fad112f 100644 --- a/amanuensis/server/forms.py +++ b/amanuensis/server/forms.py @@ -6,6 +6,7 @@ from wtforms.validators import DataRequired, ValidationError, Optional from wtforms.widgets.html5 import NumberInput from amanuensis.config import json_ro +from amanuensis.lexicon.manage import add_character from amanuensis.user import UserModel @@ -206,3 +207,31 @@ class LexiconJoinForm(FlaskForm): """/lexicon//join/""" password = StringField('Password') submit = SubmitField("Submit") + + +class LexiconCharacterForm(FlaskForm): + """/lexicon//session/character/""" + characterName = StringField("Character name", validators=[DataRequired()]) + defaultSignature = TextAreaField("Default signature") + submit = SubmitField("Submit") + + def for_new(self): + self.characterName.data = "" + self.defaultSignature.data = "~" + + def for_character(self, lexicon, cid): + char = lexicon.character.get(cid) + self.characterName.data = char.name + self.defaultSignature.data = char.signature + + def add_character(self, lexicon, user): + add_character(lexicon, user, { + 'name': self.characterName.data, + 'signature': self.defaultSignature.data, + }) + + def update_character(self, lexicon, cid): + with lexicon.edit() as l: + char = l.character.get(cid) + char.name = self.characterName.data + char.signature = self.defaultSignature.data diff --git a/amanuensis/server/lexicon.py b/amanuensis/server/lexicon.py index f8b6cad..6e78815 100644 --- a/amanuensis/server/lexicon.py +++ b/amanuensis/server/lexicon.py @@ -1,12 +1,14 @@ import json -from flask import Blueprint, render_template, url_for, redirect, g, flash +from flask import ( + Blueprint, render_template, url_for, redirect, g, flash, request) from flask_login import login_required, current_user from amanuensis.config import json_ro, open_ex from amanuensis.config.loader import ReadOnlyOrderedDict -from amanuensis.lexicon.manage import valid_add, add_player -from amanuensis.server.forms import LexiconConfigForm, LexiconJoinForm +from amanuensis.lexicon.manage import valid_add, add_player, add_character +from amanuensis.server.forms import ( + LexiconConfigForm, LexiconJoinForm,LexiconCharacterForm) from amanuensis.server.helpers import ( lexicon_param, player_required, editor_required, player_required_if_not_public) @@ -61,6 +63,50 @@ def get_bp(): def session(name): return render_template('lexicon/session.html') + def edit_character(name, form, cid): + if form.validate_on_submit(): + # Update character + form.update_character(g.lexicon, cid) + flash('Character updated') + return redirect(url_for('lexicon.session', name=name)) + + if not form.is_submitted(): + # On GET, populate with the character + form.for_character(g.lexicon, cid) + return render_template('lexicon/character.html', form=form, action='edit') + + 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.id): + flash('Operation not permitted') + return redirect(url_for('lexicon.session', name=name)) + # Add the character + form.add_character(g.lexicon, current_user) + flash('Character created') + return redirect(url_for('lexicon.session', name=name)) + + if not form.is_submitted(): + # On GET, populate form for new character + form.for_new() + return render_template('lexicon/character.html', form=form, action='create') + + @bp.route('/session/character/', methods=['GET', 'POST']) + @lexicon_param + @player_required + def character(name): + form = LexiconCharacterForm() + cid = request.args.get('cid') + if cid: + if cid not in g.lexicon.character: + flash('Character not found') + return redirect(url_for('lexicon.session', name=name)) + if g.lexicon.character.get(cid).player != current_user.id: + flash('Access denied') + return redirect(url_for('lexicon.session', name=name)) + return edit_character(name, form, cid) + return create_character(name, form) + @bp.route('/session/settings/', methods=['GET', 'POST']) @lexicon_param @editor_required @@ -77,7 +123,6 @@ def get_bp(): if not form.update_lexicon(g.lexicon): flash("Error updating settings") return render_template("lexicon/settings.html", form=form) - form.submit.submitted = False flash("Settings updated") return redirect(url_for('lexicon.session', name=name)) diff --git a/amanuensis/templates/lexicon/character.html b/amanuensis/templates/lexicon/character.html new file mode 100644 index 0000000..0d00b2a --- /dev/null +++ b/amanuensis/templates/lexicon/character.html @@ -0,0 +1,23 @@ +{% extends "lexicon/lexicon.html" %} +{% block title %}Character | {{ lexicon_title }}{% endblock %} + +{% block main %} + +

Character

+
+ {{ form.hidden_tag() }} +

+ {{ form.characterName.label }}
{{ form.characterName(size=32) }} +

+

+ {{ form.defaultSignature.label }}
{{ form.defaultSignature(class_='fullwidth') }} +

+

{{ form.submit() }}

+
+ +{% for message in get_flashed_messages() %} +{{ message }}
+{% endfor %} + +{% endblock %} +{% set template_content_blocks = [self.main()] %} \ No newline at end of file diff --git a/amanuensis/templates/lexicon/session.html b/amanuensis/templates/lexicon/session.html index 2fb7494..f7d053a 100644 --- a/amanuensis/templates/lexicon/session.html +++ b/amanuensis/templates/lexicon/session.html @@ -18,6 +18,25 @@ {% for message in get_flashed_messages() %} {{ message }}
{% endfor %} -

Placeholder text for session page

+

Player actions

+ + {% endblock %} {% set template_content_blocks = template_content_blocks + [self.main()] %} \ No newline at end of file