Saturday, August 13, 2011

Python Packaging for Harmattan

Right now I am taking a break from learning QML.  Instead I've been adding support for Harmattan to my existing QWidget projects.  It might seem pretty pointless because of how aweful QWidget can be with the default theme.  I will at least have the apps available if I need them in a bind.  Also taking working apps and repackaging them rather than new untested apps provides the benefit of controlling the number of variables to debug when things go wrong.

I will be focusing on packaging for OBS seeing as a QWidget-based application isn't worth pushing through OVI.

Packaging

I had to switch my applications packaging over from my py2deb fork to the distutils-based sdist_maemo.  A big reason is sdist_maemo already has Harmattan support.  I also figured it was a good idea to switch to distutils as it is more "proper" python packaging and because it is pluggable for various target packaging systems.  That last part will allow me to continue to support Maemo 4.1/5 and in the future support regular MeeGo.

So first I've moved all of my files to a proper distutils based layout
  • ./setup.py
  • ./LauncherName
  • ./package-name/*.py
  • ./data/package-name.desktop
  • ./data/package-name.png
I try to reuse code and packaging infrastructure between my projects so this means I need an easy way to diff between them, so I added a symlink from "./package-name/" to "./src".

I then wrote my setup.py file with an sdist_maemo command configured for each of my target deb-based distributions.  A nice thing to know is that for Maemo 5 the python module will be optified for you.

An annoying thing is each platform has different packaging requirements.  Some examples include:
  • Different ".desktop" file locations
  • Different ways of launching the app from within a desktop file.
  • Everything seems different with the app launcher icon
  • Different icon sizes for the Maemo-Icon-26 field
  • Different .deb sections
  • Different dependency names
  • Aegis file support (not needed for current apps so skipped over)
Already the differences between Maemo 4.1 and Maemo 5 were annoying from a packaging perspective.  This makes the problem even bigger.  One approach I've always rejected was maintaining separate packaging scripts for each distribution requiring me to keep duplicate information like the version number.  The approach I used with py2deb was passing a parameter in to my script to change what was passed to py2deb.  That doesn't seem to jive with distutils.  So I threw in a touch of code-gen using a nifty tool called cog.
To minimize my need for using code-gen my setup.py file creates multiple instances of sdist_maemo, one for each platform.

The app icon caused me some problems.  I had assumed it would operate like previous versions of Maemo and desktop Linux, that if you just said "ejpi" or "gonvert" it would look for the appropriate icon size in "/usr/share/icons/hicolor".  I'm glad I found that document explaining otherwise.  As an alternative some of the apps in the OVI Store just hard code an absolute path. When you do make a mistake on this, Harmattan seems to have two different default icons.  The red square came up for me when "ejpi" didn't map to an icon.  The green curved icon came up when I had an absolute path that pointed at nothing.

My makefile creates the needed icons, code-gens my desktop files, code-gens my setup.py files, and then runs "setup.*.py sdist_*".

Odds and Ends

I do not believe PyQt is available for Harmattan, so I had to finish adding support for PySide in my applications.  I've made it easy to use both bindings by centralizing all knowledge of the differences between the two.

I've tried to make the switch a couple of times already but each time I came across new bugs that the old bugs prevented me from seeing.  Luckily the PySide people are quick at resolving these issues and by 1.0.5 my applications ran smoothly.

I went ahead and made the simple switch to XDG and Harmattan-style icons though I'm not yet seeking OVI compliance.  I decided to redo the icons.  They weren't all that great, no where near the icon guidelines, and I wanted SVGs so I could use the Harmattan Icon Generator.  Not being an expert at graphics tools, the icon generator definitely saved me a good amount of work.  The main drawback is that basing the icons background gradient on the base icon's content seems to produce results without enough contrast.  I ended up using the "mean" setting to force gray backgrounds.

Distributing

Now that we have all that wrapped up, time to upload onto the OBS.  The Getting Started Guide has been updated and now is pretty good.  I setup a harmattan-specific subproject due to my code-gen specializing the source-packages per distribution.  Once everything was uploaded to my project, I logged in as root, added my sources, and away I went.

So for the fruit of my work:
Well I guess this means I need to get back to learning QML.

Resources

Desktop File:
XDG
Icon
Package
OBS

7 comments:

  1. Thanks for the nice summary. I also like the PySide/PyQt compatibility module! You should publish it somewhere standalone so it's easy to find for people (PySide Wiki maybe?). Did you try PySide Assistant at some point too, or is it too strict for already existing code? PySide Assistant can be found at: http://wiki.meego.com/Python/pyside-assistant

    ReplyDelete
  2. Great post!
    I am also working on porting my Maemo 5 apps to Harmattan. How ever I am still learning how to use QML and how to use the different restrictions/requirements for Harmattan.

    About the icon generator: javispedro now added a new mode where you can set the background color yourself.

    ReplyDelete
  3. @thp Good idea. I've been hesitant about creating a full python package because I do not wish to maintain compatibility but I can at least put them in a repo, no packaging, and include various examples or links to examples. After I fix some mistakes I made over the weekend I'll get on that.

    I was thrilled when PySide Assistant was announced even though I think my use cases are a bit too complicated for it. Because I target Ubuntu, Maemo 4.1, Maemo 5, Harmattan, and eventually MeeGo I need to handle all sorts of differences. One example is how to invoke my app through the desktop file.

    ReplyDelete
  4. @thp I've gotten started on them

    I've updated my project skeleton to be distutils based
    https://github.com/epage/MaemoPythonSkeleton

    I've separated out the utils I use and added a touch of documentation
    https://github.com/epage/PythonUtils

    I guess time to go find the PySide wiki

    ReplyDelete
  5. Saturn5:46 PM

    You are a hero!

    I was going to ask simply for the setup file you use.. :)

    Very much appreciated.

    ReplyDelete
  6. Anonymous6:41 PM

    This comment has been removed by a blog administrator.

    ReplyDelete
  7. To the person who just posted today, your post seemed to vague with an unrelated link that I assumed it was spam. If this was in error, please post with some more detail of what you are looking for.

    ReplyDelete