Web dashboard v2 step 1: public summaries, legacy issue fallback
Public issue pages and the Atom feed now carry each pick's summary and 'Why it's here' line (bodies, The Brief, World Briefing and comments stay private). Issues stored before issues.issue_json existed rebuild their colophon and Behind the paper from issues.report_json / the run row and candidate_runs, and recover the World Briefing chapter from the EPUB on disk. The dev seed mirrors that legacy shape. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NHyYupFdBiR4VfoUM7NjSM
This commit is contained in:
@@ -1 +1 @@
|
||||
{% for section in issue.sections %}<h2>{{ section.name }}</h2><ul>{% for entry in section.entries %}<li><a href="{{ entry.url }}">{{ entry.title }}</a> — {{ entry.source }} ({{ entry.domain }}){% if !entry.comment_links.is_empty() %} · {% for link in entry.comment_links %}<a href="{{ link.url }}">{{ link.label }}</a>{% endfor %}{% endif %}</li>{% endfor %}</ul>{% endfor %}
|
||||
{% for section in issue.sections %}<h2>{{ section.name }}</h2><ul>{% for entry in section.entries %}<li><a href="{{ entry.url }}">{{ entry.title }}</a> — {{ entry.source }} ({{ entry.domain }}){% match entry.summary %}{% when Some with (summary) %}<p class="summary">{{ summary }}</p>{% when None %}{% endmatch %}{% match entry.why %}{% when Some with (why) %}<p class="why"><em>Why it's here: {{ why }}</em></p>{% when None %}{% endmatch %}{% if !entry.comment_links.is_empty() %} · {% for link in entry.comment_links %}<a href="{{ link.url }}">{{ link.label }}</a>{% endfor %}{% endif %}</li>{% endfor %}</ul>{% endfor %}
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
<dt>Bulk model</dt><dd>{{ colophon.bulk_model }}</dd>
|
||||
<dt>Editor model</dt><dd>{{ colophon.editor_model }}</dd>
|
||||
<dt>Summaries model</dt><dd>{{ colophon.summaries_model }}</dd>
|
||||
<dt>Entries considered</dt><dd>{{ colophon.entries_fetched }} from {{ colophon.feeds_seen }} feeds</dd>
|
||||
<dt>Candidates scored</dt><dd>{{ colophon.candidates }}</dd>
|
||||
<dt>Entries considered</dt><dd>{% match colophon.entries_fetched %}{% when Some with (entries) %}{{ entries }}{% match colophon.feeds_seen %}{% when Some with (feeds) %} from {{ feeds }} feeds{% when None %} from n/a feeds{% endmatch %}{% when None %}n/a{% endmatch %}</dd>
|
||||
<dt>Candidates scored</dt><dd>{% match colophon.candidates %}{% when Some with (candidates) %}{{ candidates }}{% when None %}n/a{% endmatch %}</dd>
|
||||
<dt>Articles selected</dt><dd>{{ colophon.article_count }} across {{ colophon.section_count }} sections</dd>
|
||||
<dt>Words</dt><dd>{{ colophon.total_words }} · ~{{ colophon.reading_minutes }} min read</dd>
|
||||
{% for cost in colophon.provider_costs %}<dt>{{ cost.provider }} cost</dt><dd>{{ cost.cost }}</dd>{% endfor %}
|
||||
<dt>Total token cost</dt><dd>{{ colophon.cost_usd }}</dd>
|
||||
<dt>Total token cost</dt><dd>{% match colophon.cost_usd %}{% when Some with (cost) %}{{ cost }}{% when None %}n/a{% endmatch %}</dd>
|
||||
<dt>Generator</dt><dd>{{ colophon.generator_version }}</dd>
|
||||
</dl></footer>
|
||||
</article>{% endblock %}
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
<p class="dateline">{{ issue.display_date }} · No. {{ issue.issue_number }}</p><p class="stats">{{ issue.stats_line }}</p>
|
||||
<p class="strap">A personal morning paper, assembled daily; the selection is the reader's, the words are the authors'.</p>
|
||||
{% if !downloads.is_empty() %}<p class="downloads">{% for download in downloads %}<a href="{{ download.href }}">{{ download.label }} ({{ download.size }})</a>{% endfor %}</p>{% endif %}
|
||||
{% for section in issue.sections %}<section><h2>{{ section.name }}</h2>{% for entry in section.entries %}<article{% if entry.is_lead %} class="lead"{% endif %}><h3><a href="{{ entry.url }}">{{ entry.title }}</a></h3><p class="byline">{% match entry.author %}{% when Some with (author) %}{{ author }} · {% when None %}{% endmatch %}{{ entry.source }} ({{ entry.domain }}) · {{ entry.reading_minutes }} min · {{ entry.word_count }} words</p>{% if !entry.comment_links.is_empty() %}<p class="comments">{% for link in entry.comment_links %}<a rel="noopener" target="_blank" href="{{ link.url }}">{{ link.label }}{% if !link.meta.is_empty() %}: {{ link.meta }}{% endif %}</a>{% endfor %}</p>{% endif %}</article>{% endfor %}</section>{% endfor %}
|
||||
{% for section in issue.sections %}<section><h2>{{ section.name }}</h2>{% for entry in section.entries %}<article{% if entry.is_lead %} class="lead"{% endif %}><h3><a href="{{ entry.url }}">{{ entry.title }}</a></h3><p class="byline">{% match entry.author %}{% when Some with (author) %}{{ author }} · {% when None %}{% endmatch %}{{ entry.source }} ({{ entry.domain }}) · {{ entry.reading_minutes }} min · {{ entry.word_count }} words</p>{% match entry.summary %}{% when Some with (summary) %}<p class="summary">{{ summary }}</p>{% when None %}{% endmatch %}{% match entry.why %}{% when Some with (why) %}<p class="why"><em>Why it's here: {{ why }}</em></p>{% when None %}{% endmatch %}{% if !entry.comment_links.is_empty() %}<p class="comments">{% for link in entry.comment_links %}<a rel="noopener" target="_blank" href="{{ link.url }}">{{ link.label }}{% if !link.meta.is_empty() %}: {{ link.meta }}{% endif %}</a>{% endfor %}</p>{% endif %}</article>{% endfor %}</section>{% endfor %}
|
||||
<p><a href="/issues">Browse the archive</a></p>{% endif %}</article>{% endblock %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "layout.html" %}{% block content %}<article class="reading world-briefing">
|
||||
<h1>World Briefing</h1><p class="dateline">{{ display_date }}</p><hr class="rule">
|
||||
<h1>World Briefing</h1>{% match display_date %}{% when Some with (date) %}<p class="dateline">{{ date }}</p>{% when None %}{% endmatch %}<hr class="rule">
|
||||
<div class="world-body">{{ body_html|safe }}</div>
|
||||
<p><a href="{{ issue_href }}">← Back to this issue</a></p>
|
||||
</article>{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user