Sunday, February 22, 2009

The GNOME Platform, Awn, and the Cloud

Benjamin Otte recently wrote about desktop-web integration in the GNOME desktop. It's kind of interesting that he calls himself "not web enabled", given that he's the main developer of the swfdec library and associated applications. I agree with most of what he wrote, but there are a few comments I would like to make.

Benjamin asks:

Why does dconf (or GConf) not store my settings in the cloud so it uses the same settings on my university login?

As I understand it, this is one of the features of Conduit. There's a bug in Awn regarding config synchronization via Conduit. I'm probably going to look into how that works when I resume work on the config interface for libdesktop-agnostic.

There is an erroneous statement in his post:

We don't even have a http library that knows cookies.

libsoup has had (non-persistent) cookie support since 2.23.1, and persistent support will be in 2.26.0.

And then there's the main point:

[GNOME is] doing a very bad job at integrating the web into the desktop. Apart from epiphany (and the weather applet), what application does GNOME ship that speak http?

I believe there are two main reasons for this: One is GNOME developers are not "web-enabled". [...] The other, related reason is that we don't have the software to do this.

In Awn-land, we have several web-enabled applets:

  • arss
  • comics
  • digg
  • lastfm
  • meebo
  • pandora
  • rtm
  • weather
  • webapplet

In particular, webapplet is a work in progress framework, which will allow what is essentially an applet version of Mozilla Prism. It currently uses WebKit as the backend, although there is also a Gecko-based backend planned. The rest of the applets listed are written in Python. In particular, the digg, meebo, pandora, and rtm applets use the gtkmozembed Python bindings to view the respective websites. Here lies one of the problems of the web-enabling the GNOME platform. This library is acknowledged to be less than ideal. If you look at the source code of the applets, you'll see that there are some ugly hacks in order to make them work properly on Ubuntu systems. Webapplet is slated to replace that ugliness.

One of my side projects is a status aggregator applet. It's supposed to aggregate all of these social networking status feeds and also to sync all of your personal statuses. One of said social networking websites returns complex, site-specific HTML that obviously needs to be sanitized/canonicalized. The easiest (but not necessarily most memory-efficient) method of performing that task is to use the DOM. There is not currently a DOM library for the GNOME platform. There is a libgdom3 project (written in Vala) which I believe is being / will be used by the gnome2-globalmenu project, but it is unfinished. There is also an old, unmaintained library called gdome2 based on libxml2. I'm not even sure if anyone actually uses that library anymore (its last release was in 2003). I avoided using gtkmozembed and friends based on the experiences described above. I settled on a promising feature request for WebKit: a GObject/C DOM binding. (As an aside, the WebKit bug linked is a fascinating case study on several levels: conflicting coding standards, conflicting developer personalities, and some interesting coding/reviewing.) It's very nice - I can manipulate document fragments as if I were using JavaScript in a web page, among other things. I eagerly await that feature being committed to WebKit trunk.It is an important stepping stone when it comes to working with the web.

Another side project that I'm currently working on is a developer dashboard applet. It's kind of like the previous applet, except as applied to software projects. I was originally going to write it in Vala, which meant that I would have to write an interface to (at least) the Launchpad API, which meant implementing at least three specifications in Vala: OAuth, URI templates, and WADL. I finished the first two (I haven't yet decided whether to release my URI templates implementation as a separate library - the implementation plus the test app is 451 source lines of code), and WADL is a very complex specification. So, I decided to postpone working on the WADL library and instead am currently working on a prototype applet using Python and launchpadlib. Implementations for those three specifications and many others (including AtomPub) should be included in the GNOME platform if it wants to be web-enabled.

Wednesday, February 18, 2009

On Webhooks, or The Push Revolution

Mike Rooney (Awn Extras developer, among other things) posted an article on this "webhooks" idea. As I understand it, it's essentially a customizable, web-based version of the "Subscribe to future XYZ via email" features (e.g., blog comments) that are currently around. The key phrase in this sort of thinking is "push technology". Mike asks:

So will webhooks replace the current paradigm that I'm using here, or complement it?

I believe that it will complement the current paradigm. We need to have a transitional period (à la the old, rigid deadline for the US digital television transition) between the current "polling" techniques and the "new and shiny" (and arguably bandwidth-saving) push techniques. Take, for example, Twitter [1]. Let's assume that they didn't shut down their XMPP service, and they built upon it an (XML-based) API so that a client (for the purposes of this thought experiment, let's say my currently-in-vaporware Status Aggregator Awn applet) could connect to a specific JID (AKA user name + domain + "resource", or specific client) and listen for any new tweets, responses to my tweets, etc., replacing those messy timeout callbacks with messy async socket callbacks. The main benefit that I see is a savings in bandwidth for both the consumer and the producer. It avoids sending network requests every X minutes, which would add up, given the number of services/feeds that a user subscribes to (including mail). This actually leads me to my answer to Mike's other question:

Are webhooks the next step of this evolution, or something else entirely?

As evidenced by my thought experiment, I'd like to see XMPP as the next step, or at minimum, the step after webhooks. While I love HTTP, and am a big fan of the whole REST concept, it's hard for me to see it used as a facilitator for pushing data, as opposed to pulling it. In fact, given the way that ETags and the like are designed, HTTP is inherently a pull technology. The Comet model feels like a big kludge to me for that reason. XMPP, on the other hand, is designed to be a push technology, and its supporters are actively marketing it as such. It's also scalable, as servers like ejabberd and services like Google Talk can attest. I suppose the bottleneck here is a catch-22: you need both services and apps to buy into this particular implementation. Maybe when I finish one of the myriad projects I have going at once, I'll take a crack at adding a push-based web service client. Ideally, for configuration, all a user would have to do is set their app-specific JID (e.g. foo@example.com/bar_app) in both the web app and the client app, and it would "just work" (well, you would also have to set the JID password somehow as well, but that's beside the point).


Update (2009/02/18): It seems that I was subconsciously channelling a presentation on XMPP PubSub that I read over six months ago.


[1]I'm focusing on the one I actually use. Yes, I should be using identi.ca, since I am a supporter of free and open services/protocols. It even has the hallowed XMPP interface to microblogging. One of these days, I'll do what all the cool kids™ are doing and post to both. It'll probably happen when I (continue) work on the vaporware [2] mentioned above.
[2]It's vaporware until I push the source code onto a public server.

Sunday, February 15, 2009

Announcement: OAuth Client Library

For the past week or so, I've been working on various web services-related libraries, in the hopes of writing some sort of Launchpad dashboard applet for Awn. I think it would be nice to have new/recently changed bugs in Awn/Awn Extras at a glance in the dock, among other things. The first somewhat complete component is an OAuth client library. I finished the initial implementation (plaintext signature only) in under nine hours, and after the Awn 0.3.2 release (and a bit of frustration), I added HMAC-SHA1 signature support with the help of RFCs 2104 and 2202 (using GLib's checksum API). I've tested it with both the OAuth example Python server and the Launchpad API.

Also included in the source are two small test programs: one tests the HMAC-SHA1 implementation, and the other tests the OAuth implementation in its entirety. The latter uses .ini-style config files to define keys/secrets/URIs/etc. for a service.

There are a few things that still need to be done, in order for it to be a "complete" implementation. I probably want to replace my handwritten HMAC-SHA1 implementation with a libgcrypt-based one (although I'd have to figure out how to create bindings for Vala), which would also enable me to add RSA-SHA1 signature support. Additionally, I should probably add an asynchronous equivalent to the current synchronous API. Finally, it would be nice if it integrated better with libsoup's existing authentication structure. Currently, I just generate an Authorization: header to be manually added.

The next component I'm working on is a WADL dispatcher library. I don't like the idea of a library generating code (as I presume wadl2java does). We'll see how this turns out.

Friday, February 13, 2009

Awn 0.3.2 Release Postmortem

For those of you who don't know what a postmortem is in this context, it's essentially a reflection of what happened in this release: what went right, what went wrong, and what we'll try to do next time.

Before I begin, a lot of the history is from memory, so the facts may not be 100% correct.

Background

Back around July 2008 or so, we essentially had two branches: stable/bugfix-only (0.2.7) and trunk (0.3.1). A few developers wanted to release from the bugfix branch for the sake of the distributions, but since work was well on its way in trunk, there were not many volunteers to lead the effort. I volunteered to do so, and began merging bugfixes to the stable branch, with the goal of releasing by around the end of August.

Unfortunately, there were three big roadblocks in my way: the infamous make distcheck, Bug 194018 (an intermittent problem with launching launchers on docks not built with GNOME libraries, and Bug 194431, "the trash bug".

For developers, I would guess that one of the most annoying things about releases is the dreaded make distcheck command. This command makes sure that if you run make dist to generate a tarball, that it compiles correctly out-of-the-box. It took what felt like dozens of iterations to make sure that certain files were in the tarball, ready to be installed by the build system. But the most annoying part of the process was the part dealing with internationalization (i18n). I18n is handled by the intltool/gettext packages in Awn, and they expect files to be "just so", or else make distcheck fails with a semi-comprehensible error. With some help from Qball, I managed to more-or-less get the trees into a releasable state.

The desktop-agnostic launcher bug was a pain to debug, as all it did was spit out a cryptic error message to the console instead of launch the application, and this only occurred with some launchers (varying between machines). Fortunately, moonbeam managed to write a fix for it in early August.

The trash bug was more complex in its own way. In GNOME 2.22, GNOME switched virtual file system (VFS) libraries from GNOME VFS to the more desktop agnostic GIO (part of GLib). Part of this conversion was that the trash directory changed from $HOME/.Trash to the more complex Freedesktop.org standard of $XDG_DATA_HOME/Trash. In comparison to the old trash directory, which was just an intermediary directory prior to "permanent" deletion, the new standard added a trash metadata directory (e.g. for the "restore this file" feature). Now, the trash applet did not have a maintainer. As I understand it, Neil ported it from the GNOME applets package as one of the proof-of-concept Awn applets. By this time, Neil was (and still currently is) very busy with his awesome (but unrelated) work at Canonical. Thinking that this was a desktop-agnostic issue, I decided to take the bug. My first attempt, merging in the new trash implementation from GNOME applets, failed badly. My next move was to rewrite the entire thing in Vala. My reasons for doing this were twofold: I wanted to work on my skills in C#-like languages, and I wanted the applet to be a bit more readable/maintainable for the next person who would take up maintainership. Unfortunately, it took way to long to write (through no fault of Vala's). The main problem was that the algorithm to determine the number of files in the trash (an important part of the original applet) is ridiculously complex in non-GIO libraries. This is due to the fact that multiple volumes can have trash cans. By the time I figured out about half of it, it was the end of August. Given the number of people subscribed to the bug and commenting on it, plus the comments I saw on the forum, this was a showstopper bug. I couldn't very well release without it in there, so the deadline came and went, and there was no update to Awn in the fall Linux distribution release.

I should note that there will be a happy ending to this bug - last month, I managed to get trash support into libdesktop-agnostic, and as soon as I convert Awn to use libdesktop-agnostic, I will commit the Garbage applet.

Releasing 0.3.2

Fast forward to last month (January). One of the core developers (mhr3) suggested that we do a snapshot release of trunk, since work on the rewrite was well underway. Somewhat surprising to me, more developers agreed to help with this release. This time, mhr3 was release manager (for obvious reasons). For the rest of the month and the first week of February, bugfixes were committed to the trunk branches of Awn and Awn Extras. There were also some features added (I admit that I added at least one of them), but the most notable one was the merging of the AWNLib 2.0 branch. I'll get back to that shortly. People were testing applets and noting their functionality on a wiki page, which helped with finding bugs.

By around February 6th, preparations were underway for the actual release. mhr3 and gilir were busy making sure that make distcheck worked for both Awn and Awn Extras, and I was working on the release notes. DBO, a developer for GNOME Do/Docky, suggested that we put some effort into doing a little marketing, like they did with their recent 0.8 release. So, I started a wiki page with a list of volunteers who would post to various news/forum websites.

The day of release was interesting. Throughout, various people (including myself) were in and out of the IRC channel doing stuff In Real Life. I managed to finish the release notes (and get screenshots) with the help of the folks in the channel, and gilir stayed up way past midnight local time to sign and upload both the source tarball and the PPA packages. As soon as mhr3 gave the go-ahead signal, the release announcements were sent to their respective news sites. I filed bugs in Gentoo for version bumps for both packages, to head off any overzealous Gentoo + Awn users. I also notified the Mandriva packager of the release, since I had his contact info handy. A few hours later, I remembered that I had an OSNews account (for commenting on some article which was probably tangentially related to Awn) and decided to submit an article. In the morning, I was informed via IRC (on a non-Awn channel, no less) of its publication, with a surprising addition: a mini-review by one of the site's editors, which was positive.

As of publication, my blog post announcing Awn/Awn Extras 0.3.2 has received almost 5,500 pageviews (see screenshot). To put numbers on the data points in the graph:

  • Sunday: 312
  • Monday: 2,783
  • Tuesday: 953
  • Wednesday: 1,008
  • Thursday: 367

What Went Wrong

We should have reverted the AWNLib 2.0 branch merge. It caused more problems than it solved: it was inevitable that applets would break, and that at least one API change would be missed before release, especially given the amount of time between the merge and the release.

Coordinating the news/forum releases went OK, but we ended up having two Digg links, which probably spread out the total number of diggs, thereby lowering the chance that it would hit the Digg front page.

I was naïve enough to think that Debian/Ubuntu users wouldn't immediately file version bump bugs as some Gentoo users are prone to do. I was wrong.

Additionally, too many Ubuntu users did not read that we already provide binaries for Feisty through Jaunty (inclusive) - they seem to want to install from source, which we do not recommend (unless they plan on doing development).

What Went Right

The release coordination in the channel went fairly smoothly, especially given that we were all in different time zones.

Posting to OSNews was definitely a good thing. As you can see from the screenshot, it was the highest referrer to the post.

It was nice that someone not associated with the project posted to reddit - it was the second highest referrer. It was posted two days after the release, but beggars can't be choosers.

Next Steps

  • First and foremost, prepare for a 0.3.2.1 release for Awn Extras.
  • When we have a target date for 0.4.0, we should immediately branch, and said branch should only contain merges approved by the release manager.
  • A 250-character summary of the new version (complete with reminders of what the packages are) should be written for news sites, in addition to the summary and the release notes.
  • Make sure to highlight that Ubuntu users do not have to install from source.
  • I need to get a Slashdot and a reddit account. I'm doing this under protest.
  • We need to make sure that there's only one "official" Digg post.
  • I should look into one of those omni-share-to-social-networks buttons, but only for the big announcements. Those "share" buttons make me feel a bit dirty.
  • We need to get some contact information for at least the packagers for Fedora and OpenSUSE.
  • If I remember and have time, I need to learn how to use the OpenSUSE Build Service.
  • Explicitly mention in the release notes that there is no need to file version bump bugs in Debian/Ubuntu. Although, given past experience, I doubt that the people filing these bugs would read that. On the other hand, it's due diligence.

Sunday, February 08, 2009

Awn/Awn Extras 0.3.2 Released!

[Awn image, courtesy of malept]The Avant Window Navigator (Awn) and Awn Extras teams would like to announce the release of version 0.3.2. This represents a year's worth of bugfixes, performance improvements, and new applets. Note that the 0.2.8 release was cancelled, due to lack of developer interest. Our next major release, 0.4.0, will be a complete rewrite of the dock and applet API.

Avant Window Navigator is a dock for the Free Desktop which shows your launchers and open applications. It also contains support for extensions, via plugins for third-party applications, which communicate with the dock with DBus, and via applets, which allows for workspace switchers, system trays, clocks, etc., to be embedded in the dock. These applets can be written in C, Vala, or Python.

Awn currently requires compositing support in order to run. Window managers which support compositing include (but are not limited to) Metacity (part of GNOME), Xfwm4 (part of Xfce), KWin (part of KDE4.x), and Compiz. There are also standalone compositing managers, for window managers without support built-in: Cairo Compositing Manager and xcompmgr.

Awn Extras is a catch-all project which houses mainly third-party applets for use with Avant Window Navigator.

[Awn screenshot, courtesy of mhr3]

Avant Window Navigator Notable Changes

User-Visible

  • We have made it easier to enable Awn to run when you log into your desktop - there is an "Automatically start Awn on login" option.
  • If you start Awn without a compositing manager present, a pop-up dialog will appear informing you that compositing is not currently enabled.
  • Most applet icons can now be customized by dragging and dropping an icon onto the applet in question. Note that this does not apply to tasks.
  • Better compatibility with Metacity.
[Awn screenshot by h4writer]

Packager-specific

  • The (optional) Vala version dependency has been bumped to 0.5.4.
  • The location of the applet metadata files has changed, at the request of Debian. We have included a script (awn-applets-migration) which will migrate users' settings to point to the new location.

Applet Developers

  • You can now use cairo contexts/surfaces to paint text/images to AppletSimple-based applets.
  • There is now a standardized applet context menu API.
  • Advanced custom icon support via AwnIcons
  • .
[Awn screenshot by onox]

Known Issues

These will probably be fixed in 0.4.0.

  • Keyfile-based config is unstable. It works for the developer who wrote it well enough, but the GConf backend is currently the most stable configuration backend.
  • Autohide is still buggy.
  • Awn does not handle multiple screens very well.
  • You cannot move the dock to any other edge of the screen. It is currently fixed to the bottom.
[Awn screenshot, courtesy of mrooney]

Awn Extras Notable Changes

New Applets

  • Animal Farm: Various animals tell your fortune.
  • Cairo Clock: a replacement for pyclock (due to license issues). It provides three themes, and (if python-dateutil and libgweather are installed) allows you to add additional clocks for different locations.
  • Comics!: A flexible comic strip viewer.
  • CPU Frequency Monitor: controls and monitors the CPU frequency (useful for laptops)
  • Desktop Manager: manages the desktop wallpaper for GNOME and Xfce.
  • Media Player: plays anything you drop on the applet.
  • ThinkHDAPS: monitors the accelerometer for IBM/Lenovo ThinkPad hard drives.
  • PyNot: a configurable notification area AKA system tray.
  • Remember The Milk: A simple interface to the web service.
  • To-do: A todo list.
  • Tomboy: A simple interface to the Tomboy application.
[Awn screenshot by triggerhapp]

Changes to Applets

  • Battery Applet: rewritten, now requires HAL.
  • Cairo Menu: various fixes
  • Digital Clock: various fixes
  • Media Control: various fixes
  • Notification area: looks fancier now
  • Quit Applet: rewritten; supports the GNOME 2.24 quit behavioral changes
  • Shiny Switcher: various fixes
  • Terminal: various fixes
  • Volume Control: rewritten

Removed Applets

  • cairo-menu-classic (use Cairo Menu)
  • PyClock (license issues, use Cairo Clock)
  • tsclient (license issues)
  • Workspace Switcher (use Shiny Switcher)
[Awn screenshot by h4writer]

Packager-specific

  • Animal Farm: new runtime dependency on the fortune binary.
  • Battery Applet: new runtime dependency on HAL via DBus.
  • Cairo Clock: optional runtime dependencies on libgweather (for the Locations.xml(.gz) file) and the python dateutil module.
  • CPU Frequency Monitor: optional runtime dependency on gnome-applets, for the cpufreq-selector binary.
  • PyNot: runtime dependency on python-xlib.

Applet Developers

  • AWNLib has been overhauled. It is now PEP8-compliant.

Known Issues

  • Cairo Menu: Intermittent issue of submenus overlapping parents may still be present.
  • Cairo Menu and Places applets: Certain fonts/locales are broken.
  • Media Player: errors are not currently displayed.
  • Shiny Switcher: Switching window managers tends to result in inconsistent behavior.
[Awn screenshot by moonbeam]

Download

Semi-official Ubuntu packages for various Ubuntu versions will be available at the Awn Core PPA. We are working with various distributions (Mandriva, Gentoo, Debian, Ubuntu) to update their packages. You can download the source code at Launchpad (Awn Extras) - instructions on how to install from source are at our wiki (Awn Extras).

About the Images

  1. My dock, on an Ubuntu Hardy machine. I have running Cairo Menu, Show Desktop, Taskmanager/Launcher, Awn System Monitor, Animal Farm (with unfortunately a non-free image - this has been rectified for the release), and Digital Clock. The image is licensed under the Creative Commons 3.0-BY-SA (Unported).
  2. mhr3's dock screenshot contains the Shiny Switcher, Weather, Taskmanager/Launcher, Battery, Media Player, and Notification Area applets. The image is licensed under the WTFPL.
  3. h4writer's dock has Taskmanager/Launcher, Shiny Switcher, and Quit applets. The image is licensed under the WTFPL.
  4. onox's dock screenshot contains the CPU Frequency Monitor, ThinkHDAPS, Taskmanager/Launcher, Cairo Clock, Volume Control, Battery, Weather, and Notification Area applets. The image is licensed under the Creative Commons 3.0-BY-SA (Unported).
  5. mrooney's animal dock. This showcases the new, public domain images for Animal Farm, retrieved from the excellent Open Clip Art Library. Also in the dock are the Weather and Terminal applets. The image is licensed under the WTFPL.
  6. triggerhapp's dock is running on Ubuntu Jaunty. He is running the Cairo Menu, Taskmanager/Launcher, Separator, Volume Control, To-Do, Quit, and PyNot applets. Note the transparency in PyNot - this was achieved because support was finally added to GTK+ in version 2.15.0, available in Jaunty. To use it yourself, you need to run the RGBA version of PyNot and Jaunty (or equivalent distro version). The image is licensed under the WTFPL.
  7. h4writer's second screenshot contains the Cairo Menu, Separator, Taskmanager/Launcher, Separator, Media Player, Media Icon (Play), Media Icon (Previous), Media Icon (Next), Separator, and Cairo Clock applets. The image is licensed under the WTFPL.
  8. moonbeam's dock screenshot contains the Cairo Menu, Places, Taskmanager/Launcher, Shiny Switcher, Awn System Monitor, Comics, To-Do, CPU Frequency Monitor, Volume Control, Weather, and Calendar applets. The image is licensed under the Creative Commons 3.0-BY-SA (Unported).

More Information

Monday, February 02, 2009

Old Projects: pytiger

I mentioned on Twitter that I wanted to blog about some old projects. The first one is more than a year old, but it still may be useful to someone.

Back during college, I was implementing a file sharing client with Twisted - the GUI was first written using wxPython, and then rewritten in PyGTK (the reasons for the rewrite I can expound upon later, if anyone wants to know). It's not publicly released, mostly because it never got past being a chat client. Anyway, a part of the file sharing protocol involved tiger tree hashes to verify the data as it was downloaded. I couldn't find an implementation in Python (and attempts to write it myself failed), so I found some C source code and manually bound it to Python (via its C extension API). This was my first exposure to extending Python via C — I later used some of this knowledge to fix up the Python bindings for Awn.

The Python part is licensed under the Apache License v2, the tiger (tree) code is public domain-ish. (see COPYING for details)

The code can (as of the publication date) be found in a junk bzr branch on Launchpad. If you wish to continue work on it, I can move it to a full-fledged project — just contact me about it via the comments.

Edit (2009/03/24): Due to interest in the code, I've created a project for pytiger at Launchpad.