Showing posts with label renquist. Show all posts
Showing posts with label renquist. Show all posts

Unit testing

I just committed basic unit testing support to Renquist, implemented using Python's unittest framework. The results were quite pleasing. Now I can quickly run multiple automated tests to ensure correct behavior and avoid regressions! Huzzah!

For my first two tests I decided to try using a blank file as both a Feed and as a List. The blank Feed test uncovered a bug I hadn't considered, while the blank List test made me fix a problem I had already tagged as a failure point in the comments of the source code. Both bugs are fixed now, but there's surely still a lot of code that isn't being touched by these tests. But how can I identify those untested lines of code?

The first thing I thought after writing those two test cases was, There should be a way to visually identify the untested code. After looking through the Python documentation, the first thing I found was the "trace" module, which can output every single line that gets run. It would take almost no work at all to generate a very simple HTML file, highlighting tested code (or untested code).

Before I write that software, though, I'm going to search a little online. I can't imagine that someone else hasn't had that idea, too.

Here's to automated testing!

Authorship and extensibility

Feed items can now have authors associated with them in the database using a one-to-many authors-to-items relationship. Renquist by default will only use a one-to-one relationship, however (which means that there will be one author entry for each item entry). At first I struggled with the idea that there would be significant data duplication; I'm the only one writing on this blog, so why store ten identical "Kurt" authors given ten feed items? Wouldn't it make more sense to store that information only once?

Yes, but then I considered the case of comment feeds. I know already that there have been three Davids who have posted on my site. One uses "Dave", another "David", and the third showed up once and called himself "David (a different one)". There could easily be a collision of names, and it would be foolish to think that just because someone says that he's "David" that he's the same "David" who posted three other comments. Make sense?

Therefore I'm choosing to leave it up to someone else (through an as-yet-unrealized plugin framework) to decide how best to minimize duplication. Maybe the plugin could merely minimize duplication by name; easy, but perhaps not ideal in all circumstances. Maybe the plugin could minimize duplication using more advanced means (those three Davids might be writing in three separate languages, for instance). There are at least two other methods that jump to mind, but it's easy to see the potential for a smart plugin.

In the meantime, however, Renquist will store author information despite likely data duplication.

Renquist and distutils

There have been some big goings-ons with Renquist! I have more or less gotten the code in a somewhat usable state, and have removed some more hard-coded elements. In addition, I've worked on adding code so that Python's distutils can package up the software automatically. Now Renquist can be installed as a true library!

Don't expect code anytime soon, however. Since my name is going on the software, there's no chance that I'm going to be letting it out the gate without some serious vetting, and that means unit testing (via Python's unittest). Also, I haven't yet hooked up author and enclosure code.

And finally, there's no documentation, which is just unacceptable for a library. I haven't yet settled on what software to use. pydoctor looks nice, but there are no official releases to download. Epydoc does have releases available for download, though...I guess I'll cross that bridge when I come to it.

There's all of the big news right now. Fun fact: I'm currently building Renquist as version 0.0.0 alpha. When it's releasable, it'll probably be called version 0. Exciting!

Licensing Renquist

I've long thought that the GNU GPL was the software license that best reflected my ideologies about software, and with the release of the GNU GPL version 3, I've decided that it's important to man up and commit to the new version. I'm taking it a step further, however: Renquist will be licensed under the GNU Affero General Public License, version 3.

The reason I'm choosing the Affero version is that it prohibits someone from using Renquist as a backend for a web service without making the source code available. Under the regular GPL licenses, web services do not technically distribute any software to people, so there is no need to provide source code. Thus, someone could take Renquist, significantly improve it, and create a web service without ever having to release the source code of the changes. This is unacceptable; everyone should benefit from any improvements to the code. Choosing the GNU AGPLv3 helps ensure that any and all improvements will be made available to the public so that everyone benefits.

And that's the way it should be.

Feed lists

As I've had time, I've continued to work on Renquist, and have added some support for feed lists. Thus, rather than subscribing to a particular feed, a person can subscribe to a list of feeds. For instance, maybe my friend John is always finding new webcomics. I can just subscribe to his feed list and I'll automatically start seeing the new comics, too, as he adds them.

The next step may be to cook up a template so I can output feed lists in OPML format.

Renquist

I have been having a blast working on my feed software idea. I've been trying to apply good programming practices throughout, and although I have very little functional code, I do have some architectural code in place.

As an example, I've got some code in place for using the Decorator Pattern. Basically, a plugin can define new functionality and data structures that can be wrapped around feed items. Thus, while regular feed items contain information like "This article was posted on October 20th, 2007 by Kurt", a decorator might add additional information: "...and is currently unread". It looks like this will be mostly transparent to all of the other code (as it should be!), because later today I'm expecting to tinker with implementing the Factory Pattern. The Factory Pattern lets all of the rest of the code be ignorant of the existence of any decorators; the rest of the code just asks for a feed article, and any decorators will be automatically attached.

When I actually sat down to code for the first time, I came up with a name for the project: Renquist. You see, I had "True Lies" (1994) on in the background, and Arnold Schwarzenegger had just introduced himself to Tia Carrere as Renquist. Harry Renquist. I figured, Hey, if he can dance the tango with Tia Carrere and then blow up some stuff and shoot a bunch of people in the ensuing chase, Harry "Renquist" can do anything. And I'd like this software to be just as capable.

Unable to sleep

I've been reading a "For Dummies" book about design patterns, which are tried-and-true ways to solve software development problems. Unfortunately, it has triggered a sleepless state that I haven't experienced in a long time, in which I'm unable to quiet my mind because I'm thinking about software development. It's 3:30a now, and sleep is far from my mind.

For the longest time I used a desktop application called Liferea to manage and read my feeds. Not bad, but it had some shortcomings: it was slow, it was buggy, and the developer was making changes that didn't sit well with me. I switched to the web-based Google Reader and have been relatively happy, but there are long-standing limitations with Google Reader. For instance, I can't read my friend Tiffany's feed because Reader doesn't support authenticated feeds (i.e. feeds that require a username and password). Further, it's impossible to do interesting things with Reader. As an example, I'd like to have a Bayesian filter that I can train to separate interesting posts from uninteresting posts; perhaps I like Miguel de Icaza's posts about software, but would rather ignore his political posts.

So what can I do to improve the situation? I could switch from Google Reader to another service, but I still won't have extensibility. I could switch to web-based software that I run myself, such as FoFRedux, but extensibility could very well come at a high price: I don't think FoFRedux is in active development, and my changes will be almost useless when I upgrade to the next version (whenever that may come out). Or, perhaps I could take a lesson from Phillip van Hoof, who used design patterns to create TinyMail (the design of which has impressed me for almost a year now).

Now you're all caught up with what's been going through my mind: I've ideas for writing my own web-based feed reader. Maybe the idea will pass and nothing will come to fruition...but maybe I'll have a pleasant project that I can learn from and enjoy and share with others. Either way, it's 3:50a, and I need to get back to lying in bed.