Ubuntu One – The KDE Way

Over the past couple of months I had the great opportunity of taking part in this year’s Google Summer of Code. I moved out to bring Ubuntu One to the KDE desktop and I think I was rather successful with it, now all I need to do is find someone who is willing to maintain it … ๐Ÿ˜‰ Now that Google Summer of Code is over I will continue focusing my efforts on Kubuntu and general distribution development which is the reason I would very much like to find someone who is willing to maintain it.

But first let me outline what exactly you can expect from this first iteration of an Ubuntu One client.

It basically consists of a couple of libraries that allow fast creation and enhancement of client applications of any kind. In fact I suppose most of the code was produced as either a library or in a form that could become part of a library. I will blog about the underlying technology in a bit. Based on those super useful beasties I created also some user visible applications that cover basic use of Ubuntu One on the local desktop.

The foremost component is the Ubuntu One Status Notifier (posh name for tray icon). As one would expect from a thing that calls itself status notifier, it notifies about the status of your Ubuntu One client. In particular it will show you whether you are connected to the Ubuntu One server and in general what exactly is going on with your client, for example it also shows when a download or upload is occuring and which files are currently being processed. In addition to the status notifications it also is a sort of starting point for general things you might want to do with your Ubuntu One client. For that it provides 3 key capabilities:

  1. By clicking on the status notifier you will get a minimalistic browser widget that takes you directly to your Ubuntu One web interface. Should you not want to connect your client for one reason or another, or if your client is busy synchronizing gigabytes of data while you need one file you just have to click on the status notifier and have direct access to the web interface.
  2. In the context menu you can start Ubuntu One Share which is a very nice program that helps you set up a new share. The nice thing about this is that you can select the people you want to share with directly from your Akonadi addressbooks.
  3. Also in the menu you can access the configuration dialog.

Talking about configurations. Ubuntu One also embeds in System Settings’ network area. Using these awesome configuration modules you can not only get information about your space usage and Ubuntu One subscription data but also configure maximum bandwith usage or whether the Status Notifier should autostart. Of course you can also look at your shares and mange which folders ought to be synchronized with Ubuntu One.

To drive ubiquity one step further -> Ubuntu One is also in your KInfoCenter ๐Ÿ˜‰ As a side product of the regular configuration modules Ubuntu One also provides information in your KInfoCenter, which is of course the most natural place to provide information in. Thanks to the supreme design of the KDE platform doing such things is super easy and takes very little effort.

There are also some less polished components (that I do not want to talk about right now ;)). I think this is a very good starting point and much greatness can be created based on what is here. All it takes is someone to step up and take on maintainership and care for the code and improve it and polish it and make it a diamond.

How to get it you ask?
Just check the mail I recently sent to the Kubuntu development list: https://lists.ubuntu.com/archives/kubuntu-devel/2010-August/004622.html

Update: development on my end is done, please refer to the Launchpad bug report for UbuntuOne-KDE for status updates.

Should you have questions, suggestions or maybe even want to join development please join the Kubuntu development mailing list or ping me on IRC.

โ™ฅ QJSON โ™ฅ

Warning: technical babbling following.

As some of you might know from unofficial sources – I am working on bringin Ubuntu One to the KDE workspace. After I spent one month binding with the community it is now time to start talking about the important parts of life.

Namely: “How do I properly work with a JSON object”

It is more of a secret but there is a Ubuntu One server-side REST API to query all sorts of more or less useful information. From my point of view it is not the information that is interesting though, but how to make it useful in a Qt app ;).

So, this REST API returns a JSON “object”, and of course using JSON objects (which really are just strings, or rather variants of strings and other variant datatypes) is sort of ugly and horrible and defeats the concept of object-oriented programming. What’s more is that using those variants directly exposes internals such as actual names, instead of providing stable interfaces indepdent of the backing members. Clearly we want to convert the JSON stuff to something more C++y – fortunately enough there is QJSON.

Using QJSON one can easily convert a JSON object to a QObject. Although that is not exactly the right wording, more appropriate is: one can easily fill a QObject with data from a JSON object. Keeping that in mind is very important when working with JSON and making it a QObject.

When using the builtin magic to convert a parsed JSON QVariant to a QObject it will iterate over all QProperties defined for a given object and try to write the value of a key from a JSON QVariantMap to a QProperty with the same name.

This means that you need to define QProperties of the same name as the keys in the JSON QVariantMap, so if you have:

{ “foo”, “hello”; “bar”, 100;}

then you will need a QString property named “foo” and a int property named “bar” in order to deserialize this map. Please take a look at this blog post aboutย serialization and deserialization of JSON and QObjects. It should make the basics very easy to understand, or so I think ๐Ÿ™‚

Now this will probably work just fine in most cases. Most cases means for every datatype supported out-of-the-box by QVariant. If you want to deserialize a nested object though, you will have a bit of a problem there. This took me quite a while to figure out and I only noticed what went wrong by looking at the appropriate Qt code (thank god for FLOSS).

When I said that this will work for every standard QVariantable datatype, I was refering to how writing to a property works. What basically happens is that you put a QVariant in and Qt will then try to call the WRITE method of the property with the QVariant as argument. But here is the fancy thing about this: before it actually calls the setter it will check if the QVariant’ed type obtained for the setter is actually the same as the one you want to write.

Let me explain this with an example:

You have the QVariantMap from above, but this time with an addtional QVariantMap inside { “foo”, “hello”; “bar”, 100; “fluff”, {“MOTU”, “Harald”};}. What will happen if you try to convert that to a QObject is: property foo will be written using QVariant(QString), property bar will be written using QVariant(int), property fluff will be written using QVariant(QVariantMap). Now consider you want fluff to be a QObject and not a map, why can this not work considering what I wrote above about how writting a property works.

Lets recap this in detail, you have a property in the QObject that looks something like this:

Q_PROPERTY(FluffObject* fluff READ fluff WRITE setFluff)

This will rather silently fail, because what actually happens here is that you try to setFluff(QVariantMap) and not setFluff(FluffObject*) … well, to be honest it does not even get there, because Qt will catch this long before and refuse to write the property. So we have a bit of a problem. One option is of course to manually deserialize fluff with something like:

QJson::QObjectHelper::qvariant2qobject(data["fluff"].toMap(), obj->fluff());

If you have a very complex object with lots of nesting this will be rather ugly though – having this logic within the actual object we try to deseralize would be so much better, wouldnt it? So how does the imaginative developer surcome this issue?

Q_PROPERTY(QVariantMap fluff READ QVariantMap() WRITE setFluff)

Fancy, eh? ๐Ÿ˜‰

So what do we do. Basically we have a QVariantMap property that we use to write the FluffyObject. When we try to write the QVariant to the property fluff it will indeed use setFluff(QVariantMap) and within that function you can then do the qvariant2qobject magic of QJSON.

I highly doubt this precise example will work for serialization though, since it is probably using the reverse approach and creates the JSON QVariant from reading the propreties, which in this case would not work terribly well, but using a real READ function should sort this, you just also have to recursively apply the serialization magic of QJSON ๐Ÿ˜‰

With this approach you can not use the same property name for the QVariantMap and the real object, so either have an appropriate getter for the member in question and use it directly, or if you want to use a property, then use another name for it like “fluffObj” or something.

Happy JSONing everyone ๐Ÿ™‚

Kubuntu is not Ubuntu

This post is supposed to make it clear why Kubuntu is what it is. Writing this down is necessary because people constantly get the wrong picture.

Entities

Let me start to explain the relationships of entities around Ubuntu.

First and foremost there is the Ubuntu project, it is this large monster that includes Ubuntu Desktop, Ubuntu Server, Kubuntu, Xubuntu, Edubuntu and some other stuff. One could think of the Ubuntu project as an umbrella spanning across most (semi-)official activities surrounding Ubuntu. Packaging KDE software would be such an activity, so even as Kubuntu developer you are contributor to Ubuntu at large.

This relation is even publicly visible.

At Kubuntu we have a special membership status for people who have proved themselves valuable contributors to Kubuntu. With such a membership you get an @kubuntu.org email address and some other cool things. It might not be all that apparent, but this membership reflects the relationship between Kubuntu and Ubuntu. Once someone becomes Kubuntu member they also become Ubuntu member (technically speaking are Kubuntu members a subset of Ubuntu members). This is because a Kubuntu contributor is in the end also a contributor to Ubuntu (the project, not the distribution necessarily).

Now we know that Ubuntu is one big entity that consists of other entities (like Kubuntu), but at the same time Ubuntu is also the name of the GNOME featuring desktop distribution produced by Ubuntu the project.

Up until now I was talking about Ubuntu as a project, and simply put, this project is community driven. Sure, Kubuntu and Ubuntu have people working on them full time, but there are hundreds or possibly thousands of others, spending their spare time on contributing to Ubuntu. And here the whole thing gets a bit tricky to understand.

Kubuntu is by 5/1 controlled by the community, Ubuntu (the desktop distribution) is not. You might wonder how I ended up with 5/1. Well, the Kubuntu Council (pretty much in all cases the highest authority within Kubuntu) consists of 6 members, of which 5 are not working for Canonical.

Canonical, yet another entity. Canonical is a company trying to make money with Ubuntu products. Canonical is also the company that makes Ubuntu, the project, possible. Of course we easily forget about this, but without Canonical there were no *buntu websites, no launchpad, in consequence of that there would be no build daemon, no daily CD builds of consistent manner… in general there probably would not even be the computational infrastructure to run all those things. So just the infrastructural expenses (including maintenance etc.) must be of a quite considerable amount. Now I was not completely honest with you. Canonical is not only trying to make money with Ubuntu products, in fact Canonical is driving development of most of these products (to a certain degree at the very least).

So the Ubuntu project is driven by the community AND Canonical. Some parts more by the community, and others more by Canonical. As it usually works, this means that the community can focus on the fun parts while Canonical fills the gaps of the other work that needs to be done in a distribution creating project. And this is a good thing for the better part. Most of these free contributors are doing it because it is fun or because they want to achieve a personal target (say, make a system that boots within 2 seconds), but usually not all work of the distribution creation process is fun. I suppose it goes without saying that less people would contribute if they had to spend a substantial amount of their time on rather complex and boring stuff. Yet someone needs to do it, why not someone who gets paid for it? ๐Ÿ˜‰

Of course that is a much simplified picture, but the point I am trying to make is that there is a symbiosis of the activities within the Ubuntu project.

Power and responsibility

"With great power must also come great responsibility!" is it written in the first Spider-Man story. Very true words those are, in the context of Ubuntu too. Those who have the power to stir development, must also be responsible if the direction was wrong. And I would even go as far as saying that those that are responsible must deserve the power to stir development.

What does this mean for the Ubuntu project?

Canonical chose GNOME as their preferred desktop and Debian as their preferred distribution, so they made a new distribution based on those 2 existing software stacks. Canonical sells support contracts, in fact Canonical tries to only live off those and some associated activities within or around the Ubuntu universe. So to their customers and partners they are ultimately responsible for when something goes wrong in the product. So lets assume the product is Ubuntu, the distribution, and the wrongness is that GNOME is completely broken. The customer will not go complain to the community, even though they are to a certain degree contributing to the product. The customer will go complain to the one they got a contract with, which would then be Canonical. So Canonical is responsible and thus must at least have as much power to avoid situations where they would loose substantial amount of money due to problems in the product. What I am trying to say is not that Canonical does or must have absolute control over Ubuntu, the distribution or the project, but the amount of control that is necessary to secure their business and in consequence secure the future of Ubuntu as a whole.

The picture for Kubuntu is different. Kubuntu originated in a community effort to bring the KDE desktop on the Ubuntu base stack. Canonical decided to use GNOME for their desktop and some community members decided to create another version with KDE as the desktop. Canonical apparently thought of this as a good idea and incorporated Kubuntu into the Ubuntu project, thus providing infrastructure for package building and hosting and website hosting and CD building… But they only had little interest of exploiting the business potential that comes with a KDE featuring desktop based on Ubuntu, though there certainly was some potential and so they decided to take on a bit of responsibility. Namely employing one of Kubuntu’s founding fathers full time. The community however continued to be driving in just about any aspect, and so the community also had most power over the course of development, simply because they were responsible for the product and the development of the product.

Kubuntu is not Ubuntu

This statement might seem incredibly obvious, and yet once in a while someone does not exactly understand on how many levels this applies.
Sure, on a technical level Kubuntu is not Ubuntu because it uses KDE, then again it uses the Ubuntu base stack… But more important than that are some other applications of the above statement. Kubuntu is not a large project like the Ubuntu project, it is part of the Ubuntu project and thus must obey its rules and regulations to some degree. This for example means that we cannot just stick some random non-free software on our CDs. It also means that Kubuntu is not the brand Canonical chose, but Ubuntu is, that is why the project is called Ubuntu and the distribution is called Ubuntu and associated products are somehow related to Ubuntu, possibly even reusing the brand (e.g. Ubuntu One).
Another important difference is that most changes in Kubuntu do not come from Canonical. They either originate in KDE or within the Kubuntu development community (and of that also only 2 people work for Canonical … go figure). One of the most interesting examples of wrong assumptions in this category, affecting me, was that apparently the Mozilla Firefox installer, that is available in Kubuntu 9.10 and later, was created by Canonical. At least various reviews claimed so, well, indeed it was me who created it, and I am not employee of Canonical, nor does Canonical own the code.
In general one might say that stuff going on in Kubuntu mostly does not have anything to do with Canonical, and if it does, then it is still approved or tolerated by the community.

Taking up on my above statement that those that have power must be responsible and those responsible must have power I’d like to make the following clear: the Kubuntu community has the most power and the most responsibility. Holding Canonical responsible for issues in Kubuntu, of which there are many, as within any software project, is just wrong. Because even if there was wrong doing on their part, the community still did not do anything about it.

Implications

Aforementioned statement also implies some things. First and foremost is that Kubuntu doesn’t need to receive the same attention from Canonical as Ubuntu, the distribution, gets. There is no particular point to it either. Not from Kubuntu’s perspective and neither from Canonical’s.

From a business point of view, Canonical would have to invest enough resources to make Kubuntu a viable business opportunity, that then directly competes with their other system, Ubuntu, which is the main brand carrier though. So that would be a bit of a problem, since from a perception point of view, Kubuntu is a different brand than Ubuntu (even though it might be associated, one way or another). Of course this is not exactly good for either brand because they then end up sharing volume of public attention instead of specifically trying to direct it at one particular brand.
At the same time this would mean that Canonical becomes more responsible (and thus needs more power, see above). So ultimately this would make Kubuntu less of a community effort and more of a Canonical one (to about the same degree as it is now with Ubuntu one can suppose). This then would lead to Kubuntu becoming much more derived from upstream KDE, because obviously a company would want to distinguish their product by all means from its competitors, and that involves heavy branding, special features etc.

Conclusion

So since Canonical does currently not exploit all business potential coming from Kubuntu, the community will probably be responsible for quite some time to come.

This ultimately means that the community will apply the rules and judgment of which they think it is the best available. Since the community is mostly consisting of people contributing in their spare time human time resource is rather limited and thus one must choose the battles carefully. In consequence this means that some things simply cannot be done. Like say Ubuntu One integration, of course it would be nice to have, but currently there are much more important things to work on. Same goes for porting Software Center. Finally it also means that the community gets to decide how much branding gets committed, and currently the opinion is to stick with KDE’s. Not only is their artwork of incredibly high quality, but also are they the biggest contributors to the Kubuntu desktop, so they deserve most credit.

On that last note I would also like to note that Kubuntu’s target was to make the best KDE distribution, not the best Ubuntu flavor, thus deriving from KDE’s artwork and color scheme would not only be in conflict with the fact that Kubuntu’s color palette is almost identical, but also with what Kubuntu is trying to achieve.

In short: Kubuntu is not Ubuntu. Occasionally blogs and news stories and bug reports assume Canonical is responsible for things they are not. In general, me and the other Kubuntu developers are responsible for Kubuntu, please keep this in mind when moaning or praising us.

Thank you.