Merge lp:~mhr3/unity-lens-video/fix-1226573 into lp:unity-lens-video

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
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_PREVIEW_ON_LMB seems useless now as Dash always shows previews... Can you remove it (unless you see a reason to fix it, in which case we should probably use x-unity-no-preview://)?

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
=== modified file 'debian/control'
--- debian/control 2013-07-04 08:32:52 +0000
+++ debian/control 2013-09-17 12:19:35 +0000
@@ -35,7 +35,6 @@
35Architecture: any35Architecture: any
36Depends: ${misc:Depends},36Depends: ${misc:Depends},
37 ${shlibs:Depends},37 ${shlibs:Depends},
38 gvfs-bin,
39Enhances: unity-lens-video38Enhances: unity-lens-video
40Description: Remote videos engine39Description: Remote videos engine
41 This scope adds a remote videos search engine to the Video lens.40 This scope adds a remote videos search engine to the Video lens.
4241
=== modified file 'src/Makefile.am'
--- src/Makefile.am 2013-06-20 16:13:59 +0000
+++ src/Makefile.am 2013-09-17 12:19:35 +0000
@@ -95,7 +95,6 @@
95 remote-scope-globals.vala \95 remote-scope-globals.vala \
96 remote-video-main.vala \96 remote-video-main.vala \
97 remote-scope.vala \97 remote-scope.vala \
98 remote-uri.vala \
99 ubuntu-video-search.vala \98 ubuntu-video-search.vala \
100 utils.vala \99 utils.vala \
101 video-file.vala \100 video-file.vala \
102101
=== modified file 'src/remote-scope.vala'
--- src/remote-scope.vala 2013-06-20 16:13:59 +0000
+++ src/remote-scope.vala 2013-09-17 12:19:35 +0000
@@ -22,14 +22,15 @@
2222
23namespace Unity.VideoLens23namespace Unity.VideoLens
24{24{
25 public class RemoteVideoScope : Unity.DeprecatedScope25 public class RemoteVideoScope : Unity.SimpleScope
26 {26 {
27 private static int REFRESH_INTERVAL = 3600; // fetch sources & recommendations once an hour27 private const int REFRESH_INTERVAL = 3600; // fetch sources & recommendations once an hour
28 private static int RETRY_INTERVAL = 60; // retry sources/recommendations after a minute28 private const int RETRY_INTERVAL = 60; // retry sources/recommendations after a minute
2929
30 private static string PREVIEW_ON_LMB = "lmb-preview";30 private const string RESULT_PREVIEW_ON_LMB = "lmb-preview";
31 private const string RESULT_DETAILS_URI = "details-uri";
32
31 private Soup.Session session;33 private Soup.Session session;
32 private PreferencesManager preferences = PreferencesManager.get_default ();
33 Gee.ArrayList<RemoteVideoFile?> recommendations;34 Gee.ArrayList<RemoteVideoFile?> recommendations;
34 int64 recommendations_last_update = 0;35 int64 recommendations_last_update = 0;
35 Zeitgeist.DataSourceRegistry zg_sources;36 Zeitgeist.DataSourceRegistry zg_sources;
@@ -37,14 +38,18 @@
3738
38 public RemoteVideoScope ()39 public RemoteVideoScope ()
39 {40 {
40 Object (dbus_path: "/net/launchpad/scope/remotevideos", id: "video-remote.scope");41 Object (unique_name: "/net/launchpad/scope/remotevideos",
42 group_name: "net.launchpad.scope.RemoteVideos");
41 }43 }
4244
43 protected override void constructed ()45 protected override void constructed ()
44 {46 {
45 base.constructed ();47 base.constructed ();
4648
47 schema.add_field (PREVIEW_ON_LMB, "b", Unity.Schema.FieldType.OPTIONAL);49 var schema = new Unity.Schema ();
50 schema.add_field (RESULT_PREVIEW_ON_LMB, "b", Unity.Schema.FieldType.OPTIONAL);
51 schema.add_field (RESULT_DETAILS_URI, "s", Unity.Schema.FieldType.OPTIONAL);
52 this.schema = schema;
4853
49 recommendations = new Gee.ArrayList<RemoteVideoFile?> ();54 recommendations = new Gee.ArrayList<RemoteVideoFile?> ();
5055
@@ -65,39 +70,18 @@
65 session.user_agent = "Unity Video Lens Remote Scope v" + Config.VERSION;70 session.user_agent = "Unity Video Lens Remote Scope v" + Config.VERSION;
66 session.add_feature_by_type (typeof (SoupGNOME.ProxyResolverGNOME));71 session.add_feature_by_type (typeof (SoupGNOME.ProxyResolverGNOME));
6772
68 search_in_global = false;
69 search_changed.connect ((search, search_type, cancellable) =>
70 {
71 update_search_async.begin (search, search_type, cancellable);
72 });
73
74 generate_search_key.connect ((scope, search) =>
75 {
76 return search.search_string.strip ();
77 });
78
79 preferences.notify["remote-content-search"].connect ((obj, pspec) =>
80 {
81 queue_search_changed (SearchType.DEFAULT);
82 });
83
84 populate_categories ();73 populate_categories ();
85 query_list_of_sources ();
8674
87 // refresh the at least once every 30 minutes75 // refresh the search at least once every 30 minutes
88 GLib.Timeout.add_seconds (REFRESH_INTERVAL/2, () =>76 GLib.Timeout.add_seconds (REFRESH_INTERVAL/2, () =>
89 {77 {
90 queue_search_changed (SearchType.DEFAULT); return true;78 results_invalidated (SearchType.DEFAULT);
79 return true;
91 });80 });
9281
93 try82 set_search_async_func (dispatch_search);
94 {83 set_preview_async_func (dispatch_preview);
95 export ();84 set_activate_func (activate_result);
96 }
97 catch (Error e)
98 {
99 error ("Failed to export scope: %s", e.message);
100 }
101 }85 }
10286
103 private void populate_categories ()87 private void populate_categories ()
@@ -108,121 +92,89 @@
108 categories.add(new Unity.Category ("online", _("Online"), new FileIcon (icon_dir.get_child ("group-internet.svg")), Unity.CategoryRenderer.VERTICAL_TILE));92 categories.add(new Unity.Category ("online", _("Online"), new FileIcon (icon_dir.get_child ("group-internet.svg")), Unity.CategoryRenderer.VERTICAL_TILE));
109 categories.add(new Unity.Category ("more", _("More suggestions"), new FileIcon (icon_dir.get_child ("group-treat-yourself.svg")), Unity.CategoryRenderer.VERTICAL_TILE));93 categories.add(new Unity.Category ("more", _("More suggestions"), new FileIcon (icon_dir.get_child ("group-treat-yourself.svg")), Unity.CategoryRenderer.VERTICAL_TILE));
11094
111 this.categories = categories;95 this.category_set = categories;
96 }
97
98 private void dispatch_search (ScopeSearchBase search,
99 ScopeSearchBaseCallback cb)
100 {
101 perform_search.begin (search, (obj, res) =>
102 {
103 try
104 {
105 perform_search.end (res);
106 }
107 catch (Error err)
108 {
109 warning ("Unable to perform search: %s", err.message);
110 }
111 cb (search);
112 });
113 }
114
115 private void dispatch_preview (ResultPreviewer previewer,
116 AbstractPreviewCallback cb)
117 {
118 preview_result.begin (previewer.result, (obj, res) =>
119 {
120 var preview = preview_result.end (res);
121 cb (previewer, preview);
122 });
123 }
124
125 public override string normalize_search_query (string search_query)
126 {
127 return search_query.strip ();
112 }128 }
113129
114 /* Query the server for a list of sources that will be used130 /* Query the server for a list of sources that will be used
115 * to build sources filter options and search queries.131 * to build sources filter options and search queries.
116 */132 */
117 private void query_list_of_sources ()133 private async void query_list_of_sources ()
118 {134 {
119 var msg = new Soup.Message ("GET", UbuntuVideoSearch.sources_uri ());135 try
120 session.queue_message (msg, sources_cb);136 {
121 }137 var sources_msg = new Soup.Message ("GET", UbuntuVideoSearch.sources_uri ());
122138 var msg = yield queue_soup_message (sources_msg);
123 private Gee.ArrayList<RemoteVideoFile?>? handle_search_response (Soup.Message msg, bool is_treat_yourself = false)139 var sources_array = UbuntuVideoSearch.process_sources_results ((string) msg.response_body.data);
124 {140 // FIXME: do something with the sources once we support dynamic filters
125 if (msg.status_code != 200)141 }
126 {142 catch (Error e)
127 warning ("Unable to get results from the server: %u, %s", msg.status_code, msg.reason_phrase);143 {
128 }144 warning ("Got invalid json from the server");
129 else145 }
130 {146
131 try147 // refresh the sources after a while
132 {148 GLib.Timeout.add_seconds (REFRESH_INTERVAL, () =>
133 return UbuntuVideoSearch.process_search_results ((string)msg.response_body.data, is_treat_yourself);149 {
134 }150 query_list_of_sources.begin (); return false;
135 catch (Error e)
136 {
137 warning ("Error processing search results: %s", e.message);
138 }
139 }
140 return null;
141 }
142
143 private void sources_cb (Soup.Session session, Soup.Message msg)
144 {
145 uint interval = RETRY_INTERVAL;
146 if (msg.status_code != 200)
147 {
148 warning ("Unable to query the server for a list of sources, %u: %s", msg.status_code, msg.reason_phrase);
149 }
150 else
151 {
152 try
153 {
154 var sources_array = UbuntuVideoSearch.process_sources_results ((string) msg.response_body.data);
155
156 // remove all existing sources
157 var to_remove = new SList<string> ();
158 foreach (var opt in sources.options)
159 to_remove.append (opt.id);
160 foreach (var id in to_remove)
161 sources.remove_option (id);
162
163 // add sources
164 foreach (var src in sources_array)
165 {
166 sources.add_option (src, src, null);
167 }
168 interval = REFRESH_INTERVAL;
169 }
170 catch (Error e)
171 {
172 warning ("Got invalid json from the server");
173 }
174 }
175 GLib.Timeout.add_seconds (interval, () =>
176 {
177 query_list_of_sources (); return false;
178 });151 });
179 }152 }
180153
181 public override async Unity.ActivationResponse? activate_result (ScopeResult result)154 public Unity.ActivationResponse? activate_result (ScopeResult result,
155 SearchMetadata metadata,
156 string? action_id)
182 {157 {
183 var realcat = result.metadata.lookup (PREVIEW_ON_LMB);158 var realcat = result.metadata.lookup (RESULT_PREVIEW_ON_LMB);
184 // activation of More Suggestions should display a preview.159 // activation of More Suggestions should display a preview.
185 if (realcat != null && realcat.get_boolean ())160 if (action_id == null && realcat != null && realcat.get_boolean ())
186 {161 {
187 var preview = yield preview_result (result);162 return new Unity.ActivationResponse (Unity.HandledType.SHOW_PREVIEW);
188 return new Unity.ActivationResponse.with_preview (preview);
189 }163 }
190164
191 return on_activate_uri (result.uri);165 return on_activate_uri (result);
192 }166 }
193167
194 private Unity.ActivationResponse on_activate_uri (string rawuri)168 private Unity.ActivationResponse on_activate_uri (Unity.ScopeResult result)
195 {169 {
196 var fakeuri = RemoteUri.from_rawuri (rawuri);170 zeitgeist_insert_event (result.uri, result.title, result.icon_hint);
197 if (fakeuri != null)171 // let unity open the uri for us
198 {
199 if (use_zeitgeist)
200 zeitgeist_insert_event (fakeuri.uri, fakeuri.title, fakeuri.icon);
201 try
202 {
203 GLib.AppInfo.launch_default_for_uri (fakeuri.uri, null);
204 return new Unity.ActivationResponse (Unity.HandledType.HIDE_DASH);
205 }
206 catch (GLib.Error e)
207 {
208 warning ("Failed to launch default application for '%s': %s", fakeuri.uri, e.message);
209 }
210 }
211 else
212 {
213 warning ("Invalid raw uri: '%s'", rawuri);
214 }
215 return new Unity.ActivationResponse (Unity.HandledType.NOT_HANDLED);172 return new Unity.ActivationResponse (Unity.HandledType.NOT_HANDLED);
216 }173 }
217174
218 private Unity.ActivationResponse on_play_video (string rawuri)175 private Unity.Preview? build_preview (ScopeResult result, RemoteVideoDetails? details)
219 {176 {
220 return on_activate_uri (rawuri);177 string title = result.title;
221 }
222
223 private Unity.Preview? build_preview (RemoteUri uri, RemoteVideoDetails? details)
224 {
225 string title = uri.title;
226 string subtitle = "";178 string subtitle = "";
227 string description = "";179 string description = "";
228180
@@ -244,11 +196,24 @@
244 }196 }
245 }197 }
246198
247 GLib.Icon thumbnail = new GLib.FileIcon (GLib.File.new_for_uri (details != null ? details.image : uri.icon));199 GLib.Icon thumbnail;
200 if (details != null)
201 {
202 thumbnail = new GLib.FileIcon (GLib.File.new_for_uri (details.image));
203 }
204 else
205 {
206 try
207 {
208 thumbnail = GLib.Icon.new_for_string (result.icon_hint);
209 }
210 catch (Error err) { thumbnail = null; }
211 }
248212
249 var real_preview = new Unity.MoviePreview (title, subtitle, description, thumbnail);213 if (subtitle == "") subtitle = result.comment;
214 var real_preview = new Unity.MoviePreview (title, subtitle,
215 description, thumbnail);
250 var play_video = new Unity.PreviewAction ("play", _("Play"), null);216 var play_video = new Unity.PreviewAction ("play", _("Play"), null);
251 play_video.activated.connect (on_play_video);
252 real_preview.add_action (play_video);217 real_preview.add_action (play_video);
253218
254 // For now, rating == -1 and num_ratings == 0 hides the rating widget from the preview219 // For now, rating == -1 and num_ratings == 0 hides the rating widget from the preview
@@ -277,159 +242,103 @@
277 return real_preview;242 return real_preview;
278 }243 }
279244
280 public override async Preview? preview_result (ScopeResult result)245 public async Preview? preview_result (ScopeResult result)
281 {246 {
282 var fakeuri = RemoteUri.from_rawuri (result.uri);247 var uri_variant = result.metadata.lookup (RESULT_DETAILS_URI);
283 if (fakeuri != null)248 var details_uri = uri_variant.get_string ();
249 if (details_uri != null && details_uri != "")
284 {250 {
285 RemoteVideoDetails? details = null;251 try
286252 {
287 if (fakeuri.details_uri != null && fakeuri.details_uri != "")253 var details = yield get_details (details_uri);
288 {254 return build_preview (result, details);
289 try255 }
290 {256 catch (Error e)
291 details = yield get_details (fakeuri.details_uri);257 {
292 }258 warning ("Failed to fetch video details: %s", e.message);
293 catch (Error e)259 }
294 {
295 warning ("Failed to fetch video details: %s", e.message);
296 }
297 }
298
299 return build_preview (fakeuri, details);
300 }260 }
301 else261 else
302 {262 {
303 warning ("Invalid raw uri: '%s'", result.uri);263 warning ("Missing details uri for: '%s'", result.uri);
304 }264 }
305265 return build_preview (result, null);
306 return null;
307 }266 }
308267
309 private async RemoteVideoDetails? get_details (string url) throws Error268 private async RemoteVideoDetails? get_details (string url) throws Error
310 {269 {
311 var msg = new Soup.Message ("GET", url);270 try
312 session.queue_message (msg, (session_, msg_) =>271 {
313 {272 var msg = yield queue_soup_message (new Soup.Message ("GET", url));
314 msg = msg_;
315 get_details.callback ();
316 });
317
318 yield;
319
320 if (msg.status_code != 200)
321 {
322 warning ("Unable to get details from the server: %u, %s", msg.status_code, msg.reason_phrase);
323 return null;
324 }
325 else
326 {
327 var details = UbuntuVideoSearch.process_details_results ((string) msg.response_body.data);273 var details = UbuntuVideoSearch.process_details_results ((string) msg.response_body.data);
328 return details;274 return details;
329 }275 }
330 }276 catch (Error err)
331277 {
332 private async void update_search_async (DeprecatedScopeSearch search, SearchType search_type, GLib.Cancellable? cancellable)278 warning ("Unable to get details from the server: %s", err.message);
333 {279 }
334 var search_string = search.search_string.strip ();280 return null;
335 debug ("Remote search string changed to: %s", search_string);
336
337 var model = search.results_model;
338 model.clear ();
339
340 // only perform the request if the user has not disabled
341 // online/commercial suggestions. That will hide the category as well.
342 if (preferences.remote_content_search != Unity.PreferencesManager.RemoteContent.ALL)
343 {
344 search.finished();
345 return;
346 }
347
348 // create a list of activated sources
349 var active_sources = new Gee.ArrayList<string> (null);
350 foreach (var opt in sources.options)
351 {
352 if (source_activated (opt.id))
353 active_sources.add (opt.id);
354 }
355
356 // If all the sources are activated, don't bother passing them as arguments
357 if (active_sources.size == sources.options.length ())
358 {
359 active_sources.clear ();
360 }
361
362 if (search_type == Unity.SearchType.DEFAULT)
363 {
364 if (at_least_one_source_is_on (active_sources))
365 {
366 try
367 {
368 yield perform_search (search_string, search, active_sources, cancellable);
369 }
370 catch (Error e)
371 {
372 warning ("Search interrupted: %s", e.message);
373 }
374 }
375 }
376
377 search.finished ();
378 }
379
380 private bool source_activated (string id)
381 {
382 bool active = sources.get_option (id).active;
383 bool filtering = sources.filtering;
384
385 if ((active && filtering) || (!active && !filtering))
386 return true;
387 return false;
388 }
389
390 /* Return a general activation state of all sources of this scope.
391 * This is needed, because we don't want to show recommends if an option
392 * from another scope is the only one activated
393 */
394 private bool at_least_one_source_is_on (Gee.ArrayList<string> active_sources)
395 {
396 return (sources.filtering && active_sources.size > 0 || !sources.filtering);
397 }281 }
398282
399 /* Query the server with the search string and the list of sources.283 /* Query the server with the search string and the list of sources.
400 */284 */
401 private async void perform_search (string search_string, DeprecatedScopeSearch search, Gee.ArrayList<string> active_sources, GLib.Cancellable? cancellable) throws Error285 private async void perform_search (ScopeSearchBase search) throws Error
402 {286 {
403 search.results_model.clear ();287 if (search.search_context.search_type != Unity.SearchType.DEFAULT) return;
288 var search_string = search.search_context.search_query;
289 var result_set = search.search_context.result_set;
404290
405 if ((search_string == null || search_string == "") && (active_sources.size == 0) && (recommendations.size > 0))291 if ((search_string == null || search_string == "") && (recommendations.size > 0))
406 {292 {
407 var time = new DateTime.now_utc ();293 var time = new DateTime.now_utc ();
294 // do we have cached recommendations?
408 if (time.to_unix () - recommendations_last_update < REFRESH_INTERVAL)295 if (time.to_unix () - recommendations_last_update < REFRESH_INTERVAL)
409 {296 {
410 debug ("Updating search results with recommendations");297 debug ("Updating search results with recommendations");
411 update_results_model (search.results_model, recommendations);298 push_results (result_set, recommendations);
299 result_set.ttl = REFRESH_INTERVAL;
412 return;300 return;
413 }301 }
414 }302 }
415303
416 var url = UbuntuVideoSearch.build_search_uri (search_string, active_sources);304 var cancellable = search.search_context.cancellable.get_gcancellable ();
305 var url = UbuntuVideoSearch.build_search_uri (search_string, null, search.search_context.search_metadata.form_factor);
417 debug ("Querying the server: %s", url);306 debug ("Querying the server: %s", url);
418307
419 bool is_treat_yourself = (search_string == null || search_string == "" || active_sources.size == 0);308 bool is_treat_yourself = (search_string == null || search_string == "");
420 var msg = new Soup.Message ("GET", url);309
421310 var msg = yield queue_soup_message (new Soup.Message ("GET", url), cancellable);
311
312 var results = UbuntuVideoSearch.process_search_results ((string)msg.response_body.data, is_treat_yourself);
313 if (results != null)
314 {
315 if (search_string == null || search_string.strip () == "")
316 {
317 debug ("Empty search, updating recommendations");
318 var time = new DateTime.now_utc ();
319 recommendations = results;
320 recommendations_last_update = time.to_unix ();
321 }
322 push_results (result_set, results);
323 }
324 }
325
326 private async Soup.Message? queue_soup_message (Soup.Message msg,
327 GLib.Cancellable? cancellable = null)
328 throws Error
329 {
330 Soup.Message? result_msg = null;
422 session.queue_message (msg, (session_, msg_) =>331 session.queue_message (msg, (session_, msg_) =>
423 {332 {
424 msg = msg_;333 result_msg = msg_;
425 perform_search.callback ();334 queue_soup_message.callback ();
426 });335 });
427336
428 var cancelled = false;337 var cancelled = false;
429 ulong cancel_id = 0;338 ulong cancel_id = 0;
430 if (cancellable != null)339 if (cancellable != null)
431 {340 {
432 cancel_id = cancellable.connect (() =>341 cancel_id = cancellable.cancelled.connect (() =>
433 {342 {
434 cancelled = true;343 cancelled = true;
435 session.cancel_message (msg, Soup.KnownStatusCode.CANCELLED);344 session.cancel_message (msg, Soup.KnownStatusCode.CANCELLED);
@@ -442,39 +351,36 @@
442 {351 {
443 // we can't disconnect right away, as that would deadlock (cause352 // we can't disconnect right away, as that would deadlock (cause
444 // cancel_message doesn't return before invoking the callback)353 // cancel_message doesn't return before invoking the callback)
445 Idle.add (perform_search.callback);354 Idle.add (queue_soup_message.callback);
446 yield;355 yield;
447 cancellable.disconnect (cancel_id);356 cancellable.disconnect (cancel_id);
448 throw new IOError.CANCELLED ("Cancelled");357 throw new IOError.CANCELLED ("Cancelled");
449 }358 }
450359
451 if (cancellable != null)360 if (cancellable != null)
452 {
453 // clean up
454 cancellable.disconnect (cancel_id);361 cancellable.disconnect (cancel_id);
455 }362
456363 if (result_msg.status_code < 100)
457 var results = handle_search_response (msg, is_treat_yourself);364 {
458 if (results != null)365 throw new IOError.FAILED ("Request failed with error %u",
459 {366 result_msg.status_code);
460 if (search_string == null || search_string.strip () == "" && active_sources.size == 0)367 }
461 {368
462 debug ("Empty search, updating recommendations");369 if (result_msg.status_code != 200)
463 var time = new DateTime.now_utc ();370 {
464 recommendations = results;371 throw new IOError.FAILED ("Request returned status code %u",
465 recommendations_last_update = time.to_unix ();372 result_msg.status_code);
466 }373 }
467 update_results_model (search.results_model, results);374
468 }375 return result_msg;
469 }376 }
470377
471 private void update_results_model (Dee.Model model, Gee.ArrayList<RemoteVideoFile?> results)378 private void push_results (Unity.ResultSet result_set, Gee.ArrayList<RemoteVideoFile?> results)
472 {379 {
473 foreach (var video in results)380 foreach (var video in results)
474 {381 {
475 if (video.uri.has_prefix ("http"))382 if (video.uri.has_prefix ("http"))
476 {383 {
477 var fake_uri = new RemoteUri (video.uri, video.title, video.icon, video.details_uri);
478 var result_icon = video.icon;384 var result_icon = video.icon;
479385
480 if (video.category == CAT_INDEX_MORE && video.price != null && video.price != "")386 if (video.category == CAT_INDEX_MORE && video.price != null && video.price != "")
@@ -487,9 +393,19 @@
487393
488 // aggregator scope remaps categories, so we won't get real category back;394 // aggregator scope remaps categories, so we won't get real category back;
489 // put real category into metadata395 // put real category into metadata
490 var realcat = new Variant.dict_entry (PREVIEW_ON_LMB, new Variant.variant (video.category == CAT_INDEX_MORE));396 var realcat = new Variant.dict_entry (RESULT_PREVIEW_ON_LMB,
491 var metadata = new Variant.array (VariantType.VARDICT.element (), {realcat});397 new Variant.variant (video.category == CAT_INDEX_MORE));
492 model.append (fake_uri.to_rawuri (), result_icon, video.category, ResultType.DEFAULT, "text/html", video.title, video.comment, video.uri, metadata);398 var details_uri = new Variant.dict_entry (RESULT_DETAILS_URI,
399 new Variant.variant (video.details_uri));
400 var metadata = new Variant.array (VariantType.VARDICT.element (), {realcat, details_uri});
401
402 var result = new Variant ("(ssuussss@a{sv})", video.uri,
403 result_icon, video.category,
404 ResultType.DEFAULT, "text/html",
405 video.title, video.comment,
406 video.uri, metadata);
407
408 result_set.add_result_from_variant (result);
493 }409 }
494 }410 }
495 }411 }
@@ -501,18 +417,20 @@
501 var ev = new Zeitgeist.Event.full (Zeitgeist.ZG_ACCESS_EVENT, Zeitgeist.ZG_USER_ACTIVITY, "lens://unity-lens-video");417 var ev = new Zeitgeist.Event.full (Zeitgeist.ZG_ACCESS_EVENT, Zeitgeist.ZG_USER_ACTIVITY, "lens://unity-lens-video");
502 templates.add ((ev as GLib.Object).ref());418 templates.add ((ev as GLib.Object).ref());
503 var data_source = new Zeitgeist.DataSource.full ("98898", "Unity Video Lens", "", templates);419 var data_source = new Zeitgeist.DataSource.full ("98898", "Unity Video Lens", "", templates);
504 zg_sources.register_data_source (data_source, null);420 zg_sources.register_data_source.begin (data_source, null);
505 }421 }
506422
507 private void zeitgeist_insert_event (string uri, string title, string icon)423 private void zeitgeist_insert_event (string uri, string title, string icon)
508 {424 {
425 if (!use_zeitgeist) return;
426
509 var subject = new Zeitgeist.Subject.full (uri, Zeitgeist.NFO_VIDEO, Zeitgeist.NFO_REMOTE_DATA_OBJECT, "", uri, title, icon);427 var subject = new Zeitgeist.Subject.full (uri, Zeitgeist.NFO_VIDEO, Zeitgeist.NFO_REMOTE_DATA_OBJECT, "", uri, title, icon);
510 var event = new Zeitgeist.Event.full (Zeitgeist.ZG_ACCESS_EVENT, Zeitgeist.ZG_USER_ACTIVITY, "lens://unity-lens-video");428 var event = new Zeitgeist.Event.full (Zeitgeist.ZG_ACCESS_EVENT, Zeitgeist.ZG_USER_ACTIVITY, "lens://unity-lens-video");
511 event.add_subject (subject);429 event.add_subject (subject);
512430
513 var ev_array = new PtrArray.sized(1);431 var ev_array = new PtrArray.sized(1);
514 ev_array.add ((event as GLib.Object).ref ());432 ev_array.add ((event as GLib.Object).ref ());
515 Zeitgeist.Log.get_default ().insert_events_from_ptrarray (ev_array, null);433 Zeitgeist.Log.get_default ().insert_events_from_ptrarray.begin (ev_array, null);
516 }434 }
517 }435 }
518}436}
519437
=== removed file 'src/remote-uri.vala'
--- src/remote-uri.vala 2012-11-15 13:34:30 +0000
+++ src/remote-uri.vala 1970-01-01 00:00:00 +0000
@@ -1,52 +0,0 @@
1/*
2 * Copyright (C) 2012 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by Pawel Stolowski <pawel.stolowski@canonical.com>
17 */
18
19namespace Unity.VideoLens
20{
21 public class RemoteUri
22 {
23 public string uri { get; set; }
24 public string title { get; set; }
25 public string icon { get; set; }
26 public string details_uri { get; set; }
27
28 public RemoteUri (string uri, string title, string icon, string details_uri)
29 {
30 this.uri = uri;
31 this.title = title;
32 this.icon = icon;
33 this.details_uri = details_uri;
34 }
35
36 public static RemoteUri? from_rawuri (string raw_uri)
37 {
38 RemoteUri uri = null;
39 string[] args = raw_uri.split ("lens-meta://", 4);
40 if (args.length == 4)
41 {
42 uri = new RemoteUri (args[0], args[1], args[2], args[3]);
43 }
44 return uri;
45 }
46
47 public string to_rawuri ()
48 {
49 return string.join ("lens-meta://", uri, title, icon, details_uri);
50 }
51 }
52}
53\ No newline at end of file0\ No newline at end of file
541
=== modified file 'src/remote-video-main.vala'
--- src/remote-video-main.vala 2013-05-16 11:31:51 +0000
+++ src/remote-video-main.vala 2013-09-17 12:19:35 +0000
@@ -19,10 +19,6 @@
1919
20namespace Unity.VideoLens {20namespace Unity.VideoLens {
2121
22 static const string BUS_NAME = "net.launchpad.scope.RemoteVideos";
23 Unity.DeprecatedScope scope;
24 static Application? app = null;
25
26 public static int main (string[] args)22 public static int main (string[] args)
27 {23 {
28 GLib.Environment.set_prgname ("unity-remote-video-scope");24 GLib.Environment.set_prgname ("unity-remote-video-scope");
@@ -34,28 +30,19 @@
34 GLib.Intl.bind_textdomain_codeset (Config.PACKAGE, "UTF-8");30 GLib.Intl.bind_textdomain_codeset (Config.PACKAGE, "UTF-8");
35 GLib.Intl.setlocale(GLib.LocaleCategory.ALL, "");31 GLib.Intl.setlocale(GLib.LocaleCategory.ALL, "");
3632
33 var scope = new RemoteVideoScope ();
34 var exporter = new Unity.ScopeDBusConnector (scope);
37 try35 try
38 {36 {
39 app = Extras.dbus_own_name (BUS_NAME, () =>37 exporter.export ();
40 {38 }
41 scope = new RemoteVideoScope ();39 catch (GLib.Error e)
42 scope.export ();40 {
43 });41 error ("Cannot export scope to DBus: %s", e.message);
44 }42 }
45 catch (Error e)43 Unity.ScopeDBusConnector.run ();
46 {44
47 warning ("Failed to start video lens daemon: %s\n", e.message);45 return 0;
48 return 1;
49 }
50
51 if (app == null)
52 {
53 warning ("Another instance of the Unity Videos Lens " +
54 "already appears to be running.\nBailing out.\n");
55 return 2;
56 }
57
58 return app.run ();
59 }46 }
6047
61} /* namespace */48} /* namespace */
6249
=== modified file 'src/ubuntu-video-search.vala'
--- src/ubuntu-video-search.vala 2012-11-27 12:07:22 +0000
+++ src/ubuntu-video-search.vala 2013-09-17 12:19:35 +0000
@@ -28,10 +28,10 @@
2828
29 public static string recommendations_uri ()29 public static string recommendations_uri ()
30 {30 {
31 return SERVER + "/search?q=&sources=Amazon";31 return SERVER + "/search?q=";
32 }32 }
3333
34 public static string build_search_uri (string query, Gee.ArrayList<string>? sources)34 public static string build_search_uri (string query, Gee.ArrayList<string>? sources, string? form_factor = null)
35 {35 {
36 var uri = new StringBuilder ();36 var uri = new StringBuilder ();
37 uri.append (SERVER);37 uri.append (SERVER);
@@ -48,6 +48,11 @@
48 uri.append (sources[i]);48 uri.append (sources[i]);
49 }49 }
50 }50 }
51 if (form_factor != null)
52 {
53 uri.append ("&form_factor=");
54 uri.append (form_factor);
55 }
51 return uri.str;56 return uri.str;
52 }57 }
5358
@@ -226,4 +231,4 @@
226 });231 });
227 return videos;232 return videos;
228 }233 }
229}
230\ No newline at end of file234\ No newline at end of file
235}
231236
=== modified file 'tests/unit/Makefile.am'
--- tests/unit/Makefile.am 2013-06-20 18:12:31 +0000
+++ tests/unit/Makefile.am 2013-09-17 12:19:35 +0000
@@ -65,7 +65,6 @@
65 $(top_srcdir)/src/ubuntu-video-search.vala \65 $(top_srcdir)/src/ubuntu-video-search.vala \
66 $(top_srcdir)/src/video-file.vala \66 $(top_srcdir)/src/video-file.vala \
67 $(top_srcdir)/src/remote-scope.vala \67 $(top_srcdir)/src/remote-scope.vala \
68 $(top_srcdir)/src/remote-uri.vala \
69 $(top_srcdir)/src/utils.vala \68 $(top_srcdir)/src/utils.vala \
70 $(NULL)69 $(NULL)
7170

Subscribers

People subscribed via source and target branches