Merge lp:~mhr3/unity-lens-video/fix-1226573 into lp:unity-lens-video
- fix-1226573
- Merge into trunk
Proposed by
Michal Hruby
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Paweł Stołowski | ||||||||
Approved revision: | 124 | ||||||||
Merged at revision: | 121 | ||||||||
Proposed branch: | lp:~mhr3/unity-lens-video/fix-1226573 | ||||||||
Merge into: | lp:unity-lens-video | ||||||||
Diff against target: |
811 lines (+210/-355) 7 files modified
debian/control (+0/-1) src/Makefile.am (+0/-1) src/remote-scope.vala (+191/-273) src/remote-uri.vala (+0/-52) src/remote-video-main.vala (+11/-24) src/ubuntu-video-search.vala (+8/-3) tests/unit/Makefile.am (+0/-1) |
||||||||
To merge this branch: | bzr merge lp:~mhr3/unity-lens-video/fix-1226573 | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Paweł Stołowski (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+186020@code.launchpad.net |
Commit message
Simplify the scope, use the non-deprecated API, and pass a form-factor hint to the server.
Description of the change
Simplify the scope, use the non-deprecated API, and pass a form-factor hint to the server.
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
Paweł Stołowski (stolowski) wrote : | # |
Looks good and works, but the whole business with RESULT_
review:
Needs Fixing
Revision history for this message
Paweł Stołowski (stolowski) wrote : | # |
After discussing this on IRC, it's better to leave it for now as it can potentially break the behavior of current Unity8 shell.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'debian/control' |
2 | --- debian/control 2013-07-04 08:32:52 +0000 |
3 | +++ debian/control 2013-09-17 12:19:35 +0000 |
4 | @@ -35,7 +35,6 @@ |
5 | Architecture: any |
6 | Depends: ${misc:Depends}, |
7 | ${shlibs:Depends}, |
8 | - gvfs-bin, |
9 | Enhances: unity-lens-video |
10 | Description: Remote videos engine |
11 | This scope adds a remote videos search engine to the Video lens. |
12 | |
13 | === modified file 'src/Makefile.am' |
14 | --- src/Makefile.am 2013-06-20 16:13:59 +0000 |
15 | +++ src/Makefile.am 2013-09-17 12:19:35 +0000 |
16 | @@ -95,7 +95,6 @@ |
17 | remote-scope-globals.vala \ |
18 | remote-video-main.vala \ |
19 | remote-scope.vala \ |
20 | - remote-uri.vala \ |
21 | ubuntu-video-search.vala \ |
22 | utils.vala \ |
23 | video-file.vala \ |
24 | |
25 | === modified file 'src/remote-scope.vala' |
26 | --- src/remote-scope.vala 2013-06-20 16:13:59 +0000 |
27 | +++ src/remote-scope.vala 2013-09-17 12:19:35 +0000 |
28 | @@ -22,14 +22,15 @@ |
29 | |
30 | namespace Unity.VideoLens |
31 | { |
32 | - public class RemoteVideoScope : Unity.DeprecatedScope |
33 | + public class RemoteVideoScope : Unity.SimpleScope |
34 | { |
35 | - private static int REFRESH_INTERVAL = 3600; // fetch sources & recommendations once an hour |
36 | - private static int RETRY_INTERVAL = 60; // retry sources/recommendations after a minute |
37 | - |
38 | - private static string PREVIEW_ON_LMB = "lmb-preview"; |
39 | + private const int REFRESH_INTERVAL = 3600; // fetch sources & recommendations once an hour |
40 | + private const int RETRY_INTERVAL = 60; // retry sources/recommendations after a minute |
41 | + |
42 | + private const string RESULT_PREVIEW_ON_LMB = "lmb-preview"; |
43 | + private const string RESULT_DETAILS_URI = "details-uri"; |
44 | + |
45 | private Soup.Session session; |
46 | - private PreferencesManager preferences = PreferencesManager.get_default (); |
47 | Gee.ArrayList<RemoteVideoFile?> recommendations; |
48 | int64 recommendations_last_update = 0; |
49 | Zeitgeist.DataSourceRegistry zg_sources; |
50 | @@ -37,14 +38,18 @@ |
51 | |
52 | public RemoteVideoScope () |
53 | { |
54 | - Object (dbus_path: "/net/launchpad/scope/remotevideos", id: "video-remote.scope"); |
55 | + Object (unique_name: "/net/launchpad/scope/remotevideos", |
56 | + group_name: "net.launchpad.scope.RemoteVideos"); |
57 | } |
58 | |
59 | protected override void constructed () |
60 | { |
61 | base.constructed (); |
62 | |
63 | - schema.add_field (PREVIEW_ON_LMB, "b", Unity.Schema.FieldType.OPTIONAL); |
64 | + var schema = new Unity.Schema (); |
65 | + schema.add_field (RESULT_PREVIEW_ON_LMB, "b", Unity.Schema.FieldType.OPTIONAL); |
66 | + schema.add_field (RESULT_DETAILS_URI, "s", Unity.Schema.FieldType.OPTIONAL); |
67 | + this.schema = schema; |
68 | |
69 | recommendations = new Gee.ArrayList<RemoteVideoFile?> (); |
70 | |
71 | @@ -65,39 +70,18 @@ |
72 | session.user_agent = "Unity Video Lens Remote Scope v" + Config.VERSION; |
73 | session.add_feature_by_type (typeof (SoupGNOME.ProxyResolverGNOME)); |
74 | |
75 | - search_in_global = false; |
76 | - search_changed.connect ((search, search_type, cancellable) => |
77 | - { |
78 | - update_search_async.begin (search, search_type, cancellable); |
79 | - }); |
80 | - |
81 | - generate_search_key.connect ((scope, search) => |
82 | - { |
83 | - return search.search_string.strip (); |
84 | - }); |
85 | - |
86 | - preferences.notify["remote-content-search"].connect ((obj, pspec) => |
87 | - { |
88 | - queue_search_changed (SearchType.DEFAULT); |
89 | - }); |
90 | - |
91 | populate_categories (); |
92 | - query_list_of_sources (); |
93 | |
94 | - // refresh the at least once every 30 minutes |
95 | + // refresh the search at least once every 30 minutes |
96 | GLib.Timeout.add_seconds (REFRESH_INTERVAL/2, () => |
97 | { |
98 | - queue_search_changed (SearchType.DEFAULT); return true; |
99 | + results_invalidated (SearchType.DEFAULT); |
100 | + return true; |
101 | }); |
102 | |
103 | - try |
104 | - { |
105 | - export (); |
106 | - } |
107 | - catch (Error e) |
108 | - { |
109 | - error ("Failed to export scope: %s", e.message); |
110 | - } |
111 | + set_search_async_func (dispatch_search); |
112 | + set_preview_async_func (dispatch_preview); |
113 | + set_activate_func (activate_result); |
114 | } |
115 | |
116 | private void populate_categories () |
117 | @@ -108,121 +92,89 @@ |
118 | categories.add(new Unity.Category ("online", _("Online"), new FileIcon (icon_dir.get_child ("group-internet.svg")), Unity.CategoryRenderer.VERTICAL_TILE)); |
119 | categories.add(new Unity.Category ("more", _("More suggestions"), new FileIcon (icon_dir.get_child ("group-treat-yourself.svg")), Unity.CategoryRenderer.VERTICAL_TILE)); |
120 | |
121 | - this.categories = categories; |
122 | + this.category_set = categories; |
123 | + } |
124 | + |
125 | + private void dispatch_search (ScopeSearchBase search, |
126 | + ScopeSearchBaseCallback cb) |
127 | + { |
128 | + perform_search.begin (search, (obj, res) => |
129 | + { |
130 | + try |
131 | + { |
132 | + perform_search.end (res); |
133 | + } |
134 | + catch (Error err) |
135 | + { |
136 | + warning ("Unable to perform search: %s", err.message); |
137 | + } |
138 | + cb (search); |
139 | + }); |
140 | + } |
141 | + |
142 | + private void dispatch_preview (ResultPreviewer previewer, |
143 | + AbstractPreviewCallback cb) |
144 | + { |
145 | + preview_result.begin (previewer.result, (obj, res) => |
146 | + { |
147 | + var preview = preview_result.end (res); |
148 | + cb (previewer, preview); |
149 | + }); |
150 | + } |
151 | + |
152 | + public override string normalize_search_query (string search_query) |
153 | + { |
154 | + return search_query.strip (); |
155 | } |
156 | |
157 | /* Query the server for a list of sources that will be used |
158 | * to build sources filter options and search queries. |
159 | */ |
160 | - private void query_list_of_sources () |
161 | - { |
162 | - var msg = new Soup.Message ("GET", UbuntuVideoSearch.sources_uri ()); |
163 | - session.queue_message (msg, sources_cb); |
164 | - } |
165 | - |
166 | - private Gee.ArrayList<RemoteVideoFile?>? handle_search_response (Soup.Message msg, bool is_treat_yourself = false) |
167 | - { |
168 | - if (msg.status_code != 200) |
169 | - { |
170 | - warning ("Unable to get results from the server: %u, %s", msg.status_code, msg.reason_phrase); |
171 | - } |
172 | - else |
173 | - { |
174 | - try |
175 | - { |
176 | - return UbuntuVideoSearch.process_search_results ((string)msg.response_body.data, is_treat_yourself); |
177 | - } |
178 | - catch (Error e) |
179 | - { |
180 | - warning ("Error processing search results: %s", e.message); |
181 | - } |
182 | - } |
183 | - return null; |
184 | - } |
185 | - |
186 | - private void sources_cb (Soup.Session session, Soup.Message msg) |
187 | - { |
188 | - uint interval = RETRY_INTERVAL; |
189 | - if (msg.status_code != 200) |
190 | - { |
191 | - warning ("Unable to query the server for a list of sources, %u: %s", msg.status_code, msg.reason_phrase); |
192 | - } |
193 | - else |
194 | - { |
195 | - try |
196 | - { |
197 | - var sources_array = UbuntuVideoSearch.process_sources_results ((string) msg.response_body.data); |
198 | - |
199 | - // remove all existing sources |
200 | - var to_remove = new SList<string> (); |
201 | - foreach (var opt in sources.options) |
202 | - to_remove.append (opt.id); |
203 | - foreach (var id in to_remove) |
204 | - sources.remove_option (id); |
205 | - |
206 | - // add sources |
207 | - foreach (var src in sources_array) |
208 | - { |
209 | - sources.add_option (src, src, null); |
210 | - } |
211 | - interval = REFRESH_INTERVAL; |
212 | - } |
213 | - catch (Error e) |
214 | - { |
215 | - warning ("Got invalid json from the server"); |
216 | - } |
217 | - } |
218 | - GLib.Timeout.add_seconds (interval, () => |
219 | - { |
220 | - query_list_of_sources (); return false; |
221 | + private async void query_list_of_sources () |
222 | + { |
223 | + try |
224 | + { |
225 | + var sources_msg = new Soup.Message ("GET", UbuntuVideoSearch.sources_uri ()); |
226 | + var msg = yield queue_soup_message (sources_msg); |
227 | + var sources_array = UbuntuVideoSearch.process_sources_results ((string) msg.response_body.data); |
228 | + // FIXME: do something with the sources once we support dynamic filters |
229 | + } |
230 | + catch (Error e) |
231 | + { |
232 | + warning ("Got invalid json from the server"); |
233 | + } |
234 | + |
235 | + // refresh the sources after a while |
236 | + GLib.Timeout.add_seconds (REFRESH_INTERVAL, () => |
237 | + { |
238 | + query_list_of_sources.begin (); return false; |
239 | }); |
240 | } |
241 | |
242 | - public override async Unity.ActivationResponse? activate_result (ScopeResult result) |
243 | + public Unity.ActivationResponse? activate_result (ScopeResult result, |
244 | + SearchMetadata metadata, |
245 | + string? action_id) |
246 | { |
247 | - var realcat = result.metadata.lookup (PREVIEW_ON_LMB); |
248 | + var realcat = result.metadata.lookup (RESULT_PREVIEW_ON_LMB); |
249 | // activation of More Suggestions should display a preview. |
250 | - if (realcat != null && realcat.get_boolean ()) |
251 | + if (action_id == null && realcat != null && realcat.get_boolean ()) |
252 | { |
253 | - var preview = yield preview_result (result); |
254 | - return new Unity.ActivationResponse.with_preview (preview); |
255 | + return new Unity.ActivationResponse (Unity.HandledType.SHOW_PREVIEW); |
256 | } |
257 | |
258 | - return on_activate_uri (result.uri); |
259 | + return on_activate_uri (result); |
260 | } |
261 | |
262 | - private Unity.ActivationResponse on_activate_uri (string rawuri) |
263 | + private Unity.ActivationResponse on_activate_uri (Unity.ScopeResult result) |
264 | { |
265 | - var fakeuri = RemoteUri.from_rawuri (rawuri); |
266 | - if (fakeuri != null) |
267 | - { |
268 | - if (use_zeitgeist) |
269 | - zeitgeist_insert_event (fakeuri.uri, fakeuri.title, fakeuri.icon); |
270 | - try |
271 | - { |
272 | - GLib.AppInfo.launch_default_for_uri (fakeuri.uri, null); |
273 | - return new Unity.ActivationResponse (Unity.HandledType.HIDE_DASH); |
274 | - } |
275 | - catch (GLib.Error e) |
276 | - { |
277 | - warning ("Failed to launch default application for '%s': %s", fakeuri.uri, e.message); |
278 | - } |
279 | - } |
280 | - else |
281 | - { |
282 | - warning ("Invalid raw uri: '%s'", rawuri); |
283 | - } |
284 | + zeitgeist_insert_event (result.uri, result.title, result.icon_hint); |
285 | + // let unity open the uri for us |
286 | return new Unity.ActivationResponse (Unity.HandledType.NOT_HANDLED); |
287 | } |
288 | |
289 | - private Unity.ActivationResponse on_play_video (string rawuri) |
290 | - { |
291 | - return on_activate_uri (rawuri); |
292 | - } |
293 | - |
294 | - private Unity.Preview? build_preview (RemoteUri uri, RemoteVideoDetails? details) |
295 | - { |
296 | - string title = uri.title; |
297 | + private Unity.Preview? build_preview (ScopeResult result, RemoteVideoDetails? details) |
298 | + { |
299 | + string title = result.title; |
300 | string subtitle = ""; |
301 | string description = ""; |
302 | |
303 | @@ -244,11 +196,24 @@ |
304 | } |
305 | } |
306 | |
307 | - GLib.Icon thumbnail = new GLib.FileIcon (GLib.File.new_for_uri (details != null ? details.image : uri.icon)); |
308 | + GLib.Icon thumbnail; |
309 | + if (details != null) |
310 | + { |
311 | + thumbnail = new GLib.FileIcon (GLib.File.new_for_uri (details.image)); |
312 | + } |
313 | + else |
314 | + { |
315 | + try |
316 | + { |
317 | + thumbnail = GLib.Icon.new_for_string (result.icon_hint); |
318 | + } |
319 | + catch (Error err) { thumbnail = null; } |
320 | + } |
321 | |
322 | - var real_preview = new Unity.MoviePreview (title, subtitle, description, thumbnail); |
323 | + if (subtitle == "") subtitle = result.comment; |
324 | + var real_preview = new Unity.MoviePreview (title, subtitle, |
325 | + description, thumbnail); |
326 | var play_video = new Unity.PreviewAction ("play", _("Play"), null); |
327 | - play_video.activated.connect (on_play_video); |
328 | real_preview.add_action (play_video); |
329 | |
330 | // For now, rating == -1 and num_ratings == 0 hides the rating widget from the preview |
331 | @@ -277,159 +242,103 @@ |
332 | return real_preview; |
333 | } |
334 | |
335 | - public override async Preview? preview_result (ScopeResult result) |
336 | + public async Preview? preview_result (ScopeResult result) |
337 | { |
338 | - var fakeuri = RemoteUri.from_rawuri (result.uri); |
339 | - if (fakeuri != null) |
340 | + var uri_variant = result.metadata.lookup (RESULT_DETAILS_URI); |
341 | + var details_uri = uri_variant.get_string (); |
342 | + if (details_uri != null && details_uri != "") |
343 | { |
344 | - RemoteVideoDetails? details = null; |
345 | - |
346 | - if (fakeuri.details_uri != null && fakeuri.details_uri != "") |
347 | - { |
348 | - try |
349 | - { |
350 | - details = yield get_details (fakeuri.details_uri); |
351 | - } |
352 | - catch (Error e) |
353 | - { |
354 | - warning ("Failed to fetch video details: %s", e.message); |
355 | - } |
356 | - } |
357 | - |
358 | - return build_preview (fakeuri, details); |
359 | + try |
360 | + { |
361 | + var details = yield get_details (details_uri); |
362 | + return build_preview (result, details); |
363 | + } |
364 | + catch (Error e) |
365 | + { |
366 | + warning ("Failed to fetch video details: %s", e.message); |
367 | + } |
368 | } |
369 | else |
370 | { |
371 | - warning ("Invalid raw uri: '%s'", result.uri); |
372 | + warning ("Missing details uri for: '%s'", result.uri); |
373 | } |
374 | - |
375 | - return null; |
376 | + return build_preview (result, null); |
377 | } |
378 | |
379 | private async RemoteVideoDetails? get_details (string url) throws Error |
380 | { |
381 | - var msg = new Soup.Message ("GET", url); |
382 | - session.queue_message (msg, (session_, msg_) => |
383 | - { |
384 | - msg = msg_; |
385 | - get_details.callback (); |
386 | - }); |
387 | - |
388 | - yield; |
389 | - |
390 | - if (msg.status_code != 200) |
391 | - { |
392 | - warning ("Unable to get details from the server: %u, %s", msg.status_code, msg.reason_phrase); |
393 | - return null; |
394 | - } |
395 | - else |
396 | - { |
397 | + try |
398 | + { |
399 | + var msg = yield queue_soup_message (new Soup.Message ("GET", url)); |
400 | var details = UbuntuVideoSearch.process_details_results ((string) msg.response_body.data); |
401 | return details; |
402 | } |
403 | - } |
404 | - |
405 | - private async void update_search_async (DeprecatedScopeSearch search, SearchType search_type, GLib.Cancellable? cancellable) |
406 | - { |
407 | - var search_string = search.search_string.strip (); |
408 | - debug ("Remote search string changed to: %s", search_string); |
409 | - |
410 | - var model = search.results_model; |
411 | - model.clear (); |
412 | - |
413 | - // only perform the request if the user has not disabled |
414 | - // online/commercial suggestions. That will hide the category as well. |
415 | - if (preferences.remote_content_search != Unity.PreferencesManager.RemoteContent.ALL) |
416 | - { |
417 | - search.finished(); |
418 | - return; |
419 | - } |
420 | - |
421 | - // create a list of activated sources |
422 | - var active_sources = new Gee.ArrayList<string> (null); |
423 | - foreach (var opt in sources.options) |
424 | - { |
425 | - if (source_activated (opt.id)) |
426 | - active_sources.add (opt.id); |
427 | - } |
428 | - |
429 | - // If all the sources are activated, don't bother passing them as arguments |
430 | - if (active_sources.size == sources.options.length ()) |
431 | - { |
432 | - active_sources.clear (); |
433 | - } |
434 | - |
435 | - if (search_type == Unity.SearchType.DEFAULT) |
436 | - { |
437 | - if (at_least_one_source_is_on (active_sources)) |
438 | - { |
439 | - try |
440 | - { |
441 | - yield perform_search (search_string, search, active_sources, cancellable); |
442 | - } |
443 | - catch (Error e) |
444 | - { |
445 | - warning ("Search interrupted: %s", e.message); |
446 | - } |
447 | - } |
448 | - } |
449 | - |
450 | - search.finished (); |
451 | - } |
452 | - |
453 | - private bool source_activated (string id) |
454 | - { |
455 | - bool active = sources.get_option (id).active; |
456 | - bool filtering = sources.filtering; |
457 | - |
458 | - if ((active && filtering) || (!active && !filtering)) |
459 | - return true; |
460 | - return false; |
461 | - } |
462 | - |
463 | - /* Return a general activation state of all sources of this scope. |
464 | - * This is needed, because we don't want to show recommends if an option |
465 | - * from another scope is the only one activated |
466 | - */ |
467 | - private bool at_least_one_source_is_on (Gee.ArrayList<string> active_sources) |
468 | - { |
469 | - return (sources.filtering && active_sources.size > 0 || !sources.filtering); |
470 | + catch (Error err) |
471 | + { |
472 | + warning ("Unable to get details from the server: %s", err.message); |
473 | + } |
474 | + return null; |
475 | } |
476 | |
477 | /* Query the server with the search string and the list of sources. |
478 | */ |
479 | - private async void perform_search (string search_string, DeprecatedScopeSearch search, Gee.ArrayList<string> active_sources, GLib.Cancellable? cancellable) throws Error |
480 | + private async void perform_search (ScopeSearchBase search) throws Error |
481 | { |
482 | - search.results_model.clear (); |
483 | + if (search.search_context.search_type != Unity.SearchType.DEFAULT) return; |
484 | + var search_string = search.search_context.search_query; |
485 | + var result_set = search.search_context.result_set; |
486 | |
487 | - if ((search_string == null || search_string == "") && (active_sources.size == 0) && (recommendations.size > 0)) |
488 | + if ((search_string == null || search_string == "") && (recommendations.size > 0)) |
489 | { |
490 | var time = new DateTime.now_utc (); |
491 | + // do we have cached recommendations? |
492 | if (time.to_unix () - recommendations_last_update < REFRESH_INTERVAL) |
493 | { |
494 | debug ("Updating search results with recommendations"); |
495 | - update_results_model (search.results_model, recommendations); |
496 | + push_results (result_set, recommendations); |
497 | + result_set.ttl = REFRESH_INTERVAL; |
498 | return; |
499 | } |
500 | } |
501 | |
502 | - var url = UbuntuVideoSearch.build_search_uri (search_string, active_sources); |
503 | + var cancellable = search.search_context.cancellable.get_gcancellable (); |
504 | + var url = UbuntuVideoSearch.build_search_uri (search_string, null, search.search_context.search_metadata.form_factor); |
505 | debug ("Querying the server: %s", url); |
506 | |
507 | - bool is_treat_yourself = (search_string == null || search_string == "" || active_sources.size == 0); |
508 | - var msg = new Soup.Message ("GET", url); |
509 | - |
510 | + bool is_treat_yourself = (search_string == null || search_string == ""); |
511 | + |
512 | + var msg = yield queue_soup_message (new Soup.Message ("GET", url), cancellable); |
513 | + |
514 | + var results = UbuntuVideoSearch.process_search_results ((string)msg.response_body.data, is_treat_yourself); |
515 | + if (results != null) |
516 | + { |
517 | + if (search_string == null || search_string.strip () == "") |
518 | + { |
519 | + debug ("Empty search, updating recommendations"); |
520 | + var time = new DateTime.now_utc (); |
521 | + recommendations = results; |
522 | + recommendations_last_update = time.to_unix (); |
523 | + } |
524 | + push_results (result_set, results); |
525 | + } |
526 | + } |
527 | + |
528 | + private async Soup.Message? queue_soup_message (Soup.Message msg, |
529 | + GLib.Cancellable? cancellable = null) |
530 | + throws Error |
531 | + { |
532 | + Soup.Message? result_msg = null; |
533 | session.queue_message (msg, (session_, msg_) => |
534 | { |
535 | - msg = msg_; |
536 | - perform_search.callback (); |
537 | + result_msg = msg_; |
538 | + queue_soup_message.callback (); |
539 | }); |
540 | |
541 | var cancelled = false; |
542 | ulong cancel_id = 0; |
543 | if (cancellable != null) |
544 | { |
545 | - cancel_id = cancellable.connect (() => |
546 | + cancel_id = cancellable.cancelled.connect (() => |
547 | { |
548 | cancelled = true; |
549 | session.cancel_message (msg, Soup.KnownStatusCode.CANCELLED); |
550 | @@ -442,39 +351,36 @@ |
551 | { |
552 | // we can't disconnect right away, as that would deadlock (cause |
553 | // cancel_message doesn't return before invoking the callback) |
554 | - Idle.add (perform_search.callback); |
555 | + Idle.add (queue_soup_message.callback); |
556 | yield; |
557 | cancellable.disconnect (cancel_id); |
558 | throw new IOError.CANCELLED ("Cancelled"); |
559 | } |
560 | |
561 | if (cancellable != null) |
562 | - { |
563 | - // clean up |
564 | cancellable.disconnect (cancel_id); |
565 | - } |
566 | - |
567 | - var results = handle_search_response (msg, is_treat_yourself); |
568 | - if (results != null) |
569 | - { |
570 | - if (search_string == null || search_string.strip () == "" && active_sources.size == 0) |
571 | - { |
572 | - debug ("Empty search, updating recommendations"); |
573 | - var time = new DateTime.now_utc (); |
574 | - recommendations = results; |
575 | - recommendations_last_update = time.to_unix (); |
576 | - } |
577 | - update_results_model (search.results_model, results); |
578 | - } |
579 | + |
580 | + if (result_msg.status_code < 100) |
581 | + { |
582 | + throw new IOError.FAILED ("Request failed with error %u", |
583 | + result_msg.status_code); |
584 | + } |
585 | + |
586 | + if (result_msg.status_code != 200) |
587 | + { |
588 | + throw new IOError.FAILED ("Request returned status code %u", |
589 | + result_msg.status_code); |
590 | + } |
591 | + |
592 | + return result_msg; |
593 | } |
594 | |
595 | - private void update_results_model (Dee.Model model, Gee.ArrayList<RemoteVideoFile?> results) |
596 | + private void push_results (Unity.ResultSet result_set, Gee.ArrayList<RemoteVideoFile?> results) |
597 | { |
598 | foreach (var video in results) |
599 | { |
600 | if (video.uri.has_prefix ("http")) |
601 | { |
602 | - var fake_uri = new RemoteUri (video.uri, video.title, video.icon, video.details_uri); |
603 | var result_icon = video.icon; |
604 | |
605 | if (video.category == CAT_INDEX_MORE && video.price != null && video.price != "") |
606 | @@ -487,9 +393,19 @@ |
607 | |
608 | // aggregator scope remaps categories, so we won't get real category back; |
609 | // put real category into metadata |
610 | - var realcat = new Variant.dict_entry (PREVIEW_ON_LMB, new Variant.variant (video.category == CAT_INDEX_MORE)); |
611 | - var metadata = new Variant.array (VariantType.VARDICT.element (), {realcat}); |
612 | - model.append (fake_uri.to_rawuri (), result_icon, video.category, ResultType.DEFAULT, "text/html", video.title, video.comment, video.uri, metadata); |
613 | + var realcat = new Variant.dict_entry (RESULT_PREVIEW_ON_LMB, |
614 | + new Variant.variant (video.category == CAT_INDEX_MORE)); |
615 | + var details_uri = new Variant.dict_entry (RESULT_DETAILS_URI, |
616 | + new Variant.variant (video.details_uri)); |
617 | + var metadata = new Variant.array (VariantType.VARDICT.element (), {realcat, details_uri}); |
618 | + |
619 | + var result = new Variant ("(ssuussss@a{sv})", video.uri, |
620 | + result_icon, video.category, |
621 | + ResultType.DEFAULT, "text/html", |
622 | + video.title, video.comment, |
623 | + video.uri, metadata); |
624 | + |
625 | + result_set.add_result_from_variant (result); |
626 | } |
627 | } |
628 | } |
629 | @@ -501,18 +417,20 @@ |
630 | var ev = new Zeitgeist.Event.full (Zeitgeist.ZG_ACCESS_EVENT, Zeitgeist.ZG_USER_ACTIVITY, "lens://unity-lens-video"); |
631 | templates.add ((ev as GLib.Object).ref()); |
632 | var data_source = new Zeitgeist.DataSource.full ("98898", "Unity Video Lens", "", templates); |
633 | - zg_sources.register_data_source (data_source, null); |
634 | + zg_sources.register_data_source.begin (data_source, null); |
635 | } |
636 | |
637 | private void zeitgeist_insert_event (string uri, string title, string icon) |
638 | { |
639 | + if (!use_zeitgeist) return; |
640 | + |
641 | var subject = new Zeitgeist.Subject.full (uri, Zeitgeist.NFO_VIDEO, Zeitgeist.NFO_REMOTE_DATA_OBJECT, "", uri, title, icon); |
642 | var event = new Zeitgeist.Event.full (Zeitgeist.ZG_ACCESS_EVENT, Zeitgeist.ZG_USER_ACTIVITY, "lens://unity-lens-video"); |
643 | event.add_subject (subject); |
644 | |
645 | var ev_array = new PtrArray.sized(1); |
646 | ev_array.add ((event as GLib.Object).ref ()); |
647 | - Zeitgeist.Log.get_default ().insert_events_from_ptrarray (ev_array, null); |
648 | + Zeitgeist.Log.get_default ().insert_events_from_ptrarray.begin (ev_array, null); |
649 | } |
650 | } |
651 | } |
652 | |
653 | === removed file 'src/remote-uri.vala' |
654 | --- src/remote-uri.vala 2012-11-15 13:34:30 +0000 |
655 | +++ src/remote-uri.vala 1970-01-01 00:00:00 +0000 |
656 | @@ -1,52 +0,0 @@ |
657 | -/* |
658 | - * Copyright (C) 2012 Canonical Ltd |
659 | - * |
660 | - * This program is free software: you can redistribute it and/or modify |
661 | - * it under the terms of the GNU General Public License version 3 as |
662 | - * published by the Free Software Foundation. |
663 | - * |
664 | - * This program is distributed in the hope that it will be useful, |
665 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
666 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
667 | - * GNU General Public License for more details. |
668 | - * |
669 | - * You should have received a copy of the GNU General Public License |
670 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
671 | - * |
672 | - * Authored by Pawel Stolowski <pawel.stolowski@canonical.com> |
673 | - */ |
674 | - |
675 | -namespace Unity.VideoLens |
676 | -{ |
677 | - public class RemoteUri |
678 | - { |
679 | - public string uri { get; set; } |
680 | - public string title { get; set; } |
681 | - public string icon { get; set; } |
682 | - public string details_uri { get; set; } |
683 | - |
684 | - public RemoteUri (string uri, string title, string icon, string details_uri) |
685 | - { |
686 | - this.uri = uri; |
687 | - this.title = title; |
688 | - this.icon = icon; |
689 | - this.details_uri = details_uri; |
690 | - } |
691 | - |
692 | - public static RemoteUri? from_rawuri (string raw_uri) |
693 | - { |
694 | - RemoteUri uri = null; |
695 | - string[] args = raw_uri.split ("lens-meta://", 4); |
696 | - if (args.length == 4) |
697 | - { |
698 | - uri = new RemoteUri (args[0], args[1], args[2], args[3]); |
699 | - } |
700 | - return uri; |
701 | - } |
702 | - |
703 | - public string to_rawuri () |
704 | - { |
705 | - return string.join ("lens-meta://", uri, title, icon, details_uri); |
706 | - } |
707 | - } |
708 | -} |
709 | \ No newline at end of file |
710 | |
711 | === modified file 'src/remote-video-main.vala' |
712 | --- src/remote-video-main.vala 2013-05-16 11:31:51 +0000 |
713 | +++ src/remote-video-main.vala 2013-09-17 12:19:35 +0000 |
714 | @@ -19,10 +19,6 @@ |
715 | |
716 | namespace Unity.VideoLens { |
717 | |
718 | - static const string BUS_NAME = "net.launchpad.scope.RemoteVideos"; |
719 | - Unity.DeprecatedScope scope; |
720 | - static Application? app = null; |
721 | - |
722 | public static int main (string[] args) |
723 | { |
724 | GLib.Environment.set_prgname ("unity-remote-video-scope"); |
725 | @@ -34,28 +30,19 @@ |
726 | GLib.Intl.bind_textdomain_codeset (Config.PACKAGE, "UTF-8"); |
727 | GLib.Intl.setlocale(GLib.LocaleCategory.ALL, ""); |
728 | |
729 | + var scope = new RemoteVideoScope (); |
730 | + var exporter = new Unity.ScopeDBusConnector (scope); |
731 | try |
732 | { |
733 | - app = Extras.dbus_own_name (BUS_NAME, () => |
734 | - { |
735 | - scope = new RemoteVideoScope (); |
736 | - scope.export (); |
737 | - }); |
738 | - } |
739 | - catch (Error e) |
740 | - { |
741 | - warning ("Failed to start video lens daemon: %s\n", e.message); |
742 | - return 1; |
743 | - } |
744 | - |
745 | - if (app == null) |
746 | - { |
747 | - warning ("Another instance of the Unity Videos Lens " + |
748 | - "already appears to be running.\nBailing out.\n"); |
749 | - return 2; |
750 | - } |
751 | - |
752 | - return app.run (); |
753 | + exporter.export (); |
754 | + } |
755 | + catch (GLib.Error e) |
756 | + { |
757 | + error ("Cannot export scope to DBus: %s", e.message); |
758 | + } |
759 | + Unity.ScopeDBusConnector.run (); |
760 | + |
761 | + return 0; |
762 | } |
763 | |
764 | } /* namespace */ |
765 | |
766 | === modified file 'src/ubuntu-video-search.vala' |
767 | --- src/ubuntu-video-search.vala 2012-11-27 12:07:22 +0000 |
768 | +++ src/ubuntu-video-search.vala 2013-09-17 12:19:35 +0000 |
769 | @@ -28,10 +28,10 @@ |
770 | |
771 | public static string recommendations_uri () |
772 | { |
773 | - return SERVER + "/search?q=&sources=Amazon"; |
774 | + return SERVER + "/search?q="; |
775 | } |
776 | |
777 | - public static string build_search_uri (string query, Gee.ArrayList<string>? sources) |
778 | + public static string build_search_uri (string query, Gee.ArrayList<string>? sources, string? form_factor = null) |
779 | { |
780 | var uri = new StringBuilder (); |
781 | uri.append (SERVER); |
782 | @@ -48,6 +48,11 @@ |
783 | uri.append (sources[i]); |
784 | } |
785 | } |
786 | + if (form_factor != null) |
787 | + { |
788 | + uri.append ("&form_factor="); |
789 | + uri.append (form_factor); |
790 | + } |
791 | return uri.str; |
792 | } |
793 | |
794 | @@ -226,4 +231,4 @@ |
795 | }); |
796 | return videos; |
797 | } |
798 | -} |
799 | \ No newline at end of file |
800 | +} |
801 | |
802 | === modified file 'tests/unit/Makefile.am' |
803 | --- tests/unit/Makefile.am 2013-06-20 18:12:31 +0000 |
804 | +++ tests/unit/Makefile.am 2013-09-17 12:19:35 +0000 |
805 | @@ -65,7 +65,6 @@ |
806 | $(top_srcdir)/src/ubuntu-video-search.vala \ |
807 | $(top_srcdir)/src/video-file.vala \ |
808 | $(top_srcdir)/src/remote-scope.vala \ |
809 | - $(top_srcdir)/src/remote-uri.vala \ |
810 | $(top_srcdir)/src/utils.vala \ |
811 | $(NULL) |
812 |
PASSED: Continuous integration, rev:124 jenkins. qa.ubuntu. com/job/ unity-lens- video-ci/ 9/ jenkins. qa.ubuntu. com/job/ unity-lens- video-saucy- amd64-ci/ 4 jenkins. qa.ubuntu. com/job/ unity-lens- video-saucy- armhf-ci/ 4 jenkins. qa.ubuntu. com/job/ unity-lens- video-saucy- i386-ci/ 4
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins: 8080/job/ unity-lens- video-ci/ 9/rebuild
http://