audiothek

alternative frontend for ardaudiothek.de  https://audiothek.ce9e.org/
git clone https://git.ce9e.org/audiothek.git

commit
881e58f9232a7892d4a16fab42a2e2dd03017dec
parent
ecd7c1577bd374c20eceb93c049a2e2af3627a2e
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2025-12-21 11:51
render show as html

Diffstat

M audiothek.go 18 +++++++++++++++---
M style.css 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------
A templates/show.html 46 ++++++++++++++++++++++++++++++++++++++++++++++

3 files changed, 122 insertions, 13 deletions


diff --git a/audiothek.go b/audiothek.go

@@ -24,7 +24,7 @@ import (
   24    24 
   25    25 const COUNT = 20
   26    26 
   27    -1 var urlPattern = regexp.MustCompile(`^/([0-9]+|urn:ard:show:[a-z0-9]+)\.(rss|m3u)$`)
   -1    27 var urlPattern = regexp.MustCompile(`^/([0-9]+|urn:ard:show:[a-z0-9]+)(\.rss|\.m3u|\/)$`)
   28    28 var origin = ""
   29    29 
   30    30 const QUERY = `
@@ -80,6 +80,7 @@ var tplData embed.FS
   80    80 var tplFuncs = template.FuncMap{
   81    81 	"reverse":        reverse,
   82    82 	"trim":           strings.TrimSpace,
   -1    83 	"date":           formatDate,
   83    84 	"rssDate":        rssDate,
   84    85 	"imgWidth":       imgWidth,
   85    86 	"itunesCategory": itunesCategory,
@@ -147,6 +148,14 @@ func reverse(items []Item) iter.Seq[Item] {
  147   148 	}
  148   149 }
  149   150 
   -1   151 func formatDate(s string) (string, error) {
   -1   152 	t, err := time.Parse(time.RFC3339, s)
   -1   153 	if err != nil {
   -1   154 		return "", err
   -1   155 	}
   -1   156 	return t.Format("02.01.2006"), nil
   -1   157 }
   -1   158 
  150   159 func rssDate(s string) (string, error) {
  151   160 	t, err := time.Parse(time.RFC3339, s)
  152   161 	if err != nil {
@@ -230,12 +239,15 @@ func handle(w http.ResponseWriter, r *http.Request) {
  230   239 		NextOffset: offset + COUNT,
  231   240 	}
  232   241 
  233    -1 	if matches[2] == "rss" {
   -1   242 	if matches[2] == ".rss" {
  234   243 		w.Header().Set("Content-Type", "text/xml")
  235   244 		err = tpl.ExecuteTemplate(w, "show.rss", ctx)
  236    -1 	} else if matches[2] == "m3u" {
   -1   245 	} else if matches[2] == ".m3u" {
  237   246 		w.Header().Set("Content-Type", "text/plain")
  238   247 		err = tpl.ExecuteTemplate(w, "show.m3u", ctx)
   -1   248 	} else if matches[2] == "/" {
   -1   249 		w.Header().Set("Content-Type", "text/html")
   -1   250 		err = tpl.ExecuteTemplate(w, "show.html", ctx)
  239   251 	}
  240   252 
  241   253 	if err != nil {

diff --git a/style.css b/style.css

@@ -1,6 +1,10 @@
   -1     1 * {
   -1     2 	box-sizing: border-box;
   -1     3 }
   -1     4 
    1     5 body {
    2    -1 	max-inline-size: 40em;
    3    -1 	padding: 1em;
   -1     6 	max-inline-size: 50em;
   -1     7 	padding-inline: 1em;
    4     8 	margin-block: 0;
    5     9 	margin-inline: auto;
    6    10 	background-color: #000e29;
@@ -8,21 +12,68 @@ body {
    8    12 	font-family: sans-serif;
    9    13 	line-height: 1.4;
   10    14 }
   -1    15 
   11    16 a {
   12    17 	color: #007aff;
   13    18 }
   14    -1 pre {
   15    -1 	font-size: 125%;
   16    -1 	border-radius: 0.2em;
   17    -1 	background-color: #243350;
   18    -1 	padding: 0.5em;
   19    -1 	overflow: auto;
   20    -1 }
   21    -1 h2 {
   -1    19 
   -1    20 h2, h3 {
   -1    21 	line-height: 1.2;
   22    22 	margin-block: 2em 0.5rem;
   23    23 }
   -1    24 
   -1    25 img {
   -1    26 	max-inline-size: 100%;
   -1    27 	block-size: auto;
   -1    28 }
   -1    29 
   24    30 blockquote {
   25    31 	margin-inline: 0;
   26    32 	padding-inline-start: 1em;
   27    33 	border-inline-start: 0.5em solid #243350;
   28    34 }
   -1    35 
   -1    36 pre,
   -1    37 .btn {
   -1    38 	font-family: inherit;
   -1    39 	font-size: inherit;
   -1    40 	color: inherit;
   -1    41 	border: 2px solid #243350;
   -1    42 	border-radius: 0.2em;
   -1    43 	padding-inline: 1em;
   -1    44 	padding-block: 0.5em;
   -1    45 }
   -1    46 
   -1    47 pre,
   -1    48 .btn:hover {
   -1    49 	background-color: #243350;
   -1    50 }
   -1    51 .btn {
   -1    52 	background: transparent;
   -1    53 	text-decoration: none;
   -1    54 }
   -1    55 pre {
   -1    56 	font-size: 125%;
   -1    57 }
   -1    58 
   -1    59 .center {
   -1    60 	margin-block: 0 4em;
   -1    61 	text-align: center;
   -1    62 }
   -1    63 
   -1    64 .items {
   -1    65 	padding: 0;
   -1    66 }
   -1    67 .items li {
   -1    68 	display: flex;
   -1    69 	align-items: start;
   -1    70 	gap: 1em;
   -1    71 	margin-block: 0 2em;
   -1    72 }
   -1    73 .items div {
   -1    74 	flex: 1;
   -1    75 }
   -1    76 .items h3,
   -1    77 .items p {
   -1    78 	margin-block: 0 0.2em;
   -1    79 }

diff --git a/templates/show.html b/templates/show.html

@@ -0,0 +1,46 @@
   -1     1 <!DOCTYPE html>
   -1     2 <html lang="de">
   -1     3 <head>
   -1     4 	<meta charset="utf-8">
   -1     5 	<meta name="viewport" content="width=device-width">
   -1     6 	<title>{{.Show.Title | html}} &middot; Audiothek</title>
   -1     7 	<link rel="stylesheet" type="text/css" href="/style.css">
   -1     8 	<link rel="alternate" type="application/rss+xml" href="/{{.Id | html}}.rss">
   -1     9 </head>
   -1    10 <body>
   -1    11 	<main>
   -1    12 		<div class="center">
   -1    13 			<h2>{{.Show.Title | html}}</h2>
   -1    14 			<div>
   -1    15 				{{.Show.PublicationService.Title | html}}
   -1    16 				{{- if .Show.EditorialCategory.Title}}
   -1    17 				&middot; {{.Show.EditorialCategory.Title | html}}
   -1    18 				{{- end}}
   -1    19 				&middot; <a href="/{{.Id | html}}.rss" rel="alternate">RSS</a>
   -1    20 				&middot; <a href="/{{.Id | html}}.m3u" rel="alternate">M3U</a>
   -1    21 				&middot; <a href="{{.Show.SharingUrl | html}}" rel="alternate">Audiothek</a>
   -1    22 			</div>
   -1    23 			<p>{{.Show.Synopsis | html}}</p>
   -1    24 		</div>
   -1    25 		<ul class="items">
   -1    26 			{{- range .Show.Items.Nodes}}
   -1    27 			{{- $audio := index .Audios 0 }}
   -1    28 			<li>
   -1    29 				<a href="{{$audio.Url | html}}" tabindex="-1">
   -1    30 					<img src="{{.Image.Url1X1 | imgWidth 120 | html}}" alt="" width="120" height="120" loading="lazy">
   -1    31 				</a>
   -1    32 				<div>
   -1    33 					<time datetime="{{.PublishDate | html}}">{{.PublishDate | date | html}}</time>
   -1    34 					<h3><a href="{{$audio.Url | html}}">{{.Title | html}}</a></h3>
   -1    35 					<p>{{.Summary | html}}…</p>
   -1    36 				</div>
   -1    37 			</li>
   -1    38 			{{- end}}
   -1    39 		</ul>
   -1    40 		{{- if .Show.Items.PageInfo.HasNextPage}}
   -1    41 		<div class="center">
   -1    42 			<a href="?offset={{.NextOffset | html}}" rel="next" class="btn">Mehr…</a>
   -1    43 		</div>
   -1    44 		{{- end}}
   -1    45 	</main>
   -1    46 </body>