From c6f3ae4779a716d79bb41ab6c35d47c683919244 Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Fri, 27 Aug 2021 05:15:13 -0700 Subject: [PATCH] Add top-level character page --- amanuensis/backend/character.py | 7 +- amanuensis/backend/membership.py | 7 ++ amanuensis/resources/page.css | 13 +++ amanuensis/server/__init__.py | 4 +- amanuensis/server/lexicon.jinja | 6 ++ amanuensis/server/lexicon/__init__.py | 2 + .../server/lexicon/characters/__init__.py | 94 +++++++++++++++++++ .../lexicon/characters/characters.jinja | 37 ++++++++ amanuensis/server/session/__init__.py | 71 -------------- .../server/session/session.character.jinja | 26 ----- 10 files changed, 167 insertions(+), 100 deletions(-) create mode 100644 amanuensis/server/lexicon/characters/__init__.py create mode 100644 amanuensis/server/lexicon/characters/characters.jinja delete mode 100644 amanuensis/server/session/session.character.jinja diff --git a/amanuensis/backend/character.py b/amanuensis/backend/character.py index 01f5804..2090af7 100644 --- a/amanuensis/backend/character.py +++ b/amanuensis/backend/character.py @@ -2,7 +2,7 @@ Character query interface """ -from typing import Optional +from typing import Optional, Sequence from sqlalchemy import select, func @@ -68,3 +68,8 @@ def create( db.session.add(new_character) db.session.commit() return new_character + + +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 diff --git a/amanuensis/backend/membership.py b/amanuensis/backend/membership.py index dff50e2..2dd08b8 100644 --- a/amanuensis/backend/membership.py +++ b/amanuensis/backend/membership.py @@ -2,6 +2,8 @@ Membership query interface """ +from typing import Sequence + from sqlalchemy import select, func from amanuensis.db import DbContext, Membership @@ -66,6 +68,11 @@ def create( return new_membership +def get_players_in_lexicon(db: DbContext, lexicon_id: int) -> Sequence[Membership]: + """Get all users who are members of a lexicon.""" + return db(select(Membership).where(Membership.lexicon_id == lexicon_id)).scalars() + + def try_from_ids(db: DbContext, user_id: int, lexicon_id: int) -> Membership: """Get a membership by the user and lexicon ids, or None if no such membership was found.""" return db( diff --git a/amanuensis/resources/page.css b/amanuensis/resources/page.css index b22db7b..5f3f22d 100644 --- a/amanuensis/resources/page.css +++ b/amanuensis/resources/page.css @@ -126,6 +126,19 @@ div.dashboard-lexicon-item { padding: 0 10px; border-left: 3px solid black; } +ul.blockitem-list { + list-style: none; + margin-block-start: 1em; + margin-block-end: 1em; + margin-inline-start: 0.5em; + margin-inline-end: 0.5em; + padding-inline-start: 0; + padding-inline-end: 0; +} +ul.blockitem-list li { + border-inline-start: 3px solid black; + padding-inline-start: 0.5em; +} div.dashboard-lexicon-unstarted { border-left-color: blue; } diff --git a/amanuensis/server/__init__.py b/amanuensis/server/__init__.py index 5e845f8..8f5c842 100644 --- a/amanuensis/server/__init__.py +++ b/amanuensis/server/__init__.py @@ -4,7 +4,7 @@ import os from flask import Flask, g, url_for, redirect -from amanuensis.backend import lexiq, userq, memq +from amanuensis.backend import * from amanuensis.config import AmanuensisConfig, CommandLineConfig from amanuensis.db import DbContext from amanuensis.parser import filesafe_title @@ -68,7 +68,7 @@ def get_app( # Configure jinja options def include_backend(): - return {"db": db, "lexiq": lexiq, "userq": userq, "memq": memq} + return {"db": db, "lexiq": lexiq, "userq": userq, "memq": memq, "charq": charq} app.jinja_options.update(trim_blocks=True, lstrip_blocks=True) app.template_filter("date")(date_format) diff --git a/amanuensis/server/lexicon.jinja b/amanuensis/server/lexicon.jinja index 9c976eb..8393fc1 100644 --- a/amanuensis/server/lexicon.jinja +++ b/amanuensis/server/lexicon.jinja @@ -9,6 +9,10 @@ {% block sb_logo %}{% endblock %} {% block sb_home %}Home {% endblock %} +{% block sb_characters %}Characters{% endblock %} {% block sb_contents %}= 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(): +# # 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) + +# # 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)) + diff --git a/amanuensis/server/lexicon/characters/characters.jinja b/amanuensis/server/lexicon/characters/characters.jinja new file mode 100644 index 0000000..72678b0 --- /dev/null +++ b/amanuensis/server/lexicon/characters/characters.jinja @@ -0,0 +1,37 @@ +{% extends "lexicon.jinja" %} +{% 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 %}.

+ +{#
+ {{ 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/session/__init__.py b/amanuensis/server/session/__init__.py index 743754d..2f1fdff 100644 --- a/amanuensis/server/session/__init__.py +++ b/amanuensis/server/session/__init__.py @@ -68,77 +68,6 @@ def session(name): publish_form=form) -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(): - # 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) - - # 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']) -@lexicon_param -@player_required -def character(name): - form = LexiconCharacterForm() - cid = request.args.get('cid') - 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']) @lexicon_param @editor_required diff --git a/amanuensis/server/session/session.character.jinja b/amanuensis/server/session/session.character.jinja deleted file mode 100644 index 81b3036..0000000 --- a/amanuensis/server/session/session.character.jinja +++ /dev/null @@ -1,26 +0,0 @@ -{% extends "lexicon.jinja" %} -{% block title %}Character | {{ lexicon_title }}{% endblock %} - -{% block main %} - -

Character

-
- {{ 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