From af5b1c4cfa579cdb1320c73309a128a86010ea52 Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Fri, 27 Aug 2021 07:49:47 -0700 Subject: [PATCH] Add character editing page --- amanuensis/backend/character.py | 8 +- amanuensis/resources/page.css | 4 + .../server/lexicon/characters/__init__.py | 79 +++++++++---------- .../lexicon/characters/characters.edit.jinja | 24 ++++++ .../lexicon/characters/characters.jinja | 27 ++----- amanuensis/server/lexicon/characters/forms.py | 11 +++ 6 files changed, 89 insertions(+), 64 deletions(-) create mode 100644 amanuensis/server/lexicon/characters/characters.edit.jinja create mode 100644 amanuensis/server/lexicon/characters/forms.py diff --git a/amanuensis/backend/character.py b/amanuensis/backend/character.py index 2090af7..c9be1fc 100644 --- a/amanuensis/backend/character.py +++ b/amanuensis/backend/character.py @@ -3,6 +3,7 @@ Character query interface """ from typing import Optional, Sequence +from uuid import UUID from sqlalchemy import select, func @@ -72,4 +73,9 @@ def create( def get_in_lexicon(db: DbContext, lexicon_id: int) -> Sequence[Character]: """Get all characters in a lexicon.""" - return db(select(Character).where(Character.lexicon_id == lexicon_id)).scalars() \ No newline at end of file + return db(select(Character).where(Character.lexicon_id == lexicon_id)).scalars() + + +def try_from_public_id(db: DbContext, public_id: UUID) -> Optional[Character]: + """Get a character by its public id.""" + return db(select(Character).where(Character.public_id == public_id)).scalar_one_or_none() diff --git a/amanuensis/resources/page.css b/amanuensis/resources/page.css index 5f3f22d..d32161f 100644 --- a/amanuensis/resources/page.css +++ b/amanuensis/resources/page.css @@ -139,6 +139,10 @@ ul.blockitem-list li { border-inline-start: 3px solid black; padding-inline-start: 0.5em; } +ul.blockitem-list p { + margin-block-start: 0.5em; + margin-block-end: 0.5em; +} div.dashboard-lexicon-unstarted { border-left-color: blue; } diff --git a/amanuensis/server/lexicon/characters/__init__.py b/amanuensis/server/lexicon/characters/__init__.py index 8504551..5276ce2 100644 --- a/amanuensis/server/lexicon/characters/__init__.py +++ b/amanuensis/server/lexicon/characters/__init__.py @@ -1,8 +1,15 @@ -from flask import Blueprint, render_template, url_for +from typing import Optional +import uuid + +from flask import Blueprint, render_template, url_for, g, flash from werkzeug.utils import redirect +from amanuensis.backend import charq +from amanuensis.db import Character from amanuensis.server.helpers import lexicon_param, player_required +from .forms import CharacterCreateForm + bp = Blueprint("characters", __name__, url_prefix="/characters", template_folder=".") @@ -14,54 +21,40 @@ def characters(name): return render_template('characters.jinja') -@bp.post('/') +@bp.route('/edit/', methods=['GET', 'POST']) @lexicon_param @player_required -def update(name): - return redirect(url_for('lexicon.statistics', name=name)) +def edit(name, character_id): + try: + char_uuid = uuid.UUID(character_id) + except: + flash("Character not found") + return redirect(url_for('lexicon.characters.characters', name=name)) + character: Optional[Character] = charq.try_from_public_id(g.db, char_uuid) + if not character: + flash("Character not found") + return redirect(url_for('lexicon.characters.characters', name=name)) + form = CharacterCreateForm() -# @bp.route('/', methods=['GET', 'POST']) -# @lexicon_param -# @player_required -# def characters(name): -# return render_template("characters.jinja") - # form = LexiconCharacterForm() - # cid = request.args.get('cid') - # if not cid: - # # No character specified, creating a new character - # return create_character(name, form) + if not form.is_submitted(): + # GET + form.name.data = character.name + form.signature.data = character.signature + return render_template('characters.edit.jinja', character=character, form=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) + else: + # POST + if form.validate(): + # Data is valid + character.name = form.name.data + character.signature = form.signature.data + g.db.session.commit() + return redirect(url_for('lexicon.characters.characters', name=name)) - -# 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)) + else: + # POST submitted invalid data + return render_template('characters.edit.jinja', character=character, form=form) # def create_character(name: str, form: LexiconCharacterForm): diff --git a/amanuensis/server/lexicon/characters/characters.edit.jinja b/amanuensis/server/lexicon/characters/characters.edit.jinja new file mode 100644 index 0000000..b9693d7 --- /dev/null +++ b/amanuensis/server/lexicon/characters/characters.edit.jinja @@ -0,0 +1,24 @@ +{% extends "lexicon.jinja" %} +{% block title %}Edit {{ character.name }} | {{ lexicon_title }}{% endblock %} + +{% block main %} +
+ {{ form.hidden_tag() }} +

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

+ {% for error in form.name.errors %} + {{ error }}
+ {% endfor %}

+

+ {{ form.signature.label }}
{{ form.signature(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/server/lexicon/characters/characters.jinja b/amanuensis/server/lexicon/characters/characters.jinja index 72678b0..f3f023e 100644 --- a/amanuensis/server/lexicon/characters/characters.jinja +++ b/amanuensis/server/lexicon/characters/characters.jinja @@ -2,36 +2,23 @@ {% block title %}Character | {{ lexicon_title }}{% endblock %} {% block main %} -

Characters

{% set players = memq.get_players_in_lexicon(db, g.lexicon.id)|list %} {% set characters = charq.get_in_lexicon(db, g.lexicon.id)|list %}

This lexicon has {{ players|count }} player{% if players|count > 1 %}s{% endif %} and {{ characters|count }} character{% if characters|count > 1 %}s{% endif %}.

+{% for message in get_flashed_messages() %} +{{ message }}
+{% endfor %} -{#
- {{ form.hidden_tag() }} -

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

- {% for error in form.characterName.errors %} - {{ error }}
- {% endfor %}

-

- {{ 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/server/lexicon/characters/forms.py b/amanuensis/server/lexicon/characters/forms.py new file mode 100644 index 0000000..a06edd8 --- /dev/null +++ b/amanuensis/server/lexicon/characters/forms.py @@ -0,0 +1,11 @@ +from flask_wtf import FlaskForm +from wtforms import StringField, SubmitField, TextAreaField +from wtforms.validators import DataRequired + + +class CharacterCreateForm(FlaskForm): + """/lexicon//characters/edit/""" + + name = StringField("Character name", validators=[DataRequired()]) + signature = TextAreaField("Signature") + submit = SubmitField("Submit")