witter-6916811 (logo courtesy of @mece66)
I’m developing a twitter client for maemo. Yes I know there already is one. But I felt like writing my own, from scratch, and rather stupidly not just using nicely existing twitter libraries etc (note this *was* the case, but from 0.2.1 I have started to make use of those libraries so I can focus on other stuff I want to learn. no one wants to learn oauth from scratch..trust me). This is an education exercise.

There is now a maemo downloads page for Witter now that it is in the Extras repository.

From now on I’m going to keep adding new version info above old version info, rather than revise everything to keep up to date. I’m also trying to keep a reasonable record of how much time it takes for any given feature/update. Although I’m excluding all the time it take to build/package/upload test a given release. which can vary but takes about an hour per release

If you like Witter, and would like to show your appreciation, there is a button in the top right which will let you buy me a pint.

NOTE If something fails unexpectedly, please start witter from the xterm:

run-standalone.sh python2.5 /opt/witter/witter.py

This will output lots of diagnostic messages that will help me understand what I broke 😉 Also be sure to tell me which version you are using, it can change rapidly, and there are normally at least 2 available at a given time.

0.3.5-4 -> 0.3.7-2 – I’ve been pretty bad at keeping this up to date, I did a lot of work in extras-devel, and a big re-write which I didn’t want to draw too much attention to, since it was pretty unstable for a while. I’ve now pushed 0.3.7-2 to extras-testing to get broader feedback. The UI has an all new layout, There is now a ‘home’ screen which shows your profile info, from which you can toggle location sharing on/off, and jump to normal timeline, search stuff, contacts. All views how support a ctrl+up, ctrl+down to scroll to top/ bottom respectively. location can be enabled to share your location in a tweet. it is also understood in other peoples tweets so it will show their location if available. The new search view loads your saved search terms and makes a button for each one.

There is probably loads of other stuff. I’m currently aware of a defect in the contact loading if you have more than 100 contacts. will look at fixing that shortly.

Oh, and fetching tweets/mentions and profile info all have a retry loop that after any failure waits 1 second, then tries again. This hopefully smooths out a lot of the transitory type errors that you get with network blips.

0.3.5-3 – a collection of small fixes

0.3.5-2 – some fixes to remove stuff from package that shouldn’t have been there. some extra error catching code around config loading and checking for theme existence

0.3.5-1 – Allows fixing of rotation mode in either portrait or landscape in addition to auto mode. Adds some error handling for ‘bad status line’ errors from the httplib. Adds ability to scroll through tweets using up and down arrow (landscape mode). Now requests up to 200 tweets since the last received tweet. (I thought using ‘since_id’ would basically do that anyway, but apparently it still defaults to 20…which doesn’t make sense to me, but there you go)

0.3.4-8 – Update to touch theme icon to fix stretching in the user history icon. Fix to persisting gestures settings now that you can also persist notification choice. Witter not checks if it already received a tweet and doesn’t add duplicates. this allows the search view to retain history when you refresh to get more tweets, and means you can change search strings and pull new stuff on top of the already received results

0.3.4-6, 0.3.4-7 – fixing the oauth configuration dialogs that I broke a few versions back. Also added configuration to allow users to switch off the e-mail style notifications.

0.3.4-3,0.3.4-4,0.3.4-5 – I’ll treat these together as there were a very quick succession of little tweaks, after updating to PR1.2 on my n900 py2deb got re-broken and my bug tracker link was failing in the package. So that was fixed, update the version number to report at 0.3.4, and thanks to some hints provided by others, the on screen keyboard in portrait mode now pops up when you tap in the entry field, and disappears if you scroll. Also the buttons are now even sizes rather than relative to the letter size.

0.3.4-2 – Just a packaging update to include the dependency on python-dbus which was causing witter to fail to start for some people.

0.3.4-1 Implemented first pass at portrait keyboard accessed via plus button in portrait mode.

0.3.3-10 – fixed problem starting if avatar not cached to disk.

0.3.3-9 fixed problem persisting tweets with newlines in them. WARNING: need to delete /home/user/.wittertl .wittermen and .witterdm if witter isn’t starting

0.3.3-8 – added new style retweet under ‘RT’ action button as opposed to old style retweet

0.3.3-7 – adds ability to switch of swipe gestures in preferences (some people find they accidentally switch timeline views too easily) also added a locale setting on the hope it might fix some peoples timestamp problems. Initial support for starting a connection if none exists, currently it starts, but not before witter fails the connection is was trying. not sure yet how to make witter wait for active connection

0.3.3-5 & 0.3.3-6 – added support to persist timeline/mentions/dms, stores the last 20 in each of these and reloads them when you start again.

0.3.3-4 – full auto-rotation support, no longer need to hit ctrl+shift+r, icons are resized to fit in portrait. new theme ‘touch’ courtesy of biggzy on t.m.o.



Whilst I’m adding images, here is the monochrome theme



0.3.3-3 – fixing defensive code around avatar loading, loading retweets in timeline, fixing load more mentions. put following a user on a thread, so their tweets can be loaded into current timeline

0.3.3-2 – defensive code for corrupted avatars, tweak column width in portrait mode for pr1.2, grab users last 20 tweets when following.

0.3.3-1 – witter now remembers the last tweet and only loads new ones between runs. also mentions/dms get better notifications.

Notifications took ages to figure out, the documentation and examples are non existent. Currently you get notifications for mentions and dms, that vibrate and leave a persistant yellow notification like an e-mail. They also start the led flashing blue. currently no sounds. And all other timelines are as before.

This version also saves the last id received for main timeline, mentions and dms. On reloading witter it will only receive new tweets (rather than always just loading the last 20) In the future I may locally save the last few tweets to restore, so that the interface doesn’t come up blank if nothing new has happened.

0.3.2-4 – fixed a few random things, username parsing, option for refresh interval of 1 min

0.3.2-3 – added basic ability to favorite a tweet.

0.3.2-2 – added some diagnostics and failsafe code around timestamp processing added some diagnostics and fail safe code around timestamp processing


I realised in investigating the issues brought up by 0.3.2-0 that I had previously been sorting twitter id as a string rather than a long. This had been working well enough to throw me off, but having odd results for some tweets and people that meant the sorted went off. Having noticed this I have now fixed it to store the long ids as floats (because for some reason using a long in the liststore still didn’t like being given a long) This appears to be working

Also fixed sort order for the friends view to be alphabetical by friend name.

total time: 3 hours of painful ‘value not valid for column’ messages trying to put a long into a long column…what a fool, I should have realised I had  to store longs in a float column.


I switched the sorting to be based on the parsed timestamps rather than the twitter id, this appeared to work, but failed to sort newly arriving tweets into the correct order at all. It also broke a few people from using witter at all.


Added ‘theme’ support, or at least the ability to support different icon sets. Anyone can now create a set of icons under /opt/witter/icons/<name_of_theme>/

and it will become available for selection in the witter preferences section under theme.

Basically a ‘theme’ is a set of 48×48 icons with the following names:


the names should make it reasonably obvious what the icon should portray. Such icons sets could be packaged and installable independent of witter itself, they just need to place the files in the right location.


Minor fix that stopped first time users getting set up properly.


The buttons that were generated for each mentioned user, could sometimes make for a very crowded and difficult to read actions panel. If there were more than about 4 people. the buttons would go off the screen and generally not look right. This version puts all those options in a second sub window of the actions window, under a ‘mentioned users’ button. The layout is more obvious and should scale better to large numbers of mentioned users.


fixed switching accounts in views other than timeline. added diagnostics after account edit. fixed account delete. fixed failed tweet notification


fixed twitpic, added more debug for tweeting


put guard against avatar urls containing non-ASCII chars, a the moment htis just means Witter doesn’t fail, currently it doesn’t successfully load avatars if the url has non-ASCII chars,

Also put a minor tweak to turn &amp; esacaping back into & in tweets


Fixed replyall to not exclude the sender of the tweet, and make sure it cleared before building new reply all string.

updated twitter oauth to fix follow/unfollow problem, which was actually a broader problem about using GET on every request


Added @user button to action set, also added a ‘translate’ option that opens google translate in a browser passing through the tweet text. At the moment it is hardcoded to translate from auto to English. At some point I might make this configurable so you can choose your own language to translate.

Timespent about 1 hour


managed to miss ReTweet when I moved actions to a stackable window, this just adds it back in


faster than I though, I switched the action buttons when you double click a tweet to arriving on a stacked window rather than overlaid buttons.

time taken: 30 mins


ok, so after about 4 months of saying I wasn’t going to, and generally complaining about the amount of time and effort it would involve. Here at last is avatar support.


Additionally I’ve made the 140 limit a ‘soft’ limit so that you can go over if you like. twitter should truncate as it sees fit, but it might help in editing a tweet to be able to go over.

This release took me about 9 hours. Initial avatar support probably only took about 30 mins of direct coding, but coming up with a strategy for caching images and reloading etc, took a fair amount longer. plus all the reading and fixing of other problems.

Avatars are loaded once when it first sees someone. Then again every 10 times it loads a tweet from an individual. The idea is the more you see tweets from someone, the more up to date their avatar will be.

I also fixed the oauth configuration after a bug introduced by adding multi-account support.


For this release I’ve bumped up to 0.3, as I’ve done a massive restructuring job. Moving away from the monolithic code base it was, to a (slightly) better set of ui/controller/account classes which hopefully paves the way for me to try switching out UI components a little easier. In this release what it has let me do is enable…

Multi-account support – You can now create multiple accounts, with twitter/identi.ca or any other twitter compatible service. And switch between them. Currently they are managed very separately. You simply go and choose to ‘activate’ the one you want to work with.

This release has taken many hours, I’m guesstimating 30 hours at least. Many of which sadly were going down dead ends. I had hoped to use pickle to simplify my persistance of account info, but I just couldn’t make it work.

For the average person there is no reason to upgrade to this version, and plenty of reasons to hold back. So much has changed I can’t be sure I’ve not broken something subtly. So if you are not interested in muti-accounts, then probably safer to steer clear for the moment.


Switched the way bit.ly url expanding words, instead of replacing the bit.ly short url with the expanded form in the tweet, now it expands the url and pulls out the domain name, which it puts in brackets after the bit.ly url, eg:

this is a cool url http://bit.ly/fh4£hfdv  (www.google.com) good for finding stuff

There is also code to remove the expanded info when you hit retweet. I think this is a better system than the first version.

also contains some sundry fixing

time spent: approx 2 hours


Bit.ly support – under preferences it is possible to specify a bit.ly uid and api_key which then allows witter to do 2 things. Firstly if it sees a url of the form http://bit.ly/something then it will automatically call bit.ly to expand the URL (I’ve not decided whether to leave it this way, but I generally don’t like clicking on shortened URLs if I have no idea what they lead to. So I want some mechanism to preview the real URL.

Secondly there is a new menu option called ‘shorten url’ which brings up a window that lets you paste a URL into an entry field and hit a ‘shorten url’ button. This gets bit.ly to shorten the url and pastes the result into the normal tweet entry field.

Combine the bit.ly support took about 4 hours to add. I am making use of a cut of a python-bit.ly library that already existed, but that code is fairly simple. At some point I may investigate whether I can get an id with bi.ly that would allow witter to use it, without the individual users having to have an id.

Additional I re factored the whole preferences dialog into a stackable window, and changes all the number editors to touch selectors for refresh rates. This allowed me to add the bit.ly credentials and a place holder for some kind of theme support. It should bemuch easier to add extra configuration to this section now. I’ll probably end up moving the colour tweaking into this preferences page also. But haven’t gotten around to it yet. This refactoring took about 4 hours.


With many thanks to pycage, author of the very cool mediabox. Witter now can ‘zoom’ in and out. That is the font size can be increased and decreased dynamically by using the rocker button on top of the N900. It was not at all obvious how to do this and I spent *hours* looking through documentation and google trying to find what I needed. Until I realised that mediabox was also python and was clearly capturing the zoom buttons. pycage was kind enough to paste the relevant piece of code into a response on t.m.o for me. And with that it took about 30 mins to implement, test and figure out forcing a redraw.


Doh!, turns out I was obviously tired when I uploaded 0.2.2-2 and I had a mismatch between the code and the gtkbuilder .ui file. This caused witter not to start up at all.

0.2.2-3 fixed this issue.

0.2.2-2 – broken – see above

Lots of people were complaining that they didn’t like the blue background, so I decided to implement the ability to configure it. Currently it’s fairly ugly in the sense that there are 2 buttons in the menu, BgColour_top and BgColour_bottom

each of these takes you to a colour picker which itself seems to work a bit weirdly, you have to set a colour in the empty palate section, and which ever one is selected when you hit ‘ok’ is set as the colour for either the top or bottom of background gradient.It took me about 2 hours to implement this, it’s unlikely to be made a great deal easier or nicer to do, since it’s not something I expect to do often.

Colour changes are persisted so you won’t lose them when witter closes.

Whilst I was at it I persisted the font size. I had hoped to be able to use the volume/zoom rocker button to allow font to be increased/decreased. However I cannot for the life of me figure out where to hook onto those events. So for the moment it ends up as a new value in the config file.

After running this version once, and closing. go look in /home/user/.witter

It contains the colours and the font size, so you can just adjust them there.

Overall this version took me about 4 hours including time wasted looking for information I couldn’t find about hardware zoom buttons


Lots went into this one so I figured I’d up the .1 to a .2

Icons! – All the views now have icons associated instead of words on buttons. Each icon for a view has an on state and an off state, so you should be able to tell which view you’re in by the active icon.

I used inkscape to do all y own icons. I am not a designer so they’re not that good. However I’m hopeful that someone that *is* a good designer can easily make a set of icons of the right names and it will be a drop in replacement.

The icon names are:

dismiss.png – used to allow action menu buttons to be hidden again

dm.png – the active state of direct message view button

dm_off.png – the inactive state of the dm view button

friends.png – active state of friends view button

friends_off.png – inactive state of friends view button

(you get the idea)

mention.png, mention_off.png, timeline.png, timeline_off.png, public.png, public_off.png, trends.png, trends_off.png, userHistory.png, userHistory_off.png

fullscr.png – switch to fiull screen

unfullscr.png – switch out of full screen

tweet.png – send a tweet

refresh.png – refresh

plus.png – open buttons for fetching additional(older) tweets

minus.png – close buttons for fetching additional tweets

plus20.png, plus50.png, plus100.png, plus200.png – fetch an additional number of older tweets as indicated by number.


All tweets now show the ‘From <source>’ text next to the timestamp

New UserHistory view – In this view you can enter a username in the entry box and hit the refresh button and it will go and find the last 20 tweets by that user. Alternatively you can double tap any tweet and it will provide a History button for every user mentioned in the tweet, clicking those will take yout to the user history view and load up the users tweets.

New ReplyAll button – just inserts all the usernames found in the selected tweet into the entry field with spaces between them

@ user buttons, – for any user mentioned including the author you get a button which just fills their name in the entry field. This is different to reply_to since it does not link your tweet to the one selected.

Get older tweets! – in the main timeline (only here at the moment) if you want to go back and get more older tweets, hit that + symbol in the top icon bar, and you get a pop up with +20, +50, +100, +200, these do as you might imaging, fetching tweets older than the oldest one currently loaded. up to the number requested.

Notes– This version comes with it’s own verison of the python-twitter library. It really ought to use the one that is available in the repos, but that is based on the last versioned release of python-twitter from jun’09, and I needed features that were introduced to the source after that. Ihave asked the python-twtter people to cut anohter update, but couldnt be bothered to wait. Also I made an additional fix to support max_id on an API they hadn’t added it to yet. Again I will contribute this in time, but I didnt want to wait for that to filter through.

Also, follow and unfollow both currently rely on having got basic auth settings configured. For some reason they seem to fail under oAuth using python-twitter, and I’ve not figured out why yet.

FullScreen/window – there is now a specific button to do true full screen, which drops the title bar stuff etc. Consequently i no longer have witter remove all controls when you scroll, so you should always have the top icon bar, this helps you see which view you’re in, and gives you access to the button to come out of full screen again.

removed trends/search buttons from main menu as now directly available through on screen buttons.

Removed follow for authors of tweets in your timeline, since you already follow them

removed unfollow for mentioned users. Tyring to save space and it seemed a less obvious use case.

Probably the most time consuming part of this version was the icons. I had to learn how to use inkscape and demonstrate my inability to draw. Then code all the additions of icons and make sure the state transition between on/off properly as you switch views etc. probably spent 6 hours or so drawing icons

Adding the user timeline was probably the single biggest change, but probably only took about 2 hours.

Getting the right set up of dynamically generated buttons when you double tap took about 2 hours, and may still be wrong. If you double tap on a tweet with lots of mentions then it will probably over stuff the view.

If anyone feels like doing a nicer set of icons, let me know. I may even look into some kind of theme management that would all you to switch easily between different icon sets. We shall see.


Changes – fixed a regression in the friend and trend view that cropped up when I fixed a problem with the difference between an automatic background refresh versus a manual refresh.

Time to develop: 15 mins


Changes – Changed the tap’n’hold menu for actions to be a double-tap which brings up a set of buttons. Hopefully this is much more finger friendly than the menu. When you double tap on a tweet, the buttons pop up, and the pannable area attempts to scroll to keep the tweet visible above the buttons. There seems to be a glitch with this if it’s the bottom tweet, but generally it seems to work. If there are URLs in the tweet, you dynamically get buttons to launch the URLs.

Time to develop : about 7 hours went into this restructure


Fixed a bug in the dmrefresh code that if activated stopped witter from exiting cleanly. – time to implement : 2 mins after a user sent me the logs of their problem

Also tried to force the icon to retain it’s transparency again.


Switched browser launching from using ‘webbrowser’ module to using osso context to run the osso_browser. Time to implement : 10min

Although launching URLs always worked fine for me, some people inexplicably could not get it to work. Frustratingly I narrowed it down to just one line of code calling the webbrowser module, which worked for me, but not for others. With no output or errors to go on I was stumped. But having found a new way to launch the browser I’ve switched to that, and early reports indicate this now works more reliably for everyone


Changes –

OAuth support-Time to implement..about 12 hours excluding all the investigation I did the first time around.

You can now grant witter authority to access your twitter account via OAuth, there are those that will tell you this is very important for security, and much better than handed an untrusted application your user/id password, in case they do something silly (like save it base64 encoded in a file where anyone might find it) However I can tell you that OAuth support in Witter is entirely about my vanity/ego. By using OAuth when you post to twitter it registers as from Witter, as opposed to simply from the API. It makes me feel good to see my tweets coming from my application.

Not all methods use OAuth at the moment, for some reason the python-twitter library doesn’t like following/unfollowing people via oauth, so this currently still uses the basic auth credentials until I can figure out why.

Also twitPic needs me to give it your twitter login to post pics. I may investigate alternatives that work nicely with oauth.

Busy indicator– time to implement, I daren’t figure out how many hours I spent trying to figure out how to do this, and failing to find a solution. Until mwerle, author of mwTube pointed me in the right direction. After which it took about 15 minutes to add the code.

This allows witter to show a little spinny thing to show you when it is busy doing something. this tiny simple thing provides a great deal of usability in terms of feedback from the interface.

Spurious fixes – thrown in with this release are a bunch of other checks and guards against errors I saw pop out whilst I was testing. Additionally i fyou press any key the tweetbox now grabs focus, since I was getting tired of finding I hit a key to bring the controls back on screen, then selected the entry box to type something.

—–historical information——

so in extras-testing under internet-network is now witter 0.1.1-2

in extras-devel is 0.2.0-1 which adds threads and auto-refresh of feeds.It also adds support for multiple search terms separated by commas. Search terms are stored/retrieve between sessions, so you can keep a number all refreshing at a set interval

so, what is it? it’s the modern day hello world..it’s yet another twitter client.

mostly written just to educate myself on how to go through the whole process of develop and release.

it’s not pretty. but it has some useful functions.

failings first…

It is only basic auth. it stores the credentials in a file in .witter

it does base64 encode the info, but this is not to be confused for security.

it does however use https so at least comms are encrypted

now for what it does do…


It obviously gets your timeline.

you can tweet!

if you write input you can also go to the menu and select twitpic, then go select an image. when you hit ‘twitPic!’ it will send the image and whatever text was in the tweet field.

when tweeting normally there is no real notification of errors in parsing etc. (except in the terminal) however if it fails to send, it will not blank the text you’ve entered. so if it goes blank, all is well (in theory). Also normal http errors will pop up in a dialog. not exactly friendly, but it won’t hide them.

it has a sort of ‘tabs’ ideas. it has the ‘timeline’ for your normal view.

it also has a mentions view, when you refresh it loads the last 20 mentions of you.

it has a direct messages view which loads last 20 views.

it also has ‘search’ in this view if you put a search term in the text field and hit refresh it will return the top 20 search results.

and friends view will load the first 100 friends (no paging support yet)

if you load friends, it uses that list to auto-complete when you @reply someone.


under the menu it also has a trends view which will let you refresh the current 10 trending topics

and a public view, which loads just the public timeline.

It supports auto-refresh on the main timeline, mentions, direct messages and public timeline. The properties tab allows you to individually configure the rate of refresh, or set to 0 for no auto-refresh.


if you tap-and hold on a tweet, you get a context menu which will let you launch and URLS from that tweet, and some options to follow or unfollow the user.

all this should work on the n810 and the n900

though the n810 version looks slightly different the kinetic scrolling is courtesy of mokoui library, but it’s not as nice as the hildon panable area.

it also supports ‘gestures’ so swiping left or right will switch views through thedifferent ones availiable.

when you start scrolling the controlls dissapear to give all the screen space to tweets. you can get controls back by pressing any key or by swiping to another view

see the Maemo garage witter project

The main difference since the early version is the custom cell renderer which makes it look more ‘pretty’ Basically I had to write code which would drawn the rectangles and the rounded corners, and then render the text inside.

Initially I made the mistake of using cairo to render text, since that is what I found first. However if you use cairo you actually have a much harder job than you need. You have to figure out how to render text by calculating it’s width, and cutting it into lines, and figuring out line placement etc. On top of all that you don’t get any rendering of non romanised fonts.

So after much digging I found out how to do the same with pango, using a cairopango context. With pango it ‘understands’ layout to an extent, so you can specify a wrap width, and tell it to word wrap so you don’t get words split on line boundaries. It also nicely renders non-romanised fonts as you can see here.