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.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
-
-
-{% for message in get_flashed_messages() %}
-{{ message }}
-{% endfor %}
-
-{% endblock %}
-{% set template_content_blocks = [self.main()] %}
\ No newline at end of file