``` ____ __ __ __ /_/ / /_ /_/ /_/ _/ /\ __/ / / /_ /_ /_/ /__\ public domain 2020-2025 ``` I wrote ytfeed's 1.0 as ytfeed.py (an all-Python project) in 2020-2021 as I finished high school, partly as a tool I wanted and partly as a learning opportunity. My use of ytfeed.py as a learning project ended up undoing its usefulness and turning it into a >1KLoC monster that could rewrite itself (really) and had helper functions for every trick in the book. The menu system in particular was the hardest part to make feel /good/ (or at least decent, compared to a TUI) and spanned half the size of the project. I gave up on it after failing to beat it into some shape (I thought I could rewrite ytfeed.py in POSIX shell, which is definitely possible but definitely impractical) and put the code tarballs on the Internet Archive, hoping someday I could revisit it. Now, thoroughly an adult, I present the product of a number of years' reflection on what I could have done better. I started using this program as soon as it was workable and it remains my favorite design for a YouTube client. There are plenty of little hiccups and inconveniences that make it difficult to recommend to others, but I use this client daily (or so) and I hope others find it to be useful for themselves. Originally it was pronounced "youtubefeed" really fast, so that I could gloss over the fact that it is a program that only exists because YouTube does. Then, "whitefeed", as a nice pun and to reflect that I would be adding general RSS support. Then I stopped caring about RSS and never added the support, so I call it "whitefeed" in my head and "my little YouTube client" out loud. You may call ytfeed whatever suits you and your form of communication, and also you may do so for literally every formation of characters; it's your life, dude. ytfeed relies upon YouTube's RSS feed support which somehow has not yet been killed by Google. For good luck, don't breathe a word of it to any Alphabet employees. It is clunky - requiring a UCxxxx channel ID is weird - and it is reliable - it uses the network sparingly by design. ytfeed(6) is a small and simple YouTube client made using menu(1). ytfeed(6) exists as a demonstration of menu(1), menu(1) was written as a component of ytfeed(6), and they were both written for my own personal use. There are many components of ytfeed that work independently of it. ytfeed.aggregate(1) is a tool to merge many catenated YouTube RSS feeds into one XML-compliant document. The invocation `cat feed.xml feed2.xml | ytfeedmerge`, for example, assuming the given XML files are YouTube RSS feeds, will output a single YouTube RSS feed containing the entries from both feeds. ytfeed.dl(1) is a tool to download a YouTube RSS feed using curl(1) or wget(1) and store it in the location used by ytfeed(6). I don't care to document the others because they will change. Also, ytfeed's API in general (use of stdin and argv) is not finalized and will likely change. The Python programs are especially short, exclusively use Python's standard library, and are written to (hopefully) work on a reasonably recent Python 3 interpreter. Unfortunately Python will probably shit itself anyway when you try to run them. For what it's worth, they're Python programs because most Linux distributions come with Python 3 and it's one of few languages with XML parsing as part of the standard library - I figured it'd be less hassle than vendoring a dependency or (woe be unto those who think it) relying on whatever awful package managers the user has installed. At some point I'd like to refactor the project to be able to do something like ``` sh ytfeed.browse-feeds \ | menu \ | ytfeed.browse-feed \ | menu \ | ytfeed.browse-entry \ | menu ``` because I find long pipelines to be satisfying. Also, the Python programs would benefit from sharing code rather than duplicating it (it's just a few functions - I promise!). Features from ytfeed.py I will not be including: - a custom configuration file format - a better custom configuration file format (with flow control) - a migration tool from the older to the newer config format - ability to modify the program live from within the program (technically this is now easier but I don't want to) - self reproduction Here's a copy-paste of a ytfeed session on my computer: $ ytfeed ____ __ __ __ /_/ / /_ /_/ /_/ _/ /\ ytfeed 2.0.0-pre __/ / / /_ /_ /_/ /__\ dtb 2020-2025 [1]: Subscribe to new feed. [2]: Browse feeds. [3]: Browse all feeds. [4]: Refresh feeds. [5]: Show configuration [0]: Return >>> 2 [ 1]: 100th Coin ... [ 47]: jawed ... [105]: Ziwe [ 0]: Return >>> 47 [1]: [2005-04-24] jawed - Me at the zoo [0]: Return >>> 1 [2005-04-24T03:31:52+00:00] jawed - Me at the zoo Microplastics are accumulating in human brains at an alarming rate https://www.youtube.com/watch?v=0PT5c1z3LL8 “Nanoplastics and Human Health” with Matthew J Campen, PhD, MSPH https://www.youtube.com/watch?v=RRBN_4L09Mg 00:00 Intro 00:05 The cool thing 00:17 End [1]: Download feed. [2]: Print feed URL. [3]: Open feed URL in mpv. [0]: Return >>> 3