More playing around with Advogato XML-RPC
I wanted a more bloggy way of accessing my Advogato posts, so once again I turned to the XML-RPC services of Advogato to integrate my homepage with the Advogato diary. Of course, after a bit of hacking it eventually went entirely out of hand. As it turned out, I hacked a simple Java class called ALog which provides convenient access to the Advogato diary services, but also caches the data locally so that I don't have to go query the Advogato server each time a user views my home page. I did this before, but now I actually cache all diary entries and their metadata. If more than an hour has passed, the ALog queries the "diary.len" function on Advogato to see if there has been any new entries, and if so, it downloads it. An index of all diary entries is stored on disk, so that it can easily be fetched to, for example, populate a calendar or a post archive. I found this simple calendar that fulfilled my needs pretty well, and after a new rounds of DateFormatting, sorting and nicotine intoxication, I actually had JSP code that produced something resembling a blog, all based on the data on the Advogato server.
I once again got bitten (I think!) by Windows and Linux differences in Java. I wanted to make writes to the cache (which is file based) atomic, so on all places that I wrote to disk, I first wrote all data to a temporary file in the same directory, and when done, used renameTo() to atomically overwrite the old file with the new one. This seems to work well on Linux, but I'm using Windows on my workstation, where it didn't work at all. So I resorted to deleting the target file just before the rename, which creates a tiny race condition - but for I doubt I'll have to worry about those few milliseconds when it comes to my home page. :-)
I think the ugliest hack in this adventure, however, was the code to sort and count the monthly entries. I just wanted to get something done, so I created a TreeMap, wherein I put an diary count as value and as key a year-month string in the form "yyyy-mm". Then, I created a Comparator for the TreeMap that splits the key string and parses the two halves and compares first the year and then the month. This way, I can use entrySet().iterator() and retrieve an Iterator of Map.Entry objects containing each month and it's post count in a comfortable order. Of course, I had to parse the "yyyy-mm" into a time stamp that could be properly printed, too.
There are many other stupid things with the code (such as that the entire diary metadata index is read at each request), but I won't have to worry about them until the number of diaries is huge and/or I have thousands of visitors to my homepage. After all, the index file is only 272 bytes at the moment (with 16 bytes per post).