diff --git a/amanuensis/cli/lexicon.py b/amanuensis/cli/lexicon.py index faa8cb5..6bcc6b0 100644 --- a/amanuensis/cli/lexicon.py +++ b/amanuensis/cli/lexicon.py @@ -318,4 +318,7 @@ def command_publish_turn(args): from amanuensis.lexicon import attempt_publish # Internal call - attempt_publish(args.lexicon) + result = attempt_publish(args.lexicon) + + if not result: + logger.error('Publish failed, check lexicon log') diff --git a/amanuensis/lexicon/gameloop.py b/amanuensis/lexicon/gameloop.py index 0cf08c8..64f8cb4 100644 --- a/amanuensis/lexicon/gameloop.py +++ b/amanuensis/lexicon/gameloop.py @@ -152,20 +152,46 @@ def content_constraint_analysis( return infos, warnings, errors -def attempt_publish(lexicon: LexiconModel) -> None: +def attempt_publish(lexicon: LexiconModel) -> bool: """ If the lexicon's publsh policy allows the current set of approved articles to be published, publish them and rebuild all pages. """ - # TODO Check against lexicon publish policy + # Load all drafts + draft_ctx = lexicon.ctx.draft + drafts = {} + for draft_fn in draft_ctx.ls(): + with draft_ctx.read(draft_fn) as draft_obj: + drafts[draft_fn] = draft_obj + + # Check for whether the current turn can be published according to current + # publish policy + characters = [ + cid for cid, char in lexicon.cfg.character.items() if char.player] + print(characters) + has_approved = {cid: 0 for cid in characters} + has_ready = {cid: 0 for cid in characters} + for draft in drafts.values(): + if draft.status.approved: + has_approved[draft.character] = 1 + elif draft.status.ready: + has_ready[draft.character] = 1 + # If quorum isn't defined, require all characters to have an article + quorum = lexicon.cfg.publish.quorum or len(characters) + if sum(has_approved.values()) < quorum: + print(sum(has_approved.values())) + print(quorum) + lexicon.log(f'Publish failed: no quorum') + return False + # If articles are up for review, check if this blocks publish + if lexicon.cfg.publish.block_on_ready and any(has_ready.values()): + lexicon.log(f'Publish failed: articles in review') + return False # Get the approved drafts to publish - draft_ctx = lexicon.ctx.draft - to_publish = [] - for draft_fn in draft_ctx.ls(): - with draft_ctx.read(draft_fn) as draft: - if draft.status.approved: - to_publish.append(draft_fn) + to_publish = [ + draft_fn for draft_fn, draft in drafts.items() + if draft.status.approved] # Publish new articles publish_drafts(lexicon, to_publish) @@ -173,6 +199,8 @@ def attempt_publish(lexicon: LexiconModel) -> None: # Rebuild all pages rebuild_pages(lexicon) + return True + def publish_drafts(lexicon: LexiconModel, filenames: Iterable[str]) -> None: """ @@ -185,7 +213,12 @@ def publish_drafts(lexicon: LexiconModel, filenames: Iterable[str]) -> None: with draft_ctx.read(filename) as source: with src_ctx.edit(filename, create=True) as dest: dest.update(source) + dest.turn = lexicon.cfg.turn.current draft_ctx.delete(filename) + # Increment the turn + lexicon.log(f'Published turn {lexicon.cfg.turn.current}') + with lexicon.ctx.edit_config() as cfg: + cfg.turn.current += 1 def rebuild_pages(lexicon: LexiconModel) -> None: diff --git a/amanuensis/server/session/__init__.py b/amanuensis/server/session/__init__.py index c853d71..4c27787 100644 --- a/amanuensis/server/session/__init__.py +++ b/amanuensis/server/session/__init__.py @@ -57,8 +57,11 @@ def session(name): characters.append(char) form = LexiconPublishTurnForm() if form.validate_on_submit(): - attempt_publish(g.lexicon) - return redirect(url_for('lexicon.contents', name=name)) + if attempt_publish(g.lexicon): + return redirect(url_for('lexicon.contents', name=name)) + else: + flash('Publish failed') + return redirect(url_for('session.session', name=name)) return render_template( 'session.root.jinja', ready_articles=drafts, @@ -157,7 +160,7 @@ def settings(name): # POST with valid data form.save(g.lexicon) flash('Settings updated') - return redirect(url_for('session.settings', name=name)) + return redirect(url_for('session.session', name=name)) @bp_session.route('/review/', methods=['GET', 'POST']) @@ -200,17 +203,21 @@ def review(name): citations=citations) # POST with valid data - if form.approved.data == LexiconReviewForm.APPROVED: - draft.status.ready = True - draft.status.approved = True - g.lexicon.log(f"Article '{draft.title}' approved ({draft.aid})") - if g.lexicon.cfg.publish.asap: - attempt_publish(g.lexicon) - else: + if form.approved.data == LexiconReviewForm.REJECTED: draft.status.ready = False draft.status.approved = False g.lexicon.log(f"Article '{draft.title}' rejected ({draft.aid})") - return redirect(url_for('session.session', name=name)) + return redirect(url_for('session.session', name=name)) + else: + draft.status.ready = True + draft.status.approved = True + g.lexicon.log(f"Article '{draft.title}' approved ({draft.aid})") + + # Draft was approved, check for asap publishing + if g.lexicon.cfg.publish.asap: + if attempt_publish(g.lexicon): + redirect(url_for('lexicon.contents', name=name)) + return redirect(url_for('session.session', name=name)) @bp_session.route('/editor/', methods=['GET']) diff --git a/amanuensis/server/session/session.editor.jinja b/amanuensis/server/session/session.editor.jinja index 495f2fd..bbbce46 100644 --- a/amanuensis/server/session/session.editor.jinja +++ b/amanuensis/server/session/session.editor.jinja @@ -66,8 +66,7 @@ {% if article.character == char.cid %}
  • - {{ article.title if article.title.strip() else "Untitled" }} - + {{ article.title if article.title.strip() else "Untitled" }} {% if not article.status.ready %} [Draft] diff --git a/amanuensis/server/session/session.root.jinja b/amanuensis/server/session/session.root.jinja index 3ff3789..af431b4 100644 --- a/amanuensis/server/session/session.root.jinja +++ b/amanuensis/server/session/session.root.jinja @@ -52,6 +52,9 @@ {% for message in get_flashed_messages() %} {{ message }}
    {% endfor %} +{% if g.lexicon.status == ONGOING %} +

    Turn {{ g.lexicon.cfg.turn.current }}

    +{% endif %}

    Player actions