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.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 %}
-{# #}
-
-{# {% 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")