Merge lp:~jamesh/unity-scope-gdrive/previews into lp:~submarine/unity-scope-gdrive/libunity-7-compatible

Proposed by James Henstridge
Status: Merged
Approved by: Michal Hruby
Approved revision: 52
Merged at revision: 47
Proposed branch: lp:~jamesh/unity-scope-gdrive/previews
Merge into: lp:~submarine/unity-scope-gdrive/libunity-7-compatible
Diff against target: 534 lines (+290/-86)
6 files modified
debian/control (+7/-0)
debian/rules (+3/-0)
gdrive.scope (+1/-1)
test_scope.py (+142/-0)
unity-scope-gdrive.service (+1/-1)
unity_gdrive_daemon.py (+136/-84)
To merge this branch: bzr merge lp:~jamesh/unity-scope-gdrive/previews
Reviewer Review Type Date Requested Status
Michal Hruby (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+162505@code.launchpad.net

Commit message

Convert to the new scope API and add a preview.

Description of the change

Convert scope to new API, and add a simple preview showing author, modification date and whether the document has been starred or shared.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michal Hruby (mhr3) wrote :

Could we get some tests? Or is that too complex with the authentication?

review: Needs Information
50. By James Henstridge

Use InfoHint to construct the preview.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
51. By James Henstridge

Add a test for the search functionality. Unfortunately we need to use a
stub document since GData.Parsable.new_from_xml() segfaults for
GData.Feed subtypes.

The preview test is also skipped because I can't initialise the metadata
dictionary.

52. By James Henstridge

Enable tests in packaging.

Revision history for this message
James Henstridge (jamesh) wrote :

I've added some basic tests for the search functionality, although it stubs out all the account discovery code and provides a fake DocumentsEntry class.

My original plan was to use GData.Parsable.new_from_xml() to build the feed from some sample XML, but that segfaults the interpreter. A quick poke with GDB shows that this wouldn't work from C either: it looks like you can only decode into GData.Feed subclasses from the query code path.

The previewer test is also disabled because I wasn't able to initialise Unity.ScopeResult.metadata from Python in a way that wouldn't cause it to segfault.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michal Hruby (mhr3) wrote :

LGTM.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/control'
--- debian/control 2013-03-15 10:09:23 +0000
+++ debian/control 2013-05-09 07:42:25 +0000
@@ -7,6 +7,13 @@
7 pkg-config,7 pkg-config,
8 python3,8 python3,
9 python3-distutils-extra,9 python3-distutils-extra,
10 python3-nose,
11 python3-gi,
12 gir1.2-glib-2.0,
13 gir1.2-accounts-1.0,
14 gir1.2-signon-1.0,
15 gir1.2-gdata-0.0,
16 gir1.2-unity-5.0 (>= 6.91),
10Standards-Version: 3.9.317Standards-Version: 3.9.3
11Homepage: https://launchpad.net/unity-scope-gdrive18Homepage: https://launchpad.net/unity-scope-gdrive
12# If you aren't a member of ~online-accounts but need to upload packaging19# If you aren't a member of ~online-accounts but need to upload packaging
1320
=== modified file 'debian/rules'
--- debian/rules 2012-11-30 16:02:18 +0000
+++ debian/rules 2013-05-09 07:42:25 +0000
@@ -13,6 +13,9 @@
13override_dh_auto_build:13override_dh_auto_build:
14 python3 setup.py build14 python3 setup.py build
1515
16override_dh_auto_test:
17 nosetests3
18
16override_dh_auto_install:19override_dh_auto_install:
17 python3 setup.py install --root=$(CURDIR)/debian/unity-scope-gdrive --install-layout=deb20 python3 setup.py install --root=$(CURDIR)/debian/unity-scope-gdrive --install-layout=deb
1821
1922
=== modified file 'gdrive.scope'
--- gdrive.scope 2013-05-01 17:52:08 +0000
+++ gdrive.scope 2013-05-09 07:42:25 +0000
@@ -4,7 +4,7 @@
4Icon=/usr/share/icons/unity-icon-theme/places/svg/service-gdrive.svg4Icon=/usr/share/icons/unity-icon-theme/places/svg/service-gdrive.svg
5Keywords=gdrive;doc;drive;google;5Keywords=gdrive;doc;drive;google;
6Loader=/usr/share/unity-scopes/gdrive/unity_gdrive_daemon.py6Loader=/usr/share/unity-scopes/gdrive/unity_gdrive_daemon.py
7RequiredMetadata=7RequiredMetadata=author[s];shared[b];starred[b];updated[i]
8OptionalMetadata=8OptionalMetadata=
9RemoteContent=true9RemoteContent=true
10Type=file10Type=file
1111
=== added file 'test_scope.py'
--- test_scope.py 1970-01-01 00:00:00 +0000
+++ test_scope.py 2013-05-09 07:42:25 +0000
@@ -0,0 +1,142 @@
1import unittest
2
3from gi.repository import GData, GLib, Unity
4
5import unity_gdrive_daemon as gdrive
6
7
8class ResultSet(Unity.ResultSet):
9 def __init__(self):
10 Unity.ResultSet.__init__(self)
11 self.results = []
12
13 def do_add_result(self, result):
14 self.results.append(dict(uri=result.uri,
15 icon=result.icon_hint,
16 category=result.category,
17 result_type=result.result_type,
18 mimetype=result.mimetype,
19 title=result.title,
20 comment=result.comment,
21 dnd_uri=result.dnd_uri,
22 author=result.metadata['author'].get_string(),
23 shared=result.metadata['shared'].get_boolean(),
24 starred=result.metadata['starred'].get_boolean(),
25 updated=result.metadata['updated'].get_int32()))
26
27
28class FakeDocumentsEntry:
29 """A fake GData.DocumentsEntry"""
30
31 def get_resource_id(self):
32 return 'spreadsheet:abcdefghij'
33
34 def look_up_link(self, rel):
35 assert rel == GData.LINK_ALTERNATE
36 return GData.Link.new("http://example.com/view", rel)
37
38 def get_updated(self):
39 return 1000000000
40
41 def get_title(self):
42 return "Fake title"
43
44 def get_authors(self):
45 return [GData.Author.new('john.smith', '', 'john.smith@example.com')]
46
47 def get_categories(self):
48 return [GData.Category.new(
49 'http://schemas.google.com/g/2005/labels#starred',
50 'http://schemas.google.com/g/2005/labels', 'starred')]
51
52 def get_content_uri(self):
53 return "http://example.com/export"
54
55
56class StubGDocsAccount(gdrive.GDocsAccount):
57 def __init__(self):
58 self._enabled = True
59
60 def get_doc_list(self, search, filters, is_global):
61 # It would be nice if we could use
62 # GData.Parsable.new_from_xml() to generate the feed from XML,
63 # but it segfaults.
64 return [FakeDocumentsEntry()]
65
66
67def fake_setup_accounts(self):
68 self._gdocs_accounts.append(StubGDocsAccount())
69
70
71class GDriveTests(unittest.TestCase):
72 def setUp(self):
73 super(GDriveTests, self).setUp()
74 self._orig_setup_accounts = gdrive.GDriveScope.setup_accounts
75 gdrive.GDriveScope.setup_accounts = fake_setup_accounts
76
77 def tearDown(self):
78 gdrive.GDriveScope.setup_accounts = self._orig_setup_accounts
79 super(GDriveTests, self).tearDown()
80
81 def perform_query(self, query):
82 scope = gdrive.GDriveScope()
83 filter_set = scope.get_filters()
84 result_set = ResultSet()
85 context = Unity.SearchContext.create(
86 query, 0, filter_set, None, result_set, None)
87
88 search = scope.create_search_for_query(context)
89 search.run()
90 return result_set.results
91
92 def test_get_categories(self):
93 scope = gdrive.GDriveScope()
94 category_set = scope.get_categories()
95 self.assertEqual(
96 [cat.props.id for cat in category_set.get_categories()],
97 ['global', 'recent', 'downloads', 'folders'])
98
99 def test_get_filters(self):
100 scope = gdrive.GDriveScope()
101 filter_set = scope.get_filters()
102 self.assertEqual(
103 [filter.props.id for filter in filter_set.get_filters()],
104 ['modified', 'type'])
105
106 def test_search(self):
107 results = self.perform_query("foo")
108 self.assertEqual(len(results), 1)
109 self.assertEqual(results[0], dict(
110 uri='http://example.com/view',
111 icon='x-office-spreadsheet',
112 category=1,
113 result_type=Unity.ResultType.PERSONAL,
114 mimetype='text/html',
115 title='Fake title',
116 comment='spreadsheet',
117 dnd_uri='http://example.com/export',
118 author='john.smith',
119 shared=False,
120 starred=True,
121 updated=1000000000))
122
123 @unittest.skip("Can not set up metadata in ScopeResult")
124 def test_preview(self):
125 result = Unity.ScopeResult.create(
126 uri='http://example.com/view',
127 icon_hint='x-office-spreadsheet',
128 category=1,
129 result_type=Unity.ResultType.PERSONAL,
130 mimetype='text/html',
131 title='Fake title',
132 comment='spreadsheet',
133 dnd_uri='http://example.com/export',
134 metadata={
135 'author': GLib.Variant('s', 'john.smith'),
136 'shared': GLib.Variant('b', False),
137 'starred': GLib.Variant('b', True),
138 'updated': GLib.Variant('i', 1000000000)})
139 metadata = Unity.SearchMetadata()
140 scope = gdrive.GDriveScope()
141 previewer = scope.create_previewer(result, metadata)
142 preview = previewer.run()
0143
=== modified file 'unity-scope-gdrive.service'
--- unity-scope-gdrive.service 2013-03-22 15:25:03 +0000
+++ unity-scope-gdrive.service 2013-05-09 07:42:25 +0000
@@ -1,3 +1,3 @@
1[D-BUS Service]1[D-BUS Service]
2Name=com.canonical.Unity.Scope.File.Gdrive2Name=com.canonical.Unity.Scope.File.Gdrive
3Exec=/usr/share/unity-scopes/gdrive/unity_gdrive_daemon.py3Exec=/usr/bin/python3 /usr/share/unity-scopes/scope-runner-dbus.py /usr/share/unity-scopes/gdrive/unity_gdrive_daemon.py
44
=== modified file 'unity_gdrive_daemon.py' (properties changed: +x to -x)
--- unity_gdrive_daemon.py 2013-03-22 15:25:03 +0000
+++ unity_gdrive_daemon.py 2013-05-09 07:42:25 +0000
@@ -1,4 +1,5 @@
1#! /usr/bin/python31#! /usr/bin/python3
2# -*- mode: python; python-indent: 2 -*-
2#3#
3# Copyright 2012 Canonical Ltd.4# Copyright 2012 Canonical Ltd.
4#5#
@@ -7,27 +8,26 @@
7# GPLv38# GPLv3
8#9#
910
11from datetime import datetime, timedelta
12import gettext
13import locale
10import sys14import sys
15import time
16
11from gi.repository import GLib, GObject, Gio17from gi.repository import GLib, GObject, Gio
12from gi.repository import Accounts, Signon18from gi.repository import Accounts, Signon
13from gi.repository import GData19from gi.repository import GData
14from gi.repository import Unity, UnityExtras20from gi.repository import Unity
1521
16from datetime import datetime, timedelta
17import gettext
18import time
1922
20APP_NAME = "unity-scope-gdrive"23APP_NAME = "unity-scope-gdrive"
21LOCAL_PATH = "/usr/share/locale/"24LOCAL_PATH = "/usr/share/locale/"
2225
26locale.setlocale(locale.LC_ALL, '')
23gettext.bindtextdomain(APP_NAME, LOCAL_PATH)27gettext.bindtextdomain(APP_NAME, LOCAL_PATH)
24gettext.textdomain(APP_NAME)28gettext.textdomain(APP_NAME)
25_ = gettext.gettext29_ = gettext.gettext
2630
27#
28# The primary bus name we grab *must* match what we specify in our .scope file
29#
30BUS_NAME = "com.canonical.Unity.Scope.File.Gdrive"
31# Map Google Docs types to the values of the "type" filter31# Map Google Docs types to the values of the "type" filter
32TYPE_MAP = {32TYPE_MAP = {
33 "document": "documents",33 "document": "documents",
@@ -38,34 +38,34 @@
38}38}
39THEME = "/usr/share/icons/unity-icon-theme/places/svg/"39THEME = "/usr/share/icons/unity-icon-theme/places/svg/"
4040
41class Daemon:41
4242class GDriveScope(Unity.AbstractScope):
43 def __init__ (self):43 __g_type_name__ = "GDriveScope"
44 self._scope = Unity.DeprecatedScope.new ("/com/canonical/unity/scope/file/gdrive", "gdrive")44
45 self._scope.search_in_global = True;45 def __init__(self):
46 self._preferences = Unity.PreferencesManager.get_default()46 super(GDriveScope, self).__init__()
47 self._preferences.connect ("notify::remote-content-search",47 self.search_in_global = True;
48 self._on_filters_or_preferences_changed);
4948
50 self._gdocs_accounts = []49 self._gdocs_accounts = []
51 try:50 self.setup_accounts()
52 self._account_manager = Accounts.Manager.new_for_service_type("documents")51
53 except TypeError as e:52 def do_get_group_name(self):
54 print ("Couldn't start account manager, not initialising: %s" % e)53 # The primary bus name we grab *must* match what we specify in our
55 sys.exit(0)54 # .scope file
56 self._account_manager.connect("enabled-event", self._on_enabled_event);55 return "com.canonical.Unity.Scope.File.Gdrive"
57 for account in self._account_manager.get_enabled_account_services():56
58 self.add_account_service(account)57 def do_get_unique_name(self):
5958 return "/com/canonical/unity/scope/file/gdrive"
60 # Listen for changes and requests59
61 self._scope.connect ("search-changed", self._on_search_changed)60 def do_get_schema(self):
6261 schema = Unity.Schema.new()
63 # This allows us to re-do the search if any parameter on a filter has changed62 schema.add_field('author', 's', Unity.SchemaFieldType.REQUIRED)
64 # Though it's possible to connect to a more-specific changed signal on each63 schema.add_field('shared', 'b', Unity.SchemaFieldType.REQUIRED)
65 # Fitler, as we re-do the search anyway, this catch-all signal is perfect for64 schema.add_field('starred', 'b', Unity.SchemaFieldType.REQUIRED)
66 # us.65 schema.add_field('updated', 'i', Unity.SchemaFieldType.REQUIRED)
67 self._scope.connect ("notify::filtering", self._on_filters_or_preferences_changed);66 return schema
68 67
68 def do_get_filters(self):
69 filters = Unity.FilterSet.new()69 filters = Unity.FilterSet.new()
70 f = Unity.RadioOptionFilter.new ("modified", _("Last modified"), Gio.ThemedIcon.new("input-keyboard-symbolic"), False)70 f = Unity.RadioOptionFilter.new ("modified", _("Last modified"), Gio.ThemedIcon.new("input-keyboard-symbolic"), False)
71 f.add_option ("last-7-days", _("Last 7 days"), None)71 f.add_option ("last-7-days", _("Last 7 days"), None)
@@ -81,7 +81,9 @@
81 f2.add_option ("presentations", _("Presentations"), None)81 f2.add_option ("presentations", _("Presentations"), None)
82 f2.add_option ("other", _("Other"), None)82 f2.add_option ("other", _("Other"), None)
83 filters.add (f2)83 filters.add (f2)
84 self._scope.props.filters = filters84 return filters
85
86 def do_get_categories(self):
85 cats = Unity.CategorySet.new()87 cats = Unity.CategorySet.new()
86 cats.add (Unity.Category.new ('global',88 cats.add (Unity.Category.new ('global',
87 _("Files & Folders"),89 _("Files & Folders"),
@@ -99,8 +101,26 @@
99 _("Folders"),101 _("Folders"),
100 Gio.ThemedIcon.new(THEME + "group-folders.svg"),102 Gio.ThemedIcon.new(THEME + "group-folders.svg"),
101 Unity.CategoryRenderer.VERTICAL_TILE))103 Unity.CategoryRenderer.VERTICAL_TILE))
102 self._scope.props.categories = cats104 return cats
103 self._scope.export()105
106 def do_create_search_for_query(self, search_context):
107 return GDriveScopeSearch(search_context, self._gdocs_accounts)
108
109 def do_create_previewer(self, result, metadata):
110 previewer = GDriveScopePreviewer()
111 previewer.set_scope_result(result)
112 previewer.set_search_metadata(metadata)
113 return previewer
114
115 def setup_accounts(self):
116 try:
117 self._account_manager = Accounts.Manager.new_for_service_type("documents")
118 except TypeError as e:
119 print ("Couldn't start account manager, not initialising: %s" % e)
120 sys.exit(0)
121 self._account_manager.connect("enabled-event", self._on_enabled_event);
122 for account in self._account_manager.get_enabled_account_services():
123 self.add_account_service(account)
104124
105 def _on_enabled_event (self, account_manager, account_id):125 def _on_enabled_event (self, account_manager, account_id):
106 account = self._account_manager.get_account(account_id)126 account = self._account_manager.get_account(account_id)
@@ -113,32 +133,49 @@
113 for gdocs_account in self._gdocs_accounts:133 for gdocs_account in self._gdocs_accounts:
114 if gdocs_account.get_account_service() == account_service:134 if gdocs_account.get_account_service() == account_service:
115 return135 return
116 gdocs_account = GDocsAccount(self._scope, account_service);136 gdocs_account = GDocsAccount(account_service);
117 self._gdocs_accounts.append(gdocs_account)137 self._gdocs_accounts.append(gdocs_account)
118138
119 def _on_search_changed (self, scope, search, search_type, cancellable):139
120 search_string = search.props.search_string140class GDriveScopeSearch(Unity.ScopeSearchBase):
121 results = search.props.results_model141 __g_type_name__ = "GDriveScopeSearch"
122 results.clear()142
123143 def __init__(self, search_context, accounts):
124 if self._preferences.props.remote_content_search != Unity.PreferencesManagerRemoteContent.ALL:144 super(GDriveScopeSearch, self).__init__()
125 search.emit("finished")145 self.set_search_context(search_context)
126 return146 self._gdocs_accounts = accounts
127147
128 if search_type == Unity.SearchType.GLOBAL:148 def do_run(self):
129 is_global = True149 print("Search changed to: '%s'" % self.search_context.search_query)
130 else:
131 is_global = False
132
133 print("Search changed to: '%s'" % search_string)
134
135 for gdocs_account in self._gdocs_accounts:150 for gdocs_account in self._gdocs_accounts:
136 gdocs_account.update_results_model (search_string, results, search, is_global)151 gdocs_account.search(self.search_context)
137 search.emit("finished")152
138 153
139 def _on_filters_or_preferences_changed (self, *_):154class GDriveScopePreviewer(Unity.ResultPreviewer):
140 self._scope.queue_search_changed(Unity.SearchType.DEFAULT)155 __g_type_name__ = "GDriveScopePreviewer"
141 156
157 def do_run(self):
158 icon = Gio.ThemedIcon.new(self.result.icon_hint)
159 preview = Unity.GenericPreview.new(self.result.title, '', icon)
160 author = self.result.metadata['author'].get_string()
161 modified = datetime.fromtimestamp(
162 self.result.metadata['updated'].get_int32())
163 shared = self.result.metadata['shared'].get_boolean()
164 starred = self.result.metadata['starred'].get_boolean()
165 preview.props.subtitle = _("By %s") % author
166 preview.add_info(Unity.InfoHint.new(
167 "format", _("Format"), None, self.result.comment))
168 preview.add_info(Unity.InfoHint.new(
169 "modified", _("Modified"), None, modified.strftime('%x, %X')))
170 preview.add_info(Unity.InfoHint.new(
171 "shared", _("Shared"), None, _('yes') if shared else _('no')))
172 preview.add_info(Unity.InfoHint.new(
173 "starred", _("Starred"), None, _('yes') if starred else _('no')))
174
175 action = Unity.PreviewAction.new("open", _("Open"), None)
176 preview.add_action(action)
177 return preview
178
142179
143class SignOnAuthorizer(GObject.Object, GData.Authorizer):180class SignOnAuthorizer(GObject.Object, GData.Authorizer):
144 __g_type_name__ = "SignOnAuthorizer"181 __g_type_name__ = "SignOnAuthorizer"
@@ -195,8 +232,7 @@
195232
196# Encapsulates searching a single user's GDocs233# Encapsulates searching a single user's GDocs
197class GDocsAccount:234class GDocsAccount:
198 def __init__ (self, scope, account_service):235 def __init__ (self, account_service):
199 self._scope = scope
200 self._account_service = account_service236 self._account_service = account_service
201 self._account_service.connect("enabled", self._on_account_enabled)237 self._account_service.connect("enabled", self._on_account_enabled)
202 self._enabled = self._account_service.get_enabled()238 self._enabled = self._account_service.get_enabled()
@@ -212,12 +248,15 @@
212 print("account %s, enabled %s" % (account, enabled))248 print("account %s, enabled %s" % (account, enabled))
213 self._enabled = enabled249 self._enabled = enabled
214250
215 def update_results_model (self, search, model, s, is_global=False):251 def search (self, context):
216 if not self._enabled:252 if not self._enabled:
217 return253 return
218254
219 # Get the list of documents255 # Get the list of documents
220 feed = self.get_doc_list(search, s, is_global);256 is_global = context.search_type == Unity.SearchType.GLOBAL
257 feed = self.get_doc_list(
258 context.search_query, context.filter_state, is_global)
259 result_set = context.result_set
221 for entry in feed:260 for entry in feed:
222 rtype = entry.get_resource_id().split(":")[0]261 rtype = entry.get_resource_id().split(":")[0]
223262
@@ -229,22 +268,38 @@
229 else:268 else:
230 category = 1269 category = 1
231270
232 model.append(uri=entry.look_up_link(GData.LINK_ALTERNATE).get_uri(),271 authors = sorted([author.get_name() for author in entry.get_authors()])
233 icon_hint=self.icon_for_type(rtype),272 shared = False
234 category=category,273 starred = False
235 mimetype="text/html",274 for cat in entry.get_categories():
236 title=entry.props.title,275 if cat.get_scheme() != 'http://schemas.google.com/g/2005/labels':
237 comment=rtype,276 continue
238 dnd_uri=entry.props.content_uri,277 if cat.get_label() == 'shared':
239 result_type=Unity.ResultType.PERSONAL);278 shared = True
279 elif cat.get_label() == 'starred':
280 starred = True
281
282 result_set.add_result(
283 uri=entry.look_up_link(GData.LINK_ALTERNATE).get_uri(),
284 icon=self.icon_for_type(rtype),
285 category=category,
286 result_type=Unity.ResultType.PERSONAL,
287 mimetype="text/html",
288 title=entry.get_title(),
289 comment=rtype,
290 dnd_uri=entry.get_content_uri(),
291 author=GLib.Variant('s', ', '.join(authors)),
292 shared=GLib.Variant('b', shared),
293 starred=GLib.Variant('b', starred),
294 updated=GLib.Variant('i', entry.get_updated()))
240295
241 # This is where we do the actual search for documents296 # This is where we do the actual search for documents
242 def get_doc_list (self, search, s, is_global):297 def get_doc_list (self, search, filters, is_global):
243 query = GData.DocumentsQuery(q=search)298 query = GData.DocumentsQuery(q=search)
244299
245 # We do not want filters to effect global results300 # We do not want filters to effect global results
246 if not is_global:301 if not is_global:
247 self.apply_filters(query, s)302 self.apply_filters(query, filters)
248303
249 print("Searching for: " + query.props.q)304 print("Searching for: " + query.props.q)
250305
@@ -258,11 +313,11 @@
258 return []313 return []
259314
260 if not is_global:315 if not is_global:
261 feed = self.filter_results(feed, s)316 feed = self.filter_results(feed, filters)
262 return feed317 return feed
263318
264 def apply_filters (self, query, s):319 def apply_filters (self, query, filters):
265 f = s.get_filter("modified")320 f = filters.get_filter_by_id("modified")
266 if f != None:321 if f != None:
267 o = f.get_active_option()322 o = f.get_active_option()
268 if o != None:323 if o != None:
@@ -277,8 +332,8 @@
277 last_time = datetime.now() - timedelta(age)332 last_time = datetime.now() - timedelta(age)
278 query.set_updated_min(time.mktime(last_time.timetuple()))333 query.set_updated_min(time.mktime(last_time.timetuple()))
279334
280 def filter_results (self, feed, s):335 def filter_results (self, feed, filters):
281 f = s.get_filter("type")336 f = filters.get_filter_by_id("type")
282 if not f: return feed337 if not f: return feed
283 if not f.props.filtering:338 if not f.props.filtering:
284 return feed339 return feed
@@ -313,9 +368,6 @@
313368
314 return ret;369 return ret;
315370
316if __name__ == '__main__':
317 daemon = UnityExtras.dbus_own_name(BUS_NAME, Daemon, None)
318 if daemon:
319 GLib.unix_signal_add(0, 2, lambda x: daemon.quit(), None)
320 daemon.run([])
321371
372def load_scope():
373 return GDriveScope()

Subscribers

People subscribed via source and target branches

to all changes: