TaskWarrior on Android

TaskWarrior is my tool of choice to manage my list of next actions. I like it because the data is as open as it can be: it is stored as plain-text, there are many different tools to access it and TaskWarrior itself is open source. To access the same data on different devices, an easy solution is, to just copy the TaskWarrior database over to the other devices. Software like OwnCloud, Dropbox or Super Flexible File Synchronizer (this is not a recommendation) can help automate the process. With the configuration variable data.location one can control, which folder TaskWarrior uses to read and write the data and as long as you don't go crazy and execute TaskWarrior faster then you sync, everything works quite well (in case you end up with conflicts you could always use the merge command and hope for the best).

A very important use case, that was not easy to cover with this was my smartphone: My solution always was, to SSH to a server, where TaskWarrior is installed and use it there. But since I seem to be one of very very few people in the world, that would prefer a hardware QWERTY keyboard on their smartphone, there are no decent options, that make SSH user friendly enough to use it on a daily basis (yes, I tried stuff like this but quickly ran out of hands to handle it on the bus).

Finally, Konstantin Vorobyev took pity and wrote a TaskWarrior app for the Android Platform! He made the awesome design choice to not read and parse the database himself but package the TaskWarrior binary with his app and just build a GUI around it. So one should expect pretty similar behavior and it should have also reduced development time immensely (or in other words: freed up time for stuff, that can be of better use then reimplementing TaskWarrior in Java).

The app uses the synchronization integrated into TaskWarrior to synchronize with servers running the "Taskserver" taskd developed by the same people and described as "a lightweight, secure server providing multi-user, multi-client access to task data" on their website. I run a small virtualized home server and set up a dedicated Debian installation for Taskserver. The idea was, that all my devices (including my phone) can synchronize with this server, when I am connected to my home network. TaskWarrior can be used to synchronize with such a server with the command task sync and the Android app has a refresh button (and probably does it regularly). The most recent version of taskd as of this writing is 1.1.0 and its installation went quite smoothly (I felt adventurous and decided to go for "Option 3: Install from git"). Taskserver uses client side certificates for authentication, but if you follow the installation instructions carefully, you shouldn't need a deep understanding of PKIs and certificates. One should pay attention to the hostname CN, but I'll come back to this in a minute.

The first hurdle was my Windows system and the fact, that the installed version TaskWarrior (2.5.0) was not compiled with TLS support. Pulling the source and doing cmake, make, make didn't work because some function definition was missing from some header file. Passing -DHAVE_GET_CURRENT_DIR_NAME=0 to the cmake call did the trick (it was sheer luck, that I stumbled upon the correct line of C code and noticed the preprocessor macro). Running task diagnostic | grep tls now tells me, that I use libgnutls in version 3.3.17.

Now let's come back to the server name: The hostname of the virtual server is office. If you choose localhost as a server name (which is totally stupid and I have no idea, who might even try this *cough*), taskd doesn't bind to the correct network interface and is only reachable from the machine itself. Choosing office as the CN and in all configuration variables (note, that the values need to be exactly the same for the TaskWarrior client task and the Taskserver taskd), it binds to the address 127.0.1.1 (sic) which seems to be just another notion of localhost and still is not reachable from the network. Using office.fritz.box finally did the trick. The whole process took some time because you need the generate all keys and certificates (for both server and clients) again. Unrelated side note: you have to restart taskd after changing certificates.

The following commands are your friends while debugging:
* netstat tulpen | grep 53589
* nmap -sS -O -p53589 office
* taskd config debug.tls 3

You need 4 things to authenticate at the server:
* server certificate ca.cert.pem
* client side certificate first_last.cert.pem
* client key file first_last.key.pem
* UUID of the user

After setting the following configuration variables correctly, task sync worked for me (and is pretty fast):

taskd.certificate=/path/to/first_last.cert.pem
taskd.key=/path/to/first_last.key.pem
taskd.ca=/path/to/ca.cert.pem
taskd.server=office.fritz.box:53589
taskd.credentials=OrgName/first_last/01234567-89abc-cdef-0123-456789abcdef

TaskWarrior now also tells you, when you need to execute the sync.

The configuration page of the Android App for TaskWarrior was pretty useful. A small remark to save your time: The recommended way of placing the necessary files in the profile folder works perfectly, but you should *not* place them in the data directory underneath the profile folder but in the profile folder directly.

Good luck and @TaskWarrior: thanks for all the fish!

Comment on this article

Readable Git Annex Unused

So unless you know and use git annex, this is not going to be very useful for you. Check it out, though. It's pretty cool. Unless you are on Windows. In that case it's hell. Anyway, I wrote a script to help me figure out the output of git annex unused. In short, it tells you what those files used to be called before you lost them. Script:

#!/usr/local/bin/python3.5
import re, sys, os
from subprocess import Popen,PIPE
FNULL = open(os.devnull, 'w')

def seeker(s):
  process = Popen(["git", "log", "--stat", "-S", s], stderr=FNULL, stdout=PIPE)
  log = process.stdout.read().decode("utf-8")
  match = re.search(r"(([ -~]*\/)*[ -~]*)\|", log)
  if not match: return ''
  else: return match.group(1).strip()

if len(sys.argv)>1:
  print( seeker(sys.argv[1]) )
else:
  clist = []
  while True:
    crawl = input().strip()
    if not crawl: break
    crawl = crawl.split()
    clist.append(crawl)
  for x in clist:
    print('%s : %s' % ( x[0], seeker(x[1]) ) )

You can either call it with one argument which should be a key, or if you call it with no argument, it expects you to paste the list of results you got from git annex unused into stdin. It then goes through the list and tells you the corresponding filename for each key.

This script is phenomenally stupid in that it does quite a terrible regular expression search on the output of git log and returns the first match it finds. Sue me, it works pretty well at my end.

Comment on this article

Batch edit your PuTTY Sessions

The color that PuTTY uses for blue is simply too dark. The scrollback buffer, by default, is 200 lines. That's ridiculous, I have several gigabytes of RAM going to waste here. In case you have a lot of stored sessions, it's quite tiresome to use PuTTY to go through all of them and fix whatever settings you would like to change. You can edit them directly in the registry, though - or use this Python 3 script!

from winreg import OpenKey, EnumKey, QueryValueEx, SetValueEx, \
  KEY_WRITE, KEY_READ, HKEY_CURRENT_USER as HKCU

class callrange:      
    def __init__(self, call_function):
        self.call = call_function
    def __getitem__(self,index):
        try: return self.call(index)
        except OSError: raise IndexError

with OpenKey(HKCU,"SOFTWARE\SimonTatham\PuTTY\Sessions") as sessions:
    for s in callrange(lambda i: EnumKey(sessions,i)):
        with OpenKey(sessions,s,access=KEY_WRITE|KEY_READ) as key:
            for name,value in [
                ('Colour14','100,100,250'),
                ('Colour15','120,120,250'),
                ('TerminalType','xterm'),
                ('ScrollbackLines',6000)
            ]:
                type = QueryValueEx(key,name)[1]
                SetValueEx(key,name,0,type,value)

By the way, searching the tubes reveals some useful suggestions to improve PuTTY's default settings.

Comment on this article

Finally get rid of Camera Roll

Ever since I started using Windows 10, it has been creating folders called "Camera Roll" and "Saved Pictures" in the "My Pictures" folder. It was the last straw. Applications had been creating subdirectories in the "My Documents" folder for ages now. Not again. The line must be drawn here. This far, no further. And I will make them pay for what they've done!

Do you want to know more?

5 Comments

Disable the Windows 8 / 10 lock screen

Are you also annoyed with the Windows lock screen? You know, the one you must swipe or click away before you can enter your login data. The one that doesn't even respond to shift anymore since Windows 10.

It can be disabled as follows:

  1. Open the Group Policy Editor. Either
    • press Win+R and run gpedit or, if you don't have gpedit.msc,
    • open the Microsoft Management Console by pressing Win+R and entering mmc. Go to File -> Add/Remove Snap-In, select the Group Policy Object Editor, press Add, Finish and OK. Expand the Local Computer Policy.
  2. Navigate to
    • Computer Configuration
    • Administrative Templates
    • Control Panel
    • Personalization,

    edit Do not display the lock screen and set it to Enabled.

Comment on this article

Protect your Android and still enjoy it

Just recently, the latest CyanogenMod nightly began supporting encryption on my phone, even though the bugreport still says it's an open issue. I don't mind. Anyway, this allowed me to finish a major project of mine: Protect the data on my phone, even in the case of a theft, while maintaining the ability to use the device conveniently.

The goal. I want a strong disk encryption password, but i want a weak screen password or PIN, because unlocking the device is a frequent task. In such a scenario, it makes sense to implement an account lockout policy: In other words, we want the phone to shut down after, say, 3 failed attempts to unlock the screen. This prevents the screen password from being brute forced.

Your device needs to be rooted to do everything I did. You will also need the Android studio if you want to do this properly, and it's a large download, you might as well start now. Click here if you're still interested.

3 Comments