Files
weircon-front/templates/podcast.html
T
agw 4274047158
CD / deploy (push) Successful in 16s
CI / check (push) Successful in 22s
feat(podcast): familiens podcast med personlige feeds
/podcast viser familiens podcasts (Slægtens Stemmer) med afspiller og en
abonnér-knap til Apple Podcasts, Overcast, Pocket Casts og AntennaPod. Podcast-
apps kan ikke logge ind med Authentik, så hver lytter får sin egen hemmelige
nøgle i adressen (/podcast/<nøgle>/<show>.xml); mp3-filer og omslag ligger
under samme nøgle. En nøgle kan trækkes tilbage i /admin/podcast uden at de
andre mærker det, og admin ser hvem der henter hvad.

Episoder kan ligge som kladde: så ses de kun af administratorer, også i deres
eget feed, indtil de udgives fra admin-siden. Adgang: gruppen PODCAST_GROUP
(standard Familie) og admins. Forsiden får et kort, når der er episoder.

Data ligger i DATA/podcast/ og kommer aldrig i git. mutagen læser varigheden.

Claude-Session: https://claude.ai/code/session_012LCTmU2ewo8tnM1dByYAoG
2026-10-04 19:31:11 +02:00

80 lines
3.9 KiB
HTML

{% extends "base.html" %}
{% block title %}Podcast{% endblock %}
{% block body %}
{% if saved %}<div class="wt-flash">{{ saved }}</div>{% endif %}
{% if not udsendelser %}
<h1>Podcast</h1>
<p class="wt-muted">Der er ingen podcasts endnu.</p>
{% endif %}
{% for u in udsendelser %}
<section style="margin:1rem 0 2.5rem">
<div style="display:flex;gap:1.2rem;align-items:flex-start;flex-wrap:wrap">
{% if u.har_cover %}
<img src="/podcast/{{ key }}/{{ u.slug }}/cover.jpg" alt="" width="160" height="160"
style="border-radius:14px;flex:0 0 auto;box-shadow:0 4px 18px rgba(0,0,0,.25)">
{% endif %}
<div style="flex:1 1 18rem;min-width:0">
<h1 style="margin:.1rem 0 .4rem">{{ u.titel }}</h1>
<p class="wt-lead" style="margin:0">{{ u.beskrivelse }}</p>
</div>
</div>
<div class="wt-card" style="margin:1.4rem 0;padding:1rem 1.2rem">
<h2 style="font-size:1.05rem;margin:0 0 .5rem">Abonnér i din podcast-app</h2>
<p class="wt-muted" style="margin:.2rem 0 .8rem">Tryk på din app. Nye episoder kommer så af sig selv. Adressen er din egen, så del den ikke; familien får hver sin.</p>
<div style="display:flex;flex-wrap:wrap;gap:.5rem">
<a class="wt-btn wt-btn--primary" href="podcast://{{ u.uden_skema }}">Apple Podcasts</a>
<a class="wt-btn" href="overcast://x-callback-url/add?url={{ u.feed_enc }}">Overcast</a>
<a class="wt-btn" href="pktc://subscribe/{{ u.uden_skema }}">Pocket Casts</a>
<a class="wt-btn" href="https://antennapod.org/deeplink/subscribe?url={{ u.feed_enc }}">AntennaPod</a>
</div>
<details style="margin-top:.9rem">
<summary class="wt-muted" style="cursor:pointer">Anden app? Kopiér adressen</summary>
<div style="display:flex;gap:.5rem;margin-top:.5rem;flex-wrap:wrap">
<input class="wt-input" readonly value="{{ u.feed }}" id="feed-{{ u.slug }}"
style="flex:1 1 20rem;font-family:ui-monospace,monospace;font-size:.85rem" onclick="this.select()">
<button class="wt-btn" type="button" data-kopier="feed-{{ u.slug }}">Kopiér</button>
</div>
<p class="wt-muted" style="font-size:.85rem;margin:.5rem 0 0">Spotify kan ikke abonnere på private podcasts. På Android virker AntennaPod og Pocket Casts.</p>
</details>
</div>
<h2 style="font-size:1.15rem">Episoder</h2>
{% for e in u.episoder %}
<article class="wt-card" style="margin:.8rem 0;padding:1rem 1.2rem">
<div style="display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap">
<h3 style="margin:0;font-size:1.05rem">{% if e.nr %}{{ e.nr }}. {% endif %}{{ e.titel }}</h3>
<span class="wt-muted" style="font-size:.85rem">
{% if e.kladde %}<strong>Kladde, kun du kan se den</strong> · {% endif %}{{ (e.varighed // 60) }} min
</span>
</div>
{% if e.beskrivelse %}<p style="margin:.5rem 0">{{ e.beskrivelse }}</p>{% endif %}
<audio controls preload="none" style="width:100%;margin-top:.4rem"
src="/podcast/{{ key }}/{{ u.slug }}/{{ e.slug }}.mp3"></audio>
</article>
{% else %}
<p class="wt-muted">Ingen episoder endnu.</p>
{% endfor %}
</section>
{% endfor %}
{% if udsendelser %}
<form method="post" action="/podcast/ny-noegle" style="margin:2rem 0"
onsubmit="return confirm('Din gamle adresse holder op med at virke, og du skal abonnere igen i din app. Fortsæt?')">
<button class="wt-btn" type="submit">Lav en ny adresse</button>
<span class="wt-muted" style="font-size:.85rem">Hvis du har delt din adresse ved et uheld.</span>
</form>
{% endif %}
<script>
document.querySelectorAll('[data-kopier]').forEach(function (b) {
b.addEventListener('click', function () {
var i = document.getElementById(b.dataset.kopier);
i.select();
(navigator.clipboard ? navigator.clipboard.writeText(i.value) : Promise.reject())
.catch(function () { document.execCommand('copy'); })
.finally(function () { b.textContent = 'Kopieret'; });
});
});
</script>
{% endblock %}