blog.rupamsunyata.org

Decklin’s excuse for some blogging software. Est. 2006.

The cradle rocks above an abyss

In related news: with sup out of the way, I have returned to packaging Mnemosyne, the program that powers this blog. It is also in NEW, so expect to see it soon. (Like sup, which is packaged as sup-mail since sup is the Software Update Protocol, it is mnemosyne-blog since mnemosyne is the program formerly known as PyQt MemAid.)

If you're just joining us, Mnemosyne compiles a Maildir into a static site. You can use it for a blog or just about anything else where a traditional CMS would be overkill. It's all XML and Python-extensible. The documentation kind of sucks, though, so I'm also hoping I get some more users from this to tell me what to fix. It hasn't otherwise seen much action since the beginning of 2006. Drop me a line if you have any feedback!

(If it's not obvious, I think blog "comments" in general are pretty worthless. But with some craftiness, they could certainly be implemented within Mnemosyne as it stands. As could a general mailing list archive, etc...)

What's sup?

After some weeks of final testing, I've just uploaded packages for sup-mail to NEW. I'm pretty excited about this.

Sup is a console-based MUA, like mutt (which I have used for many years). A few things distinguish it from most mail readers targeted at geeks like us:

  • Sup has no folders, a la Gmail. After watching many friends and even fellow hackers switch to Gmail, I have to admit: this literal hierarchical organization thing doesn't scale. I was planning to totally redo my mail folder system Any Day Now for about six months prior to starting on this. It was never going to happen.
  • Sup uses a Ferret full-text index to make this approach plausible. Search is super fast and beats (for me) both any kind of "organization" I could have disciplined myself into and the fine-grained control of something like mutt's search. It's sort of like git: until you do it, you don't realize how much more productive you can be when previously-expensive operations become instantaneous.
  • Sup works with threads, not messages; this is another thing Gmail got right. I used to waste brain cells thinking about which messages in a thread were worthwhile enough to save or not. Given the absurdly cheap price of disk relative to what we can type out in plain text since, like, a decade ago, this is crazy. In the index, I only have to look at whether a thread has new chatter or not, not its size, shape, or where the new messages are relative to it. All that's in the thread-view buffer where I actually read content.
  • Sup is written in Ruby. Back in the dawn of time, I used Gnus, and while I wasn't very good at elisp, the hackability afforded by being written in a high-level language was very nice compared to programs mostly implemented in C (even if they had a tacked-on scripting language). Plus, I love Ruby right now.

Despite all of those wins, sup currently has many drawbacks, and I don't recommend it for everyone. (And I mean everyone who thinks that the above are good ideas and are interested in using it; plenty of people, I'm sure, already think everything about this is idiotic, not new, or inferior to their preferred MUA. That's fine! You can ignore it all.) Here's what's still problematic:

  • At version 0.6, sup is very much not-yet-1.0. While it handles insanely large amounts of email without breaking a sweat, I still keep an additional backup of everything. (If Ferret crashes, the original copies of mail will be untouched, but it never hurts to be paranoid.)
  • The flow of data from your physical mail store to the sup index is currently one-way only. Actually removing deleted/spam messages is a big hack (if it works at all), and labels/flags/etc live entirely in Ferret-land. If you want to manipulate an actual mailbox, mutt is still the tool for the job (and then, you need to re-sync sup). This is probably the deal-breaker for most of us. I jumped in anyway because I feel like it can be solved (or more likely, made irrelevant) later.
  • William (upstream) is currently re-designing the whole thing from scratch, replacing the index library with Sphinx, and decoupling the index from the console frontend. As a result, the previous item is pretty much a non-priority (and bugs in general are not going to get the same amount of love as usual). I am hoping that we end up dumping mail into the index directly, then writing more frontends to write to Maildir backup, serve as webmail/whatever, but this is a long way off. On the plus side, thanks to Thrift, they will not be limited to Ruby.
  • Ruby's ncurses library still doesn't handle Unicode correctly. It can be patched (still doesn't work totally right), but I'm trying to find a more permanent solution for Debian.

So, if you're interested enough that you want to deal with these warts for now, apt-get install sup-mail (as soon as it hits the archive) and join us! Hopefully being in Debian will increase the userbase and get things fixed faster. If you're unsure, stay tuned for the next-generation version later.

(There are screenshots and a few introductory docs over at Rubyforge that illustrate and explain all this in more depth, which I recommend checking out if you're still saying, "...huh." Me, I'm a sucker for any piece of software with a manifesto.)

When mayonnaise goes bad

This is is a wonderful metaphor: "looking in the fridge every few minutes and hoping that something tasty will appear".

I may be thick, but Planet does not appear to store any information about how often a feed ought to be polled (my blog seems to be hit every 20 minutes even when I'm AWOL). I use rawdog, which does.

When adding a feed, I make a vague guess at how often I want to poll it, and then periodically adjust the time based on how often updates actually happened. This is done with a terrible, awful, ugly hack that reads the database[1] and spits out the config file with new-and-improved times. Pretty dumb, but good enough "for now" (apparently I haven't touched it in over a year).

rawdog will also automatically update feed locations if given a 301. Since it already rewrites the config for that, I might try to merge time updating into the core someday, but no one has demanded such a feature AFAIK.

[1]And by "database", I mean "pickle", since Adam doesn't want any fancy dependencies. Despite how slow this ought to be, the combination of optimized (such as it is) feed-polling and ever-faster CPUs in my web servers have made it fast enough for me not to care.

Catch 22

$ hg ci
abort: cannot commit over an applied mq patch
$ hg qpop
abort: local changes found, refresh first

Obviously, I just need to RTFM, but I still find this amusing in an existential sort of way.

(If I write a replacement for mq, please shoot me. I have too many things to do already.)

You keep using that word. I do not think it means what you think it means.

I always feel like tar ought to say:

tar: data.tar.gz: inconceivable time stamp 1969-12-31 19:00:00

But it never does.

We’re here to help

Every time I read my Apache logs I get a very strong urge to block anything claiming to be Mozilla that is not actually Mozilla. Then I go make some tea and chill out.

(Years ago this was sheer eccentricity. But for the love of God, software that didn’t even exist in 2005 is still doing it.)

Flow Control

Raise your hand if you have ever said, “I wish I could use C-s and C-q in Firefox.”

Dee Ess Double-yoo

Occasionally I see an absurd discussion like this one continue to drag itself out and I feel sort of guilty for writing one of the big “minimalist” things. The point of writing less code is not to conserve memory or cycles or soothe some “first thing we’ll do, let’s purge all the libraries” fetish. The point is to only write what you want to express. If a feature would require that to get lost in a bunch of dreary nonsense, then it’s not worth it. If there’s a library you can call that lets you say the what and not the how, then it is.

More importantly if there’s a standard program that you can call that’s the same standard program that everyone has agreed on for decades and that saves you from implementing a protocol which you are obviously not smart enough to implement on your own, then you just shut up and fucking call it. And if that causes you to realize that your program is pointless, don’t write it.

Not writing it is the least amount of code you can produce. And that is the best possible thing you can do. That’s what this unix thing is all about. Those who do not understand it are condemned to reimplement it, poorly.

The good fight

This is wonderful. (via Amaya.)

Also, I really need to do something about my aggregator situation. Gendergeek is on my list and it’s gotten so lost in the flood that I haven’t clicked through to it in forever. Sometimes I just go to a few of the sites I care about directly. This has to stop.

Constants of the universe

One of the few annoying things about free software is simply finding it. You can get a very good idea of what is to your taste or not from people around you, but if you don't know or care (or want to care!) about some particular problem, generally people whose opinions you trust don’t like any of this crack either.

In particular, Web Frameworks(tm). Lots of people love them. I’ll take vanilla. After paging through several manuals last weekend for things which I might be able to use a templater from, and finding that despite all the other features, no one seemed to even care that much about even doing inheritance sanely, I got annoyed and grumbled something about how they all sucked and figured I could just factor that logic out myself and use what I was already using for the boring bit.

However, Erich pointed out that that sucked too. And if you care about being correct (says me who serves all these pages with the XHTML mime type despite it breaking Internet Explorer and Google), you should probably assume that if you give your users (including yourself!) something fragile, they’re inevitably going to break it (and if they’re the sort of users that have been crawling out of the woodwork these days, well...). So I checked out Kid, to which I am giving yet another link here because it’s just that good. I’ve seen attempts to implement the “it’s all valid XHTML” thing before and they were rather blah. This one seems to actually fit with its being hosted on lesscode.org. And I am nothing if not a sucker for less code. And for things being pleasant to read.

So I ported my templates over and added the four lines I alluded to, and now (since I know my output is provably valid), although I have not put them live yet, I have a starting point for making them be a little less crack (really, it’s very bad). Has anyone registered lesscrack.org yet?

This is where we do some shameless self-promotion I think

Erich, I’ve been working on one for this blog. No persistent cache to speak of except for the files themselves when their sources haven’t been touched, and I haven’t found any reason to need XML, but I was trying to avoid much of the same nonsense you mention. As such, the templating is as dumb as possible. Perhaps you can do a lot more with XSLT, but I didn’t find it very interesting. Templating systems in general make me itchy.

I am now, however, thinking about making it easy to subclass that part of things as well, which could be interesting. Write something to talk to the big XML library, one import in layout, a few lines to save the cache in a pickle... hmm!

(I always stick a “raw-html” role into reST if I really need it for something, but generally, I try not to think about HTML period.)

I haven’t heard from anyone about it yet so I don’t know which X, Y, and Z are obviously lacking. :)

Fitts' Revenge

Tip of the day:

.toolbar-primary > toolbarbutton .toolbarbutton-icon {
    padding: 5px !important;
}

More target-acquisition space, no distracting labels. People who write extensions tend to make their labels ridiculous.

Hate

I truly, truly hate email. First you have the __getitem__ and __setitem__ that work nothing like a dict (no KeyError ever, just returns None, despite there being a get, silently fails to overwrite an existing value, no update). But of course they're just as stupid as a dict if you change the content, instead of associating the type with that object. And then. decode_header. Does this:

[('Foo', 'utf-8'), ('Bar', None)]

Hint: ('Bar', None) is not a valid list of arguments for creating a unicode object. I don’t even want to create it myself. I just want the thing decoded. Ugh, ugh, ugh. Everything that possibly could have sucked here has sucked. Lots.

One of the reasons I decided to use Maildir is because it takes two lines of code to turn it into a structured list of objects. Except of course both of the standard modules that make that possible are horribly designed. I really don’t want to reimplement this shit. I really don’t want to go to a “real” database backend where suddenly you can't use any standard unix tools to do anything and you have to write them all from scratch.

All software sucks. Down, not across.

Gratuitous Non-discoverability of Interfaces

Actually, what really bothers me about the GTK+ file dialogs is having to click “Browse for other folders” every single time I open the one for saving. (Last I looked this up, the only solution was to patch GTK+.)

My understanding of all this touchy-feely user-interface stuff is that humans are supposed to be oriented spatially (classic Finder) or by breadcrumbs (Netscape). A tiny little dropdown with a text label of just the current directory's name (not even a full path) gives me no idea whatsoever “where” I am. I constantly save things in the wrong directory from Firefox.

While basename $PWD is all the directory information I put in my shell prompt, I can do considerably more from there, and new shells don’t tend to pop up two hours later when you forgot where you cd’d to last time. What is acceptable for me there is not acceptable for a normal user here. I really don’t get what they were thinking.

Generated by Mnemosyne 0.12.