This commit is contained in:
Florian Maury 2024-10-12 17:26:17 +02:00
commit 52e4d2eca4
17 changed files with 778 additions and 0 deletions

0
.hugo_build.lock Normal file
View file

75
archetypes/episode.md Normal file
View file

@ -0,0 +1,75 @@
---
title: '{{ replace .File.ContentBaseName "-" " " | title }}' # podcast field: itunes:title ; title of the episode
description: "" # podcast field: description
date: {{ .Date }} # podcast field: pubDate
outputs:
- html
- json
params:
enclosure:
resource_file: "" # name of the resource in the episode directory
external_url: "" # absolute external URL if the audio file is hosted somewhere else
length: 0 # byte length of the episode
type: "" # mime type of the enclosed file
alternate_enclosures:
- sources: # one of resource_file or external_url per item
- resource_file: "" # name of the resource in the episode directory
external_url: "" # URL to download that enclosure
sri_hash: "" # SRI hash of the file to download
type: "" # MIME type of that enclosure
length: 0 # optional/recommended; byte length of the file to download
bitrate: 0 # optional; bitrate of the file, expressed as bits per second
lang: fr # optional; language tag from IETF BCP 47
title: "" # optional; title of the asset; max 32 chars
codecs: "" # optional; codec string as in RFC 6381
guid: "" # podcast field: guid
# duration: 0 # podcast field: itunes:duration ; expressed in seconds
# image: "" # podcast field: itunes:image ; image for the episode
# explicit: false # podcast field: itunes:explicit
# episode_number: 0 # podcast field: itunes:episode ; the number of the episode in the series/season
# season: 0 # podcast field: itunes:season ; the number of the season
# episode_type: "" # podcast field: itunes:episodeType ; one of "Full", "Trailer" or "Bonus"
# transcript: # podcast field: podcast:transcript
# - url: "" # URL to the transcript file
# type: "" # one of text/vtt, application/srt, text/html, application/json or application/x-subrip or text/plain
# language: fr # optional; if omitted, language is the same as the podcast language attribute
# rel: "captions" # ; optional ; only valid value is "captions"; indicates that this transcript contains time codes
# funding: # podcast field: podcast:funding
# - url: ""
# - comment: ""
# chapters: # podcast field: podcast:chapters
# - start_time: 0.0
# title: ""
# image: ""
# url: ""
# toc: true
# end_time: 0.0
# location:
# name: ""
# geo: ""
# soundbites: # podcast field: podcast:soundbite
# - start_time: 0.0 # expressed in seconds since the start of the episode
# duration: 0.0
# persons: # podcast field: podcast:person ; description and links to a podcast participant
# - name: Florian Maury
# href: https://infosec.exchange/@x_cli
# img: "" # url to avatar
# group: Cast # as listed in https://github.com/Podcastindex-org/podcast-namespace/blob/main/taxonomy.json
# role: Host
# location: # podcast field: podcast:location ; used to associate the podcast or the episode to a specific location
# freeform: "" # Description of the place (128 chars max)
# geo: "" # lattitude and longitude expressed in "geo" notation
# osm: "" # Open Street Map Identifier
# episode: 0 # podcast field: podcast:episode ; number of the episode in the season ; ignored if season is 0
# licence:
# name: CC-BY 4.0
# url: https://creativecommons.org/licenses/by/4.0/
# social_interacts: # podcast field: podcast:socialInteracts ; links to interact on social media with the podcast
# - protocol: activitypub # one of https://github.com/Podcastindex-org/podcast-namespace/blob/main/socialprotocols.txt
# uri: "" # URL of the root post for the channel as a whole
# priority: 10
# recommendations: # poodcast field: podcast:recommandations
# - url: https://pod.broken-by-design.fr/recommendations.fr.json
# language: fr
# comment: Recommandations générales
---

452
assets/categories.json Normal file
View file

@ -0,0 +1,452 @@
{
"Categories": [
{
"id": 1,
"name": "Arts"
},
{
"id": 2,
"name": "Books"
},
{
"id": 3,
"name": "Design"
},
{
"id": 4,
"name": "Fashion"
},
{
"id": 5,
"name": "Beauty"
},
{
"id": 6,
"name": "Food"
},
{
"id": 7,
"name": "Performing"
},
{
"id": 8,
"name": "Visual"
},
{
"id": 9,
"name": "Business"
},
{
"id": 10,
"name": "Careers"
},
{
"id": 11,
"name": "Entrepreneurship"
},
{
"id": 12,
"name": "Investing"
},
{
"id": 13,
"name": "Management"
},
{
"id": 14,
"name": "Marketing"
},
{
"id": 15,
"name": "Non-Profit"
},
{
"id": 16,
"name": "Comedy"
},
{
"id": 17,
"name": "Interviews"
},
{
"id": 18,
"name": "Improv"
},
{
"id": 19,
"name": "Stand-Up"
},
{
"id": 20,
"name": "Education"
},
{
"id": 21,
"name": "Courses"
},
{
"id": 22,
"name": "How-To"
},
{
"id": 23,
"name": "Language"
},
{
"id": 24,
"name": "Learning"
},
{
"id": 25,
"name": "Self-Improvement"
},
{
"id": 26,
"name": "Fiction"
},
{
"id": 27,
"name": "Drama"
},
{
"id": 28,
"name": "History"
},
{
"id": 29,
"name": "Health"
},
{
"id": 30,
"name": "Fitness"
},
{
"id": 31,
"name": "Alternative"
},
{
"id": 32,
"name": "Medicine"
},
{
"id": 33,
"name": "Mental"
},
{
"id": 34,
"name": "Nutrition"
},
{
"id": 35,
"name": "Sexuality"
},
{
"id": 36,
"name": "Kids"
},
{
"id": 37,
"name": "Family"
},
{
"id": 38,
"name": "Parenting"
},
{
"id": 39,
"name": "Pets"
},
{
"id": 40,
"name": "Animals"
},
{
"id": 41,
"name": "Stories"
},
{
"id": 42,
"name": "Leisure"
},
{
"id": 43,
"name": "Animation"
},
{
"id": 44,
"name": "Manga"
},
{
"id": 45,
"name": "Automotive"
},
{
"id": 46,
"name": "Aviation"
},
{
"id": 47,
"name": "Crafts"
},
{
"id": 48,
"name": "Games"
},
{
"id": 49,
"name": "Hobbies"
},
{
"id": 50,
"name": "Home"
},
{
"id": 51,
"name": "Garden"
},
{
"id": 52,
"name": "Video-Games"
},
{
"id": 53,
"name": "Music"
},
{
"id": 54,
"name": "Commentary"
},
{
"id": 55,
"name": "News"
},
{
"id": 56,
"name": "Daily"
},
{
"id": 57,
"name": "Entertainment"
},
{
"id": 58,
"name": "Government"
},
{
"id": 59,
"name": "Politics"
},
{
"id": 60,
"name": "Buddhism"
},
{
"id": 61,
"name": "Christianity"
},
{
"id": 62,
"name": "Hinduism"
},
{
"id": 63,
"name": "Islam"
},
{
"id": 64,
"name": "Judaism"
},
{
"id": 65,
"name": "Religion"
},
{
"id": 66,
"name": "Spirituality"
},
{
"id": 67,
"name": "Science"
},
{
"id": 68,
"name": "Astronomy"
},
{
"id": 69,
"name": "Chemistry"
},
{
"id": 70,
"name": "Earth"
},
{
"id": 71,
"name": "Life"
},
{
"id": 72,
"name": "Mathematics"
},
{
"id": 73,
"name": "Natural"
},
{
"id": 74,
"name": "Nature"
},
{
"id": 75,
"name": "Physics"
},
{
"id": 76,
"name": "Social"
},
{
"id": 77,
"name": "Society"
},
{
"id": 78,
"name": "Culture"
},
{
"id": 79,
"name": "Documentary"
},
{
"id": 80,
"name": "Personal"
},
{
"id": 81,
"name": "Journals"
},
{
"id": 82,
"name": "Philosophy"
},
{
"id": 83,
"name": "Places"
},
{
"id": 84,
"name": "Travel"
},
{
"id": 85,
"name": "Relationships"
},
{
"id": 86,
"name": "Sports"
},
{
"id": 87,
"name": "Baseball"
},
{
"id": 88,
"name": "Basketball"
},
{
"id": 89,
"name": "Cricket"
},
{
"id": 90,
"name": "Fantasy"
},
{
"id": 91,
"name": "Football"
},
{
"id": 92,
"name": "Golf"
},
{
"id": 93,
"name": "Hockey"
},
{
"id": 94,
"name": "Rugby"
},
{
"id": 95,
"name": "Running"
},
{
"id": 96,
"name": "Soccer"
},
{
"id": 97,
"name": "Swimming"
},
{
"id": 98,
"name": "Tennis"
},
{
"id": 99,
"name": "Volleyball"
},
{
"id": 100,
"name": "Wilderness"
},
{
"id": 101,
"name": "Wrestling"
},
{
"id": 102,
"name": "Technology"
},
{
"id": 103,
"name": "True Crime"
},
{
"id": 104,
"name": "TV"
},
{
"id": 105,
"name": "Film"
},
{
"id": 106,
"name": "After-Shows"
},
{
"id": 107,
"name": "Reviews"
},
{
"id": 108,
"name": "Climate"
},
{
"id": 109,
"name": "Weather"
},
{
"id": 110,
"name": "Tabletop"
},
{
"id": 111,
"name": "Role-Playing"
},
{
"id": 112,
"name": "Cryptocurrency"
}
]
}

3
go.mod Normal file
View file

@ -0,0 +1,3 @@
module git.broken-by-design.fr/fmaury/podcast-mod
go 1.22.7

3
hugo.toml Normal file
View file

@ -0,0 +1,3 @@
baseURL = 'https://example.org/'
languageCode = 'en-us'
title = 'My New Hugo Site'

4
i18n/en.yaml Normal file
View file

@ -0,0 +1,4 @@
season: season
seasons: seasons
episode: episode
episodes: episodes

4
i18n/fr.yaml Normal file
View file

@ -0,0 +1,4 @@
season: saison
seasons: saisons
episode: épisode
episodes: épisodes

View file

@ -0,0 +1,9 @@
Podcast {{ .Title }}
{{ range .Sections }}
<p><a href="{{ .RelPermalink }}">{{ .Title}}</a></p>
{{ end }}
{{ T "episodes" | strings.FirstUpper }} :
{{ range .RegularPagesRecursive.ByParam "season" }}
<p>{{ if .Params.season }}Season {{ .Params.season }} : {{ end }} {{ .Title }}</p>
{{ end }}

View file

@ -0,0 +1,165 @@
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:podcast="https://podcastindex.org/namespace/1.0" version="2.0">
<channel>
<title>{{ .Title | transform.XMLEscape }}</title>
<description>{{ .Description | transform.XMLEscape}}</description>
<generator>Hugo (with git.broken-by-design.fr/fmaury/podcast-mod)</generator>
<lastBuildDate>{{ time.Now.Format "Mon, 02 Jan 2006 15:04:05 MST" }}</lastBuildDate>
<language>{{ .Language.Lang }}</language>
{{- with .Params.copyright }}
<copyright>{{ . | transform.XMLEscape }}</copyright>
{{- end }}
<itunes:image>
{{- /* Either external_url or resource_file must be defined; use external_url if it is defined. If not, get the resource designated by the resource_file paramter. The resource identifier must be relative to the podcast directory */ -}}
{{- if collections.Index .Params.image "external_url" -}}
{{- collections.Index .Params.image "external_url" | transform.XMLEscape -}}
{{- else if collections.Index .Params.image "resource_file" -}}
{{- with collections.Index .Params.image "resource_file" | .Resources.Get -}}
{{- .Permalink -}}
{{- else -}}
{{- errorf "failed to fetch resource %q" (collections.Index .Params.image "resource_file") -}}
{{- end -}}
{{- else -}}
{{- errorf "empty image parameter on the podcast %q definition" .Title -}}
{{- end -}}
</itunes:image>
{{- /* Categories are restricted to a set of values. The acceptable values are listed here: https://github.com/Podcastindex-org/podcast-namespace/blob/main/categories.json */ -}}
{{- /* The following code ensures the attribute is set (Apple requires it) and validates the value against the list of acceptable values */ -}}
{{- with .Params.category }}
{{- $categories := resources.Get "categories.json" | transform.Unmarshal -}}
{{- $categoryFound := 0 -}}
{{- range ( collections.Index $categories "Categories") -}}
{{- if collections.Index . "name" | compare.Eq $.Params.category -}}
{{- $categoryFound = 1 -}}
{{- end -}}
{{- end -}}
{{- if $categoryFound }}
<itunes:category>{{ . | transform.XMLEscape }}</itunes:category>
{{- else -}}
{{- errorf "could not find %q in known categories" . -}}
{{- end -}}
{{- else -}}
{{- errorf "missing category definition for podcast %q" .Title -}}
{{- end }}
{{- with .Params.website_link }}
<link>{{ . | transform.XMLEscape }}</link>
{{- end }}
<itunes:explicit>{{ .Params.explicit | transform.XMLEscape }}</itunes:explicit>
{{- with .Params.author }}
<itunes:author>{{ . | transform.XMLEscape }}</itunes:author>
{{- end }}
{{- with .Params.podcast_type }}
<itunes:type>{{ . | transform.XMLEscape }}</itunes:type>
{{- end }}
{{- if and .Params.author .Params.email }}
<itunes:owner>
<itunes:name>{{ .Params.author | transform.XMLEscape }}</itunes:name>
<itunes:email>{{ .Params.email | transform.XMLEscape }}</itunes:email>
</itunes:owner>
{{- end }}
<podcast:guid>{{ .Params.guid | transform.XMLEscape }}</podcast:guid>
{{- if and .Params.email .Params.locked }}
<podcast:locked owner="{{ .Params.email | transform.XMLEscape }}">{{ .Params.locked | transform.XMLEscape }}</podcast:locked>
{{- end }}
{{- with .Params.medium }}
<podcast:medium>{{ . | transform.XMLEscape }}</podcast:medium>
{{- end }}
{{- with .Params.licence }}
<podcast:licence url="{{ .url | transform.XMLEscape }}">{{ .name | transform.XMLEscape }}</podcast:licence>
{{- end }}
{{- with .Params.images }}
<podcast:images srcset="
{{- $image_url_list := slice -}}
{{- range . -}}
{{- $entry := . -}}
{{- $url := "" -}}
{{- $width := collections.Index $entry "width" | transform.XMLEscape -}}
{{- with collections.Index $entry "resource_file" -}}
{{- $r := $.Resources.Get . -}}
{{- $url = $r.Permalink -}}
{{- else -}}
{{- $url = collections.Index $entry "external_url" | transform.XMLEscape -}}
{{- end -}}
{{- $attr := printf "%s %sw" $url $width -}}
{{- $image_url_list = append $attr $image_url_list -}}
{{- end -}}
{{- delimit $image_url_list "," -}}
"></podcast:images>
{{- end }}
{{- with .Params.funding -}}
{{- range . }}
<podcast:funding url="{{ .url | transform.XMLEscape }}">{{ .comment | transform.XMLEscape }}</podcast:funding>
{{- end -}}
{{- end }}
{{- with .Params.location }}
<podcast:location geo="{{ collections.Index . "geo" | transform.XMLEscape }}" osm="{{ collections.Index . "osm" | transform.XMLEscape }}">{{ collections.Index . "description" | transform.XMLEscape }}</podcast:location>
{{- end }}
{{- with .Params.trailer -}}
{{- range . -}}
{{- $season_attr := "" -}}
{{ $url := ""}}
{{- with collections.Index . "resource_file" | $.Resources.Get -}}
{{- $url = .Permalink -}}
{{- else -}}
{{- $url = collections.Index . "external_url" -}}
{{- end -}}
<podcast:trailer pubdate="
{{- collections.Index . "pubdate" | transform.XMLEscape -}}
" url="
{{- $url -}}
" length="
{{- collections.Index . "length" | transform.XMLEscape -}}
" type="{{- collections.Index . "type" | transform.XMLEscape -}}"
{{- if collections.Index . "season" }} season="{{- collections.Index . "season" | transform.XMLEscape -}}"
{{- end -}}
>{{- collections.Index . "title" | transform.XMLEscape -}}</podcast:trailer>
{{- end -}}
{{- end }}
{{- with .Params.social_interacts }}
{{- range . -}}
<podcast:socialInteract protocol="
{{- collections.Index . "protocol" | transform.XMLEscape -}}
" uri="
{{- collections.Index . "uri" | transform.XMLEscape -}}
" priority="
{{- collections.Index . "priority" | transform.XMLEscape -}}
" />
{{- end -}}
{{- end }}
{{- with .Params.podroll }}
<podcast:podroll>
{{- range . }}
<podcast:remoteItem feedGuid="
{{- collections.Index . "feed_guid" -}}
" feedUrl="
{{- collections.Index . "feed_url" -}}
" medium="
{{- collections.Index . "medium" -}}
" title="
{{- collections.Index . "title" -}}
" />
{{- end }}
</podcast:podroll>
{{- end }}
{{- with .Params.update_frequency }}
<podcast:updateFrequency {{ if collections.Index . "complete" -}}
complete="true"
{{- else -}}
{{- $dtstart := collections.Index . "dtstart" -}}
rrule="{{- collections.Index . "rrule" | transform.XMLEscape -}}" {{ if $dtstart -}}
dtstart="{{- $dtstart | transform.XMLEscape -}}"
{{- end -}}
{{- end -}}
>{{- collections.Index . "description" | transform.XMLEscape -}}</podcast:updateFrequency>
{{- end }}
{{- with .Params.recommendations -}}
{{- range . }}
<podcast:recommendations url="
{{- collections.Index . "url" | transform.XMLEscape -}}
" type="application/json" language="
{{- collections.Index . "language" | transform.XMLEscape -}}
" />
{{- end -}}
{{- end }}
</channel>
</rss>

View file

@ -0,0 +1,5 @@
<p>{{ .Title }}</p>
{{ $subSections := .Sections }}
{{ range $subSections }}
<p><a href="{{ .RelPermalink }}">{{ .Title }}</a></p>
{{ end }}

View file

@ -0,0 +1,4 @@
Episodes :
{{ range .RegularPages }}
<p>{{ .Title }}</p>
{{ end }}

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Categories on My New Hugo Site</title>
<link>http://localhost:1313/categories/</link>
<description>Recent content in Categories on My New Hugo Site</description>
<generator>Hugo</generator>
<language>en-us</language>
<atom:link href="http://localhost:1313/categories/index.xml" rel="self" type="application/rss+xml" />
</channel>
</rss>

12
public/index.xml Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>My New Hugo Site</title>
<link>http://localhost:1313/</link>
<description>Recent content on My New Hugo Site</description>
<generator>Hugo</generator>
<language>en-us</language>
<lastBuildDate></lastBuildDate>
<atom:link href="http://localhost:1313/index.xml" rel="self" type="application/rss+xml" />
</channel>
</rss>

View file

@ -0,0 +1 @@
<script src="/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=livereload" data-no-instant defer></script>Test

View file

@ -0,0 +1 @@
<script src="/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=livereload" data-no-instant defer></script>Test

18
public/sitemap.xml Normal file
View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>http://localhost:1313/</loc>
<lastmod>2024-10-11T00:00:00+00:00</lastmod>
</url><url>
<loc>http://localhost:1313/podcasts/</loc>
<lastmod>2024-10-11T00:00:00+00:00</lastmod>
</url><url>
<loc>http://localhost:1313/podcasts/yakafokon/season_1/</loc>
<lastmod>2024-10-11T00:00:00+00:00</lastmod>
</url><url>
<loc>http://localhost:1313/categories/</loc>
</url><url>
<loc>http://localhost:1313/tags/</loc>
</url>
</urlset>

11
public/tags/index.xml Normal file
View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Tags on My New Hugo Site</title>
<link>http://localhost:1313/tags/</link>
<description>Recent content in Tags on My New Hugo Site</description>
<generator>Hugo</generator>
<language>en-us</language>
<atom:link href="http://localhost:1313/tags/index.xml" rel="self" type="application/rss+xml" />
</channel>
</rss>