Tinymail finally displays my folders using camel

I finally master camel. Today, just a few seconds ago, tinymail for the first time displayed the folders of my own IMAP account. It’s even doing it recursively correct (it can do folders in folders in folders in f..).

Tinymail uses the camel library which was created for Evolution. It uses camel in combination with mainly the proxy design pattern (Although I must admit it’s not yet using the proxy class itself, it’s design is fully ready to use such a proxy class. I first need to create a factory for the real subject which is used in the proxy classes for lazy getting the real subject instances).

There’s still a lot tweaking needed. Anyway, if you’re into crazy GObject coding, using an even more crazy library like camel, if you’d like to help me create a E-mail client targeted at mobile devices: tell me. Not that I’m promising something that might work sooner or later. As usual, as it’s a free-time project, I’m not promising anything :-p.

Its documentation isn’t very complete, so I do hope to some day speak the camel authors at some conference and/or on IRC. Fejj told me I’m the first to use camel outside of Evolution. If true, I hope libtinymail-camel will also be a guide for using camel as a decoupled library.

Oh and, sure it scales to a lot IMAP folders. My “spam” account is subscribed to a lot mailing list. Look for a screenshot of tinymail doing that account here. In fact, it should even scale to a lot E-mail accounts. As I’m also going to build proxy classes for the “account”-type. The treeview model is an account-list model. Its current implementation is a very simple inherited gtktreestore (I wanted something that works a.s.a.p., this might change in future).

SVN mime-types, ooo.o version control and tinymail

Subversion svn:mime-type property on files

This one-line UNIX command will echo command-lines that’ll fix the “svn:mime-type” property of files in a Subversion repository (perform it on a fresh untouched checkout, you might have to replace quotes as some browsers make mistakes or as perhaps WP converted it incorrectly; I don’t know):

find . -name ‘.svn’ -prune -o -type f -exec echo ‘svn propset svn:mime-type `gnomevfs-info {} | grep MIME | cut -d : -f 2 | cut -c 2-` {}’ \;

I don’t recommend doing this without the echo as perhaps not all your files should get a non-default mime-type in subversion. If you are brave, go for it. Don’t forget to svn commit once the find-script ran.

If the svn:mime-type property is correct, using the Subversion browser-mode will automatically display the file in the browser-window if the mime-type can be viewed by a browser or will ask for a viewer and download-box if the mime-type can’t be viewed. For example if you have an xhtml or a dia file or a odt in a subversion repository (the links should all suggest the correct mime-type to your browser).

Thanks to Tommi for pointing me to that problem, which triggered me into creating that one-line script. Perhaps this is another reason why gnome should some day switch to a modern source control system? (I, personally, definitely prefer subversion over CVS)

OpenOffice.org2 document version control?

Another question related to the odt file format: Does somebody know of a version control system for odt files? Are the brave OpenOffice.Org2 developers working on this?

Such a system would allow a team to work on the same file simultaneously, would show differences between versions, etcetera. So not just a document-version tracking system for binary files. I really want the differences, merging possibilities. Simple stuff. Given the fact that the odt format uses XML, should make it possible. You could create a merge-tool that is intelligent about not causing XML mistakes.

Right now, it’s unpractical to decompress the file, check it in. Check it out, compress the files, work on it, check it in. That doesn’t work as workflow. It just doesn’t. Perhaps a subversion client plugin or openoffice.org subversion integration to automate this?

Tinymail

After looking at it more carefully, I corrected some GObject standards in tinymail. For example the finalize, class_init and the iface_init methods of each type.

Functional description and updated class diagram for deconf

People might start wondering how deconf is doing these days. Deconf is a funny project of mine. Some weeks I’m very actively busy with it, other weeks I’m not. That way I distillate the best ideas from the cruft some people suggest and even more from the cruft I come up with myself.

I’ve been distillating ideas for a few months now. Sometimes, I believe I have a good idea of what such system needs and what it doesn’t need. I decided to create two class diagrams and write some sort of functional analysis that describes the different components I have in mind: the complete complex class diagram, the simplified class diagram and the functional description of the components.

These links point to the real crack. Not other peoples proposals. The code in that repository is prove of concept code. It’s probably not going to be like that.

Some conclusions, more on codegen and GObject

Some conclusions about the design-patterns-in-gobject-at-fosdem post

Some people responded very positive about doing the presentation, saying they are very interested. So chances are very high (it’s more or less certain) that I’ll do the presentation.

It looks like I’m not the only one who’s been trying to use design patterns in combination with GObject: one person told me he’s planning to document the places in the gtk+ library code where specific design patterns where used (ie. gtktreemodel, gdkdisplaymanager). Another person corrected some little glitch in one of the headers of my code and replaced the private data handling of the proxy sample with the standard GObject way of doing that. And another person tells me he’s interested in helping with the XSLT templates for generating GObject classes and interfaces using codegen.

That last one is the main reason for this conclusion-blog. Perhaps are others also interested in helping with that? So I’ll put some pointers:

Note that Codegen is LGPL and that I’m highly interested in any type of contribution or add-on. I already gave one person a commit-account on the subversion repository. Note that codegen itself is heavily based on the strategy design pattern. This makes extending it, yet not having to touch the core of it, trivial. At this moment I’m not focused on codegen. However, things like “which free software project I’m focusing a.t.m.”, change frequently. So it’s perfectly possible that suddenly a huge commit happens, that adds supports for some insanely cool feature :-p.

Design patterns in GObject at FOSDEM

Somebody of the FOSDEM team asked me to do a talk about programming techniques a.k.a. design patterns using GObject.

I have to decide whether or not I’ll do it tomorrow. So I thought, well .. okay. Let’s prepare some samples.

Because else this blog entry would be to long, I created a page that explains the proxy and strategy design patterns and contains the links to the samples.

Note that yes, I did read Head First Design Patterns. And that yes, I based the strategy sample on the chapter in that book.

Also note that I’m planning to create an XSLT for generating GObject interfaces and classes using codegen. If you want to help me with that, contact me.

There’s probably not a single good reason why to do this type of development using GObject and not using a higher environment like C# or Java. My talk will not illustrate why you should use a programming language like C with glib-object.h rather than C# or Java. It’s not going to be the point. I guess there’s no real reason. In fact is any discussion about which programming languages is the better, stupid. The talk will be about what is possible. I’m not going to play the defender of the GObject religion.

FOSDEM

My employer, well actually mainly Kris, would like me to do talks on conferences. The problem is, however, that I don’t feel like I have a lot to talk about. I can of course jump the stage and talk about whatever I know a little bit about. Which is what most conference speakers do, I guess. Another problem is that FOSDEM will happen sooner or later: Kris will likely again ask me whether or not I submitted a paper.

So the question. What should I talk about? By now I think people have had enough custom treemodel stuff from me. I could talk a little bit about how to get started as an evolution contributor and how you could earn some bounty money by doing that. But then again, it looks like these days nobody likes the evolution code anyway. Tinymail is unfinished and not yet worth a conference talk. Gnome-schedule is way to simple. If I’d do a talk about deconf, people would throw large objects at me, would start yelling and would put the building on fire (just take a look at the xdg-list if you want to know what a heated subject like that can do). And finally codegen can’t yet generate GObjects (which can change, of course). And again, some people would throw large objects at me if I’d do a talk about a .NET subject. Especially Kris, the guy who wants me to do talks, would.

So basically, I have nothing to talk about :p. Lucky me!

Anyway. I will be at FOSDEM. That’s for sure. This year, a developer room for Gnomies is arranged (and else, we’ll just steal/take/pick a room. Right?)! Brussels is easy to fly, drive, travel, etc. And they say we Belgians have great chocolate (and the Belgian chocolate is, of course, much cheaper in Belgium), waffles and good beer. So let’s all be there :p! Jeff has setup this wiki page. You can fill in the attendees page if you’re coming.

Tinymail & Camel

Wow, it looks like I’m taking that TinyMail thingy serious. It’s the second evening in a row that I’m working on it. That’s a good sign!

Probably because I’m learning (learned and now enjoying) how to use the GTypeInterface stuff of GObject and Camel with it.

I’ll guide my blog readers through to idea. Note that all subversion URL’s might change as the subversion repository is just a temporary one.

The library libtinymail is a small abstract library that defines all types as interfaces and adds some proxy classes. It defines types like “account”, “message”, “body”, “header”, “folder”, “attachment” and the simple relations between these types. It also contains a few proxy classes which might get moved to the implementation library. This depends on how I’ll design my factory. If done fully correctly, I won’t need to depend the proxy classes on the implementation: think abstract factory technique. But I’ll see how far I’ll get.

I’m planning to use the proxy technique like how I used it in the treeview demo of last week, a lot. The experiment will be whether or not camel can cope with a concept that utilises the proxy technique. So far I haven’t found anything in the camel API that tells me that it won’t work. I’m hoping to speak the authors of camel about this sooner or later. NotZed, of you catch me on IRC or wherever: ping me? :-p

The library libtinymail-camel implements these types using Camel. It’s extremely unfinished, but the implementation for the type “account” shows what I mean. I’m not yet testing with the disksummary branch, but if the camel API doesn’t change a lot, the transition to that shouldn’t be difficult, right? My plan is to eventually only depend on that disksummary branch.

So far I haven’t found any reason why camel would be a lot less resource friendly compared to other imap4/pop3/smtp libraries. So for now I’m convinced that camel is a good candidate for mobile devices. And it comes with additional support for many stores and transports. It would, perhaps, be better if it wouldn’t be bundled with e-d-s. I don’t really understand why the evolution team didn’t simply make camel a separate package and let e-d-s depend on it. Rather than putting camel in a e-d-s subdirectory and cut-and-paste it’s build environment into the build environment of e-d-s. Harish, if you catch me on IRC .. please explain :-p?!

Note that the application itself will at this moment not do much useful for a normal user. It’s still to early. Developers, however, might be interested.

TinyMail – trying to create an e-mail client for mobile devices

I started a new project called TinyMail named after my girlfriend (Tinne). The plan is to create an E-mail client designed for mobile devices like the Nokia 770. The chances of ever achieving finishing a usable tool are small to zero, but … I guess it’s fun. Which is why I started nevertheless.

What I did so far is creating interfaces (a lot like what I did with that TreeView demo of last week). At this moment, I’m basically preparing all the objects and interfaces.

If you’re interested, please contact me.

You can follow the developments and latest code in this temporary subversion repository. Sure is whatever-forge cooler and whateverer but heck, it’s just a temporary location anyway. And the chances of somebody joining early in the game are extremely small.

The idea is the make use of the proxy programming technique, use an existing library like camel in the implementations of the real subjects and attempt to be as correct as possible in terms of design pattern usage. So that basically means that probably every type will have an interface, and that I’m going to try using for-c-programmers crazy programming principles and techniques. I know this is more or less nuts if you use gobject (checkout the gtktreemodel and gtktreestore code if you want to know how to create and work with interfaces in gobject). So be it.

Here’s some pointers to interesting information:

The libtinymail and libtinymailui are components that will sit in between for example a library like camel and the user interface. They will take care of the high level caching (making sure that only visible things are abusing the memory — i.e. the proxy technique –). A lot like the models that can be used with ETable.

Note that no, a compiled version of whatever is in the repository a.t.m. will not do anything useful at this moment. It’s way to early for that. I might finished it in a few hundred years. You can, of course, join and help me.

Treeview conclusions

It looks like you guys are interested in loading three million rows in a GtkTreeView. Yesterday 512 (new) visitors visited our company subversion service to checkout the demo :-p. I think +- 100 people checked it out completely (the less obvious files, like Makefile.am’s, got viewed +- 90 times). That tops codegen‘s first day. Well, you can now put comments on my blog. So if you have questions about it: go ahead.

Note that I updated some files in the repository. Now it’s using a more correct way of implementing interfaces in C. The usage of the proxy pattern, thus implementing an interface, is actually the point of the demo. Sure is the wow cool thing about it that you can load millions of rows in a view. But the point is the proxy pattern. So it should be correct, if the intention is to ‘show’ how to do it. Right? Note that the proxy technique can be used in all sorts of model view controller situations. Not just for a treeview or datagrid.

In that demo, I should also do more with the proxy classes to show that you can treat them as if they are real subjects. That’s because they fulfill the contract (the interface) of the subject (a message header, in the case of the demo). Yet these proxy instances consume only 20 bytes. By the way, my favorite programming technique is strategy (I promised somebody not to use the word design pattern anymore. He felt design pattern is a buzzword). I’m likely going to do/show something with strategy sooner or later :-p. When browsing free software code, I often see “less good” designs decisions. Performance tweaking is very good but it wont help if the application developers aren’t going to use their brains before designing the application. The era of typical VB6 development should be over. A lot ‘managers’ should stop whining about KISS and first learn what it really means. KISS, like the KISS most people think KISS is, sucks. It doesn’t scale and it’s impossible to integrate unit testing and modern programming methods with it. The other KISS is a different story. Read Head First, Design Patterns and learn all about it. There, I’ve said it.

As a consultant I guess I got tired of manager-type guys who don’t have a clue, telling me to do everything KISS. Perhaps those guys should read about Peter Principle?! Sorry for this opinionated entry. I know I shouldn’t.

Auwch, I made a big mistake:

$ svn diff -r 14
Index: src/msg-header-proxy.c
=============================================================
--- src/msg-header-proxy.c      (revision 14)
+++ src/msg-header-proxy.c      (working copy)
@@ -76,7 +76,7 @@
 MsgHeaderProxy**
 msg_header_proxy_new_alot (gint amount)
 {
-       MsgHeaderProxy **proxies = (MsgHeaderProxy **) g_new (MsgHeaderProxy, amount);
+       MsgHeaderProxy **proxies = (MsgHeaderProxy **) g_new (MsgHeaderProxy*, amount);
        gint i=0;

        for (i=0; i < amount; i++)
$

Wow .. that would have been a total waste of memory AND a huge leak! Note that doing one huge allocation in stead of one allocation of a pointer-index-table followed by many g_slice_alloc, might improve the cpu usage a little bit (less expensive malloc syscalls). So perhaps it can be made even a little bit faster than the current result. Try it, send me a diff.

Migrated to wordpress

Some people might have noticed on the blog aggregators that yesterday, I’ve switched from DotClear to WordPress. I guess the reason some blog aggregators repeat old blog entries is because they compare cache. And after a migration, for example the unique IDs are often different. So no, there’s nothing wrong with my blog :-p!

I also installed a RewriteRule in such a way that most old blog url’s will resolve to the new WordPress URL. I can’t make all of them work automatically because DotClear and WordPress use a different algorithm for forming the title-part of the URL (called the post slug). But most work. You can tell me if a specific “old” URL isn’t working. WordPress allows me to set the “post slug” manually. I can easily set it to the old slug or in such a way that my redirector stuff resolves it correctly.

Oh, and somebody tell the DotClear developers to get themselves a real anti-spam feature. Perhaps a captcha or something like that? For my case it’s to late: goodbye DotClear.

I’m probably going to regret it, but after installing bad-behaviour on both my wiki and my blog and on the blog also Akismet, I re-enabled editing the wiki and posting comments on the blog. As I weed through thousands of moderated spam messages in my old blogs database, I’ll try to recover the relevant comments and restore them in the WordPress database of my new WordPress blog.

Some code that might help you migrate DotClear to WordPress:

Three million rows in a GtkTreeView

Edit, the repository has since disappeared, you can find a Subversion Dump of it here:

Three million rows (the size per cell doesn’t matter a lot) in a treeview, and loading the treeview in four seconds. Is that doable? Sure! The treeview wil become very slow you think? Nope, it works as fast as any other (smaller) treeview. The amount of visible rows is what would slow it down. Since most screens can’t show more than 500 rows, and since showing more would be useless from a usability point of view, it’s fast.

I committed my performance tweaks to the demo repository. It includes using g_slice for allocating the real subject and replacing the GSList in the custom model with an implementation that uses a pointer position.

So I don’t have to depend on a slow linked list anymore. In stead I simply allocate a large block of proxy instances (three million proxy instances of 20 bytes each in a continuous allocation) and inject that as index in my custom treemodel.

Since those are proxy instances, they’ll each check whether their this->real property isn’t NULL when they are needed. When a row becomes visible, that instance is needed for the from, id and to properties. When it becomes invisible, it’s no longer needed (and should therefore be freed, but the unref_node thingy of gtktreeview doesn’t work perfectly — so when scrolling a little bit, around 200 instances are kept around for no reason, I’m going to try fixing that behaviour in gtktreeview soon).

Most of the time is spend in the loop that prepares the proxy instances (msg_header_proxy_new_alot). Bringing the (visible) items to the treeview doesn’t take a lot time, as the GtkTreeView is smart enough not to load everything in case fixed-row-height mode is on.

You don’t have to believe me, you can checkout the code here. Compile it (autotools) and try.

Anyway, I’m convinced GtkTreeView by itself isn’t slow. But that doesn’t mean that the way you use it can’t make it slow. I hope others will enjoy the demo as a starting point for getting their way of using the gtktreeview optimized. For most use-cases, the use of a GSList or GList is a better technique. A linked list makes it more easy to add new items to your model. Inserting and removing items would be a lot more difficult if you use the technique I used in the demo. That technique, however, is fast because you can allocate it as one large block and excercise your high-school pointer knowledge with.

Nevertheless, I swear the unref_node stuff isn’t working correctly! :-p. Or I misunderstood it’s purpose.

Nooo! It’s that GtkTreeView proxy guy again!

And I’m not finished with the GtkTreeView. No I’m not. Moehaha!

I created this full sample that shows what I meant with custom treemodels and only allocating the model items behind visible rows. It includes an autotools environment and more or less good way of creating classes in C (except that I didn’t yet use GObject for MsgHeader nor MsgHeaderProxy, feel free to send me a diff).
This is a Subversion repository. Use “svn checkout” in front of the url after installing subversion.

It uses the “unref_node” method of the GtkTreeModelIface interface which gets triggered by gtk_tree_model_unref_node to unallocate the real subjects that aren’t visible in the view.

I noticed that it (it is the GtkTreeView stuff) sometimes “misses” rows that become invisible (if you scroll very fast). So I fear this unref_node method will need fixes and/or if you use it, you’ll need to also create a background thread/procedure that checks for leftovers. This sample shows how you can walk the entire treemodel and do things with only the unvisible ones. I know it’s ugly. IMHO the full demo isn’t, but regretfully doesn’t the unref_node stuff work perfectly.

Feel free to request SVN accounts and/or send diffs if you want to experiment.

Good morning and by the way

Good morning (for people in Europe, of course) .. and by the way. About that GtkTreeView sample of last night:

Say you wanted to use a string value of the subject as a row-value in a column of such a treeview? I didn’t show that yesterday. You can do that by converting it to a GValue and setting that as the “text” property of the cell. You do it like this:

static void
msg_header_treeview_get_model_item (GtkTreeViewColumn *tree_c,
                                   GtkCellRenderer *cell,
				   GtkTreeModel *tree_m,
                                   GtkTreeIter *iter, gpointer data)
{
	GValue val = {0,};
	IMsgHeader *header;

	gtk_tree_model_get (tree_m, iter, COLUMN_HEADER,
			&header, -1);
	g_value_init (&val, G_TYPE_STRING);
	g_value_set_string (&val,
		imsg_header_get_from (header));
	g_object_set_property (G_OBJECT (cell), "text", &val);
	g_value_unset (&val);
}

  gtk_tree_view_column_set_cell_data_func (column, renderer,
	msg_header_treeview_get_model_item, NULL, ...);

What will happen? The proxy classes will be instantiated. Yes, all of them. If you don’t want that to happen, you will need to create a custom GtkTreeModel implementation or use ETable, which is available in gal. Evolution also uses the ETable widget and it’s models for displaying the headers of your big INBOX. However, the proxy classes are rather small. I didn’t do it here, but if you want to avoid memory segmentation, there’s tools in glib (memory pools, etc) for allocating lots of such instances. Or simply use the amount as second argument of the g_new function and increase your pointer each iteration (this causes a large block of memory, this is likely going to be less or not segmented. Doing 10.000 times g_new(MsgHeaderPrxy,1) will cause memory segmentation and you don’t want that).

In the sample case only a g_strdup is happening in the real subject instantiation. In reality it’s often far worse. Don’t change your model items: View and Model should be decoupled.

In stead, you simply create proxy classes for it. The first time those are needed (when their rows become visible in the treeview, for example. As one of it’s values are now used to draw the treeview rows themselves), they will instantiate the real subject and use that to deliver the requested property. Note that this “first time they become visible”-behaviour is only valid for GtkTreeView when the fixed-height of the treeview widget and the fixed-width of the column properties are set. Else a background procedure will fetch all to calculate the scrollbar (ask kris and jrb on IRC for more details about this).

You are, of course, responsible for cleaning them up (also that, I didn’t show). You could, for example, in GObject overload the destroy and check for this->real not being NULL, and free it if that is the case. There’s also other methods (a factory that caches the real subject instances and always gives the same instance in case you have the same id multiple times in your list model: in this case, freeing up the real subject instances might get more complicated). This depends on your application design, of course.

I’m now searching for a technique to auto-free the real subjects behind the rows that aren’t visible. If you know: tell me :-p. Note that when using something like this, you want to use a memory pool for the real subjects (else: possible memory segmentation).

Using GtkTreeView: Proxy classes and lazy instantiation

The technique of using proxy classes as items in a list model applied to GtkTreeView gives you for instance the possibility of displaying list of many email subjects whilst mostly instantiating only inexpensive stub objects to represent them, rather than real header objects; something of immense value for memory-constrained scenarios of embedded devices and similar.
You can find its explained here. A sample e-mail application that could use it is osso-email. Follow the link for more information.

Edit: unbuzzworded :-p

“Free software” subjects for 2006

Part 1

These are the/my “free software” subjects that I have in mind for this year. I guess that in 2007 I will look back at this blog-entry of mine and laugh with the fact that none of my plans got achieved (I do have a professional career and girlfriend, you know). Oh well.

  • Redesign and recreate osso-email. Let it use a very strict model view controller paradigm and develop a custom MsgHeader list model. Let the view become an observer of that model and let that view request only the “visible” e-mail headers from the model. The model will be smart enough not to load all the MsgHeader instances from slow disk cache into a faster memory cache. Perhaps also reuse the E-mail header treeview of evolution and talk with Harish about decoupling such parts from Evolution. A lot like what I did with EMsgComposer last year;
  • Replace the GtkHtml with Gecko in Evolution-ui. I adapted the EMsgComposer source code for this purpose last year (moved the struct to the c file so that it becomes really private outside of the implementation file);
  • Create a libmainloop. Patch glib to use libmainloop. Patch qt to use libmainloop. This depends on what the decisions on “shared mainloops” will become. Perhaps also patch D-BUS and stuff like Twisted. This is still in “concept/design” phase;
  • Help with dvfs/common-vfs/or FUSE integration in KIO and gnome-vfs. Or port KIO to C (yeah, I know I’m insane) or decouple it from Qt and develop a wrapper library for Glib. Perhaps also patch KIO in kde to use the shared library. All this depend on what the decisions on “shared VFS” will become. Some concepts/designs also depend on a libmainloop.
  • Work on a shareable infrastructure for desktop configuration. For now I dubbed this as deconf-desk. This depends on the libmainloop stuff (else I would need to do the same tricks D-BUS did for the mainloop integration: this is insanely stupid code duplication).
  • Work on a infrastructure for remote desktop configuration. My plans are to use XMPP (Jabber) as protocol for inter process communication between service and clients (getting clients informed about updates). There’s a JEP that proposes a standard for “offline messaging” in Jabber. I discussed this JEP with Peter Saint Andre last year for this purpose;
  • I also have some idea’s for gnome-schedule. Not sure about it yet (I know I initially wrote gnome-schedule (but Kristof and Gaute changed a lot, btw), but I disike using Python, it’s not my programming language).

Feel free to E-mail me if you want to put comments on my blog. I disabled this feature because to many bots are trying to put spam on it. I counted at least 15 such bots! Insane. And no matter what PHP code I add, the operators of the bots adapt their botcode. So I’m waiting for some more intelligent anti spam solutions. Perhaps I’ll soon migrate to WordPress. Note that I’d hate making it more difficult for (for example) blind people to use my blog. Suggestions are welcome.

  • Oh .. well: Integrate spamassassin with some blog engines like WordPress. Or has that been done already? (edit: ‘ikke’ on IRC told me it is using some plugin)
  • Since I also have troubles with spambots on a wiki of mine, integrate spamassassin with MediaWiki.

Part 2

Mono and Fedora: FINALLY guys. I’m extremely happy that this decision has finally been made.

First real gnome-schedule release

Gaute Hope, my companion and the person to whom we (Kristof Vansant, myself and Gaute) gave the maintainership of it, decided to release the first one point zero release of gnome-schedule (But I’ve seen some important fixes going in CVS and on Bugzilla already).

The gnome-schedule tool can be used to configure your crontab and at services in a user interface oriented way.

At this moment gnome-schedule has been translated to +- 60 languages and has a manual written by Rodrigo Marcos Fombellida. It’s written in Python and uses gnome-python components like GConf and Glade.

You can check it out here. For the packagers interested in packaging gnome-schedule: please inform Gaute in detail about the many aspects of package building if you have any difficulties preparing your packages (use Bugzilla, of course).

I noticed Gaute openend a a new bug which he’ll depend on all the bugs that are important for the next (one point one) release. Note that it’s been a while since I last coded stuff in the gnome-schedule sources (I mainly helped creating the very very first alpha versions and assembled it’s build environment). So for development questions you better ask Gaute.