2
# -*- coding: utf-8 -*-
4
# Copyright (C) 2013 name <email>
5
# This program is free software: you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License version 3, as published
7
# by the Free Software Foundation.
9
# This program is distributed in the hope that it will be useful, but
10
# WITHOUT ANY WARRANTY; without even the implied warranties of
11
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12
# PURPOSE. See the GNU General Public License for more details.
14
# You should have received a copy of the GNU General Public License along
15
# with this program. If not, see <http://www.gnu.org/licenses/>.
17
from gi.repository import Unity
18
from gi.repository import Gio
25
import oauthlib.oauth1
27
APP_NAME = 'unity-scope-tumblr'
28
LOCAL_PATH = '/usr/share/locale/'
29
gettext.bindtextdomain(APP_NAME, LOCAL_PATH)
30
gettext.textdomain(APP_NAME)
33
GROUP_NAME = 'com.canonical.Unity.Scope.Graphics.Tumblr'
34
UNIQUE_PATH = '/com/canonical/unity/scope/graphics/tumblr'
36
SEARCH_HINT = _('Search Tumblr')
37
NO_RESULTS_HINT = _('Sorry, there are no Tumblr results that match your search.')
38
PROVIDER_CREDITS = _('Powered by Tumblr')
39
SVG_DIR = '/usr/share/icons/unity-icon-theme/places/svg/'
40
PROVIDER_ICON = SVG_DIR + 'service-tumblr.svg'
41
DEFAULT_RESULT_ICON = SVG_DIR + 'group-notes.svg'
42
DEFAULT_RESULT_MIMETYPE = 'text/html'
43
DEFAULT_RESULT_TYPE = Unity.ResultType.DEFAULT
47
'icon': SVG_DIR + 'group-installed.svg',
48
'renderer': Unity.CategoryRenderer.VERTICAL_TILE}
51
'icon': SVG_DIR + 'group-installed.svg',
52
'renderer': Unity.CategoryRenderer.VERTICAL_TILE}
60
'field': Unity.SchemaFieldType.OPTIONAL}
61
m2 = {'id': 'metadata2',
63
'field': Unity.SchemaFieldType.OPTIONAL}
64
EXTRA_METADATA = [m1, m2]
68
def search(search, filters):
70
Any search method returning results as a list of tuples.
71
Available tuple fields:
79
result_type (Unity ResultType)
80
extras metadata fields (string or int)
83
if not search or len(search) < 3:
85
key = "IIHEZXn6tO0PMBbAcz0YFZ2uujM0ey2iUBd0JWleIRe4lYKdpk"
86
blog = urllib.parse.quote(search.replace('#', ''))
87
uri = "https://api.tumblr.com/v2/blog/%s.tumblr.com/posts?api_key=%s&limit=24" % (blog, key)
88
if search.startswith('#'):
89
uri = "http://api.tumblr.com/v2/tagged?tag=%s&filter=text&api_key=%s&limit=24" % (blog, key)
91
res = urllib.request.urlopen(uri).read()
92
data = json.loads(res.decode('utf-8'))
94
if search.startswith('#'):
95
source = data['response']
97
source = data['response']['posts']
102
for l in e['photos']:
103
icon = l['alt_sizes'][-2]['url']
104
photo = l['alt_sizes'][1]['url']
107
# caption = e['caption']
108
# cap_match = re.match('.*<p>.*>*([^<]+)<*.*</p>.*', caption)
110
# print (cap_match.group(0))
111
# title = cap_match.group(1)
116
results.append({'uri': e['post_url'],
123
class Preview(Unity.ResultPreviewer):
126
preview = Unity.GenericPreview.new(self.result.title,
129
# if self.result.metadata['photo'].get_string() != '':
130
im = Gio.FileIcon.new(Gio.file_new_for_uri(self.result.metadata['photo'].get_string()))
131
preview.props.image = im
133
# preview.props.image_source_uri = self.result.icon
134
icon = Gio.FileIcon.new(Gio.file_new_for_path(PROVIDER_ICON))
135
view_action = Unity.PreviewAction.new('view',
138
preview.add_action(view_action)
142
# Classes below this point establish communication
143
# with Unity, you probably shouldn't modify them.
146
class MySearch(Unity.ScopeSearchBase):
147
def __init__(self, search_context):
148
super(MySearch, self).__init__()
149
self.set_search_context(search_context)
153
Adds results to the model
156
result_set = self.search_context.result_set
157
for i in search(self.search_context.search_query,
158
self.search_context.filter_state):
159
if not 'uri' in i or not i['uri'] or i['uri'] == '':
161
if not 'icon' in i or not i['icon'] or i['icon'] == '':
162
i['icon'] = DEFAULT_RESULT_ICON
163
if not 'mimetype' in i or not i['mimetype'] or i['mimetype'] == '':
164
i['mimetype'] = DEFAULT_RESULT_MIMETYPE
165
if not 'result_type' in i or not i['result_type'] or i['result_type'] == '':
166
i['result_type'] = DEFAULT_RESULT_TYPE
167
if not 'category' in i or not i['category'] or i['category'] == '':
169
if not 'title' in i or not i['title']:
171
if not 'comment' in i or not i['comment']:
173
if not 'dnd_uri' in i or not i['dnd_uri'] or i['dnd_uri'] == '':
174
i['dnd_uri'] = i['uri']
175
result_set.add_result(**i)
176
except Exception as error:
180
class Scope (Unity.AbstractScope):
182
Unity.AbstractScope.__init__(self)
184
def do_get_search_hint(self):
187
def do_get_schema(self):
189
Adds specific metadata fields
191
schema = Unity.Schema.new()
193
for m in EXTRA_METADATA:
194
schema.add_field(m['id'], m['type'], m['field'])
195
#FIXME should be REQUIRED for credits
196
schema.add_field('provider_credits',
198
Unity.SchemaFieldType.OPTIONAL)
201
def do_get_categories(self):
205
cs = Unity.CategorySet.new()
208
cat = Unity.Category.new(c['id'], c['name'],
209
Gio.ThemedIcon.new(c['icon']),
214
def do_get_filters(self):
218
fs = Unity.FilterSet.new()
222
def do_get_group_name(self):
225
def do_get_unique_name(self):
228
def do_create_search_for_query(self, search_context):
229
se = MySearch(search_context)
232
def do_create_previewer(self, result, metadata):
234
rp.set_scope_result(result)
235
rp.set_search_metadata(metadata)
238
def do_activate(self, result, metadata, id):
239
return Unity.ActivationResponse()