youtube-feed.html - 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
---
youtube-feed.html (6936B)
---
1 <!DOCTYPE html>
2 <html dir="ltr" lang="en">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
5 <meta http-equiv="Content-Language" content="en" />
6 <meta name="viewport" content="width=device-width" />
7 <meta name="keywords" content="youtube, sfeed, RSS, atom, frontends" />
8 <meta name="description" content="Improved Youtube Atom feed by adding video duration and filtering away shorts" />
9 <meta name="author" content="Hiltjo" />
10 <meta name="generator" content="Static content generated using saait: https://codemadness.org/saait.html" />
11 <title>Improved Youtube RSS/Atom feed - Codemadness</title>
12 <link rel="stylesheet" href="style.css" type="text/css" media="screen" />
13 <link rel="stylesheet" href="print.css" type="text/css" media="print" />
14 <link rel="alternate" href="atom.xml" type="application/atom+xml" title="Codemadness Atom Feed" />
15 <link rel="alternate" href="atom_content.xml" type="application/atom+xml" title="Codemadness Atom Feed with content" />
16 <link rel="icon" href="/favicon.png" type="image/png" />
17 </head>
18 <body>
19 <nav id="menuwrap">
20 <table id="menu" width="100%" border="0">
21 <tr>
22 <td id="links" align="left">
23 <a href="index.html">Blog</a> |
24 <a href="/git/" title="Git repository with some of my projects">Git</a> |
25 <a href="/releases/">Releases</a> |
26 <a href="gopher://codemadness.org">Gopherhole</a>
27 </td>
28 <td id="links-contact" align="right">
29 <span class="hidden"> | </span>
30 <a href="feeds.html">Feeds</a> |
31 <a href="pgp.asc">PGP</a> |
32 <a href="mailto:hiltjo@AT@codemadness.DOT.org">Mail</a>
33 </td>
34 </tr>
35 </table>
36 </nav>
37 <hr class="hidden" />
38 <main id="mainwrap">
39 <div id="main">
40 <article>
41 <header>
42 <h1>Improved Youtube RSS/Atom feed</h1>
43 <p>
44 <strong>Last modification on </strong> <time>2023-11-20</time>
45 </p>
46 </header>
47
48 <p>... improved at least for my preferences ;)</p>
49 <p>It scrapes the channel data from Youtube and combines it with the parsed Atom
50 feed from the channel on Youtube.</p>
51 <p>The Atom parser is based on sfeed, with some of the code removed because it is
52 not needed by this program. It scrapes the metadata of the videos from the
53 channel its HTML page and uses my custom JSON parser to convert the
54 Javascript/JSON structure.</p>
55 <p>This parser is also used by the <a href="json2tsv.html">json2tsv</a> tool. It has few dependencies.</p>
56 <h2>Features</h2>
57 <ul>
58 <li>Add the video duration to the title to quickly see how long the video is.</li>
59 <li>Filter away Youtube shorts and upcoming videos / announcements: only videos are shown.</li>
60 <li>Supports more output formats: Atom, <a href="https://www.jsonfeed.org/version/1.1/">JSON Feed</a> or
61 <a href="sfeed.1.txt">sfeed</a> Tab-Separated-Value format.</li>
62 <li>Easy to build and deploy: can be run as a CGI program as a static-linked
63 binary in a chroot.</li>
64 <li>Secure: additionally to running in a chroot it can use pledge(2) and unveil(2)
65 on OpenBSD to restrict system calls and access to the filesystem.</li>
66 </ul>
67 <h2>How to use</h2>
68 <p>There is an option to run directly from the command-line or in CGI-mode. When
69 the environment variable $REQUEST_URI is set then it is automatically run in
70 CGI mode.</p>
71 <p>Command-line usage:</p>
72 <pre><code>youtube_feed channelid atom
73 youtube_feed channelid gph
74 youtube_feed channelid html
75 youtube_feed channelid json
76 youtube_feed channelid tsv
77 youtube_feed channelid txt
78 </code></pre>
79 <p>CGI program usage:</p>
80 <p>The last basename part of the URL should be the channelid + the output format
81 extension. It defaults to TSV if there is no extension.
82 The CGI program can be used with a HTTPd or a Gopher daemon such as geomyidae.</p>
83 <p>For example:</p>
84 <pre><code>Atom XML: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.xml
85 HTML: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.html
86 JSON: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.json
87 TSV: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.tsv
88 twtxt: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.txt
89 TSV, default: https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw
90
91 Gopher dir: gopher://codemadness.org/1/feed.cgi/UCrbvoMC0zUvPL8vjswhLOSw.gph
92 Gopher TSV: gopher://codemadness.org/0/feed.cgi/UCrbvoMC0zUvPL8vjswhLOSw
93 </code></pre>
94 <p>An OpenBSD httpd.conf using slowcgi as an example:</p>
95 <pre><code>server "codemadness.org" {
96 location "/yt-chan/*" {
97 request strip 1
98 root "/cgi-bin/yt-chan"
99 fastcgi socket "/run/slowcgi.sock"
100 }
101 }
102 </code></pre>
103 <h2>Using it with <a href="sfeed.html">sfeed</a></h2>
104 <p>sfeedrc example of an existing Youtube RSS/Atom feed:</p>
105 <pre><code># list of feeds to fetch:
106 feeds() {
107 # feed <name> <feedurl> [basesiteurl] [encoding]
108 # normal Youtube Atom feed.
109 feed "yt IM" "https://www.youtube.com/feeds/videos.xml?channel_id=UCrbvoMC0zUvPL8vjswhLOSw"
110 }
111 </code></pre>
112 <p>Use the new Atom feed directly using the CGI-mode and Atom output format:</p>
113 <pre><code># list of feeds to fetch:
114 feeds() {
115 # feed <name> <feedurl> [basesiteurl] [encoding]
116 # new Youtube Atom feed.
117 feed "idiotbox IM" "https://codemadness.org/yt-chan/UCrbvoMC0zUvPL8vjswhLOSw.xml"
118 }
119 </code></pre>
120 <p>... or convert directly using a custom connector program on the local system via the command-line:</p>
121 <pre><code># fetch(name, url, feedfile)
122 fetch() {
123 case "$1" in
124 "connector example")
125 youtube_feed "$2";;
126 *)
127 curl -L --max-redirs 0 -H "User-Agent:" -f -s -m 15 \
128 "$2" 2>/dev/null;;
129 esac
130 }
131
132 # parse and convert input, by default XML to the sfeed(5) TSV format.
133 # parse(name, feedurl, basesiteurl)
134 parse() {
135 case "$1" in
136 "connector example")
137 cat;;
138 *)
139 sfeed "$3";;
140 esac
141 }
142
143 # list of feeds to fetch:
144 feeds() {
145 # feed <name> <feedurl> [basesiteurl] [encoding]
146 feed "connector example" "UCrbvoMC0zUvPL8vjswhLOSw"
147 }
148 </code></pre>
149 <h2>Screenshot using sfeed_curses</h2>
150 <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>
151 <h2>Clone</h2>
152 <pre><code>git clone git://git.codemadness.org/frontends
153 </code></pre>
154 <h2>Browse</h2>
155 <p>You can browse the source-code at:</p>
156 <ul>
157 <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>
158 <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>
159 </ul>
160 <p>The program is: youtube/feed</p>
161 <h2>Dependencies</h2>
162 <ul>
163 <li>C compiler.</li>
164 <li>LibreSSL + libtls.</li>
165 </ul>
166 <h2>Build and install</h2>
167 <pre><code>$ make
168 # make install
169 </code></pre>
170 <h2>That's all</h2>
171 <p>I hope by sharing this it is useful to someone other than me as well.</p>
172
173 </article>
174 </div>
175 </main>
176 </body>
177 </html>