```
     ____ __  __  __
 /_/  /  /_  /_/ /_/  _/  /\
__/  /  /   /_  /_  /_/  /__\  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