So, the (very) rough draft of my RSS aggregator is up and running.
There's still a lot of room for improvement (easier configuration, caching the feeds to avoid redownloading them each time the command runs, processing them asynchronously instead of one after the other like a dummy...) but it works.
Handling the feeds was about as straightforward as I expected (with a small caveat: the spec is quite loose regarding which field should be mandatory or not, which can cause some shenanigans if you're expecting to find some data that's not included. One feed I used for testing had a modification date, but not a publication one, for instance. No big deal for a toy script, but I can see how this could become a pain in the butt1).
Outputting the html turned out a bit tricker though. I planned to use Jinja's inheritance to integrate the markup into the global site layout, like I do with pretty much every other page, only to realize that this was supposed to run on the server.
Pelican runs on my local machine, which is where all the templates are. Only the generated output gets uploaded to production. So there's no base template to inherit from.
Well, Duh. I just dumped a document fragment and include it in the main page via javascript. Not great, but hey, it works. I could see it becoming useful if the feed grow large enough, though.2
As often, the only real hurdle was due to one pretty stupid oversight. I planned to organize the various feeds into several categories, and display each category in its own box, like so:
I stole the idea from the old aggregator Sam & Max3 used to run. Sadly, it's not online anymore, so this is from memory. And no, I don't see what's wrong with the design.
No matter where I got the idea, the rub is that I'm currently subscribed to a grand total of 4 feeds. Two of which strike me as interesting to share here. So while the idea of having different categories is cute, I just don't see how this is useful right now.
Oh well. I'll keep the idea in mind and wait and see if it makes sense one day. Until then, I'll just stuff everything in a single category and call it a day.
It's probably gonna be a little while before this page gets interesting, but the plumbing is in place, so adding sources to it should be easy.
Unrelated: I hate Python type hints
The python community have been pretty keen on adopting type hints over the last few years. I've tried to use them a couple of times now and got rid of them after 10 minutes.
I get the appeal of static typing, and I even enjoy it when I'm fooling around in C or some other, stricter language. The general consensus seems to be that dynamic languages didn't turn out so great, and the compromise of optionally declaring your types seems to be getting popular4. That's fine.
But Python's implementation just feels wrong to me. Maybe Its just old habits clouding my judgment. And I'm sure I could get the hang of it after some practice.
It starts out nice enough, but pretty soon you're having to import a dozen names to handle builtin types like lists or dictionnaries. Function signatures become a mess.
# Exemple lifted from https://www.geeksforgeeks.org/type-hints-in-python/
from typing import Optional, List, Tuple
def get_user(id: int) -> Optional[str]:
return None if id == 0 else "User"
def sum(num: List[int]) -> int:
return sum(num)
def get_name_and_age() -> Tuple[str, int]:
return ("Abc", 25)
Sure, there's a lot of information packed in there. But I can't parse any of this from a casual glance. The same code used to look like this:
def get_user(id) :
return None if id == 0 else "User"
def sum(num):
return sum(num)
def get_name_and_age():
return ("Abc", 25)
I don't know about you, but if I were to check out a language praised for its
readability, I'd sure expect something closer to the second exemple (although
to be fair, the first one is pretty mild, but things can get much hairier. Also,
the sum
function shadows the builtin one and triggers an infinite recursion.5
This has nothing to do with type hints, though (then again... it was easier to
to spot in the distraction free version...)).
Also, I ran into this case:
class Feed:
def __init__(self, some_stuff: StuffType):
self.stuff = some_stuff
@classmethod
def from_url(cls, url: str) -> Feed:
stuff = get_stuff(url)
return cls(stuff)
Which is simple enough, but blows up with a NameError
. Since the class is built
dynamically, the name Feed
is not defined yet when it's used as from_url
's
return value.
Python 3.13 fixed this, and you can get it to work on earlier versions with a
__future__
import.6 I'm far from being a language expert, but I do know
that evolving syntax is hard, and this tells me the devs have to modify the
parser to handle corner cases that feel like they should be obvious, which confirms
my overall impression that this whole thing is being duct-taped on top of something
that was not designed for it.
Again, I may just be an old fart yelling at the clouds here. People way smarter than me are endorsing this, and my pythoning has been pretty anecdotic since 2019, so I'm not really in a position to argue with anyone who deals with it on a daily basis. Also, I'm not defending dynamic typing at all cost here. I'm just worried than this evolution is just not as straightforward as it seems. It's been 10 years since the syntax was first introduced and cases like the one I ran into are only now being handled.7
I keep telling myself I'll give it a fair try sometime, but I just can't be bothered for the quick and dirty stuff I tend to do these days.
Okay, rant over. See ya and long live duck typing.
-
This is why people are pushing to move to Atom, which is a stricter specification for syndication. I tend to call them both "RSS" out of habit. ↩
-
I resisted including htmx just for that and wrote the plain js version. Hurray for discipline. ↩
-
Content Warning: this is a french blog. Also, NSFW. ↩
-
The new hot thing seems to be type inference, in which the language is statically typed but can infer those types when its obvious (typically when declaring variables). I haven't played much with it, but I like it. Also, Zig code can get pretty ugly, but for some reason its signatures don't bother me one bit. It feels like a natural part of the syntax. ↩
-
AKA stack overflow ↩
-
This brings back memories of supporting both Python 2 et 3. ↩
-
I'm not trying to imply that the python devs are doing a bad job here. Far from it. I vaguely understand why it happened, and I know that changing the fundamentals of a language is a long and thankless job. I just wonder if the end result is worth so much hard work. ↩