add article about my improved Youtube feed program - www.codemadness.org - www.codemadness.org saait content files
(HTM) git clone git://git.codemadness.org/www.codemadness.org
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit aba64f95f1ffa6c0ee720fbfb10810e93a9a53f7
(DIR) parent 12d6dc6b20047145a307bef9197cef3d42abfcf5
(HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Mon, 20 Nov 2023 21:32:48 +0100
add article about my improved Youtube feed program
Diffstat:
M config.cfg | 2 +-
M output/atom.xml | 14 +++++++++++++-
M output/atom_content.xml | 141 ++++++++++++++++++++++++++++++-
M output/index | 1 +
M output/index.html | 1 +
A output/phlog/youtube-feed | 2 ++
M output/rss.xml | 8 ++++++++
M output/rss_content.xml | 134 +++++++++++++++++++++++++++++++
M output/sitemap.xml | 4 ++++
M output/twtxt.txt | 1 +
M output/urllist.txt | 1 +
A output/youtube-feed.html | 178 +++++++++++++++++++++++++++++++
A output/youtube-feed.md | 159 +++++++++++++++++++++++++++++++
A pages/youtube-feed.cfg | 6 ++++++
A pages/youtube-feed.md | 159 +++++++++++++++++++++++++++++++
15 files changed, 808 insertions(+), 3 deletions(-)
---
(DIR) diff --git a/config.cfg b/config.cfg
@@ -1,5 +1,5 @@
# last updated the site.
-siteupdated = 2023-05-11
+siteupdated = 2023-11-20
sitetitle = Codemadness
siteurl = https://www.codemadness.org
(DIR) diff --git a/output/atom.xml b/output/atom.xml
@@ -2,11 +2,23 @@
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
<title>Codemadness</title>
<subtitle>blog with various projects and articles about computer-related things</subtitle>
- <updated>2023-05-11T00:00:00Z</updated>
+ <updated>2023-11-20T00:00:00Z</updated>
<link rel="alternate" type="text/html" href="https://www.codemadness.org" />
<id>https://www.codemadness.org/atom.xml</id>
<link rel="self" type="application/atom+xml" href="https://www.codemadness.org/atom.xml" />
<entry>
+ <title>Improved Youtube RSS/Atom feed</title>
+ <link rel="alternate" type="text/html" href="https://www.codemadness.org/youtube-feed.html" />
+ <id>https://www.codemadness.org/youtube-feed.html</id>
+ <updated>2023-11-20T00:00:00Z</updated>
+ <published>2023-11-20T00:00:00Z</published>
+ <author>
+ <name>Hiltjo</name>
+ <uri>https://www.codemadness.org</uri>
+ </author>
+ <summary>Improved Youtube Atom feed by adding video duration and filtering away shorts</summary>
+</entry>
+<entry>
<title>Setup your own mail paste service</title>
<link rel="alternate" type="text/html" href="https://www.codemadness.org/mailservice.html" />
<id>https://www.codemadness.org/mailservice.html</id>
(DIR) diff --git a/output/atom_content.xml b/output/atom_content.xml
@@ -2,11 +2,150 @@
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
<title>Codemadness</title>
<subtitle>blog with various projects and articles about computer-related things</subtitle>
- <updated>2023-05-11T00:00:00Z</updated>
+ <updated>2023-11-20T00:00:00Z</updated>
<link rel="alternate" type="text/html" href="https://www.codemadness.org" />
<id>https://www.codemadness.org/atom_content.xml</id>
<link rel="self" type="application/atom+xml" href="https://www.codemadness.org/atom_content.xml" />
<entry>
+ <title>Improved Youtube RSS/Atom feed</title>
+ <link rel="alternate" type="text/html" href="https://www.codemadness.org/youtube-feed.html" />
+ <id>https://www.codemadness.org/youtube-feed.html</id>
+ <updated>2023-11-20T00:00:00Z</updated>
+ <published>2023-11-20T00:00:00Z</published>
+ <author>
+ <name>Hiltjo</name>
+ <uri>https://www.codemadness.org</uri>
+ </author>
+ <summary>Improved Youtube Atom feed by adding video duration and filtering away shorts</summary>
+ <content type="html"><![CDATA[<h1>Improved Youtube RSS/Atom feed</h1>
+ <p><strong>Last modification on </strong> <time>2023-11-20</time></p>
+ <p>... improved at least for my preferences ;)</p>
+<p>It scrapes the channel data from Youtube and combines it with the parsed Atom
+feed from the channel on Youtube.</p>
+<p>The Atom parser is based on sfeed, with some of the code removed because it is
+not needed by this program. It scrapes the metadata of the videos from the
+channel its HTML page and uses my custom JSON parser to convert the
+Javascript/JSON structure.</p>
+<p>This parser is also used by the <a href="/json2tsv.html">json2tsv</a> tool. It has few dependencies.</p>
+<h2>Features</h2>
+<ul>
+<li>Add the video duration to the title to quickly see how long the video is.</li>
+<li>Filter away Youtube shorts and upcoming videos / announcements: only videos are shown.</li>
+<li>Supports more output formats: Atom, <a href="https://www.jsonfeed.org/version/1.1/">JSON Feed</a> or
+<a href="sfeed.1.txt">sfeed</a> Tab-Separated-Value format.</li>
+<li>Easy to build and deploy: can be run as a CGI program as a static-linked
+binary in a chroot.</li>
+<li>Secure: additionally to running in a chroot it can use pledge(2) and unveil(2)
+on OpenBSD to restrict system calls and access to the filesystem.</li>
+</ul>
+<h2>How to use</h2>
+<p>There is an option to run directly from the command-line or in CGI-mode. When
+the environment variable $REQUEST_URI is set then it is automatically run in
+CGI mode.</p>
+<p>Command-line usage:</p>
+<pre><code>youtube_feed channelid atom
+youtube_feed channelid gph
+youtube_feed channelid html
+youtube_feed channelid json
+youtube_feed channelid tsv
+youtube_feed channelid txt
+</code></pre>
+<p>CGI program usage:</p>
+<p>The last basename part of the URL should be the channelid + the output format
+extension. It defaults to TSV if there is no extension.
+The CGI program can be used with a HTTPd or a Gopher daemon such as geomyidae.</p>
+<p>For example:</p>
+<pre><code>Atom XML: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.xml
+HTML: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.html
+JSON: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.json
+TSV: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.tsv
+twtxt: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.txt
+TSV, default: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw
+
+Gopher dir: gopher://codemadness.org/1/feed.cgi/UCrbvoMC0zUvPL8vjswhLOSw.gph
+Gopher TSV: gopher://codemadness.org/0/feed.cgi/UCrbvoMC0zUvPL8vjswhLOSw
+</code></pre>
+<p>An OpenBSD httpd.conf using slowcgi as an example:</p>
+<pre><code>server "codemadness.org" {
+ location "/yt-chan/*" {
+ request strip 1
+ root "/cgi-bin/yt-chan"
+ fastcgi socket "/run/slowcgi.sock"
+ }
+}
+</code></pre>
+<h2>Using it with <a href="sfeed.html">sfeed</a></h2>
+<p>sfeedrc example of an existing Youtube RSS/Atom feed:</p>
+<pre><code># list of feeds to fetch:
+feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ # normal Youtube Atom feed.
+ feed "yt IM" "https://www.youtube.com/feeds/videos.xml?channel_id=UCrbvoMC0zUvPL8vjswhLOSw"
+}
+</code></pre>
+<p>Use the new Atom feed directly using the CGI-mode and Atom output format:</p>
+<pre><code># list of feeds to fetch:
+feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ # new Youtube Atom feed.
+ feed "idiotbox IM" "https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.xml"
+}
+</code></pre>
+<p>... or convert directly using a custom connector program on the local system via the command-line:</p>
+<pre><code># fetch(name, url, feedfile)
+fetch() {
+ case "$1" in
+ "connector example")
+ youtube_feed "$2";;
+ *)
+ curl -L --max-redirs 0 -H "User-Agent:" -f -s -m 15 \
+ "$2" 2>/dev/null;;
+ esac
+}
+
+# parse and convert input, by default XML to the sfeed(5) TSV format.
+# parse(name, feedurl, basesiteurl)
+parse() {
+ case "$1" in
+ "connector example")
+ cat;;
+ *)
+ sfeed "$3";;
+ esac
+}
+
+# list of feeds to fetch:
+feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ feed "connector example" "UCrbvoMC0zUvPL8vjswhLOSw"
+}
+</code></pre>
+<h2>Screenshot using sfeed_curses</h2>
+<p><a href="downloads/screenshots/sfeed_curses_youtube.png"><img src="downloads/screenshots/sfeed_curses_youtube.png" alt="Screenshot showing the improved Youtube feed" width="480" height="270" loading="lazy" /></a></p>
+<h2>Clone</h2>
+<pre><code>git clone git://git.codemadness.org/frontends
+</code></pre>
+<h2>Browse</h2>
+<p>You can browse the source-code at:</p>
+<ul>
+<li><a href="https://git.codemadness.org/frontends/file/youtube/feed.c.html">https://git.codemadness.org/frontends/file/youtube/feed.c.html</a></li>
+<li><a href="gopher://codemadness.org/1/git/frontends/file/youtube/feed.c.gph">gopher://codemadness.org/1/git/frontends/file/youtube/feed.c.gph</a></li>
+</ul>
+<p>The program is: youtube/feed</p>
+<h2>Dependencies</h2>
+<ul>
+<li>C compiler.</li>
+<li>LibreSSL + libtls.</li>
+</ul>
+<h2>Build and install</h2>
+<pre><code>$ make
+# make install
+</code></pre>
+<h1>That's all</h1>
+<p>I hope by sharing this it is useful to someone other than me as well.</p>
+]]></content>
+</entry>
+<entry>
<title>Setup your own mail paste service</title>
<link rel="alternate" type="text/html" href="https://www.codemadness.org/mailservice.html" />
<id>https://www.codemadness.org/mailservice.html</id>
(DIR) diff --git a/output/index b/output/index
@@ -11,6 +11,7 @@ i codemadness.org 70
i codemadness.org 70
iPhlog posts codemadness.org 70
i codemadness.org 70
+12023-11-20 Improved Youtube RSS/Atom feed /phlog/youtube-feed codemadness.org 70
12023-10-25 Setup your own mail paste service /phlog/mailservice codemadness.org 70
12022-07-01 A simple TODO application /phlog/todo codemadness.org 70
12022-03-23 2FA TOTP without crappy authenticator apps /phlog/totp codemadness.org 70
(DIR) diff --git a/output/index.html b/output/index.html
@@ -40,6 +40,7 @@
<div id="main">
<h1>Posts</h1>
<table>
+<tr><td><time>2023-11-20</time></td><td><a href="youtube-feed.html">Improved Youtube RSS/Atom feed</a></td></tr>
<tr><td><time>2023-10-25</time></td><td><a href="mailservice.html">Setup your own mail paste service</a></td></tr>
<tr><td><time>2022-07-01</time></td><td><a href="todo-application.html">A simple TODO application</a></td></tr>
<tr><td><time>2022-03-23</time></td><td><a href="totp.html">2FA TOTP without crappy authenticator apps</a></td></tr>
(DIR) diff --git a/output/phlog/youtube-feed b/output/phlog/youtube-feed
@@ -0,0 +1 @@
+youtube-feed-improved
+\ No newline at end of file
(DIR) diff --git a/output/rss.xml b/output/rss.xml
@@ -7,6 +7,14 @@
<description>blog with various projects and articles about computer-related things</description>
<link>https://www.codemadness.org</link>
<item>
+ <title>Improved Youtube RSS/Atom feed</title>
+ <link>https://www.codemadness.org/youtube-feed.html</link>
+ <guid>https://www.codemadness.org/youtube-feed.html</guid>
+ <dc:date>2023-11-20T00:00:00Z</dc:date>
+ <author>Hiltjo</author>
+ <description>Improved Youtube Atom feed by adding video duration and filtering away shorts</description>
+</item>
+<item>
<title>Setup your own mail paste service</title>
<link>https://www.codemadness.org/mailservice.html</link>
<guid>https://www.codemadness.org/mailservice.html</guid>
(DIR) diff --git a/output/rss_content.xml b/output/rss_content.xml
@@ -7,6 +7,140 @@
<description>blog with various projects and articles about computer-related things</description>
<link>https://www.codemadness.org</link>
<item>
+ <title>Improved Youtube RSS/Atom feed</title>
+ <link>https://www.codemadness.org/youtube-feed.html</link>
+ <guid>https://www.codemadness.org/youtube-feed.html</guid>
+ <dc:date>2023-11-20T00:00:00Z</dc:date>
+ <author>Hiltjo</author>
+ <description><![CDATA[<h1>Improved Youtube RSS/Atom feed</h1>
+ <p><strong>Last modification on </strong> <time>2023-11-20</time></p>
+ <p>... improved at least for my preferences ;)</p>
+<p>It scrapes the channel data from Youtube and combines it with the parsed Atom
+feed from the channel on Youtube.</p>
+<p>The Atom parser is based on sfeed, with some of the code removed because it is
+not needed by this program. It scrapes the metadata of the videos from the
+channel its HTML page and uses my custom JSON parser to convert the
+Javascript/JSON structure.</p>
+<p>This parser is also used by the <a href="/json2tsv.html">json2tsv</a> tool. It has few dependencies.</p>
+<h2>Features</h2>
+<ul>
+<li>Add the video duration to the title to quickly see how long the video is.</li>
+<li>Filter away Youtube shorts and upcoming videos / announcements: only videos are shown.</li>
+<li>Supports more output formats: Atom, <a href="https://www.jsonfeed.org/version/1.1/">JSON Feed</a> or
+<a href="sfeed.1.txt">sfeed</a> Tab-Separated-Value format.</li>
+<li>Easy to build and deploy: can be run as a CGI program as a static-linked
+binary in a chroot.</li>
+<li>Secure: additionally to running in a chroot it can use pledge(2) and unveil(2)
+on OpenBSD to restrict system calls and access to the filesystem.</li>
+</ul>
+<h2>How to use</h2>
+<p>There is an option to run directly from the command-line or in CGI-mode. When
+the environment variable $REQUEST_URI is set then it is automatically run in
+CGI mode.</p>
+<p>Command-line usage:</p>
+<pre><code>youtube_feed channelid atom
+youtube_feed channelid gph
+youtube_feed channelid html
+youtube_feed channelid json
+youtube_feed channelid tsv
+youtube_feed channelid txt
+</code></pre>
+<p>CGI program usage:</p>
+<p>The last basename part of the URL should be the channelid + the output format
+extension. It defaults to TSV if there is no extension.
+The CGI program can be used with a HTTPd or a Gopher daemon such as geomyidae.</p>
+<p>For example:</p>
+<pre><code>Atom XML: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.xml
+HTML: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.html
+JSON: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.json
+TSV: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.tsv
+twtxt: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.txt
+TSV, default: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw
+
+Gopher dir: gopher://codemadness.org/1/feed.cgi/UCrbvoMC0zUvPL8vjswhLOSw.gph
+Gopher TSV: gopher://codemadness.org/0/feed.cgi/UCrbvoMC0zUvPL8vjswhLOSw
+</code></pre>
+<p>An OpenBSD httpd.conf using slowcgi as an example:</p>
+<pre><code>server "codemadness.org" {
+ location "/yt-chan/*" {
+ request strip 1
+ root "/cgi-bin/yt-chan"
+ fastcgi socket "/run/slowcgi.sock"
+ }
+}
+</code></pre>
+<h2>Using it with <a href="sfeed.html">sfeed</a></h2>
+<p>sfeedrc example of an existing Youtube RSS/Atom feed:</p>
+<pre><code># list of feeds to fetch:
+feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ # normal Youtube Atom feed.
+ feed "yt IM" "https://www.youtube.com/feeds/videos.xml?channel_id=UCrbvoMC0zUvPL8vjswhLOSw"
+}
+</code></pre>
+<p>Use the new Atom feed directly using the CGI-mode and Atom output format:</p>
+<pre><code># list of feeds to fetch:
+feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ # new Youtube Atom feed.
+ feed "idiotbox IM" "https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.xml"
+}
+</code></pre>
+<p>... or convert directly using a custom connector program on the local system via the command-line:</p>
+<pre><code># fetch(name, url, feedfile)
+fetch() {
+ case "$1" in
+ "connector example")
+ youtube_feed "$2";;
+ *)
+ curl -L --max-redirs 0 -H "User-Agent:" -f -s -m 15 \
+ "$2" 2>/dev/null;;
+ esac
+}
+
+# parse and convert input, by default XML to the sfeed(5) TSV format.
+# parse(name, feedurl, basesiteurl)
+parse() {
+ case "$1" in
+ "connector example")
+ cat;;
+ *)
+ sfeed "$3";;
+ esac
+}
+
+# list of feeds to fetch:
+feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ feed "connector example" "UCrbvoMC0zUvPL8vjswhLOSw"
+}
+</code></pre>
+<h2>Screenshot using sfeed_curses</h2>
+<p><a href="downloads/screenshots/sfeed_curses_youtube.png"><img src="downloads/screenshots/sfeed_curses_youtube.png" alt="Screenshot showing the improved Youtube feed" width="480" height="270" loading="lazy" /></a></p>
+<h2>Clone</h2>
+<pre><code>git clone git://git.codemadness.org/frontends
+</code></pre>
+<h2>Browse</h2>
+<p>You can browse the source-code at:</p>
+<ul>
+<li><a href="https://git.codemadness.org/frontends/file/youtube/feed.c.html">https://git.codemadness.org/frontends/file/youtube/feed.c.html</a></li>
+<li><a href="gopher://codemadness.org/1/git/frontends/file/youtube/feed.c.gph">gopher://codemadness.org/1/git/frontends/file/youtube/feed.c.gph</a></li>
+</ul>
+<p>The program is: youtube/feed</p>
+<h2>Dependencies</h2>
+<ul>
+<li>C compiler.</li>
+<li>LibreSSL + libtls.</li>
+</ul>
+<h2>Build and install</h2>
+<pre><code>$ make
+# make install
+</code></pre>
+<h1>That's all</h1>
+<p>I hope by sharing this it is useful to someone other than me as well.</p>
+]]></description>
+</item>
+<item>
<title>Setup your own mail paste service</title>
<link>https://www.codemadness.org/mailservice.html</link>
<guid>https://www.codemadness.org/mailservice.html</guid>
(DIR) diff --git a/output/sitemap.xml b/output/sitemap.xml
@@ -1,6 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
+ <loc>https://www.codemadness.org/youtube-feed.html</loc>
+ <lastmod>2023-11-20</lastmod>
+</url>
+<url>
<loc>https://www.codemadness.org/mailservice.html</loc>
<lastmod>2023-10-30</lastmod>
</url>
(DIR) diff --git a/output/twtxt.txt b/output/twtxt.txt
@@ -1,3 +1,4 @@
+2023-11-20T00:00:00Z Improved Youtube RSS/Atom feed: https://www.codemadness.org/youtube-feed.html
2023-10-25T00:00:00Z Setup your own mail paste service: https://www.codemadness.org/mailservice.html
2022-07-01T00:00:00Z A simple TODO application: https://www.codemadness.org/todo-application.html
2022-03-23T00:00:00Z 2FA TOTP without crappy authenticator apps: https://www.codemadness.org/totp.html
(DIR) diff --git a/output/urllist.txt b/output/urllist.txt
@@ -1,3 +1,4 @@
+https://www.codemadness.org/youtube-feed.html
https://www.codemadness.org/mailservice.html
https://www.codemadness.org/todo-application.html
https://www.codemadness.org/totp.html
(DIR) diff --git a/output/youtube-feed.html b/output/youtube-feed.html
@@ -0,0 +1,178 @@
+<!DOCTYPE html>
+<html dir="ltr" lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <meta name="viewport" content="width=device-width" />
+ <meta name="keywords" content="youtube, sfeed, RSS, atom, frontends" />
+ <meta name="description" content="Improved Youtube Atom feed by adding video duration and filtering away shorts" />
+ <meta name="author" content="Hiltjo" />
+ <meta name="generator" content="Static content generated using saait: https://codemadness.org/saait.html" />
+ <title>Improved Youtube RSS/Atom feed - Codemadness</title>
+ <link rel="stylesheet" href="style.css" type="text/css" media="screen" />
+ <link rel="stylesheet" href="print.css" type="text/css" media="print" />
+ <link rel="alternate" href="atom.xml" type="application/atom+xml" title="Codemadness Atom Feed" />
+ <link rel="alternate" href="atom_content.xml" type="application/atom+xml" title="Codemadness Atom Feed with content" />
+ <link rel="icon" href="/favicon.png" type="image/png" />
+</head>
+<body>
+ <nav id="menuwrap">
+ <table id="menu" width="100%" border="0">
+ <tr>
+ <td id="links" align="left">
+ <a href="index.html">Blog</a> |
+ <a href="/git/" title="Git repository with some of my projects">Git</a> |
+ <a href="/releases/">Releases</a> |
+ <a href="gopher://codemadness.org">Gopherhole</a>
+ </td>
+ <td id="links-contact" align="right">
+ <span class="hidden"> | </span>
+ <a href="/donate/">Donate</a> |
+ <a href="feeds.html">Feeds</a> |
+ <a href="pgp.asc">PGP</a> |
+ <a href="mailto:hiltjo@AT@codemadness.DOT.org">Mail</a>
+ </td>
+ </tr>
+ </table>
+ </nav>
+ <hr class="hidden" />
+ <main id="mainwrap">
+ <div id="main">
+ <article>
+<header>
+ <h1>Improved Youtube RSS/Atom feed</h1>
+ <p>
+ <strong>Last modification on </strong> <time>2023-11-20</time>
+ </p>
+</header>
+
+<p>... improved at least for my preferences ;)</p>
+<p>It scrapes the channel data from Youtube and combines it with the parsed Atom
+feed from the channel on Youtube.</p>
+<p>The Atom parser is based on sfeed, with some of the code removed because it is
+not needed by this program. It scrapes the metadata of the videos from the
+channel its HTML page and uses my custom JSON parser to convert the
+Javascript/JSON structure.</p>
+<p>This parser is also used by the <a href="/json2tsv.html">json2tsv</a> tool. It has few dependencies.</p>
+<h2>Features</h2>
+<ul>
+<li>Add the video duration to the title to quickly see how long the video is.</li>
+<li>Filter away Youtube shorts and upcoming videos / announcements: only videos are shown.</li>
+<li>Supports more output formats: Atom, <a href="https://www.jsonfeed.org/version/1.1/">JSON Feed</a> or
+<a href="sfeed.1.txt">sfeed</a> Tab-Separated-Value format.</li>
+<li>Easy to build and deploy: can be run as a CGI program as a static-linked
+binary in a chroot.</li>
+<li>Secure: additionally to running in a chroot it can use pledge(2) and unveil(2)
+on OpenBSD to restrict system calls and access to the filesystem.</li>
+</ul>
+<h2>How to use</h2>
+<p>There is an option to run directly from the command-line or in CGI-mode. When
+the environment variable $REQUEST_URI is set then it is automatically run in
+CGI mode.</p>
+<p>Command-line usage:</p>
+<pre><code>youtube_feed channelid atom
+youtube_feed channelid gph
+youtube_feed channelid html
+youtube_feed channelid json
+youtube_feed channelid tsv
+youtube_feed channelid txt
+</code></pre>
+<p>CGI program usage:</p>
+<p>The last basename part of the URL should be the channelid + the output format
+extension. It defaults to TSV if there is no extension.
+The CGI program can be used with a HTTPd or a Gopher daemon such as geomyidae.</p>
+<p>For example:</p>
+<pre><code>Atom XML: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.xml
+HTML: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.html
+JSON: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.json
+TSV: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.tsv
+twtxt: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.txt
+TSV, default: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw
+
+Gopher dir: gopher://codemadness.org/1/feed.cgi/UCrbvoMC0zUvPL8vjswhLOSw.gph
+Gopher TSV: gopher://codemadness.org/0/feed.cgi/UCrbvoMC0zUvPL8vjswhLOSw
+</code></pre>
+<p>An OpenBSD httpd.conf using slowcgi as an example:</p>
+<pre><code>server "codemadness.org" {
+ location "/yt-chan/*" {
+ request strip 1
+ root "/cgi-bin/yt-chan"
+ fastcgi socket "/run/slowcgi.sock"
+ }
+}
+</code></pre>
+<h2>Using it with <a href="sfeed.html">sfeed</a></h2>
+<p>sfeedrc example of an existing Youtube RSS/Atom feed:</p>
+<pre><code># list of feeds to fetch:
+feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ # normal Youtube Atom feed.
+ feed "yt IM" "https://www.youtube.com/feeds/videos.xml?channel_id=UCrbvoMC0zUvPL8vjswhLOSw"
+}
+</code></pre>
+<p>Use the new Atom feed directly using the CGI-mode and Atom output format:</p>
+<pre><code># list of feeds to fetch:
+feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ # new Youtube Atom feed.
+ feed "idiotbox IM" "https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.xml"
+}
+</code></pre>
+<p>... or convert directly using a custom connector program on the local system via the command-line:</p>
+<pre><code># fetch(name, url, feedfile)
+fetch() {
+ case "$1" in
+ "connector example")
+ youtube_feed "$2";;
+ *)
+ curl -L --max-redirs 0 -H "User-Agent:" -f -s -m 15 \
+ "$2" 2>/dev/null;;
+ esac
+}
+
+# parse and convert input, by default XML to the sfeed(5) TSV format.
+# parse(name, feedurl, basesiteurl)
+parse() {
+ case "$1" in
+ "connector example")
+ cat;;
+ *)
+ sfeed "$3";;
+ esac
+}
+
+# list of feeds to fetch:
+feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ feed "connector example" "UCrbvoMC0zUvPL8vjswhLOSw"
+}
+</code></pre>
+<h2>Screenshot using sfeed_curses</h2>
+<p><a href="downloads/screenshots/sfeed_curses_youtube.png"><img src="downloads/screenshots/sfeed_curses_youtube.png" alt="Screenshot showing the improved Youtube feed" width="480" height="270" loading="lazy" /></a></p>
+<h2>Clone</h2>
+<pre><code>git clone git://git.codemadness.org/frontends
+</code></pre>
+<h2>Browse</h2>
+<p>You can browse the source-code at:</p>
+<ul>
+<li><a href="https://git.codemadness.org/frontends/file/youtube/feed.c.html">https://git.codemadness.org/frontends/file/youtube/feed.c.html</a></li>
+<li><a href="gopher://codemadness.org/1/git/frontends/file/youtube/feed.c.gph">gopher://codemadness.org/1/git/frontends/file/youtube/feed.c.gph</a></li>
+</ul>
+<p>The program is: youtube/feed</p>
+<h2>Dependencies</h2>
+<ul>
+<li>C compiler.</li>
+<li>LibreSSL + libtls.</li>
+</ul>
+<h2>Build and install</h2>
+<pre><code>$ make
+# make install
+</code></pre>
+<h1>That's all</h1>
+<p>I hope by sharing this it is useful to someone other than me as well.</p>
+
+ </article>
+ </div>
+ </main>
+</body>
+</html>
(DIR) diff --git a/output/youtube-feed.md b/output/youtube-feed.md
@@ -0,0 +1,159 @@
+... improved at least for my preferences ;)
+
+It scrapes the channel data from Youtube and combines it with the parsed Atom
+feed from the channel on Youtube.
+
+The Atom parser is based on sfeed, with some of the code removed because it is
+not needed by this program. It scrapes the metadata of the videos from the
+channel its HTML page and uses my custom JSON parser to convert the
+Javascript/JSON structure.
+
+This parser is also used by the [json2tsv](https://codemadness.org/json2tsv.html) tool. It has few dependencies.
+
+
+## Features
+
+* Add the video duration to the title to quickly see how long the video is.
+* Filter away Youtube shorts and upcoming videos / announcements: only videos are shown.
+* Supports more output formats: Atom, [JSON Feed](https://www.jsonfeed.org/version/1.1/) or
+ [sfeed](https://codemadness.org/sfeed.1.txt) Tab-Separated-Value format.
+* Easy to build and deploy: can be run as a CGI program as a static-linked
+ binary in a chroot.
+* Secure: additionally to running in a chroot it can use pledge(2) and unveil(2)
+ on OpenBSD to restrict system calls and access to the filesystem.
+
+
+## How to use
+
+There is an option to run directly from the command-line or in CGI-mode. When
+the environment variable $REQUEST_URI is set then it is automatically run in
+CGI mode.
+
+
+Command-line usage:
+
+ youtube_feed channelid atom
+ youtube_feed channelid gph
+ youtube_feed channelid html
+ youtube_feed channelid json
+ youtube_feed channelid tsv
+ youtube_feed channelid txt
+
+
+CGI program usage:
+
+The last basename part of the URL should be the channelid + the output format
+extension. It defaults to TSV if there is no extension.
+The CGI program can be used with a HTTPd or a Gopher daemon such as geomyidae.
+
+For example:
+
+ Atom XML: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.xml
+ HTML: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.html
+ JSON: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.json
+ TSV: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.tsv
+ twtxt: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.txt
+ TSV, default: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw
+
+ Gopher dir: gopher://codemadness.org/1/feed.cgi/UCrbvoMC0zUvPL8vjswhLOSw.gph
+ Gopher TSV: gopher://codemadness.org/0/feed.cgi/UCrbvoMC0zUvPL8vjswhLOSw
+
+
+An OpenBSD httpd.conf using slowcgi as an example:
+
+ server "codemadness.org" {
+ location "/yt-chan/*" {
+ request strip 1
+ root "/cgi-bin/yt-chan"
+ fastcgi socket "/run/slowcgi.sock"
+ }
+ }
+
+
+## Using it with [sfeed](https://codemadness.org/sfeed.html)
+
+sfeedrc example of an existing Youtube RSS/Atom feed:
+
+ # list of feeds to fetch:
+ feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ # normal Youtube Atom feed.
+ feed "yt IM" "https://www.youtube.com/feeds/videos.xml?channel_id=UCrbvoMC0zUvPL8vjswhLOSw"
+ }
+
+
+Use the new Atom feed directly using the CGI-mode and Atom output format:
+
+ # list of feeds to fetch:
+ feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ # new Youtube Atom feed.
+ feed "idiotbox IM" "https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.xml"
+ }
+
+... or convert directly using a custom connector program on the local system via the command-line:
+
+ # fetch(name, url, feedfile)
+ fetch() {
+ case "$1" in
+ "connector example")
+ youtube_feed "$2";;
+ *)
+ curl -L --max-redirs 0 -H "User-Agent:" -f -s -m 15 \
+ "$2" 2>/dev/null;;
+ esac
+ }
+
+ # parse and convert input, by default XML to the sfeed(5) TSV format.
+ # parse(name, feedurl, basesiteurl)
+ parse() {
+ case "$1" in
+ "connector example")
+ cat;;
+ *)
+ sfeed "$3";;
+ esac
+ }
+
+ # list of feeds to fetch:
+ feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ feed "connector example" "UCrbvoMC0zUvPL8vjswhLOSw"
+ }
+
+
+## Screenshot using sfeed_curses
+
+[](https://codemadness.org/downloads/screenshots/sfeed_curses_youtube.png)
+
+
+## Clone
+
+ git clone git://git.codemadness.org/frontends
+
+
+## Browse
+
+You can browse the source-code at:
+
+* <https://git.codemadness.org/frontends/file/youtube/feed.c.html>
+* <gopher://codemadness.org/1/git/frontends/file/youtube/feed.c.gph>
+
+The program is: youtube/feed
+
+
+## Dependencies
+
+* C compiler.
+* LibreSSL + libtls.
+
+
+## Build and install
+
+ $ make
+ # make install
+
+
+# That's all
+
+I hope by sharing this it is useful to someone other than me as well.
(DIR) diff --git a/pages/youtube-feed.cfg b/pages/youtube-feed.cfg
@@ -0,0 +1,6 @@
+title = Improved Youtube RSS/Atom feed
+id = youtube-feed
+description = Improved Youtube Atom feed by adding video duration and filtering away shorts
+keywords = youtube, sfeed, RSS, atom, frontends
+created = 2023-11-20
+updated = 2023-11-20
(DIR) diff --git a/pages/youtube-feed.md b/pages/youtube-feed.md
@@ -0,0 +1,159 @@
+... improved at least for my preferences ;)
+
+It scrapes the channel data from Youtube and combines it with the parsed Atom
+feed from the channel on Youtube.
+
+The Atom parser is based on sfeed, with some of the code removed because it is
+not needed by this program. It scrapes the metadata of the videos from the
+channel its HTML page and uses my custom JSON parser to convert the
+Javascript/JSON structure.
+
+This parser is also used by the [json2tsv](/json2tsv.html) tool. It has few dependencies.
+
+
+## Features
+
+* Add the video duration to the title to quickly see how long the video is.
+* Filter away Youtube shorts and upcoming videos / announcements: only videos are shown.
+* Supports more output formats: Atom, [JSON Feed](https://www.jsonfeed.org/version/1.1/) or
+ [sfeed](sfeed.1.txt) Tab-Separated-Value format.
+* Easy to build and deploy: can be run as a CGI program as a static-linked
+ binary in a chroot.
+* Secure: additionally to running in a chroot it can use pledge(2) and unveil(2)
+ on OpenBSD to restrict system calls and access to the filesystem.
+
+
+## How to use
+
+There is an option to run directly from the command-line or in CGI-mode. When
+the environment variable $REQUEST_URI is set then it is automatically run in
+CGI mode.
+
+
+Command-line usage:
+
+ youtube_feed channelid atom
+ youtube_feed channelid gph
+ youtube_feed channelid html
+ youtube_feed channelid json
+ youtube_feed channelid tsv
+ youtube_feed channelid txt
+
+
+CGI program usage:
+
+The last basename part of the URL should be the channelid + the output format
+extension. It defaults to TSV if there is no extension.
+The CGI program can be used with a HTTPd or a Gopher daemon such as geomyidae.
+
+For example:
+
+ Atom XML: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.xml
+ HTML: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.html
+ JSON: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.json
+ TSV: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.tsv
+ twtxt: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.txt
+ TSV, default: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw
+
+ Gopher dir: gopher://codemadness.org/1/feed.cgi/UCrbvoMC0zUvPL8vjswhLOSw.gph
+ Gopher TSV: gopher://codemadness.org/0/feed.cgi/UCrbvoMC0zUvPL8vjswhLOSw
+
+
+An OpenBSD httpd.conf using slowcgi as an example:
+
+ server "codemadness.org" {
+ location "/yt-chan/*" {
+ request strip 1
+ root "/cgi-bin/yt-chan"
+ fastcgi socket "/run/slowcgi.sock"
+ }
+ }
+
+
+## Using it with [sfeed](sfeed.html)
+
+sfeedrc example of an existing Youtube RSS/Atom feed:
+
+ # list of feeds to fetch:
+ feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ # normal Youtube Atom feed.
+ feed "yt IM" "https://www.youtube.com/feeds/videos.xml?channel_id=UCrbvoMC0zUvPL8vjswhLOSw"
+ }
+
+
+Use the new Atom feed directly using the CGI-mode and Atom output format:
+
+ # list of feeds to fetch:
+ feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ # new Youtube Atom feed.
+ feed "idiotbox IM" "https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.xml"
+ }
+
+... or convert directly using a custom connector program on the local system via the command-line:
+
+ # fetch(name, url, feedfile)
+ fetch() {
+ case "$1" in
+ "connector example")
+ youtube_feed "$2";;
+ *)
+ curl -L --max-redirs 0 -H "User-Agent:" -f -s -m 15 \
+ "$2" 2>/dev/null;;
+ esac
+ }
+
+ # parse and convert input, by default XML to the sfeed(5) TSV format.
+ # parse(name, feedurl, basesiteurl)
+ parse() {
+ case "$1" in
+ "connector example")
+ cat;;
+ *)
+ sfeed "$3";;
+ esac
+ }
+
+ # list of feeds to fetch:
+ feeds() {
+ # feed <name> <feedurl> [basesiteurl] [encoding]
+ feed "connector example" "UCrbvoMC0zUvPL8vjswhLOSw"
+ }
+
+
+## Screenshot using sfeed_curses
+
+[](downloads/screenshots/sfeed_curses_youtube.png)
+
+
+## Clone
+
+ git clone git://git.codemadness.org/frontends
+
+
+## Browse
+
+You can browse the source-code at:
+
+* <https://git.codemadness.org/frontends/file/youtube/feed.c.html>
+* <gopher://codemadness.org/1/git/frontends/file/youtube/feed.c.gph>
+
+The program is: youtube/feed
+
+
+## Dependencies
+
+* C compiler.
+* LibreSSL + libtls.
+
+
+## Build and install
+
+ $ make
+ # make install
+
+
+# That's all
+
+I hope by sharing this it is useful to someone other than me as well.