Merge lp:~mandel/unity-lens-music/plan-b into lp:unity-lens-music

Proposed by Manuel de la Peña
Status: Rejected
Rejected by: Alejandro J. Cura
Proposed branch: lp:~mandel/unity-lens-music/plan-b
Merge into: lp:unity-lens-music
Diff against target: 396 lines (+132/-66)
2 files modified
src/musicstore-scope.vala (+21/-1)
src/ubuntuone-webservices.vala (+111/-65)
To merge this branch: bzr merge lp:~mandel/unity-lens-music/plan-b
Reviewer Review Type Date Requested Status
Unity Team Pending
Review via email: mp+158384@code.launchpad.net

Description of the change

Add code to ensure that a label is shown when u1 creds are not present.

To post a comment you must log in.

Unmerged revisions

133. By Manuel de la Peña

Check creds.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/musicstore-scope.vala'
2--- src/musicstore-scope.vala 2013-02-28 09:48:46 +0000
3+++ src/musicstore-scope.vala 2013-04-11 14:16:23 +0000
4@@ -18,15 +18,19 @@
5 */
6
7 using GLib;
8+using Ubuntuone.Webservice;
9
10 namespace Unity.MusicLens {
11
12 public class MusicStoreScopeProxy : SimpleScope
13 {
14+ const string NO_CREDENTIALS_LABEL_TEXT = _("Before you can purchase music you need to log in to the Ubuntu One app");
15 private MusicStoreCollection collection;
16 private Unity.Extras.PreviewPlayerController preview_player;
17 private Unity.MusicPreview? music_preview;
18 private PreferencesManager preferences = PreferencesManager.get_default ();
19+ private PurchaseService purchase_service;
20+ private bool have_credentials = false;
21
22 public MusicStoreScopeProxy ()
23 {
24@@ -41,6 +45,7 @@
25 base.initialize ();
26
27 collection = new MusicStoreCollection ();
28+ purchase_service = new PurchaseService ();
29
30 preferences.notify["remote-content-search"].connect((obj, pspec) => { scope.queue_search_changed(SearchType.DEFAULT); });
31
32@@ -111,12 +116,19 @@
33 }
34 }
35
36- GLib.Icon? icon = new GLib.FileIcon (File.new_for_path (Config.DATADIR + "/icons/unity-icon-theme/places/svg/service-u1.svg"));
37+ if (have_credentials) {
38+ GLib.Icon? icon = new GLib.FileIcon (File.new_for_path (Config.DATADIR + "/icons/unity-icon-theme/places/svg/service-u1.svg"));
39 var download_action = new Unity.PreviewAction ("download_album", _("Download"), icon);
40 if (album.formatted_price != null)
41 download_action.extra_text = album.formatted_price;
42 download_action.activated.connect (download_album);
43 music_preview.add_action (download_action);
44+ } else {
45+ var data = new HashTable<string, Variant>(str_hash, str_equal);
46+ data["no_credentials_label"] = NO_CREDENTIALS_LABEL_TEXT;
47+ InfoHint info_hint = new InfoHint.with_variant("music_preview", "", null, data);
48+ music_preview.add_info(info_hint);
49+ }
50 }
51 return music_preview;
52 }
53@@ -142,6 +154,14 @@
54 }
55
56 try {
57+ yield purchase_service.fetch_credentials ();
58+ have_credentials = true;
59+ } catch (PurchaseError e) {
60+ // this is not a serious error, just missing credentials
61+ have_credentials = false;
62+ }
63+
64+ try {
65 debug ("model has %u rows before search", search.results_model.get_n_rows ());
66 yield collection.search (search, search_type, (owned) filters, max_results, cancellable);
67 debug ("model has %u rows after search", search.results_model.get_n_rows ());
68
69=== modified file 'src/ubuntuone-webservices.vala'
70--- src/ubuntuone-webservices.vala 2012-12-06 15:39:38 +0000
71+++ src/ubuntuone-webservices.vala 2013-04-11 14:16:23 +0000
72@@ -21,26 +21,29 @@
73
74 [DBus (name = "com.ubuntuone.CredentialsManagement")]
75 interface CredentialsManagement : GLib.Object {
76+ public signal void authorization_denied ();
77 public signal void credentials_found (HashTable <string, string> info);
78+ public signal void credentials_not_found ();
79 public signal void credentials_error ();
80
81 [DBus (name = "find_credentials")]
82 public abstract void find_credentials () throws IOError;
83 }
84
85-const string WEBAPI_URI = "https://edge.one.ubuntu.com/";
86-const string ACCOUNT_URI = WEBAPI_URI + "api/account";
87-const string PAYMENT_METHOD_URI = WEBAPI_URI + "music-store/api/1/user/retrieve-payment-method?purchase_sku=%s";
88-const string PURCHASE_WITH_DEFAULT_PAYMENT_URI = WEBAPI_URI + "music-store/api/1/user/purchase-with-default-payment?purchase_sku=%s&authentication=%s";
89-const string AUTHENTICATION_URI = "https://login.staging.ubuntu.com/api/1.1/authentications";
90+const string WEBAPI_SERVER = "https://one.ubuntu.com/";
91+const string ACCOUNT_PATH = "api/account";
92+const string PAYMENT_METHOD_PATH = "music-store-up/api/1/user/retrieve-payment-method?purchase_sku=%s";
93+const string PURCHASE_WITH_DEFAULT_PAYMENT_PATH = "music-store-up/api/1/user/purchase-with-default-payment?purchase_sku=%s&authentication=%s";
94+const string AUTHENTICATION_SERVER = "https://login.ubuntu.com/";
95+const string AUTHENTICATION_PATH = "api/1.1/authentications";
96 const string AUTHENTICATE_PARAMS = "ws.op=authenticate&token_name=Purchase_Token";
97-const int PASSWORD_CACHE_SECONDS = 300;
98-const int PAYMENT_METHOD_CACHE_SECONDS = 120;
99+
100
101 namespace Ubuntuone.Webservice
102 {
103 public errordomain PurchaseError
104 {
105+ MISSING_CREDENTIALS_ERROR,
106 PURCHASE_ERROR,
107 WRONG_PASSWORD_ERROR,
108 UNSPECIFIED_ERROR
109@@ -56,17 +59,13 @@
110 public string selected_payment_method { get; internal set; default = null; }
111 public string consumer_key { get; private set; default = null; }
112 public string token { get; private set; default = null; }
113- internal DateTime _selected_payment_method_expiry;
114- DateTime _password_expiry;
115+ public string open_url { get; private set; default = null; }
116 internal HashTable <string, string> _ubuntuone_credentials = null;
117
118 construct {
119 http_session = build_http_session ();
120 http_session_sso = build_http_session ();
121
122- reset_payment_method_cache (0);
123- reset_password_cache (0);
124-
125 credentials_management = build_credentials_management ();
126 }
127
128@@ -77,24 +76,40 @@
129 return session;
130 }
131
132- internal DateTime now ()
133- {
134- return new DateTime.now_utc ();
135- }
136-
137- internal bool expired_payment_method_cache ()
138- {
139- return _selected_payment_method_expiry.compare (now ()) <= 0;
140- }
141-
142- internal void reset_payment_method_cache (int seconds_from_now)
143- {
144- _selected_payment_method_expiry = now ().add_seconds (seconds_from_now);
145- }
146-
147- internal void reset_password_cache (int seconds_from_now)
148- {
149- _password_expiry = now ().add_seconds (seconds_from_now);
150+ string webapi_server ()
151+ {
152+ string staging_webapi = Environment.get_variable ("U1_STAGING_WEBAPI");
153+ return staging_webapi != null ? staging_webapi : WEBAPI_SERVER;
154+ }
155+
156+ string account_uri ()
157+ {
158+ return webapi_server() + ACCOUNT_PATH;
159+ }
160+
161+ string payment_method_uri ()
162+ {
163+ return webapi_server() + PAYMENT_METHOD_PATH;
164+ }
165+
166+ string purchase_with_default_payment_uri ()
167+ {
168+ return webapi_server() + PURCHASE_WITH_DEFAULT_PAYMENT_PATH;
169+ }
170+
171+ string authentication_server ()
172+ {
173+ string staging_authentication = Environment.get_variable ("U1_STAGING_AUTHENTICATION");
174+ return staging_authentication != null ? staging_authentication : AUTHENTICATION_SERVER;
175+ }
176+
177+ string authentication_uri ()
178+ {
179+ return authentication_server() + AUTHENTICATION_PATH;
180+ }
181+
182+ public bool got_credentials () {
183+ return _ubuntuone_credentials != null;
184 }
185
186 internal virtual CredentialsManagement build_credentials_management ()
187@@ -125,28 +140,38 @@
188 email = root_object.get_string_member("email");
189 }
190
191- internal void parse_payment_method_json (string json_string) throws GLib.Error
192+ internal void parse_payment_method_json (string json_string) throws GLib.Error, PurchaseError
193 {
194+ stdout.printf("Response is \n%s\n", json_string);
195 var root_object = parse_json (json_string);
196- Json.Object payload = root_object.get_object_member("payload");
197- selected_payment_method = payload.get_string_member("selected_payment_method");
198+ if (root_object.has_member ("selected_payment_method")) {
199+ selected_payment_method = root_object.get_string_member("selected_payment_method");
200+ } else {
201+ open_url = root_object.get_string_member ("open_url");
202+ var error_message = root_object.get_string_member ("error_message");
203+ throw new PurchaseError.PURCHASE_ERROR (error_message);
204+ }
205 }
206
207 internal void parse_authentication_json (string json_string) throws GLib.Error
208 {
209+ stdout.printf ("Creds are %s\n", json_string);
210 var root_object = parse_json (json_string);
211- consumer_key = root_object.get_string_member("consumer_key");
212- token = root_object.get_string_member("token");
213+ consumer_key = root_object.get_string_member ("consumer_key");
214+ token = root_object.get_string_member ("token");
215 }
216
217 internal string parse_purchase_json (string json_string) throws GLib.Error
218 {
219 var root_object = parse_json (json_string);
220- Json.Object payload = root_object.get_object_member("payload");
221- return payload.get_string_member("open_url");
222+ if (root_object.has_member ("open_url")) {
223+ return root_object.get_string_member("open_url");
224+ } else {
225+ return "";
226+ }
227 }
228
229- internal virtual async void fetch_credentials () throws PurchaseError
230+ public virtual async void fetch_credentials () throws PurchaseError
231 {
232 PurchaseError error = null;
233
234@@ -155,8 +180,12 @@
235 debug ("got credentials");
236 fetch_credentials.callback ();
237 });
238+ ulong not_found_handler = credentials_management.credentials_not_found.connect ((credentials) => {
239+ error = new PurchaseError.MISSING_CREDENTIALS_ERROR ("Can't get Ubuntu One tokens.");
240+ fetch_credentials.callback ();
241+ });
242 ulong error_handler = credentials_management.credentials_error.connect (() => {
243- error = new PurchaseError.PURCHASE_ERROR ("Can't get Ubuntu One tokens.");
244+ error = new PurchaseError.MISSING_CREDENTIALS_ERROR ("Can't get Ubuntu One tokens.");
245 fetch_credentials.callback ();
246 });
247
248@@ -164,10 +193,11 @@
249 credentials_management.find_credentials ();
250 yield;
251 } catch (IOError e) {
252- error = new PurchaseError.PURCHASE_ERROR ("Can't get Ubuntu One tokens: %s", e.message);
253+ error = new PurchaseError.MISSING_CREDENTIALS_ERROR ("Can't get Ubuntu One tokens: %s", e.message);
254 }
255
256 credentials_management.disconnect (found_handler);
257+ credentials_management.disconnect (not_found_handler);
258 credentials_management.disconnect (error_handler);
259
260 if (error != null) {
261@@ -208,7 +238,7 @@
262 internal virtual async void fetch_account () throws PurchaseError
263 {
264 string response;
265- PurchaseError error = yield call_api ("GET", ACCOUNT_URI, out response);
266+ PurchaseError error = yield call_api ("GET", account_uri(), out response);
267
268 if (error != null) {
269 debug ("Error while fetching U1 account: %s.", error.message);
270@@ -224,43 +254,40 @@
271 }
272 }
273
274- internal virtual async void fetch_payment_method (string purchase_sku) throws PurchaseError
275+ internal virtual void fetch_payment_method (string purchase_sku) throws PurchaseError
276 {
277- string response;
278- var uri = PAYMENT_METHOD_URI.printf (purchase_sku);
279- PurchaseError error = yield call_api ("GET", uri, out response);
280+ var uri = payment_method_uri().printf (purchase_sku);
281
282- if (error != null) {
283- debug ("Error while fetching payment method: %s.", error.message);
284- throw error;
285+ var message = send_signed_webservice_call ("GET", uri);
286+ if (message.status_code != Soup.KnownStatusCode.OK) {
287+ debug ("Purchase request failed: HTTP %u", message.status_code);
288+ debug ("Reason: %s", message.reason_phrase);
289+ try {
290+ message.response_body.flatten ();
291+ debug ("body: ------\n%s\n------\n", (string) message.response_body.data);
292+ } catch (Error e) {
293+ }
294+ throw new PurchaseError.PURCHASE_ERROR ("Retrieve payment method failed: %s".printf (message.reason_phrase));
295 }
296-
297 try {
298- parse_payment_method_json (response);
299- debug ("got payment method");
300+ message.response_body.flatten ();
301+ var result = (string) message.response_body.data;
302+ parse_payment_method_json (result);
303 } catch (GLib.Error e) {
304 debug ("Error while getting payment method: %s.", e.message);
305 throw new PurchaseError.PURCHASE_ERROR (e.message);
306 }
307 }
308
309- internal virtual async void refetch_payment_info (string purchase_sku) throws PurchaseError
310+ public virtual async void fetch_account_info () throws PurchaseError
311 {
312 yield fetch_credentials ();
313 yield fetch_account ();
314- yield fetch_payment_method (purchase_sku);
315- reset_payment_method_cache (PAYMENT_METHOD_CACHE_SECONDS);
316 }
317
318- public async void fetch_payment_info (string purchase_sku) throws PurchaseError
319+ public void fetch_payment_info (string purchase_sku) throws PurchaseError
320 {
321- if (expired_payment_method_cache ())
322- {
323- debug ("refetching");
324- yield refetch_payment_info (purchase_sku);
325- } else {
326- debug ("in cache");
327- }
328+ fetch_payment_method (purchase_sku);
329 }
330
331 internal virtual void _do_sso_webcall (Soup.Message message, string password)
332@@ -286,6 +313,11 @@
333 if (message.status_code == Soup.KnownStatusCode.UNAUTHORIZED) {
334 throw new PurchaseError.WRONG_PASSWORD_ERROR ("Wrong password");
335 }
336+ try {
337+ message.response_body.flatten ();
338+ debug ("body: ------\n%s\n------\n", (string) message.response_body.data);
339+ } catch (Error e) {
340+ }
341 throw new PurchaseError.PURCHASE_ERROR (message.reason_phrase);
342 }
343 message.response_body.flatten ();
344@@ -294,12 +326,14 @@
345
346 internal virtual string get_purchase_token (string password) throws PurchaseError
347 {
348- var result = authenticated_sso_webcall ("POST", AUTHENTICATION_URI, AUTHENTICATE_PARAMS, password);
349+ var result = authenticated_sso_webcall ("POST", authentication_uri(), AUTHENTICATE_PARAMS, password);
350 try {
351 parse_authentication_json (result);
352 } catch (GLib.Error e) {
353 throw new PurchaseError.PURCHASE_ERROR (e.message);
354 }
355+
356+ stdout.printf ("%s:%s\n", consumer_key, token);
357 return "%s:%s".printf (consumer_key, token);
358 }
359
360@@ -311,14 +345,24 @@
361 return message;
362 }
363
364- internal virtual void purchase_with_default_payment (string sku, string purchase_token) throws PurchaseError
365+ internal virtual void purchase_with_default_payment (string album_id, string purchase_token) throws PurchaseError
366 {
367- var uri = PURCHASE_WITH_DEFAULT_PAYMENT_URI.printf (sku, purchase_token);
368+ var uri = purchase_with_default_payment_uri().printf (album_id, purchase_token);
369+ stdout.printf("Uri is %s\n", uri);
370+
371 var message = send_signed_webservice_call ("GET", uri);
372
373 if (message.status_code != Soup.KnownStatusCode.OK) {
374+ stdout.printf("Purchase request failed: HTTP %u", message.status_code);
375+ stdout.printf("Reason: %s", message.reason_phrase);
376 debug ("Purchase request failed: HTTP %u", message.status_code);
377 debug ("Reason: %s", message.reason_phrase);
378+ try {
379+ message.response_body.flatten ();
380+ stdout.printf("body: ------\n%s\n------\n", (string) message.response_body.data);
381+ debug ("body: ------\n%s\n------\n", (string) message.response_body.data);
382+ } catch (Error e) {
383+ }
384 throw new PurchaseError.PURCHASE_ERROR ("Purchase failed: %s".printf (message.reason_phrase));
385 }
386 try {
387@@ -336,7 +380,9 @@
388 public void purchase (string album_id, string password) throws PurchaseError
389 {
390 var purchase_token = get_purchase_token (password);
391+ debug ("purchasing...");
392 purchase_with_default_payment (album_id, purchase_token);
393+ debug ("purchase completed.");
394 }
395 }
396 }

Subscribers

People subscribed via source and target branches

to all changes: