The Unity Dash provides a lightweight, instant and easy means to browse and retrieve interesting content. Through the use of lenses, it enables the user to search for information both locally and remotely. In this article you’ll learn how to easily write a lens to comfortably search the Wikipedia right from your desktop.
To follow this tutorial, you’ll need the following:
- Ubuntu 12.04 LTS – get Ubuntu ›
- Quickly – install quickly ›
- Quickly Lens Template – install the Quickly Lens Template ›
Writing a Wikipedia Unity Lens
Making a lens begins with a simple step to set up the project. Fire up a terminal by pressing the Ctrl+Alt+T key combo, where you can type the commands below.
Create the project
quickly create unity-lens wikipedia cd wikipedia
Now, let’s code!
This command will open three files in your favourite editor, the one we are going to edit is __init__.py
The first interesting thing you can see here, is the Meta class. It defines the behaviour of the lens :
class Meta: name = 'Wikipedia' description = 'Wikipedia Lens' search_hint = 'Search Wikipedia' icon = 'wikipedia.svg' search_on_blank=True
Most of the time, when you make a simple lens, you don’t need to change anything here and in our case, we won’t.
A lens needs categories, which are used to visually separate different types of results. For Wikipedia, we only need one category, and we are going to name it “Articles”.
Below the Meta class, we see this line of code:
example_category = ListViewCategory("Examples", 'help')
We are going to modify it to suit our needs
- First, we rename the variable to articles_category, for the sake of clarity
- Then, we have to choose between ListView and IconView, which are different ways of presenting the results inside a category. Let’s keep the default: ListView
- We also need to give our category a display name: Articles
- Finally, we need a decent icon for the category header, and we will choose a stock item from the system: dialog-information-symbolic
articles_category = ListViewCategory("Articles", "dialog-information-symbolic")
Now that we have the architecture of our lens ready, we are going to add what a lens is supposed to do: searching. The default code illustrates how to add results to a lens…
def search(self, search, results): # TODO: Add your search results results.append('https://wiki.ubuntu.com/Unity/Lenses/Singlet', 'ubuntu-logo', self.example_category, "text/html", 'Learn More', 'Find out how to write your Unity Lens', 'https://wiki.ubuntu.com/Unity/Lenses/Singlet') pass
…but what we want is to ask results to Wikipedia.
Searching on Wikipedia
Let’s create a new function to search Wikipedia, that we will plug into this one.
We name it wikipedia_query, which sounds appropriate. It will take the string typed by the user in the search bar as an argument. We are also going to need a few Python modules to do the search: urllib2 to do the HTTP call and simplejson to parse the data delivered by Wikipedia.
At the top of the file, with all the other import, we import the modules we need:
import urllib2 import simplejson
Then, inside the WikipediaLens(SingleScopeLens) class, our main class, we add a wiki variable, which will help to simplify the code:
wiki = "http://en.wikipedia.org"
And we create our function :
def wikipedia_query(self, search):
search, is the string typed by the user in the search bar. We need to change it a little before sending it to Wikipedia, by replacing blank spaces with | , as it’s the way Wikipedia understands queries.
search = search.replace(" ", "|")
We now create our query url, using the Wikipedia opensearch API
url = ("%s/w/api.php?action=opensearch&limit=25&format=json&search=%s" % (self.wiki, search))
And we store our returned results in a results variable, they are in json, so we use the simplejson module to turn them into a list.
results = simplejson.loads(urllib2.urlopen(url).read())
We also add a debug line, to show what we are doing.
print "Searching Wikipedia for %s" % (search)
And we finish our work on this function by making it return something.
Our wikipedia_query function should look like this, or almost, as I’ve added a try and an except, to catch eventual errors (network error, results error, etc.). If there is one, it will print an informative debug message and return an empty list of results.
def wikipedia_query(self,search): try: search = search.replace(" ", "|") url = ("%s/w/api.php?action=opensearch&limit=25&format=json&search=%s" % (self.wiki, search)) results = simplejson.loads(urllib2.urlopen(url).read()) print "Searching Wikipedia" return results except (IOError, KeyError, urllib2.URLError, urllib2.HTTPError, simplejson.JSONDecodeError): print "Error : Unable to search Wikipedia" return 
Next, all we need to do is plugging this new function into our existing search function
def search(self, search, results): for article in self.wikipedia_query(search): results.append("%s/wiki/%s" % (self.wiki, article), "http://upload.wikimedia.org/wikipedia/commons/6/63/Wikipedia-logo.png", self.articles_category, "text/html", article, "Wikipedia Article", "%s/wiki/%s" % (self.wiki, article)) pass
Which can be translated as: for each result returned by wikipedia_query, add an article to the lens.
What happens in results.append is really important to understand what we can display in a lens. Here is what we need to pass to Unity for each result:
results.append (url, icon, category, mime-type, text, comment, drag and drop url)
That’s it, your lens is done.
Using the Wikipedia Lens
You can now make it visible in the Dash by typing the following command on the terminal:
sudo quickly install
and run it with
It does what it’s supposed to, which is great, but we are going to make it a bit nicer…
Making it nicer
First, the way of displaying results is not appropriate for Wiki results, we don’t need to see “Wikipedia Article” on each one. Let’s change the category to use the IconView:
articles_category = IconViewCategory("Articles", "dialog-information-symbolic")
Then, you may have noticed that it only returns English results, which is fine… if you assume that all your users will speak English. Let’s try to improve this by finding out the user’s session language and ask Wikipedia for this language only.
At the top of our file we need to add a new import : the locale module.
Then, inside our main class, above the wiki variable, we need to find the user’s locale :
locale.setlocale(locale.LC_MESSAGES, '') loc = locale.getlocale(locale.LC_MESSAGES).split("_")
loc is now a variable containing a string like “en”, “fr”, “de”, etc.
We modify our wiki variable to use loc.
wiki = "http://%s.wikipedia.org" % (loc)
And if we run our lens again…
Localized results in your language, as expected from an OS for human beings
This tutorial demonstrated how to easily create lens for the Unity dash to enrich the Ubuntu user experience and provide the ability to search on the wikipedia right from the desktop.
- Learn more about Unity and related technologies
- Learn more about Unity lenses and scopes
- Unity API reference
- Wikipedia opensearch API
- For reference, here is the default lens template you will find when opening __init__.py, and here is the finished lens made with this tutorial.
- 10 of the best Unity Lenses & Scopes for Ubuntu (via OMG!Ubuntu)
If you’ve got any questions on this tutorial, or on the technologies that it uses, just ask on Askubuntu!
Oh, and don’t forget to leave your feedback in the comments!
Follow Ubuntu App Development on: