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 &lt;name&gt; &lt;feedurl&gt; [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 &lt;name&gt; &lt;feedurl&gt; [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&gt;/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 &lt;name&gt; &lt;feedurl&gt; [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 &lt;name&gt; &lt;feedurl&gt; [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 &lt;name&gt; &lt;feedurl&gt; [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&gt;/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 &lt;name&gt; &lt;feedurl&gt; [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 &lt;name&gt; &lt;feedurl&gt; [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 &lt;name&gt; &lt;feedurl&gt; [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&gt;/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 &lt;name&gt; &lt;feedurl&gt; [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
       +
       +[![Screenshot showing the improved Youtube feed](https://codemadness.org/downloads/screenshots/sfeed_curses_youtube.png =480x270)](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
       +
       +[![Screenshot showing the improved Youtube feed](downloads/screenshots/sfeed_curses_youtube.png =480x270)](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.