I am a big fan of GeekTool. For those not familiar, GeekTool is an OS X application that allows you to place “Geeklets” on your desktop. Geeklets come in 3 flavors: a file plugin to track the contents of a file, a shell plugin to run shell scripts and get the output, and an image plugin to load images. Each plugin has customization and layout options to allow you to create a dynamic desktop that is more useful, usable, and compelling than that picture of the Millennium Falcon you’ve been sporting for so long. The featured image for this post gives you a peek at my desktop. This portion shows date and time, an image plugin loading NASA’s Astronomy Picture of the Day, and local weather using code by Brett Terpstra.
I’m also a big fan of Wunderlist which, after much trial and error, became my to-do list app of choice. So when I created my desktop, I searched for a Geeklet to display my to-dos, and found this one. However, when they upgraded to version 3, they stopped using a SQLite database to store tasks and started storing them as JSON fragments. I could have used the file plugin to pull in the contents, but the schema was not that straightforward.
JSON to the desktop
I decided to reach out to the Wunderlist team to see if they had any suggestions and they gave me early access to their API, which is still in beta. However, it gave me a path forward to get the list of tasks to display on my desktop, and what I developed can be used for just about any OAuth 2 feed you might want to use.
The first step was to create an application in Wunderlist’s dev center, which was straight forward enough. This gave me the Client ID and Client Secret I needed to start the OAuth authentication process. I’ve been using PHP OAuth distributed at phpclasses.org to do a lot of OAuth work. It was simple enough to customize the code to include Wunderlist. While I’m still working on getting the web version to work completely, I was able to get far enough in the process to get the access token necessary to make calls to the app on my user’s behalf.
Next Step: cURL
Now that I had a Client ID and an Access Token, it was time to fire up terminal and get to work. In order to make a successful OAuth call to an API, you need to modify the header to include those items, and you do that with the -H option. So, the front end of the cURL call looks something like this:
curl -H "X-Access-Token: insert-access-token-here" -H "X-Client-ID: insert-client-id-here"
This gives you the ability to make calls to different API URLs. I made a call to the URL to get the list of lists I maintain on Wunderlist. This allowed me to get the list ID of the list I wanted to display on my desktop which was necessary to get the specific tasks I wanted. So, I added the URL to the tasks request and my call now looked like this:
curl -H "X-Access-Token: insert-access-token-here" -H "X-Client-ID: insert-client-id-here" https://a.wunderlist.com/api/vq/tasks?list_id=insert-list-id-here
And, voila! I could see the JSON for the tasks I was interested in. However, it was a little messy and more information than I needed.
The next step was to pretty up the output and limit it to just the information I needed. So, the first step was to pipe the output of the cURL call into a function that could help make it pretty. I decided on the Python json library to help. I used the json.tool call to make the results more readable by a human. The code now looked like this:
curl -H "X-Access-Token: insert-access-token-here" -H "X-Client-ID: insert-client-id-here" https://a.wunderlist.com/api/vq/tasks?list_id=insert-list-id-here | python -m json.tool
This gave me nicely formatted output, but much more information than I needed for my purposes. Enter grep. By piping the output from there to grep, it gave me the chance to only pull the lines that contained the task name (or, “title,” as it’s called in the JSON).
curl -H "X-Access-Token: insert-access-token-here" -H "X-Client-ID: insert-client-id-here" https://a.wunderlist.com/api/vq/tasks?list_id=insert-list-id-here | python -m json.tool | grep 'title'
This returned just the lines within the JSON output that contained the title, but they were still in key: value format. All I wanted was the actual text of the title.
That’s what she sed
The sed command was what I needed to strip away the extra info. First, to get rid of the “title”: text up front, I used: sed -e ‘s/”title”: “//g’. Then, I piped that into another sed command to remove the quotes and comma at the end using: sed -e ‘s/”,//g’. I’m sure a clever coder could have written a single sed command to accomplish both, but I was having a hard time doing so, so it was easier just to pipe them in sequence. So, the final script looked like this:
curl -H "X-Access-Token: insert-access-token-here" -H "X-Client-ID: insert-client-id-here" https://a.wunderlist.com/api/vq/tasks?list_id=insert-list-id-here | python -m json.tool | grep 'title' | sed -e 's/"title": "//g' | sed -e 's/",//g'
And that’s it. I placed that script into my Geeklet and formatted it to be pretty, and now I see my to-do list whenever I look at my desktop.
This specific example is only useful if you are a fan of both GeekTool and Wunderlist like I am, but this tactic should work for any OAuth-protected content returned as JSON that you want to get at via shell script.