comparison libpurple/protocols/myspace/user.c @ 24767:295464ae2d2a

No functionality change--just cleanup. * Remove stray whitespace * Make functions static that don't need to be public * Shuffling functions around so there is a general bottom-to-top logic flow * Remove foward declarations for functions that don't need them
author Mark Doliner <mark@kingant.net>
date Tue, 16 Dec 2008 03:35:22 +0000
parents 694591875bc9
children 5f8e8b89b143 e22bc87b758b
comparison
equal deleted inserted replaced
24766:ce108a92fa4e 24767:295464ae2d2a
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
18 */ 18 */
19 19
20 #include "myspace.h" 20 #include "myspace.h"
21 21
22 static void msim_store_user_info_each(const gchar *key_str, gchar *value_str, MsimUser *user); 22 static void msim_check_username_availability_cb(PurpleConnection *gc, const char *username_to_check);
23 static gchar *msim_format_now_playing(const gchar *band, const gchar *song); 23
24 static void msim_downloaded_buddy_icon(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text,
25 gsize len, const gchar *error_message);
26
27 /* Callbacks for setting the username bit */
28 static void msim_check_username_availability_cb(PurpleConnection *gc, const char *value);
29 static void msim_username_is_available_cb(MsimSession *session, MsimMessage *userinfo, gpointer data);
30 static void msim_set_username_confirmed_cb(PurpleConnection *gc);
31 static void msim_username_is_set_cb(MsimSession *session, MsimMessage *userinfo, gpointer data);
32 static void msim_set_username(MsimSession *session, const gchar *username,
33 MSIM_USER_LOOKUP_CB cb, gpointer data);
34 static char *msim_username_to_set; 24 static char *msim_username_to_set;
35 25
36 /** Format the "now playing" indicator, showing the artist and song. 26 /**
27 * Format the "now playing" indicator, showing the artist and song.
28 *
37 * @return Return a new string (must be g_free()'d), or NULL. 29 * @return Return a new string (must be g_free()'d), or NULL.
38 */ 30 */
39 static gchar * 31 static gchar *
40 msim_format_now_playing(const gchar *band, const gchar *song) 32 msim_format_now_playing(const gchar *band, const gchar *song)
41 { 33 {
45 (song && *song) ? song : "Unknown Song"); 37 (song && *song) ? song : "Unknown Song");
46 } else { 38 } else {
47 return NULL; 39 return NULL;
48 } 40 }
49 } 41 }
50 /** Get the MsimUser from a PurpleBuddy, creating it if needed. */ 42
43 /**
44 * Get the MsimUser from a PurpleBuddy, creating it if needed.
45 */
51 MsimUser * 46 MsimUser *
52 msim_get_user_from_buddy(PurpleBuddy *buddy) 47 msim_get_user_from_buddy(PurpleBuddy *buddy)
53 { 48 {
54 MsimUser *user; 49 MsimUser *user;
55 50
63 /* TODO: where is this freed? */ 58 /* TODO: where is this freed? */
64 user = g_new0(MsimUser, 1); 59 user = g_new0(MsimUser, 1);
65 user->buddy = buddy; 60 user->buddy = buddy;
66 user->id = purple_blist_node_get_int(&buddy->node, "UserID"); 61 user->id = purple_blist_node_get_int(&buddy->node, "UserID");
67 buddy->proto_data = (gpointer)user; 62 buddy->proto_data = (gpointer)user;
68 } 63 }
69 64
70 user = (MsimUser *)(buddy->proto_data); 65 user = (MsimUser *)(buddy->proto_data);
71 66
72 return user; 67 return user;
73 } 68 }
74 69
75 /** Find and return an MsimUser * representing a user on the buddy list, or NULL. */ 70 /**
71 * Find and return an MsimUser * representing a user on the buddy list, or NULL.
72 */
76 MsimUser * 73 MsimUser *
77 msim_find_user(MsimSession *session, const gchar *username) 74 msim_find_user(MsimSession *session, const gchar *username)
78 { 75 {
79 PurpleBuddy *buddy; 76 PurpleBuddy *buddy;
80 MsimUser *user; 77 MsimUser *user;
87 user = msim_get_user_from_buddy(buddy); 84 user = msim_get_user_from_buddy(buddy);
88 85
89 return user; 86 return user;
90 } 87 }
91 88
92 /** Append user information to a PurpleNotifyUserInfo, given an MsimUser. 89 /**
90 * Append user information to a PurpleNotifyUserInfo, given an MsimUser.
93 * Used by msim_tooltip_text() and msim_get_info_cb() to show a user's profile. 91 * Used by msim_tooltip_text() and msim_get_info_cb() to show a user's profile.
94 */ 92 */
95 void 93 void
96 msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, MsimUser *user, gboolean full) 94 msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, MsimUser *user, gboolean full)
97 { 95 {
98 PurplePresence *presence; 96 PurplePresence *presence;
99 gchar *str; 97 gchar *str;
100 guint cv; 98 guint cv;
101 99
102 /* Useful to identify the account the tooltip refers to. 100 /* Useful to identify the account the tooltip refers to.
103 * Other prpls show this. */ 101 * Other prpls show this. */
104 if (user->username) { 102 if (user->username) {
105 purple_notify_user_info_add_pair(user_info, _("User"), user->username); 103 purple_notify_user_info_add_pair(user_info, _("User"), user->username);
106 } 104 }
107 105
183 purple_notify_user_info_add_pair(user_info, NULL, profile); 181 purple_notify_user_info_add_pair(user_info, NULL, profile);
184 g_free(profile); 182 g_free(profile);
185 } 183 }
186 } 184 }
187 185
188 /** Set the currently playing song artist and or title. 186 /**
187 * Callback for when a buddy icon finished being downloaded.
188 */
189 static void
190 msim_downloaded_buddy_icon(PurpleUtilFetchUrlData *url_data,
191 gpointer user_data,
192 const gchar *url_text,
193 gsize len,
194 const gchar *error_message)
195 {
196 MsimUser *user;
197
198 user = (MsimUser *)user_data;
199
200 purple_debug_info("msim_downloaded_buddy_icon",
201 "Downloaded %" G_GSIZE_FORMAT " bytes\n", len);
202
203 if (!url_text) {
204 purple_debug_info("msim_downloaded_buddy_icon",
205 "failed to download icon for %s",
206 user->buddy->name);
207 return;
208 }
209
210 purple_buddy_icons_set_for_user(user->buddy->account,
211 user->buddy->name,
212 g_memdup((gchar *)url_text, len), len,
213 /* Use URL itself as buddy icon "checksum" (TODO: ETag) */
214 user->image_url); /* checksum */
215 }
216
217 /**
218 * Set the currently playing song artist and or title.
189 * 219 *
190 * @param user User associated with the now playing information. 220 * @param user User associated with the now playing information.
191 * 221 *
192 * @param new_artist New artist to set, or NULL/empty to not change artist. 222 * @param new_artist New artist to set, or NULL/empty to not change artist.
193 * 223 *
222 252
223 presence = purple_buddy_get_presence(user->buddy); 253 presence = purple_buddy_get_presence(user->buddy);
224 254
225 if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_TUNE)) { 255 if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_TUNE)) {
226 PurpleStatus *status; 256 PurpleStatus *status;
227 257
228 status = purple_presence_get_status(presence, "tune"); 258 status = purple_presence_get_status(presence, "tune");
229 prev_title = purple_status_get_attr_string(status, PURPLE_TUNE_TITLE); 259 prev_title = purple_status_get_attr_string(status, PURPLE_TUNE_TITLE);
230 prev_artist = purple_status_get_attr_string(status, PURPLE_TUNE_ARTIST); 260 prev_artist = purple_status_get_attr_string(status, PURPLE_TUNE_ARTIST);
231 } 261 }
232 262
233 if (!new_artist) 263 if (!new_artist)
234 new_artist = prev_artist; 264 new_artist = prev_artist;
235 265
236 if (!new_title) 266 if (!new_title)
237 new_title = prev_title; 267 new_title = prev_title;
238 268
239 purple_prpl_got_user_status(user->buddy->account, user->buddy->name, "tune", 269 purple_prpl_got_user_status(user->buddy->account, user->buddy->name, "tune",
240 PURPLE_TUNE_TITLE, new_title, 270 PURPLE_TUNE_TITLE, new_title,
241 PURPLE_TUNE_ARTIST, new_artist, 271 PURPLE_TUNE_ARTIST, new_artist,
242 NULL); 272 NULL);
243 } 273 }
244 274
245 /** Store a field of information about a buddy. 275 /**
276 * Store a field of information about a buddy.
246 * 277 *
247 * @param key_str Key to store. 278 * @param key_str Key to store.
248 * @param value_str Value string, either user takes ownership of this string 279 * @param value_str Value string, either user takes ownership of this string
249 * or it is freed if MsimUser doesn't store the string. 280 * or it is freed if MsimUser doesn't store the string.
250 * @param user User to store data in. Existing data will be replaced. 281 * @param user User to store data in. Existing data will be replaced.
251 * */ 282 */
252 void 283 static void
253 msim_store_user_info_each(const gchar *key_str, gchar *value_str, MsimUser *user) 284 msim_store_user_info_each(const gchar *key_str, gchar *value_str, MsimUser *user)
254 { 285 {
255 if (g_str_equal(key_str, "UserID") || g_str_equal(key_str, "ContactID")) { 286 if (g_str_equal(key_str, "UserID") || g_str_equal(key_str, "ContactID")) {
256 /* Save to buddy list, if it exists, for quick cached uid lookup with msim_uid2username_from_blist(). */ 287 /* Save to buddy list, if it exists, for quick cached uid lookup with msim_uid2username_from_blist(). */
257 user->id = atol(value_str); 288 user->id = atol(value_str);
284 g_free(value_str); 315 g_free(value_str);
285 } else if (g_str_equal(key_str, "ImageURL") || g_str_equal(key_str, "AvatarURL")) { 316 } else if (g_str_equal(key_str, "ImageURL") || g_str_equal(key_str, "AvatarURL")) {
286 const gchar *previous_url; 317 const gchar *previous_url;
287 318
288 if (user->temporary_user) { 319 if (user->temporary_user) {
289 /* This user will be destroyed soon; don't try to look up its image or avatar, 320 /* This user will be destroyed soon; don't try to look up its image or avatar,
290 * since that won't return immediately and we will end up accessing freed data. 321 * since that won't return immediately and we will end up accessing freed data.
291 */ 322 */
292 g_free(value_str); 323 g_free(value_str);
293 return; 324 return;
294 } 325 }
295 326
296 if (user->temporary_user) { 327 if (user->temporary_user) {
297 /* This user will be destroyed soon; don't try to look up its image or avatar, 328 /* This user will be destroyed soon; don't try to look up its image or avatar,
298 * since that won't return immediately and we will end up accessing freed data. 329 * since that won't return immediately and we will end up accessing freed data.
299 */ 330 */
300 g_free(value_str); 331 g_free(value_str);
301 return; 332 return;
302 } 333 }
340 371
341 g_free(msg); 372 g_free(msg);
342 } 373 }
343 } 374 }
344 375
345 /** Save buddy information to the buddy list from a user info reply message. 376 /**
377 * Save buddy information to the buddy list from a user info reply message.
346 * 378 *
347 * @param session 379 * @param session
348 * @param msg The user information reply, with any amount of information. 380 * @param msg The user information reply, with any amount of information.
349 * @param user The structure to save to, or NULL to save in PurpleBuddy->proto_data. 381 * @param user The structure to save to, or NULL to save in PurpleBuddy->proto_data.
350 * 382 *
352 * information (UserID) is stored in the blist node of the buddy list (and 384 * information (UserID) is stored in the blist node of the buddy list (and
353 * ends up in blist.xml, persisted to disk) if it exists. 385 * ends up in blist.xml, persisted to disk) if it exists.
354 * 386 *
355 * If the function has no buddy information, this function 387 * If the function has no buddy information, this function
356 * is a no-op (and returns FALSE). 388 * is a no-op (and returns FALSE).
357 * 389 */
358 */ 390 gboolean
359 gboolean
360 msim_store_user_info(MsimSession *session, MsimMessage *msg, MsimUser *user) 391 msim_store_user_info(MsimSession *session, MsimMessage *msg, MsimUser *user)
361 { 392 {
362 gchar *username; 393 gchar *username;
363 MsimMessage *body, *body_node; 394 MsimMessage *body, *body_node;
364 395
371 } 402 }
372 403
373 username = msim_msg_get_string(body, "UserName"); 404 username = msim_msg_get_string(body, "UserName");
374 405
375 if (!username) { 406 if (!username) {
376 purple_debug_info("msim", 407 purple_debug_info("msim",
377 "msim_process_reply: not caching body, no UserName\n"); 408 "msim_process_reply: not caching body, no UserName\n");
378 msim_msg_free(body); 409 msim_msg_free(body);
379 g_free(username); 410 g_free(username);
380 return FALSE; 411 return FALSE;
381 } 412 }
382 413
383 /* Null user = find and store in PurpleBuddy's proto_data */ 414 /* Null user = find and store in PurpleBuddy's proto_data */
384 if (!user) { 415 if (!user) {
385 user = msim_find_user(session, username); 416 user = msim_find_user(session, username);
386 if (!user) { 417 if (!user) {
387 msim_msg_free(body); 418 msim_msg_free(body);
389 return FALSE; 420 return FALSE;
390 } 421 }
391 } 422 }
392 423
393 /* TODO: make looping over MsimMessage's easier. */ 424 /* TODO: make looping over MsimMessage's easier. */
394 for (body_node = body; 425 for (body_node = body;
395 body_node != NULL; 426 body_node != NULL;
396 body_node = msim_msg_get_next_element_node(body_node)) 427 body_node = msim_msg_get_next_element_node(body_node))
397 { 428 {
398 const gchar *key_str; 429 const gchar *key_str;
399 gchar *value_str; 430 gchar *value_str;
400 MsimMessageElement *elem; 431 MsimMessageElement *elem;
408 439
409 if (msim_msg_get_integer(msg, "dsn") == MG_OWN_IM_INFO_DSN && 440 if (msim_msg_get_integer(msg, "dsn") == MG_OWN_IM_INFO_DSN &&
410 msim_msg_get_integer(msg, "lid") == MG_OWN_IM_INFO_LID) { 441 msim_msg_get_integer(msg, "lid") == MG_OWN_IM_INFO_LID) {
411 /* TODO: do something with our own IM info, if we need it for some 442 /* TODO: do something with our own IM info, if we need it for some
412 * specific purpose. Otherwise it is available on the buddy list, 443 * specific purpose. Otherwise it is available on the buddy list,
413 * if the user has themselves as their own buddy. 444 * if the user has themselves as their own buddy.
414 * 445 *
415 * However, much of the info is already available in MsimSession, 446 * However, much of the info is already available in MsimSession,
416 * stored in msim_we_are_logged_on(). */ 447 * stored in msim_we_are_logged_on(). */
417 } else if (msim_msg_get_integer(msg, "dsn") == MG_OWN_MYSPACE_INFO_DSN && 448 } else if (msim_msg_get_integer(msg, "dsn") == MG_OWN_MYSPACE_INFO_DSN &&
418 msim_msg_get_integer(msg, "lid") == MG_OWN_MYSPACE_INFO_LID) { 449 msim_msg_get_integer(msg, "lid") == MG_OWN_MYSPACE_INFO_LID) {
423 g_free(username); 454 g_free(username);
424 455
425 return TRUE; 456 return TRUE;
426 } 457 }
427 458
459 #if 0
460 /**
461 * Return whether a given username is syntactically valid.
462 * Note: does not actually check that the user exists.
463 */
464 static gboolean
465 msim_is_valid_username(const gchar *user)
466 {
467 return !msim_is_userid(user) && /* Not all numeric */
468 strlen(user) <= MSIM_MAX_USERNAME_LENGTH
469 && strspn(user, "0123456789"
470 "abcdefghijklmnopqrstuvwxyz"
471 "_"
472 "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == strlen(user);
473 }
474 #endif
475
476 /**
477 * Check if a string is a userid (all numeric).
478 *
479 * @param user The user id, email, or name.
480 *
481 * @return TRUE if is userid, FALSE if not.
482 */
483 gboolean
484 msim_is_userid(const gchar *user)
485 {
486 g_return_val_if_fail(user != NULL, FALSE);
487
488 return strspn(user, "0123456789") == strlen(user);
489 }
490
491 /**
492 * Check if a string is an email address (contains an @).
493 *
494 * @param user The user id, email, or name.
495 *
496 * @return TRUE if is an email, FALSE if not.
497 *
498 * This function is not intended to be used as a generic
499 * means of validating email addresses, but to distinguish
500 * between a user represented by an email address from
501 * other forms of identification.
502 */
503 static gboolean
504 msim_is_email(const gchar *user)
505 {
506 g_return_val_if_fail(user != NULL, FALSE);
507
508 return strchr(user, '@') != NULL;
509 }
510
428 /** 511 /**
429 * Asynchronously lookup user information, calling callback when receive result. 512 * Asynchronously lookup user information, calling callback when receive result.
430 * 513 *
431 * @param session 514 * @param session
432 * @param user The user id, email address, or username. Not freed. 515 * @param user The user id, email address, or username. Not freed.
433 * @param cb Callback, called with user information when available. 516 * @param cb Callback, called with user information when available.
434 * @param data An arbitray data pointer passed to the callback. 517 * @param data An arbitray data pointer passed to the callback.
435 */ 518 */
436 /* TODO: change to not use callbacks */ 519 /* TODO: change to not use callbacks */
437 void 520 void
438 msim_lookup_user(MsimSession *session, const gchar *user, MSIM_USER_LOOKUP_CB cb, gpointer data) 521 msim_lookup_user(MsimSession *session, const gchar *user, MSIM_USER_LOOKUP_CB cb, gpointer data)
439 { 522 {
440 MsimMessage *body; 523 MsimMessage *body;
441 gchar *field_name; 524 gchar *field_name;
442 guint rid, cmd, dsn, lid; 525 guint rid, cmd, dsn, lid;
458 541
459 cmd = MSIM_CMD_GET; 542 cmd = MSIM_CMD_GET;
460 543
461 if (msim_is_userid(user)) { 544 if (msim_is_userid(user)) {
462 field_name = "UserID"; 545 field_name = "UserID";
463 dsn = MG_MYSPACE_INFO_BY_ID_DSN; 546 dsn = MG_MYSPACE_INFO_BY_ID_DSN;
464 lid = MG_MYSPACE_INFO_BY_ID_LID; 547 lid = MG_MYSPACE_INFO_BY_ID_LID;
465 } else if (msim_is_email(user)) { 548 } else if (msim_is_email(user)) {
466 field_name = "Email"; 549 field_name = "Email";
467 dsn = MG_MYSPACE_INFO_BY_STRING_DSN; 550 dsn = MG_MYSPACE_INFO_BY_STRING_DSN;
468 lid = MG_MYSPACE_INFO_BY_STRING_LID; 551 lid = MG_MYSPACE_INFO_BY_STRING_LID;
469 } else { 552 } else {
484 "uid", MSIM_TYPE_INTEGER, session->userid, 567 "uid", MSIM_TYPE_INTEGER, session->userid,
485 "lid", MSIM_TYPE_INTEGER, lid, 568 "lid", MSIM_TYPE_INTEGER, lid,
486 "rid", MSIM_TYPE_INTEGER, rid, 569 "rid", MSIM_TYPE_INTEGER, rid,
487 "body", MSIM_TYPE_DICTIONARY, body, 570 "body", MSIM_TYPE_DICTIONARY, body,
488 NULL)); 571 NULL));
489 } 572 }
490 573
491 574 /**
492 /** 575 * Called after username is set.
493 * Check if a string is a userid (all numeric). 576 */
494 * 577 static void msim_username_is_set_cb(MsimSession *session, MsimMessage *userinfo, gpointer data)
495 * @param user The user id, email, or name. 578 {
496 * 579 gchar *username, *errmsg;
497 * @return TRUE if is userid, FALSE if not. 580 MsimMessage *body;
498 */ 581
499 gboolean 582 guint rid;
500 msim_is_userid(const gchar *user) 583 gint cmd,dsn,uid,lid,code;
501 { 584 /* \persistr\\cmd\258\dsn\9\uid\204084363\lid\14\rid\369\body\UserName=TheAlbinoRhino1.Code=0\final\ */
502 g_return_val_if_fail(user != NULL, FALSE); 585
503 586 purple_debug_info("msim","username_is_set made\n");
504 return strspn(user, "0123456789") == strlen(user);
505 }
506
507 /** Return whether a given username is syntactically valid.
508 * Note: does not actually check that the user exists. */
509 gboolean
510 msim_is_valid_username(const gchar *user)
511 {
512 return !msim_is_userid(user) && /* Not all numeric */
513 strlen(user) <= MSIM_MAX_USERNAME_LENGTH
514 && strspn(user, "0123456789"
515 "abcdefghijklmnopqrstuvwxyz"
516 "_"
517 "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == strlen(user);
518 }
519
520 /**
521 * Check if a string is an email address (contains an @).
522 *
523 * @param user The user id, email, or name.
524 *
525 * @return TRUE if is an email, FALSE if not.
526 *
527 * This function is not intended to be used as a generic
528 * means of validating email addresses, but to distinguish
529 * between a user represented by an email address from
530 * other forms of identification.
531 */
532 gboolean
533 msim_is_email(const gchar *user)
534 {
535 g_return_val_if_fail(user != NULL, FALSE);
536
537 return strchr(user, '@') != NULL;
538 }
539
540
541 /** Callback for when a buddy icon finished being downloaded. */
542 static void
543 msim_downloaded_buddy_icon(PurpleUtilFetchUrlData *url_data,
544 gpointer user_data,
545 const gchar *url_text,
546 gsize len,
547 const gchar *error_message)
548 {
549 MsimUser *user;
550
551 user = (MsimUser *)user_data;
552
553 purple_debug_info("msim_downloaded_buddy_icon",
554 "Downloaded %" G_GSIZE_FORMAT " bytes\n", len);
555
556 if (!url_text) {
557 purple_debug_info("msim_downloaded_buddy_icon",
558 "failed to download icon for %s",
559 user->buddy->name);
560 return;
561 }
562
563 purple_buddy_icons_set_for_user(user->buddy->account,
564 user->buddy->name,
565 g_memdup((gchar *)url_text, len), len,
566 /* Use URL itself as buddy icon "checksum" (TODO: ETag) */
567 user->image_url); /* checksum */
568 }
569
570 /***
571 * If they hit cancel or no at any point in the Setting Username process, we come here. *
572 * Currently.. We're safe letting them get by without setting it.. Unless we hear otherwise.. *
573 * So for now, give them a menu.. If this becomes an issue with the Official client.. boot them here */
574 void msim_do_not_set_username_cb(PurpleConnection *gc) {
575 purple_debug_info("msim", "Don't set username");
576
577 /* Protocol won't log in now without a username set.. Disconnect */
578 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("No username set"));
579 }
580
581 /** They've decided to set a username! Yay! */
582 void msim_set_username_cb(PurpleConnection *gc) {
583 g_return_if_fail(gc != NULL);
584 purple_debug_info("msim","Set username\n");
585 purple_request_input(gc, _("MySpaceIM - Please Set a Username"),
586 _("Please enter a username to check its availability:"),
587 NULL,
588 "", FALSE, FALSE, NULL,
589 _("OK"), G_CALLBACK(msim_check_username_availability_cb),
590 _("Cancel"), G_CALLBACK(msim_do_not_set_username_cb),
591 purple_connection_get_account(gc),
592 NULL,
593 NULL,
594 gc);
595 }
596
597 /** Once they've submitted their desired new username,
598 * check if it is available here. */
599 static void msim_check_username_availability_cb(PurpleConnection *gc, const char *username_to_check)
600 {
601 MsimMessage *user_msg;
602 MsimSession *session;
603
604 g_return_if_fail(gc != NULL);
605
606 session = (MsimSession *)gc->proto_data;
607 587
608 g_return_if_fail(MSIM_SESSION_VALID(session)); 588 g_return_if_fail(MSIM_SESSION_VALID(session));
609 589
610 purple_debug_info("msim_check_username_availability_cb", "Checking username: %s\n", username_to_check); 590 msim_msg_dump("username_is_set message is: %s\n", userinfo);
611 591 cmd = msim_msg_get_integer(userinfo, "cmd");
612 user_msg = msim_msg_new( 592 dsn = msim_msg_get_integer(userinfo, "dsn");
613 "user", MSIM_TYPE_STRING, g_strdup(username_to_check), 593 uid = msim_msg_get_integer(userinfo, "uid");
614 NULL); 594 lid = msim_msg_get_integer(userinfo, "lid");
615
616 /* 25 characters: letters, numbers, underscores */
617 /* TODO: VERIFY ABOVE */
618
619 /* \persist\1\sesskey\288500516\cmd\1\dsn\5\uid\204084363\lid\7\rid\367\body\UserName=Jaywalker\final\ */
620 /* Official client uses a standard lookup... So do we! */
621 msim_lookup_user(session, username_to_check, msim_username_is_available_cb, user_msg);
622 }
623
624 /** This is where we do a bit more than merely prompt the user.
625 * Now we have some real data to tell us the state of their requested username
626 * \persistr\\cmd\257\dsn\5\uid\204084363\lid\7\rid\367\body\UserName=TheAlbinoRhino1\final\ */
627 static void msim_username_is_available_cb(MsimSession *session, MsimMessage *userinfo, gpointer data)
628 {
629 MsimMessage *msg;
630 gchar *username;
631 MsimMessage *body;
632 gint userid;
633
634 purple_debug_info("msim_username_is_available_cb", "Look up username callback made\n");
635
636 msg = (MsimMessage *)data;
637 g_return_if_fail(MSIM_SESSION_VALID(session));
638 g_return_if_fail(msg != NULL);
639
640 username = msim_msg_get_string(msg, "user");
641 body = msim_msg_get_dictionary(userinfo, "body"); 595 body = msim_msg_get_dictionary(userinfo, "body");
596 errmsg = g_strdup("An error occurred while trying to set the username.\n"
597 "Please try again, or visit http://editprofile.myspace.com/index.cfm?"
598 "fuseaction=profile.username to set your username.");
642 599
643 if (!body) { 600 if (!body) {
644 purple_debug_info("msim_username_is_available_cb", "No body for %s?!\n", username); 601 purple_debug_info("msim_username_is_set_cb", "No body");
645 purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, 602 /* Error: No body! */
646 "An error occurred while trying to set the username.\n" 603 purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
647 "Please try again, or visit http://editprofile.myspace.com/index.cfm?" 604 }
648 "fuseaction=profile.username to set your username."); 605 username = msim_msg_get_string(body, "UserName");
649 return; 606 code = msim_msg_get_integer(body,"Code");
650 } 607
651
652 userid = msim_msg_get_integer(body, "UserID");
653
654 purple_debug_info("msim_username_is_available_cb", "Returned username is %s and userid is %d\n", username, userid);
655 msim_msg_free(body); 608 msim_msg_free(body);
656 msim_msg_free(msg); 609
657 610 purple_debug_info("msim_username_is_set_cb",
658 /* The response for a free username will ONLY have the UserName in it.. 611 "cmd = %d, dsn = %d, lid = %d, code = %d, username = %s\n",
659 * thus making UserID return 0 when we msg_get_integer it */ 612 cmd, dsn, lid, code, username);
660 if (userid == 0) { 613
661 /* This username is currently unused */ 614 if (cmd == (MSIM_CMD_BIT_REPLY | MSIM_CMD_PUT)
662 purple_debug_info("msim_username_is_available_cb", "Username available. Prompting to Confirm.\n"); 615 && dsn == MC_SET_USERNAME_DSN
663 msim_username_to_set = g_strdup(username); 616 && lid == MC_SET_USERNAME_LID)
664 g_free(username); 617 {
665 purple_request_yes_no(session->gc, 618 purple_debug_info("msim_username_is_set_cb", "Proper cmd,dsn,lid for username_is_set!\n");
666 _("MySpaceIM - Username Available"), 619 purple_debug_info("msim_username_is_set_cb", "Username Set with return code %d\n",code);
667 _("This username is available. Would you like to set it?"), 620 if (code == 0) {
668 _("ONCE SET, THIS CANNOT BE CHANGED!"), 621 /* Good! */
669 0, 622 session->username = username;
670 session->account, 623 msim_we_are_logged_on(session);
671 NULL, 624 } else {
672 NULL, 625 purple_debug_info("msim_username_is_set", "code is %d",code);
673 session->gc, 626 /* TODO: what to do here? */
674 G_CALLBACK(msim_set_username_confirmed_cb), 627 }
675 G_CALLBACK(msim_do_not_set_username_cb)); 628 } else if (cmd == (MSIM_CMD_BIT_REPLY | MSIM_CMD_GET)
629 && dsn == MG_MYSPACE_INFO_BY_STRING_DSN
630 && lid == MG_MYSPACE_INFO_BY_STRING_LID) {
631 /* Not quite done... ONE MORE STEP :) */
632 rid = msim_new_reply_callback(session, msim_username_is_set_cb, data);
633 body = msim_msg_new("UserName", MSIM_TYPE_STRING, g_strdup(username), NULL);
634 if (!msim_send(session, "persist", MSIM_TYPE_INTEGER, 1,
635 "sesskey", MSIM_TYPE_INTEGER, session->sesskey,
636 "cmd", MSIM_TYPE_INTEGER, MSIM_CMD_PUT,
637 "dsn", MSIM_TYPE_INTEGER, MC_SET_USERNAME_DSN,
638 "uid", MSIM_TYPE_INTEGER, session->userid,
639 "lid", MSIM_TYPE_INTEGER, MC_SET_USERNAME_LID,
640 "rid", MSIM_TYPE_INTEGER, rid,
641 "body", MSIM_TYPE_DICTIONARY, body,
642 NULL)) {
643 /* Error! */
644 /* Can't set... Disconnect */
645 purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
646 }
647
676 } else { 648 } else {
677 /* Looks like its in use or we have an invalid response */ 649 /* Error! */
678 purple_debug_info("msim_username_is_available_cb", "Username unavaiable. Prompting for new entry.\n"); 650 purple_debug_info("msim","username_is_set Error: Invalid cmd/dsn/lid combination");
679 purple_request_input(session->gc, _("MySpaceIM - Please Set a Username"), 651 purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
680 _("This username is unavailable."), 652 }
681 _("Please try another username:"), 653 g_free(errmsg);
682 "", FALSE, FALSE, NULL,
683 _("OK"), G_CALLBACK(msim_check_username_availability_cb),
684 _("Cancel"), G_CALLBACK(msim_do_not_set_username_cb),
685 session->account,
686 NULL,
687 NULL,
688 session->gc);
689 }
690 }
691
692 /* They've confirmed that username that was available, Lets make the call to set it */
693 static void msim_set_username_confirmed_cb(PurpleConnection *gc)
694 {
695 MsimMessage *user_msg;
696 MsimSession *session;
697
698 g_return_if_fail(gc != NULL);
699
700 session = (MsimSession *)gc->proto_data;
701
702 g_return_if_fail(MSIM_SESSION_VALID(session));
703
704
705 user_msg = msim_msg_new(
706 "user", MSIM_TYPE_STRING, g_strdup(msim_username_to_set),
707 NULL);
708
709 purple_debug_info("msim_set_username_confirmed_cb", "Setting username to %s\n", msim_username_to_set);
710
711 /* Sets our username... keep your fingers crossed :) */
712 msim_set_username(session, msim_username_to_set, msim_username_is_set_cb, user_msg);
713 g_free(msim_username_to_set);
714 } 654 }
715 655
716 /** 656 /**
717 * Asynchronously set new username, calling callback when receive result. 657 * Asynchronously set new username, calling callback when receive result.
718 * 658 *
719 * @param session 659 * @param session
720 * @param username The username we're setting for ourselves. Not freed. 660 * @param username The username we're setting for ourselves. Not freed.
721 * @param cb Callback, called with user information when available. 661 * @param cb Callback, called with user information when available.
722 * @param data An arbitray data pointer passed to the callback. 662 * @param data An arbitray data pointer passed to the callback.
723 */ 663 */
724 static void 664 static void
725 msim_set_username(MsimSession *session, const gchar *username, 665 msim_set_username(MsimSession *session, const gchar *username,
726 MSIM_USER_LOOKUP_CB cb, gpointer data) 666 MSIM_USER_LOOKUP_CB cb, gpointer data)
727 { 667 {
728 MsimMessage *body; 668 MsimMessage *body;
729 guint rid; 669 guint rid;
763 "rid", MSIM_TYPE_INTEGER, rid, 703 "rid", MSIM_TYPE_INTEGER, rid,
764 "body", MSIM_TYPE_DICTIONARY, body, 704 "body", MSIM_TYPE_DICTIONARY, body,
765 NULL)); 705 NULL));
766 } 706 }
767 707
768 /** Called after username is set. */ 708 /**
769 static void msim_username_is_set_cb(MsimSession *session, MsimMessage *userinfo, gpointer data) 709 * They've confirmed that username that was available, Lets make the call to set it
770 { 710 */
771 gchar *username, *errmsg; 711 static void msim_set_username_confirmed_cb(PurpleConnection *gc)
712 {
713 MsimMessage *user_msg;
714 MsimSession *session;
715
716 g_return_if_fail(gc != NULL);
717
718 session = (MsimSession *)gc->proto_data;
719
720 g_return_if_fail(MSIM_SESSION_VALID(session));
721
722
723 user_msg = msim_msg_new(
724 "user", MSIM_TYPE_STRING, g_strdup(msim_username_to_set),
725 NULL);
726
727 purple_debug_info("msim_set_username_confirmed_cb", "Setting username to %s\n", msim_username_to_set);
728
729 /* Sets our username... keep your fingers crossed :) */
730 msim_set_username(session, msim_username_to_set, msim_username_is_set_cb, user_msg);
731 g_free(msim_username_to_set);
732 }
733
734 /**
735 * This is where we do a bit more than merely prompt the user.
736 * Now we have some real data to tell us the state of their requested username
737 * \persistr\\cmd\257\dsn\5\uid\204084363\lid\7\rid\367\body\UserName=TheAlbinoRhino1\final\
738 */
739 static void msim_username_is_available_cb(MsimSession *session, MsimMessage *userinfo, gpointer data)
740 {
741 MsimMessage *msg;
742 gchar *username;
772 MsimMessage *body; 743 MsimMessage *body;
773 744 gint userid;
774 guint rid; 745
775 gint cmd,dsn,uid,lid,code; 746 purple_debug_info("msim_username_is_available_cb", "Look up username callback made\n");
776 /* \persistr\\cmd\258\dsn\9\uid\204084363\lid\14\rid\369\body\UserName=TheAlbinoRhino1.Code=0\final\ */ 747
777 748 msg = (MsimMessage *)data;
778 purple_debug_info("msim","username_is_set made\n");
779
780 g_return_if_fail(MSIM_SESSION_VALID(session)); 749 g_return_if_fail(MSIM_SESSION_VALID(session));
781 750 g_return_if_fail(msg != NULL);
782 751
783 msim_msg_dump("username_is_set message is: %s\n", userinfo); 752 username = msim_msg_get_string(msg, "user");
784 cmd = msim_msg_get_integer(userinfo, "cmd");
785 dsn = msim_msg_get_integer(userinfo, "dsn");
786 uid = msim_msg_get_integer(userinfo, "uid");
787 lid = msim_msg_get_integer(userinfo, "lid");
788 body = msim_msg_get_dictionary(userinfo, "body"); 753 body = msim_msg_get_dictionary(userinfo, "body");
789 errmsg = g_strdup("An error occurred while trying to set the username.\n" 754
790 "Please try again, or visit http://editprofile.myspace.com/index.cfm?"
791 "fuseaction=profile.username to set your username.");
792
793 if (!body) { 755 if (!body) {
794 purple_debug_info("msim_username_is_set_cb", "No body"); 756 purple_debug_info("msim_username_is_available_cb", "No body for %s?!\n", username);
795 /* Error: No body! */ 757 purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
796 purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg); 758 "An error occurred while trying to set the username.\n"
797 } 759 "Please try again, or visit http://editprofile.myspace.com/index.cfm?"
798 username = msim_msg_get_string(body, "UserName"); 760 "fuseaction=profile.username to set your username.");
799 code = msim_msg_get_integer(body,"Code"); 761 return;
800 762 }
763
764 userid = msim_msg_get_integer(body, "UserID");
765
766 purple_debug_info("msim_username_is_available_cb", "Returned username is %s and userid is %d\n", username, userid);
801 msim_msg_free(body); 767 msim_msg_free(body);
802 768 msim_msg_free(msg);
803 purple_debug_info("msim_username_is_set_cb", 769
804 "cmd = %d, dsn = %d, lid = %d, code = %d, username = %s\n", 770 /* The response for a free username will ONLY have the UserName in it..
805 cmd, dsn, lid, code, username); 771 * thus making UserID return 0 when we msg_get_integer it */
806 772 if (userid == 0) {
807 if (cmd == (MSIM_CMD_BIT_REPLY | MSIM_CMD_PUT) 773 /* This username is currently unused */
808 && dsn == MC_SET_USERNAME_DSN 774 purple_debug_info("msim_username_is_available_cb", "Username available. Prompting to Confirm.\n");
809 && lid == MC_SET_USERNAME_LID) { 775 msim_username_to_set = g_strdup(username);
810 purple_debug_info("msim_username_is_set_cb", "Proper cmd,dsn,lid for username_is_set!\n"); 776 g_free(username);
811 purple_debug_info("msim_username_is_set_cb", "Username Set with return code %d\n",code); 777 purple_request_yes_no(session->gc,
812 if (code == 0) { 778 _("MySpaceIM - Username Available"),
813 /* Good! */ 779 _("This username is available. Would you like to set it?"),
814 session->username = username; 780 _("ONCE SET, THIS CANNOT BE CHANGED!"),
815 msim_we_are_logged_on(session); 781 0,
816 } else { 782 session->account,
817 purple_debug_info("msim_username_is_set", "code is %d",code); 783 NULL,
818 /* TODO: what to do here? */ 784 NULL,
819 } 785 session->gc,
820 } else if (cmd == (MSIM_CMD_BIT_REPLY | MSIM_CMD_GET) 786 G_CALLBACK(msim_set_username_confirmed_cb),
821 && dsn == MG_MYSPACE_INFO_BY_STRING_DSN 787 G_CALLBACK(msim_do_not_set_username_cb));
822 && lid == MG_MYSPACE_INFO_BY_STRING_LID) {
823 /* Not quite done... ONE MORE STEP :) */
824 rid = msim_new_reply_callback(session, msim_username_is_set_cb, data);
825 body = msim_msg_new("UserName", MSIM_TYPE_STRING, g_strdup(username), NULL);
826 if (!msim_send(session, "persist", MSIM_TYPE_INTEGER, 1,
827 "sesskey", MSIM_TYPE_INTEGER, session->sesskey,
828 "cmd", MSIM_TYPE_INTEGER, MSIM_CMD_PUT,
829 "dsn", MSIM_TYPE_INTEGER, MC_SET_USERNAME_DSN,
830 "uid", MSIM_TYPE_INTEGER, session->userid,
831 "lid", MSIM_TYPE_INTEGER, MC_SET_USERNAME_LID,
832 "rid", MSIM_TYPE_INTEGER, rid,
833 "body", MSIM_TYPE_DICTIONARY, body,
834 NULL)) {
835 /* Error! */
836 /* Can't set... Disconnect */
837 purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg);
838 }
839
840 } else { 788 } else {
841 /* Error! */ 789 /* Looks like its in use or we have an invalid response */
842 purple_debug_info("msim","username_is_set Error: Invalid cmd/dsn/lid combination"); 790 purple_debug_info("msim_username_is_available_cb", "Username unavaiable. Prompting for new entry.\n");
843 purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg); 791 purple_request_input(session->gc, _("MySpaceIM - Please Set a Username"),
844 } 792 _("This username is unavailable."),
845 g_free(errmsg); 793 _("Please try another username:"),
846 } 794 "", FALSE, FALSE, NULL,
795 _("OK"), G_CALLBACK(msim_check_username_availability_cb),
796 _("Cancel"), G_CALLBACK(msim_do_not_set_username_cb),
797 session->account,
798 NULL,
799 NULL,
800 session->gc);
801 }
802 }
803
804 /**
805 * Once they've submitted their desired new username,
806 * check if it is available here.
807 */
808 static void msim_check_username_availability_cb(PurpleConnection *gc, const char *username_to_check)
809 {
810 MsimMessage *user_msg;
811 MsimSession *session;
812
813 g_return_if_fail(gc != NULL);
814
815 session = (MsimSession *)gc->proto_data;
816
817 g_return_if_fail(MSIM_SESSION_VALID(session));
818
819 purple_debug_info("msim_check_username_availability_cb", "Checking username: %s\n", username_to_check);
820
821 user_msg = msim_msg_new(
822 "user", MSIM_TYPE_STRING, g_strdup(username_to_check),
823 NULL);
824
825 /* 25 characters: letters, numbers, underscores */
826 /* TODO: VERIFY ABOVE */
827
828 /* \persist\1\sesskey\288500516\cmd\1\dsn\5\uid\204084363\lid\7\rid\367\body\UserName=Jaywalker\final\ */
829 /* Official client uses a standard lookup... So do we! */
830 msim_lookup_user(session, username_to_check, msim_username_is_available_cb, user_msg);
831 }
832
833 /***
834 * If they hit cancel or no at any point in the Setting Username process,
835 * we come here. Currently we're safe letting them get by without
836 * setting it, unless we hear otherwise. So for now give them a menu.
837 * If this becomes an issue with the official client then boot them here.
838 */
839 void msim_do_not_set_username_cb(PurpleConnection *gc)
840 {
841 purple_debug_info("msim", "Don't set username");
842
843 /* Protocol won't log in now without a username set.. Disconnect */
844 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("No username set"));
845 }
846
847 /**
848 * They've decided to set a username! Yay!
849 */
850 void msim_set_username_cb(PurpleConnection *gc)
851 {
852 g_return_if_fail(gc != NULL);
853 purple_debug_info("msim","Set username\n");
854 purple_request_input(gc, _("MySpaceIM - Please Set a Username"),
855 _("Please enter a username to check its availability:"),
856 NULL,
857 "", FALSE, FALSE, NULL,
858 _("OK"), G_CALLBACK(msim_check_username_availability_cb),
859 _("Cancel"), G_CALLBACK(msim_do_not_set_username_cb),
860 purple_connection_get_account(gc),
861 NULL,
862 NULL,
863 gc);
864 }