~unity-team/unity-lens-sample/trunk

« back to all changes in this revision

Viewing changes to python/simple/unity-scope-wikipedia

  • Committer: Mikkel Kamstrup Erlandsen
  • Date: 2012-04-13 09:55:02 UTC
  • Revision ID: mikkel.kamstrup@gmail.com-20120413095502-tq8doso9ne97otem
Import javascript and python examples and add a simple top level README

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/python
 
2
 
 
3
from gi.repository import GLib, GObject, Gio
 
4
from gi.repository import Dee
 
5
from gi.repository import Unity
 
6
import urllib2, simplejson, socket
 
7
 
 
8
#Set the timeout (in seconds) for http calls. By design, lenses shouldn't take more than 4 seconds to give results or indicate they have failed.
 
9
socket.setdefaulttimeout(3)
 
10
 
 
11
# The scope dbus id
 
12
BUS_NAME = "net.launchpad.scope.information.wikipedia"
 
13
 
 
14
class Daemon:
 
15
        def __init__ (self):
 
16
                # Create the scope (this matches the path defined in the .scope file)
 
17
                self.scope = Unity.Scope.new ("/net/launchpad/scope/information/wikipedia")
 
18
                # Is the scope searchable from the home dash?
 
19
                self.scope.search_in_global = False
 
20
                # Connect to the search changed signal (it is fired when the lens is opened for the first time, then for each search change)
 
21
                self.scope.connect ("search-changed", self.on_search_changed)
 
22
                # Listen to the lens filters
 
23
                self.scope.connect ("filters-changed", lambda scope : scope.queue_search_changed(Unity.SearchType.DEFAULT))
 
24
                # The scope is ready
 
25
                self.scope.export()
 
26
        
 
27
        # On each search change, this method is called
 
28
        def on_search_changed (self, scope, search, search_type, cancellable):
 
29
                # Get the search string
 
30
                search_string = search.props.search_string.strip()
 
31
                print "Search changed to \"%s\"" % search_string
 
32
                # Get the Dee model (the database used by the lens to store and display search results)
 
33
                model = search.props.results_model
 
34
                # Empty the model
 
35
                model.clear()
 
36
                # Update the model
 
37
                self.update_results_model (search_string, model)
 
38
                # Signal to the lens that the search is finished (the spinning search icon stops)
 
39
                search.finished()
 
40
 
 
41
        # Update the model
 
42
        def update_results_model(self, search, model):
 
43
                self.wikipedia(search, model)
 
44
 
 
45
        # This method sends the search string to Wikipedia and brings back results
 
46
        def wikipedia_search(self,search):
 
47
                try:
 
48
                        # Replace spaces by | to match the Wikipedia query format
 
49
                        search = search.replace(" ", "|")
 
50
                        # The Wikipedia "opensearch" API ( http://www.mediawiki.org/wiki/API:Opensearch )
 
51
                        url = ("http://en.wikipedia.org/w/api.php?action=opensearch&limit=25&format=json&search=%s" % (search))
 
52
 
 
53
                        # urllib2.urlopen(url) : send the query
 
54
                        # read() : read the results
 
55
                        # simplejson.loads() : we have asked Wikipedia to return the results in json format, we use simplejson to parse them
 
56
                        results = simplejson.loads(urllib2.urlopen(url).read())
 
57
                        print "Searching Wikipedia"
 
58
 
 
59
                        # We return the results list (the use of [1] is specific to Wikipedia json results)
 
60
                        return results[1]
 
61
                except (IOError, KeyError, urllib2.URLError, urllib2.HTTPError, simplejson.JSONDecodeError):
 
62
                        print "Error : Unable to search Wikipedia"
 
63
                        return []
 
64
 
 
65
        # This method parses the results and adds them to the model
 
66
        def wikipedia(self, search, model):
 
67
                # We iterate through each of the returned results
 
68
                for i in self.wikipedia_search(search):
 
69
                        # Lens results are made of several things :
 
70
                        # An uri
 
71
                        uri = "http://en.wikipedia.org/wiki/%s" % i
 
72
                        # A title
 
73
                        title = i
 
74
                        # An icon
 
75
                        icon = 'http://upload.wikimedia.org/wikipedia/commons/6/63/Wikipedia-logo.png'
 
76
                        # A comment (optional)
 
77
                        comment = 'Wikipedia article'
 
78
                        # If the uri seems valid, we add the results to the Dee model
 
79
                        if (uri.startswith("http://")):
 
80
                                # uri, icon, category (matching the order of the categories in the lens), mimetype, title, comment, drag and drop uri
 
81
                                model.append(uri, icon, 0, "text/html", title, comment, uri)
 
82
                                # We can append the same result to multiple models, just by changing the category
 
83
                                model.append(uri, icon, 1, "text/html", title, comment, uri)
 
84
                                
 
85
# The following lines take care of the Bus connexion.
 
86
if __name__ == "__main__":
 
87
        session_bus_connection = Gio.bus_get_sync (Gio.BusType.SESSION, None)
 
88
        session_bus = Gio.DBusProxy.new_sync (session_bus_connection, 0, None,
 
89
                                              'org.freedesktop.DBus',
 
90
                                              '/org/freedesktop/DBus',
 
91
                                              'org.freedesktop.DBus', None)
 
92
        result = session_bus.call_sync('RequestName',
 
93
                                       GLib.Variant ("(su)", (BUS_NAME, 0x4)),
 
94
                                       0, -1, None)
 
95
 
 
96
        # Unpack variant response with signature "(u)". 1 means we got it.
 
97
        result = result.unpack()[0]
 
98
        
 
99
        if result != 1 :
 
100
                print >> sys.stderr, "Failed to own name %s. Bailing out." % BUS_NAME
 
101
                raise SystemExit (1)
 
102
        
 
103
        daemon = Daemon()
 
104
        GObject.MainLoop().run()