2
# -*- coding: utf-8 -*-
5
# Copyright (C) 2011 Stefano Palazzo <stefano.palazzo@gmail.com>
6
# 2011 Mark Tully <markjtully@gmail.com>
8
# This program is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
18
# You should have received a copy of the GNU General Public License
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
28
from gi.repository import GLib
29
from gi.repository import GObject
30
from gi.repository import Gio
31
from gi.repository import Unity
33
BUS_NAME = "net.launchpad.lens.medicines"
39
class Daemon (object):
40
""" Yelp Daemon sets up the lens & searches Ubuntu Help for results
44
special_searches = ["me", "chat", "meta", "au", "help", "lens"]
47
""" Sets up the lens and default scope
48
The lens has 2 categories: One for SPCs (technical documents about
49
the properties of a medicine aimed at healthcare professionals)
50
and one for PILs (Patient information leaflets enclosed with a
51
medicine, which are aimed at the person taking the medicine) There
52
is also a filter for searching different websites
54
self.location = self.get_location()
56
self.lens = Unity.Lens.new("/net/launchpad/lens/medicines", "medicines")
57
self.scope = Unity.Scope.new("/net/launchpad/lens/medicines/scope/ie")
59
self.lens.props.search_hint = "Search for help with Ubuntu"
60
self.lens.props.visible = True
61
self.lens.props.search_in_global = False
62
self.scope.props.search_in_global = False
64
# Set up categories. Categories for all scopes must be set up here.
65
# They can not be done from within the scopes themselves
67
cats.append(Unity.Category.new("Summary of Product Characteristics",
68
Gio.ThemedIcon.new("/usr/lib/unity-lens-medicines/Rx.svg"),
69
Unity.CategoryRenderer.HORIZONTAL_TILE))
70
cats.append(Unity.Category.new("Patient Information Leaflets",
71
Gio.ThemedIcon.new("/usr/lib/unity-lens-medicines/Rx.svg"),
72
Unity.CategoryRenderer.HORIZONTAL_TILE))
73
self.lens.props.categories = cats
76
f = Unity.CheckOptionFilter.new("sources",
78
Gio.ThemedIcon.new("input-keyboard-symbolic"),
81
f.add_option("ie", "medicines.ie", None)
82
f.add_option("uk", "emc.medicines.org.uk", None)
84
self.lens.props.filters = filters
86
# Listen for changes and requests
87
self.scope.connect("search-changed", self.on_search_changed)
88
self.scope.connect("filters-changed", self.on_filters_changed)
89
self.scope.connect("notify::active", self.on_lens_active)
90
#self.scope.connect("activate-uri", self.activate_uri)
91
self.lens.add_local_scope(self.scope)
94
def get_location(self):
95
""" Determine the user's location using Ubuntu's GeoIP
98
The country the user's IP address is in as a 2 letter code
101
f = urllib2.urlopen('http://geoip.ubuntu.com/lookup')
103
country = re.findall(u'''\<CountryCode\>(.*)\</CountryCode\>''', content)[0].lower()
108
def on_filters_changed(self, *_):
109
""" Called when a filter is clicked. Queue's a new search
111
self.scope.queue_search_changed(Unity.SearchType.DEFAULT)
113
def on_lens_active(self, *_):
114
""" Called when the lens is activated. Queue's a new search
116
if self.scope.props.active:
117
self.scope.queue_search_changed(Unity.SearchType.DEFAULT)
119
def on_search_changed(self, scope, search=None, search_type=0, cancellable=None):
120
""" Called when the search is changed. Gets the search string and search
121
type and passes it to update_results_model()
123
scope: a scope object
124
search: the search string
125
search_type: the search type (global or local)
126
cancellable: cancellable object
128
if hasattr(search, "props"):
129
search_string = search.props.search_string
133
if search_type == Unity.SearchType.DEFAULT:
134
results = scope.props.results_model
136
results = scope.props.global_results_model
138
print "Search changed to: '%s'" % search_string
139
self.update_results_model(search_string, results)
140
if hasattr(search, "finished"):
143
def update_results_model(self, search, model):
144
""" Takes the search string and determines the active filters,
145
then runs a search of the relevant sources
147
search: the search string
148
model: the model object that results are added to
152
filters = self.scope.get_filter("sources")
153
if not filters.props.filtering:
154
if self.location == "ie":
155
active_filters.append("ie")
157
active_filters.append("uk")
158
for source in filters.options:
159
if source.props.active:
160
active_filters.append(source.props.id)
164
if "ie" in active_filters:
165
url = "http://www.medicines.ie/searchresults.aspx?term=%s&searchtype=AdvancedSearch" % search
166
self.append_results(url, model)
168
if "uk" in active_filters:
169
url = "http://www.medicines.org.uk/EMC/searchresults.aspx?term=%s&searchtype=QuickSearch" % search
170
self.append_results(url, model)
172
def append_results(self, url, model):
173
""" Parses the html of the page of the url and adds results to
176
url: the url of the website's results page
177
model: the model object that results are added to
179
icon_hint = Gio.ThemedIcon.new("application-pdf").to_string()
180
tree = lxml.html.parse(url)
181
tree.getroot().make_links_absolute()
182
array = [tree.xpath("//tr[@class='GridRow_Office2007']"), tree.xpath("//tr[@class='GridAltRow_Office2007']")]
185
title = item.xpath("td/table/tr/td/a")[0]
186
drug = item.xpath("td/span")[0]
187
itemtype = item.xpath("td/table/tr/td/img/@alt")[0]
188
uri = item.xpath("td/table/tr/td/a/@href")[0]
189
company = item.xpath("td/a")[0]
191
if itemtype == "PIL":
193
icon_hint = Gio.ThemedIcon.new("application-pdf").to_string()
194
model.append(str(uri), icon_hint, group, "text/html", title.text_content().strip(), drug.text_content().strip() + "\n" + company.text_content().strip(), str(uri))
197
if __name__ == "__main__":
198
session_bus_connection = Gio.bus_get_sync(Gio.BusType.SESSION, None)
199
session_bus = Gio.DBusProxy.new_sync(session_bus_connection, 0, None,
200
'org.freedesktop.DBus', '/org/freedesktop/DBus',
201
'org.freedesktop.DBus', None)
202
result = session_bus.call_sync('RequestName',
203
GLib.Variant("(su)", (BUS_NAME, 0x4)), 0, -1, None)
204
result = result.unpack()[0]
205
# We could try to do some automated rescue when this happens:
207
print >> sys.stderr, "Failed to own name %s. Bailing out." % BUS_NAME
208
print >> sys.stderr, "Do you have another instance running?"
211
print "entering the main loop"
212
GObject.MainLoop().run()