Call for polyglots

The next release of Music Applet is approaching, with the main task remaining before 2.3.0 ships being to updating the translations.

Here’s where you can help. According to intltool-update -r, the current status of the translations is:

ar: 73 translated messages, 33 fuzzy translations, 14 untranslated messages.
de: 8 translated messages, 23 fuzzy translations, 89 untranslated messages.
es: 8 translated messages, 23 fuzzy translations, 89 untranslated messages.
fr: 8 translated messages, 23 fuzzy translations, 89 untranslated messages.
it: 38 translated messages, 51 fuzzy translations, 31 untranslated messages.
ja: 8 translated messages, 23 fuzzy translations, 89 untranslated messages.
nb: 12 translated messages, 18 fuzzy translations, 90 untranslated messages.
nl: 106 translated messages, 14 fuzzy translations.
pl: 106 translated messages, 14 fuzzy translations.
pt_BR: 97 translated messages, 18 fuzzy translations, 5 untranslated messages.
sv: 106 translated messages, 14 fuzzy translations.

Clearly, some of the translations have been unmaintained for some time now, and trying to use them would actually be worse than not having them at all. Why? The “fuzzy” translations are ones where the string that had been translated doesn’t quite match what the program is using, so the “translation” that will be used might not actually be correct anymore. With some of these languages, the translated text is literally more likely to be wrong than right.

So, unless someone volunteers new translations for German (de), Spanish (es), French (fr), Italian (it), Japanese (ja), or Norwegian (nb), I’ll drop them entirely rather than include them in the 2.3.0 release. If you’re interested in contributing, you can download the translation files and get to work.

I’ll be contacting the translators who have contributed translations for Arabic (ar), Dutch (nl), Polish (pl), Portuguese/Brazil (pt_BR), and Swedish (sv) privately to let them know about the string changes since 2.2.1 and give them an opportunity to update their translations accordingly.

I’m planning on pushing out the 2.3.0 release sometime in about a week. If you’re interested in maintaining one of the old translations, or wish to contribute a new one, but need a little more time, let me know.

Thank you to all translators, past and present, who have contributed to Music Applet. I’m still amazed at how so many people have volunteered to contribute translations, even though this is the first time I’ve ever asked for any publicly.

Cop versus Bus (D- edition)

[Disclaimer: Despite what you may have assumed from the title, this post does not discuss the obscure rock, paper, scissors variant “cop, bus, driver” (where driver controls bus, bus runs over cop, cop shoots driver). We apologize for any confusion.]

It has been remarked that the great thing about standards is that there’s so many to choose from. While working on adding support for Amarok to the next version of Music Applet, I ran into this first-hand.

GNOME and KDE, the two main desktop environments for Linux, each have a preferred IPC mechanism to provide a relatively easy way for programs to talk to one another. GNOME uses D-Bus, and several of the players currently supported by Music Applet use it. KDE, however, uses DCOP, and since Amarok is a KDE-based application, it provides a DCOP interface.

D-Bus and DCOP are, at a high level at least, pretty similar: they’re based on making method calls on objects exported by applications. They’re mutually incompatible with each other, of course, but they’re targeting the same niche. So, since Music Applet 2.3.0 will be using both of them to some extent, how do they shape up against each other?

I’m not going to go into the technical merits of each, or any of their implementation details. I’m only looking from the perspective of someone trying to write some Python code that interacts with other programs via D-Bus or DCOP.

Both D-Bus and DCOP provide a command-line interface for issuing individual method calls. While you wouldn’t normally use this interface in a program (unless you’re writing a shell script, of course), it is handy for quick testing, making sure the method you’re looking at does what you think it does.

Let’s say we want to ask our music player what song it’s currently playing. For Rhythmbox, which uses D-Bus, we need to do this:

$ dbus-send --print-reply --dest=org.gnome.Rhythmbox /org/gnome/Rhythmbox/Player  \
method return sender=:1.13 -> dest=:1.23 reply_serial=2
   string "file:///home/paul/music/Jonathon%20Coulton/Chiron%20Beta%20Prime.mp3"

You’ll note that I had to break the command across two lines to get it to fit in this column, and a lot of that command looks pretty redundant. Yes, yes, it avoids namespace pollution in case an application or an object supports multiple interfaces defined by different parties, but it’s a pain to type out. Also note that I had to include --print-reply so that the command would actually say what got returned. Also also, not pictured here, if you’re passing arguments to the method you’re calling, you have to explicitly say what the type of each argument is. Ick.

Now let’s see what the equivalent use of the DCOP command-line tool for calling the equivalent method on Amarok is:

$ dcop amarok player encodedURL

Even though it’s saying the same sort of thing (listing an application, an object owned by that application, and a method on that object), this is much easier to type. And even better, if we leave out some of the arguments, the command will list what’s available. For example, if we instead did:

$ dcop amarok player

It would list all the methods available on the player object exported by amarok. Pretty nifty. Sure, there’s a D-Bus way to do that, but you need to remember what method to call on the org.freedesktop.whatever interface of the object — or is it a separate object that handles introspection? I’d have to look up the D-Bus documentation. But the DCOP command-line tool doesn’t make you do that.

When we turn to the Python interface, things improve a bit for D-Bus, even though we’re still stuck with those very long fully qualified names for everything. Here’s a quick Python program that does the same thing as the command-line example:

import dbus
bus = dbus.SessionBus ()
player_proxy = bus.get_object ("org.gnome.Rhythmbox", "/org/gnome/Rhythmbox/Player")
player = dbus.Interface (player_proxy, "org.gnome.Rhythmbox.Player")
url = player.getPlayingUri ()
print url

Of course, if we’re going to make multiple calls to the object, we only have to set things up once, and then reuse the object as many times as we want.

The DCOP equivalent once again looks simpler (at least for now):

import pcop
import pydcop
# Magic goes here, to be discussed later...
amarok = pydcop.anyAppCalled ("amarok")
url = amarok.player.encodedURL ()
print url

While this might seem like another win for DCOP, things don’t look so good once we move away from these toy examples. For starters, the Python DCOP bindings don’t provide any support for asynchronous calls. Instead, all calls are synchronous: once we make the call, the program sits there and does nothing until it receives a response. If that other program you’re talking to takes a long time to respond, that spells trouble for our program’s responsiveness to the user, especially in a GUI, where now our program won’t even be able to redraw itself.

The Python D-Bus bindings do provide a way to do asynchronous calls, by passing a function that should be invoked once a response comes back from the other program. In the meantime, our program can go on to do other things. This also lets our program issue multiple IPC calls all at once more efficiently: in the ideal case, the other program can send its responses to all our calls during a single timeslice. If we’re stuck with synchronous calls, each one gets serviced in separate timeslices, which will end up taking longer.

Technically, this lack of asynchronous calls isn’t a fault with DCOP per se, but rather with its Python bindings. The underlying C++ library supports asynchronous calls. Adding support for this for Python programs is listed in the TODO file.

However, there’s a more obnoxious problem with DCOP when compared to D-Bus. Although D-Bus is used by GNOME, it’s not actually part of GNOME; it’s a project with minimal dependencies. So, if D-Bus isn’t already running (which in GNOME is pretty unlikely anyway), there isn’t that much the library has to do to start it up.

DCOP, on the other hand, is a part of KDE itself, and to assure that it’s running, it’s necessary to initialize at least the base set of KDE services. Remember that code in the Python DCOP example I didn’t show you before? Here’s what it is:

import kdecore
import sys
app = kdecore.KApplication (sys.argv, "program name")

That’s right, our program has to initialize a KDE application object. It doesn’t look like much code-wise, but that initialization will go ahead and start up DCOP and a handful of other KDE services before it returns, if they’re not already running. And if you’re running a GNOME-based desktop — and if you’re running Music Applet, you certainly are — you probably don’t have all the KDE services running yet.

On my laptop at least, this initialization takes several seconds. As a result, if you have Music Applet’s Amarok plugin enabled, this adds several seconds to start-up time before the applet appears in the panel.

To avoid this delay, it’ll be necessary to create a thread in the Amarok plugin just to do that initialization. Ick. Note that deferring initializing the plugin until the applet appears in the panel doesn’t really help, since the applet would then just become unresponsive while that initialization is taking place. And no, launching dcopserver via a call to os.system instead of initializing KDE doesn’t quite work. I mean, it does work just for DCOP, but when a proper KDE application starts, it will get confused about how only some of the KDE services are running and will start spitting out error messages and will behave a bit strangely.

Even worse, if the Python DCOP bindings try to connect to the DCOP server and fail, they will never try again. So you have to make sure the DCOP server is running before you try using it at all.

So, while DCOP does have simplicity going for it, D-Bus ends up providing a more robust Python interface and lower initialization overhead, which are both big plusses when you want your program to be small and responsive.

Fun fact: KDE4 will be ditching DCOP in favor of D-Bus. Unfortunately, I expect this will require having both DCOP and D-Bus in Music Applet’s Amarok plugin, so that it works with Amarok-for-KDE3 and Amarok-for-KDE4 seamlessly. Sort of like how, back in Music Applet’s C days, there was Rhythmbox-via-D-Bus and Rhythmbox-via-Bonobo. Thankfully no Music Applet users seem to care about compatibility with semi-ancient Rhythmbox pre-0.9 compatibility these days.

Music Applet 2.2.1 Released

Music Applet 2.2.1 has been released! As you might guess from the version number, this is primarily a bug-fix release. In particular, this release fixes a compatibility issue with GTK+ 2.12 that prevented the song information tooltip from actually having any song information in it. In addition to a few other, more minor, bug fixes, there’s also an updated Polish translation.

Music Applet 2.2.0 Released

The latest version of Music Applet is finally out, and hopefully you’ll find it well worth the wait. The biggest change is that there’s now support for MPD, Quod Libet, and the original XMMS. There’s also now support for a notification popup whenever the current song changes, which can be disabled if you so choose. Of course, there’s also bug fixes and updated translations; take a look at the release notes and the changelog for all the details.

Music Applet 2.1.0 Released

Music Applet 2.1.0 is out! This is mostly a bug-fix release, but there’s also a new plugin for Exaile as well as a new translation into Polish. The tarball‘s in the usual place.

Music Applet 2.0.0 Released

The latest version of Music Applet, the GNOME panel applet that makes it easy to control your favorite music player, is out!

Why the big jump in version number? While at first glance not much has changed, plenty’s different under the hood.

Music Applet 2.0.0

OK, a little has changed at first glance. Music Applet now supports album art; the song information tooltip will also show you any artwork associated with the current song. (Well, usually it will. It doesn’t work with Rhythmbox yet.)

Preferences Dialog

Music Applet also now gives you more control over the applet’s appearance than just showing or hiding the rating display. This should be helpful for people short on panel space.

But that’s all small potatoes compared to this:

Plugins Dialog

No longer are you stuck with whatever player support was available at compile time; Music Applet now has a plugin system that will make it much easier to add support for new music players without having to worry about recompiling things.

Or compiling anything for that matter, as Music Applet has been reimplemented in Python. Those plugins are just little Python scripts you can drop into a search directory that the applet checks at startup.

If you don’t care about plugins, that’s fine. Music Applet ships with plugins for all the players that older versions supported, so you shouldn’t run into any problems upgrading. In fact, this should make it easier for third-party distributors, since they can ship all the plugins together without forcing you to install a bunch of support libraries for music players you don’t want to use. If the dependencies for a plugin aren’t available, the plugin will quietly disable itself.

In other words, the applet should just do the right thing, without you having to worry about anything.

Download Music Applet 2.0.0 now!

Music Applet Website Move

Music Applet has a new home on the web:

The old site will automatically redirect you to the new one for a while (at least, until Purdue gets around to shutting down my account on their servers). Updating your bookmarks is highly recommended.

To those of you who may be accessing Music Applet’s Arch repository, you’ll need to update the repository’s location. The following two commands should do it:

$ tla register-archive --delete
$ tla register-archive

Music Applet 0.9.2 Released

At long last, the version 0.9.2 of Music Applet is out! This release adds two significant features:

  • Support for Muine.
  • The ability to launch your favorite music player if needed. When there’s no music player running, Music Applet shrinks down to an ordinary launcher.

There’s also several bug fixes (especially in the Banshee support) and a few new translations too.

Music Applet 0.9.1 Released

Music Applet 0.9.1 is out. The applet now supports XMMS2 in addition to Rhythmbox and Banshee. The right-click menu has been cleaned up, and there’s now translations for Norwegian and Portuguese.

For those of you hoping Muine support would make an appearance, that’s been pushed back to 0.9.2. There’s also a whole bunch of other things I have planned for future releases, so stay tuned.

Call for Artwork

As you may have noticed, Music Applet currently doesn’t have an icon. I don’t have the artistic skills necessary to make a good-looking icon for the applet, but you might.

If you’d like to contribute an icon for Music Applet, please e-mail it to me. I’ll choose the best one and add it to a future release of the applet.

Thanks in advance!

(ObLegal: Of course, the icon must be your own creation and it must be offered under the GPL or a compatible license.)

Music Applet 0.9.0 Released

Rhythmbox Applet is dead! Long live Music Applet!

That’s right, with the advent of support for Banshee, the name Rhythmbox Applet is no longer suitable for a GNOME panel applet that lets you control your favorite music player. So, despite Benji‘s best efforts to get me to name it “Kulinibox” (“it’s eponymously cool!”), its name has changed to Music Applet

And accordingly with big changes, there’s been a big jump in the version number (0.9.0) and a new web site for the software, one that should hopefully load much faster than the old one did.

Here’s a quick sketch of the roadmap for Music Applet’s future. This is all subject to change, of course:

  • For 0.9.1: Muine support.
  • For 0.9.2: Album art support (and figuring out how to properly handle features that are supported by only some music players, such as album art and song ratings).
  • For 0.9.3 and beyond: Improving the applet GUI.

For those of you using the old Rhythmbox Applet RSS feed, you’ll want to switch over to the new Music Applet RSS feed, which will carry all future announcements for the software.