Articles tagged with "IT misadventures"

Much more fun with Planning poker

When I wrote about my Planning poker app for the first time, I had invested 3.5 hours into the app itself plus some more time into rescuing its version history. Things have been moving forward since then. More precisely, they've been moving in several different directions - sometimes all at once - for about 16 more coding hours.

What bothered me about the first "finished" version were slight glitches in the layout. Some gaps between cards were one pixel wider than the rest and it was just wrong. The wrongness was exacerbated by the fact that the cards were being carefully laid out by a script upon page load (I had to use absolute positioning due to the particular transition effect I had come up with).

I decided to fix both problems by letting CSS do its thing and using an overlaid extra card for the transition (yeah, I called it "joker"). It simplified the code and removed the layout irregularities. It also introduced aliasing artifacts. In other words, edges of cards were getting blurred at certain viewport sizes. The new transition mechanic also didn't work flawlessly - it glitched when you poked the app during the transition. I chalked it up as a failed experiment (the best kind!) and decided to be rigorous.

In the end, I have a responsive layout script that works with a size unit one might call VRSTAWPP (vmin reduced slightly to align with physical pixels). The entire layout takes up 100 VRSTAWPP on the shorter side of the display and however many are necessary on the longer side. As it's a reduced vmin, there may be extra pixels left. I distribute those as evenly and symmetrically as possible. The result is a joy to look at, provided you have a phone-vs.-eyes setup that lets you discern individual pixels. Otherwise you just won't care.

So what's next? Planning poker is now in that weird limbo between a project and a product. I'm happy with how it works but there are still bits that need polishing:

  • the cards look like they were designed by a programmer
  • there is no proper logo and no proper icon to show in an app store
  • the app has no proper name to distinguish it from other Planning poker efforts
  • only one deck of cards is supported
  • there are other features I'd like to add (OK, those are "nice to haves")

As for cross-browser support, testing in Chrome has indicated that the web platform is as inconsistent as ever. There's a schism, for instance, when changing the transition CSS property on an element while it is transitioning: Chrome cancels the running transition immediately, Firefox lets it finish. The app is thus pretty much unusable in Chrome. I haven't done any testing in other browsers.

You can check out the current version of Planning poker at my modest projects page. The page features an install link as well; if clicked in a recent Firefox, it should store the entire app on your device for easy offline use. On Android and Debian it even gets nicely integrated into the appropriate menu.

I have yet to seriously try turning Planning poker into a faux-native Android app (for possible inclusion in the F-Droid market). I've played with mozilla-apk-cli but the resulting .apk weighs just 1.4 MB and I don't suppose it'd work on a device without Firefox installed.

I'm not really sure this is worth pursuing further but at least I could try publishing it into the Firefox Marketplace. As of now it only contains two other Planning poker apps, what a shame :-)


Too much fun with Planning poker

The new team lead on my current project started using Planning poker for estimation. It turned out that all colleagues except me had installed a corresponding smartphone app in order to avoid mucking about with actual paper cards. The apps are exceedingly simple: all the cards are displayed on the screen, you tap one and it fills the entire screen, you tap it again to restore the initial view. Pretty graphics and fancy animated transitions are just about the only embellishments.

My Fairphone comes without Google Play and I usually fulfill my app needs through F-Droid, the app store dedicated to open source offerings. To my surprise, F-Droid offered no Planning poker app (granted, the store is rather small at about 1000 items). I decided to build my own, of course. Given my current interests, I chose to write it as a HTML5 page instead of a native Android job.

I was done in about 30 minutes and the result was perfectly adequate for the intended purpose. It was pretty spartan, though, so I spent about an hour tweaking the visuals and two more hours adding an animated transition effect. I did all the work in one file without any version control and by the end I wished I had kept track of the various stages. I hadn't done much work in HTML5 before and there was a lot of trial and error involved, especially concerning CSS (I have to thank the friendly spirits at Stackoverflow, MDN and W3C, of course, for speeding up the journey immensely).

And then I found out that I had, in fact, kept all the intermediate versions without even knowing about it! You see, I had set up a shortcut to the Poker page on my Android home screen to speed things up a bit. As it happens, each time I tapped the icon, Firefox opened the page in a new tab. By the time I noticed, I had 60 open tabs. It's a pretty annoying behavior, if you ask me, but in this case it provided a welcome benefit: all iterations of my creation were neatly laid out in chronological order. I only had to save them as separate files.

Yeah, I didn't think it would be simple, either. Firefox for Android offers just one "Save as" option: "Save as PDF" which wasn't much use to me as I was after the source code. The Firefox Add-ons page yielded an interesting extension called "View Source Code". I installed it pronto, only to find out that it displayed the source code of the latest version of the file, regardless of which tab I was looking at (all the tabs had the same URL and the extension obviously reloads the source in order to display it).

I tried another extension: "Save as TXT". This one saved only the text visible on the rendered page, of course, which wasn't that useful either. The extension looked rather simple, though, so I downloaded it and poked around in its source code to see if I could adapt it for my purposes. I had had some exposure to the XUL universe before so I wasn't completely confused but even so, the task was far from simple.

My biggest hurdle consisted of the fact that I had to iterate here as well but couldn't restart Firefox in between (lest I lose all my precious tabs!). I found out that uninstalling an extension and installing a newer version of it leaves some hooks registered by the older version in place (something a restart would surely fix) so my changes weren't taking effect. I had to install each new version with a different extension ID, making the whole process pretty cumbersome.

In the end, I bludgeoned the extension into doing what I needed after 8 or 9 iterations. It took two and a half hours and the result was a primitive hack. Having to activate the extension 60x by hand afterwards wasn't much fun either. I did rescue the history of my Planning poker page, however, and that's all that matters.


What I did last summer

My three-month break from paid programming work was largely spent dealing with various Real Life issues. I did get to try a few things, however, mostly in September in preparation for various interviews. Here's an overview of those experiences for posterity:

  • I started on my first Android app. I was surprised by how rich my own testing feedback was - it substantially changed the whole proposition I'd had in mind. Touch UIs really are a completely different ballgame. That's why I can't see myself developing with emulated devices. I don't worry too much about fragmentation, testing on one specimen of each feasible screen size (say 4.5", 7" and 10"). For a modest app that doesn't use any esoteric hardware features, it seems to be working out OK.

  • I took a look at JSF 2, CDI and the rest of the JEE 5 stack (or at least the web profile). I was pleasantly surprised by how easy it was to deploy a toy application into the various containsers. I tried GlassFish, TomEE and JBoss. Especially the latter surprised me as a well-thought-out, approachable piece of software. I even ventured to create a FrankenContainer by mashing up JBoss Weld with Mojarra, Apache OpenEJB, Hibernate JPA etc. That didn't quite work but the few hours of debugging proved amusing.

    I also used the JEE web profile to implement a basic version of a web app idea I'd had for some time. I deployed to all three containers and there wasn't any issue. I do have to say, though, that I didn't find the experience all that enjoyable. The templating approach taken by JSF 2 is about equally powerful as other mature approaches yet it makes you suffer its baroque verbosity. This became even more apparent when I re-implemented the app in Python (using the Pylons framework and Mako templating) to keep my OpenBSD home server free of Java. The Python version is much more compact and has much easier URL manipulation. I suppose JEE comes into its own with really big projects.

  • I was fortunate to play a little with Apache Wicket, as well. It feels incredibly fresh compared to JEE. I found the binding between the Java and HTML incarnations of a page to be slightly tighter than I'd expected (the component trees have to match pretty much exactly) and I missed an expression language a bit (not wanting to muck around with Velocity integration) but I found myself doing a lot of work very quickly and fluently. Unless the heavy sessions are a deal-breaker, I find Wicket a pretty obvious choice for writing web apps.

    Regarding Wicket, I was amused by how varied the Spring integration examples I found turned out to be. One had the standard Wicket servlet with a Spring context starting in the init method of the Application class. Another used a special Spring dispatcher servlet with the Application class as its init parameter. It goes to show that both technologies are well suited for working with other components (in case of Spring that's the whole point, of course). Having multiple ways of doing the same thing is a mixed blessing but what I saw was pretty easy to follow.

  • I wrote a plug-in for the QStarDict desktop dictionary. QStarDict has a really nice Qt-based UI and perfect KDE integration but I found its German-Czech dataset quite useless. I did found a great German-English dataset that ships with another tool, though, so I taught QStarDict to parse it. This was my first "major" C++ undertaking since my high-scool project in 1995 so I spent some time scratching my head over things such as namespaces, references and nested template parameters. In the end it all worked out OK. I have to find the time to polish it a bit and talk to the QStarDict folks to see if it's interesting for them.

    Working with Qt was a pleasure as always, it all looked rather civilized despite the C++. It even made me feel a bit uneasy the way C++11 does. On the one hand, improved safety and readability are generally worthy goals. On the other, the language should signal its fundamentally unsafe nature. Hiding it too well gives a false sense of safety and it somehow feels hypocritical. I do suppose experienced C++ folks working on large projects simply appreciate all the help they can get.

  • Finally, for the current project I needed to look into the Eclipse Rich Client Platform. It's not trivial and I'm sure I'll keep discovering new facets for a while. It's really nice to interact with the underlying UI libraries (SWT and JFace) simply due to their contrast vis-a-vis Swing. Exploring a different way of thinking is always useful as well as fascinating.

    While investigating Eclipse RCP I stumbled upon SWTBot, a functional testing tool for SWT applications. It's not perfect but it seems to be usable. It fits neatly into my toolbox alongside FEST and Selenium.


Now that I look at it, the summer wasn't completely wasted after all! I wish I could've delved into some of the topics a little deeper but so is life. I don't like how I've been neglecting the JavaScript/HTML/CSS universe. I hope I'll make good use of my commute time to fill this void.


PIMp my calendar: Aftermath

I spent some of my free time over the past few weeks trying to get the Calendar app on my Android phone to run with a non-Google and non-MS-Exchange account (see part 1, part 2, part 3, part 4 and part 5). As with my printer woes, it turned out to be an enlightening excercise. I ended up running the Radicale CALDav server on my home server and Marten Gajda's CalDAV adapter on the little machine. I discovered fun facts about Android and its development tools along the way (the highlight was discovering that changing the minimum API level in Eclipse ADT fails to trigger a re-build).

As for the lessons learned, I guess there is a balance to be struck when troubleshooting a technical issue. One approach involves poking and prodding the system, observing responses and formulating hypotheses. Another option is to study information about the system - source code, documentation, online forums and other resources. Combining these modes optimally is rather delicate and I do tend to err on the side of experimentation. The knowledge it yields may be overly specific and not very reusable but the process fosters a problem-solving mind-set that comes in handy in other situations as well. Besides, documentation may be out of date and, as we've seen, even source code may not be quite what it seems. In fact, what hindered me in resolving the calendaring problem was that I failed to recognize the extent of the system I was working with - namely that it included the development environment.


PIMp my calendar, part 5

The self-hosted calendaring solution I had been trying to set up turned out not to work due to an incompatibility between my Android phone and the CalDAV client I tried to run on it. My options at this point consisted of

  1. upgrading the firmware in my phone to Ice Cream Sandwich or higher
  2. buying a new phone
  3. porting the CalDAV Adapter to the unofficial and unsupported APIs
  4. choosing a different calendaring solution

My handset is a Geeksphone One - a sturdy little machine well supported by Cyanogen Mod yet simply too weak to handle anything beyond 2.3.x. It's condemned to stay in the Gingerbread zombie army until I retire it. Buying a new phone is plausible in the mid- to long-term but I do want a slide-out QWERTY keyboard. Looks like I'll have to overcome my allergy to Sony.

I looked into back-porting the CalDAV adapter to the unofficial APIs available in Gingerbread. It seemed like a ton of work with dubious benefits - especially when I found out the work had already been done. You see, the adapter I'd been working with (written by Gérald Garcia) was not the only one I'd found - there is also another adapter written by Marten Gajda which I hadn't considered since it isn't distributed as open-source. It does work under Gingerbread, however, which made a proper impression on me given everything I knew at this stage.

I ended up doing something I hadn't done in years - I purchased and installed a piece of closed-source software. One thing that convinced me was Marten's website which is simple and sticks to the point; the same can be said of the software. Unfortunately, even with a bona-fide polished product on the Android side it wasn't smooth sailing. I had a Radicale instance installed on my notebook for debugging and it talked to the adapter just fine - unlike the home server. Both were running Radicale 0.7 by this point so I compared their OS-specific patches (using apt-get src on my Debian notebook and the ports tree on the OpenBSD home server). One of the Debian patches added automatic creation of calendars which was lacking in the OpenBSD version (this functionality is mentioned in current Radicale documentation but that supposedly refers to 0.7.1; the experiment with Mozilla Lightning in part 3 had worked because the Debian version was involved). Porting the patch and installing from ports was a matter of minutes. After that, everything worked like a charm.


PIMp my calendar, part 4

Previous parts of the saga brought me to a point where I had an upgraded instance of the Radicale CalDAV server talking to my Android phone's CalDAV adapter and still getting nowhere. I decided to debug the Android-side code.

Attaching the debugger was a bit of a trick since the adapter has no Activity. Once I got past that, I discovered the response from Radicale was getting parsed just fine but it was only happening in an authentication context (i.e. while adding the new "CalDAV account"). I generally found that the adapter was basically a bunch of callbacks and I seemed unable to properly trigger them.

I then noticed something funny in the log (i.e. the LogCat view in the DDMS perspective in Eclipse):

VFY: unable to resolve static field 27 (CONTENT_URI) in Landroid/provider/CalendarContract$Events;

According to the documentation, Events.CONTENT_URI is one of the basic constants used when working with calendars - how could it be missing? The question led to a quick series of discoveries:

  • My phone runs Android 2.3.7 a.k.a. Gingerbread (well, not really a discovery for me but a key piece of the puzzle).
  • Proper support for non-Google calendars was only added in version 4.0 a.k.a. Ice Cream Sandwich; what there was before was unofficial and unsupported.
  • The CalDAV Adapter project lists API level 14 (Ice Cream Sandwich) as the minimum required API level in its Android manifest.
  • Back when I first tried to run the CalDAV adapter, Eclipse ADT had told me I had no compatible device; I tried modifying the manifest, changing the minimum API level to 10 (Gingerbread).
  • Changing the minimum API level of an Android project doesn't trigger a re-build in Eclipse ADT; changing the target API level does trigger a re-build.
  • Once prompted to re-build the project, ADT flags usage of higher-than-minimum-level APIs as an error, breaking the build.
  • When Dalvik encounters unknown API usage while executing the code, it marks the block where the API was used as dead code and moves on.

So I was trying to use an application that was incompatible with my handset and both the development environment and the runtime responded with silent failures. I think ADT in particular behaved quite impolitely. If using APIs beyond the minimum level is off-limits then changing the minimum level should trigger a re-build, right? As for the Android runtime, the documentation says

...the application will crash during runtime when attempting to access the unavailable APIs.

which seems to be false (or at least no indication of a crash reaches the user). In any case, the approach I'd been taking turned out to be a dead end. Continued in part 5.


PIMp my calendar, part 3

My efforts to put a server-backed calendar on my Android phone entered a new phase. I had Radicale on the server and the CalDAV adapater on the phone but they seemed to talk past each other. My phone would set up a CalDAV account successfully but then tell me "You have no calendar" when I tried to create events.

Radicale documentation says calendars are created automagically based on a URL convention, i.e. simply accessing a non-existent calendar should bring it into existence. I tried it with the Mozilla Lightning client and it worked as advertised. The Android adapter, however, still wouldn't see the new calendar nor its events.

WireShark revealed that a CalDAV client apparently enjoys a lot of freedom when formulating requests. A PROPFIND request from Lightning looked like this:

<D:propfind xmlns:D="DAV:"
    xmlns:CS="http://calendarserver.org/ns/"
    xmlns:C="urn:ietf:params:xml:ns:caldav">
  <D:prop>
    <D:resourcetype/>
    <D:owner/>
    <D:supported-report-set/>
    <C:supported-calendar-component-set/>
    <CS:getctag/>
  </D:prop>
</D:propfind>

whereas the Android adapter was sending

<d:propfind xmlns:d="DAV:"
    xmlns:c="urn:ietf:params:xml:ns:caldav"
    xmlns:cs="http://calendarserver.org/ns/"
    xmlns:ic="http://apple.com/ns/ical/">
  <d:prop>
    <d:displayname />
    <d:resourcetype />
    <cs:getctag />
  </d:prop>
</d:propfind>

and it seemed Radicale was not happy with the displayname bit:

...
<propstat>
  <prop>
    <displayname />
  </prop>
  <status>HTTP/1.1 404 Not Found</status>
</propstat>
...

Server-side source code revealed that Radicale returns 404 for properties which it does not recognize (see the final else in the long if-elif chain in _propfind_response() in xmlutils.py). My installed version of Radicale was 0.7. I downloaded the most recent stable release (0.7.1) from the project site and tried that instead. Lo and behold, it finally said

<multistatus xmlns="DAV:"
    xmlns:C="urn:ietf:params:xml:ns:caldav"
    xmlns:CS="http://calendarserver.org/ns/">
  <response>
    <href>/jh/calendar/</href>
    <propstat>
      <prop>
        <displayname>calendar</displayname>
        <resourcetype>
          <C:calendar />
          <collection />
        </resourcetype>
        <CS:getctag>"0"</CS:getctag>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
</multistatus>

The Calendar app on my phone, however, still insisted I had no calendar. Continued in part 4.


PIMp my calendar, part 2

My effort to set up a self-hosted calendaring solution is taking on epic proportions, turning into another CUPS saga:

  • I quickly discarded the local iCal option because I can't trust a piece of closed-source freeware from someone calling themselves "Khaos".
  • The Kolab connector dropped out of the race because Kolab itself has complex dependencies and no OpenBSD package.
  • Zafara just felt too heavy-weight and, well, corporate for my needs.

I decided to concentrate on CalDAV servers with existing OpenBSD packages: DAVical, ownCloud, Radicale and SabreDAV. All except Radicale were PHP-based which made my decision easy as I'm allergic to PHP. I have to admit, though, ownCloud looks mighty fine and seems to have a lot of momentum.

Radicale has a no-nonsense, focused feel. It is written in Python which is very nice indeed. Installing it was a breeze. I then tried to set up a calendar in Kontact and failed miserably. CalDAV support in Akonadi is apparently confined to a legacy KResource implementation and blah blah blah. I had no stamina to go there. What was important was my phone.

Installing Gérald Garcia's open-source AndroidCaldavSyncAdapater via Google Play would have been a snap. The thing is, just as I don't want Google knowing about my appointments I don't want it knowing what I run on my phone. Don't get me wrong - I'm quite fond of Google. I'm simply more fond of my privacy.

Installing the adapter from GitHub turned out to be quite smooth. Once I cloned the repository I found out the project relied on the ADT Eclipse plugin for building and signing the installation package - no trouble there. I had a bit of fun getting ADT to see my phone because I made a typo in the udev rule file. I figured it out eventually and got the package onto the phone.

Adding a Radicale account on Android involved going to Settings > Accounts & sync > Add account > CalDAV Sync Adapter and filling out my user name, password and the URL. Excited, I opened the calendar application. No nagging about MS Exchange - great. Alas, when I tried to create an event I was told "You have no calendars." Continued in part 3.


« Page 1 / 4 »
Proudly powered by Pelican, which takes great advantage of Python.