Hey ! I’m making KDE Now, an application for the Plasma Desktop. It would help the user see important stuff from his email, on a plasmoid. It’s similar to what Google Now does on Android. To know more, click here
I know, I know. I haven’t blogged for a while. But the past couple of weeks have been busy. Not just in terms of my project, but also my personal life, with a lot of things happening lately that demand my attention. Thankfully, I have been able to commit proper time to my project.
This time, there’s a lot to talk about.
I implemented all the extractors as run time plugins this time around. Earlier the daemon was not independent of it, with the extractors implemented as part of processor itself. Now, thanks to plugin architecture they are independent, and the daemon loads the plugins at run time. This was also part of my Season of KDE project for Plasma Media Center last year. It was only a lot more fun this time around, since I was starting from scratch. The advantage of having this architecture is the ease with which you can add support for plugins/extractors in future. At the end of this post, I’ll describe roughly how you can do this.
Next up, I added support for database. It was always a plan to cache stuff, to avoid unnecessary network usage. But we had not decided on the exact details of this implementation. I wasn’t sure whether to cache on files or use a database. I went to IRC and asked around. Bhushan (bshah) suggested to use a database since that adds security. Trojita, which is a Qt based IMAP client also uses a database for this. Hence, I planned to use a database altogether. My mentor suggested something along the lines of MongoDB in which I can save the whole data map and would not have to manually map everything (cheers !). My data was JSON so things would be a cakewalk. Both saving as well as retrieving data. Unfortunately, Qt doesn’t provide support for it. I looked for some C++ drivers around, but couldn’t find anything useful. In the end we settled for SQLite since it’s lightweight, supported by Qt and generally has compiled drivers for most distributions.
Next, I exposed data from these plugins to D-Bus. I must say, I enjoyed learning about D-Bus. I had read about it earlier, during community bonding stage. But I forgot most of it, with all the things going on during my semester exams. Lol :D. Hence, when I read about D-Bus now, it was as good as a fresh start. I wrote small test programs too, for trying out QDBus. I came across a rather nasty problem related to D-Bus however. I was registering the proper service and object, but on calling the method, I repeatedly got the error of D-Bus Unknown object. After many hours, I consulted my mentor. He guessed it might be because, the object was getting destroyed on leaving scope (since it was in stack memory). His guess was spot on. I changed the object to heap memory and it worked like a charm ! We later decided to completely remove the extra interface files I had made, and currently we expose data from the plugin itself.
As I promised earlier (did I ?), here’s how you can add plugins now.
- Get into the reservations directory and create a directory for your plugin
- Include the directory, in reservations/CMakeLists.txt
- In yourPluginDirectory, you need to make four files: yourPlugin.desktop to describe the plugin, yourPlugin.h, yourPlugin.cpp and CMakeLists.txt files
- Make sure that yourPlugin inherits publicly from AbstractReservationPlugin, and make sure to define the start() method in yourPlugin. (I have made it virtual in AbstactReservationPlugin, hence you must implement it).
- Do whatever you need in your plugin.
- Describe your plugin in a yourPlugin.desktop file, and make sure you set the ServiceTypes to KDENow/Plugin (*Hint* Look at the ones already made and make relevant changes )
- You need to store stuff to Database. Cache what you extracted.
- Expose your data map to D-Bus. For this, yourPlugin.h must have this macro: Q_CLASSINFO(“D-Bus Interface”, “org.kde.kdenow.<yourPlugin>”)
- In yourPlugin.cpp, bind the D-Bus Adaptor, and register the object and service (Look at the ones I already have done)
- Implement a public Q_SLOT for getting the data. It can be whatever, but preferably a QVariantMap. However, if it’s a custom data type that is not natively handled by Qt DBus then you need to implement the stream operator functions and pass data byte by byte. Look at the Qt D-Bus Type System docs, to see whether your data type is natively handled or not.
- Make a CMakelists.txt describing the build specs. Make sure to call the qt5_generate_dbus_interface and qt5_add_dbus_adaptor and kcoreaddons_desktop_to_json methods with relevant arguments
- Make sure to install all the things at the right place.
- Or, you can just copy the CMakeLists.txt I made and make relevant changes 😉
- Test with relevant data
With all of this, I think most of my backend work regarding emails and all has finished. For the next few things, I plan to write the receivers for the D-Bus data and do something to get data, when the daemon is not running, but the plasmoid is running (Hence, fetch from database). Also, after that I need to write User Interfaces for the plasmoid and cards.
I’ll catch you in the next one