I’ve been playing for a while with Evernote and their API, which I find rather simple and effective (well done, guys!) — and as such on a few pet projects I have started considering moving the storage to Evernote itself. The beauty of using Evernote is that the storage is already structured for you in an XML document, with a syntax which looks a bit like HTML — that means that you can parse it as you would with any XML document, but also you can use occasionally a HTML parser to achieve the same!
One of the areas where I started considering Evernote is storing lists — if you look at your apps, I’m sure that every now and then you find the need to simply store some form of lists, and in such cases a lot of times we end up re-inventing the wheel, using TEXT
fields in MySQL, plain text files in S3 and all sorts, all of which needing coding, maintenance and so on. Rather than doing that, I thought instead of using a dedicated service like Evernote and more recently UbiquiList. UbiquiList, as it turns out, is actually specifically designed to deal with just lists — and it’s growing rapidly into a nice tool for that! I’ve spoken to Ian too (the coder behind UbiquiList) and as I understand they’re working on a REST API for it, so expect soon a new post in these series about using UbiquiList for the same; meanwhile though I’m only going to touch on using Evernote for the purpose of storing lists in this article.
So, the idea is simple: you need to store a list of “things” for your user — nothing fancy, just a random list of strings, for the purpose of your app. You can of course use a simple TEXT
field in MySQL, and make the convention that each line is an item in your list….Unless of course your strings contain new line characters, which you might have to escape… Or switch to something like XML… And maybe these are getting now bigger and growing the size of your database unwantingly …. So let’s move it to S3… And you can see how this simple problem can spiral quickly to a complex one! Or you can use Evernote 🙂
The rational behind it is simple — we move all the retrieving and saving to Evernote in exchange for a very simple API, where we just retrieve a note and its content. To retrieve the items in the list, knowing that Evernote uses its own markup similar to HTML, we’d be just simply parsing the content and look for <li>
elements only — inside those are our list items.
Now you can argue that parsing XML and traversing it can be a still daunting task in Java — but here’s a little trick: use JSoup! JSoup allows you to use a JQuery like expression to retrieve the elements you want from a document, which means that our code for retrieving our list items becomes something as simple as this (look at the App.java file, in extractListItems
function):
String content = noteStore.getNoteContent(note.getGuid()); Document doc = Jsoup.parse(content); Elements el = doc.select(PATH_LIST_ITEM); |
From there on, you can interpret these items whichever way you want and treat them as separate list items, without the headaches of escaping new lines, storing and retrieving from S3 and so on.
A few notes on this (very very simple) app:
- as per usual, the code for it is in GitHub: https://github.com/liviutudor/EvernoteTestList , it’s mavenized and it relies on the Evernote API as well as JSoup (the only other dependency is JUnit for unit testing).
- by default, the code uses the Sandbox Evernote environment — however, change the
SERVICE
constant in App.java to point it toPRODUCTION
if you are willing to run this against your own live Evernote account - in order to run it, you will need a developer token from Evernote — you need to save this in a file called
.evernotetestlist
in your home directory as the app will be looking for this on startup and reading the token from there. - For the purpose of my testing, I have used this sandbox note: https://sandbox.evernote.com/shard/s1/sh/fc1e6790-b901-4234-ae70-83294c4d9487/d47178851d453bc014bc6febfe4df036 which looks like this:
As such, when running the app, it will select only the following items and interpret them as list items:
Select notebook 0 ) liviutudor's notebook [05ed7e85-b26e-4be5-9411-81a6ab629f65] 0 Select note 0 ) Getting Started [31097cab-50d8-4380-bff6-01b6c904e668] 1 ) Test List [fc1e6790-b901-4234-ae70-83294c4d9487] 1 LIST ITEMS * but this is * and so is this * like this * and this
As you can see, the app simply merges ALL list items into one big list, however, there is nothing to say you cannot change the code to support multiple lists, or indeed change the storage to use a different tag (<div>? <ul> ? <ol>?)
I’ll hopefully come back soon with a follow-up on using a 3rd party to store lists in an app based on UbiquiList.