Mercurial > pidgin.yaz
changeset 18912:7519560095f7
Use MsimUser structure for storing ephemeral information on users, instead
of permanently storing the information using purple_blist_node_*. The uid
is still stored using purple_blist_node_*, so it ends up in blist.xml since
it never changes. But the rest of the fields can change easily, so they're
stored only in memory. There are still some rough edges with this new code.
author | Jeffrey Connelly <jaconnel@calpoly.edu> |
---|---|
date | Sun, 12 Aug 2007 23:20:07 +0000 |
parents | 692b128fe74a |
children | 1d243e70db35 |
files | libpurple/protocols/myspace/myspace.c libpurple/protocols/myspace/myspace.h |
diffstat | 2 files changed, 217 insertions(+), 139 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/protocols/myspace/myspace.c Sun Aug 12 23:16:53 2007 +0000 +++ b/libpurple/protocols/myspace/myspace.c Sun Aug 12 23:20:07 2007 +0000 @@ -129,6 +129,9 @@ static gchar *msim_markup_to_html(MsimSession *, const gchar *raw); static gchar *html_to_msim_markup(MsimSession *, const gchar *raw); +static MsimUser *msim_get_user_from_buddy(PurpleBuddy *buddy); +static MsimUser *msim_find_user(MsimSession *session, const gchar *username); + static gboolean msim_incoming_bm_record_cv(MsimSession *session, MsimMessage *msg); static gboolean msim_incoming_bm(MsimSession *session, MsimMessage *msg); @@ -146,13 +149,14 @@ #endif static void msim_get_info_cb(MsimSession *session, MsimMessage *userinfo, gpointer data); +static gchar *msim_format_now_playing(gchar *band, gchar *song); static void msim_set_status_code(MsimSession *session, guint code, gchar *statstring); -static void msim_store_buddy_info_each(gpointer key, gpointer value, +static void msim_store_user_info_each(gpointer key, gpointer value, gpointer user_data); -static gboolean msim_store_buddy_info(MsimSession *session, MsimMessage *msg); +static gboolean msim_store_user_info(MsimSession *session, MsimMessage *msg); static gboolean msim_process_server_info(MsimSession *session, MsimMessage *msg); static gboolean msim_web_challenge(MsimSession *session, MsimMessage *msg); @@ -307,7 +311,7 @@ gc = purple_account_get_connection(buddy->account); g_return_if_fail(gc != NULL); - session = (MsimSession *)(gc->proto_data); + session = (MsimSession *)gc->proto_data; g_return_if_fail(session != NULL); username = buddy->name; @@ -467,7 +471,7 @@ g_return_val_if_fail(buf != NULL, -1); g_return_val_if_fail(total_bytes >= 0, -1); - session = (MsimSession *)(gc->proto_data); + session = (MsimSession *)gc->proto_data; g_return_val_if_fail(MSIM_SESSION_VALID(session), -1); @@ -1409,13 +1413,56 @@ return markup; } +/** Get the MsimUser from a PurpleBuddy, creating it if needed. */ +static MsimUser * +msim_get_user_from_buddy(PurpleBuddy *buddy) +{ + MsimUser *user; + + if (!buddy) { + return NULL; + } + + if (!buddy->proto_data) { + /* TODO: where is this freed? */ + user = g_new0(MsimUser, 1); + user->buddy = buddy; + buddy->proto_data = (gpointer)user; + purple_debug_info("msim_get_user_from_buddy", + "creating new user for %s to %X\n", + buddy->name, buddy->proto_data); + } + + user = (MsimUser *)(buddy->proto_data); + + return user; +} + +/** Find and return an MsimUser * representing a user on the buddy list, or NULL. */ +static MsimUser * +msim_find_user(MsimSession *session, const gchar *username) +{ + PurpleBuddy *buddy; + MsimUser *user; + + buddy = purple_find_buddy(session->account, username); + if (!buddy) { + return NULL; + } + + user = msim_get_user_from_buddy(buddy); + + return user; +} + + /** Record the client version in the buddy list, from an incoming message. */ static gboolean msim_incoming_bm_record_cv(MsimSession *session, MsimMessage *msg) { gchar *username, *cv; gboolean ret; - PurpleBuddy *buddy; + MsimUser *user; username = msim_msg_get_string(msg, "_username"); cv = msim_msg_get_string(msg, "cv"); @@ -1426,10 +1473,10 @@ return FALSE; } - buddy = purple_find_buddy(session->account, username); - - if (buddy) { - purple_blist_node_set_int(&buddy->node, "client_cv", atol(cv)); + user = msim_find_user(session, username); + + if (user) { + user->client_cv = atol(cv); ret = TRUE; } else { ret = FALSE; @@ -1657,7 +1704,7 @@ static gboolean msim_incoming_unofficial_client(MsimSession *session, MsimMessage *msg) { - PurpleBuddy *buddy; + MsimUser *user; gchar *username, *client_info; username = msim_msg_get_string(msg, "_username"); @@ -1669,15 +1716,17 @@ purple_debug_info("msim", "msim_incoming_unofficial_client: %s is using client %s\n", username, client_info); - buddy = purple_find_buddy(session->account, username); + user = msim_find_user(session, username); - g_return_val_if_fail(buddy != NULL, FALSE); - - purple_blist_node_remove_setting(&buddy->node, "client"); - purple_blist_node_set_string(&buddy->node, "client", client_info); + g_return_val_if_fail(user != NULL, FALSE); + + if (user->client_info) { + g_free(user->client_info); + } + user->client_info = client_info; g_free(username); - /* Do not free client_info - the blist now owns it. */ + /* Do not free client_info - the MsimUser now owns it. */ return TRUE; } @@ -1743,6 +1792,21 @@ return 0; } +/** Format the "now playing" indicator, showing the artist and song. + * @return Return a new string (must be g_free()'d), or NULL. + */ +static gchar * +msim_format_now_playing(gchar *band, gchar *song) +{ + if ((band && strlen(band)) || (song && strlen(song))) { + return g_strdup_printf("%s - %s", + (band && strlen(band)) ? band : "Unknown Artist", + (song && strlen(song)) ? song : "Unknown Song"); + } else { + return NULL; + } +} + /** Callback for msim_get_info(), for when user info is received. */ static void msim_get_info_cb(MsimSession *session, MsimMessage *user_info_msg, @@ -1751,10 +1815,10 @@ GHashTable *body; gchar *body_str; MsimMessage *msg; - gchar *user; + gchar *username; PurpleNotifyUserInfo *user_info; - PurpleBuddy *buddy; - const gchar *str, *str2; + MsimUser *user; + const gchar *str; g_return_if_fail(MSIM_SESSION_VALID(session)); @@ -1763,30 +1827,30 @@ msg = (MsimMessage *)data; g_return_if_fail(msg != NULL); - user = msim_msg_get_string(msg, "user"); - if (!user) { + username = msim_msg_get_string(msg, "user"); + if (!username) { purple_debug_info("msim", "msim_get_info_cb: no 'user' in msg"); return; } msim_msg_free(msg); - purple_debug_info("msim", "msim_get_info_cb: got for user: %s\n", user); + purple_debug_info("msim", "msim_get_info_cb: got for user: %s\n", username); body_str = msim_msg_get_string(user_info_msg, "body"); g_return_if_fail(body_str != NULL); body = msim_parse_body(body_str); g_free(body_str); - buddy = purple_find_buddy(session->account, user); - /* Note: don't assume buddy is non-NULL; will be if lookup random user - * not on blist. */ + user = msim_find_user(session, username); + /* Note: user will be NULL if not on buddy list. */ user_info = purple_notify_user_info_new(); /* Identification */ - purple_notify_user_info_add_pair(user_info, _("User"), user); - - /* note: g_hash_table_lookup does not create a new string! */ + purple_notify_user_info_add_pair(user_info, _("User"), username); + + /* XXX TODO XXX TODO Avoid duplicating this and tooltip text, and + * maybe integrate msim_store_buddy_info() here? */ str = g_hash_table_lookup(body, "UserID"); if (str) purple_notify_user_info_add_pair(user_info, _("User ID"), @@ -1794,35 +1858,31 @@ /* a/s/l...the vitals */ str = g_hash_table_lookup(body, "Age"); - if (str) + if (str && strcmp(str, "0")) purple_notify_user_info_add_pair(user_info, _("Age"), g_strdup(str)); str = g_hash_table_lookup(body, "Gender"); - if (str) + if (str && strlen(str) != 0) purple_notify_user_info_add_pair(user_info, _("Gender"), g_strdup(str)); str = g_hash_table_lookup(body, "Location"); - if (str) + if (str && strlen(str) != 0) purple_notify_user_info_add_pair(user_info, _("Location"), g_strdup(str)); /* Other information */ - if (buddy) { + if (user) { /* Headline comes from buddy status messages */ - str = purple_blist_node_get_string(&buddy->node, "Headline"); - if (str) - purple_notify_user_info_add_pair(user_info, "Headline", str); + if (user->headline) + purple_notify_user_info_add_pair(user_info, "Headline", user->headline); } - str = g_hash_table_lookup(body, "BandName"); - str2 = g_hash_table_lookup(body, "SongName"); - if (str || str2) { - purple_notify_user_info_add_pair(user_info, _("Song"), - g_strdup_printf("%s - %s", - str ? str : "Unknown Artist", - str2 ? str2 : "Unknown Song")); + str = msim_format_now_playing(g_hash_table_lookup(body, "BandName"), g_hash_table_lookup(body, "SongName")); + + if (str) { + purple_notify_user_info_add_pair(user_info, _("Song"), str); } @@ -1832,74 +1892,72 @@ purple_notify_user_info_add_pair(user_info, _("Total Friends"), g_strdup(str)); } - - if (buddy) { + g_hash_table_destroy(body); + + if (user) { gint cv; - str = purple_blist_node_get_string(&buddy->node, "client"); - cv = purple_blist_node_get_int(&buddy->node, "client_cv"); - - if (str) { + str = user->client_info; + cv = user->client_cv; + + if (str && cv != 0) { purple_notify_user_info_add_pair(user_info, _("Client Version"), g_strdup_printf("%s (build %d)", str, cv)); + } else if (str) { + purple_notify_user_info_add_pair(user_info, _("Client Version"), + g_strdup(str)); + } else if (cv) { + purple_notify_user_info_add_pair(user_info, _("Client Version"), + g_strdup_printf("Build %d", cv)); } } - purple_notify_userinfo(session->gc, user, user_info, NULL, NULL); - purple_debug_info("msim", "msim_get_info_cb: username=%s\n", user); - //purple_notify_user_info_destroy(user_info); + purple_notify_userinfo(session->gc, username, user_info, NULL, NULL); + purple_debug_info("msim", "msim_get_info_cb: username=%s\n", username); + + /* purple_notify_user_info_destroy(user_info); */ /* Do not free username, since it will be used by user_info. */ - g_hash_table_destroy(body); } -/** Retrieve a user's profile. */ +/** Retrieve a user's profile. + * @param username Username, user ID, or email address to lookup. + */ void -msim_get_info(PurpleConnection *gc, const gchar *user) +msim_get_info(PurpleConnection *gc, const gchar *username) { - PurpleBuddy *buddy; MsimSession *session; + MsimUser *user; guint uid; gchar *user_to_lookup; MsimMessage *user_msg; g_return_if_fail(gc != NULL); - g_return_if_fail(user != NULL); + g_return_if_fail(username != NULL); session = (MsimSession *)gc->proto_data; g_return_if_fail(MSIM_SESSION_VALID(session)); /* Obtain uid of buddy. */ - buddy = purple_find_buddy(session->account, user); - if (buddy) { - uid = purple_blist_node_get_int(&buddy->node, "UserID"); - if (!uid) { - PurpleNotifyUserInfo *user_info; - - user_info = purple_notify_user_info_new(); - purple_notify_user_info_add_pair(user_info, NULL, - _("This buddy appears to not have a userid stored in the buddy list, can't look up. Is the user really on the buddy list?")); - - purple_notify_userinfo(session->gc, user, user_info, NULL, NULL); - purple_notify_user_info_destroy(user_info); - return; - } - + user = msim_find_user(session, username); + + /* If is on buddy list, lookup by uid since it is faster. */ + if (user && (uid = purple_blist_node_get_int(&user->buddy->node, "UserID"))) { user_to_lookup = g_strdup_printf("%d", uid); } else { /* Looking up buddy not on blist. Lookup by whatever user entered. */ - user_to_lookup = g_strdup(user); + user_to_lookup = g_strdup(username); } /* Pass the username to msim_get_info_cb(), because since we lookup * by userid, the userinfo message will only contain the uid (not - * the username). + * the username) but it would be useful to display the username too. */ user_msg = msim_msg_new( - "user", MSIM_TYPE_STRING, g_strdup(user), + "user", MSIM_TYPE_STRING, g_strdup(username), NULL); - purple_debug_info("msim", "msim_get_info, setting up lookup, user=%s\n", user); + purple_debug_info("msim", "msim_get_info, setting up lookup, user=%s\n", username); msim_lookup_user(session, user_to_lookup, msim_get_info_cb, user_msg); @@ -2456,24 +2514,46 @@ /** Store an field of information about a buddy. */ static void -msim_store_buddy_info_each(gpointer key, gpointer value, gpointer user_data) +msim_store_user_info_each(gpointer key, gpointer value, gpointer user_data) { - PurpleBuddy *buddy; + MsimUser *user; gchar *key_str, *value_str; - buddy = (PurpleBuddy *)user_data; + user = (MsimUser *)user_data; key_str = (gchar *)key; value_str = (gchar *)value; - if (strcmp(key_str, "UserID") == 0 || - strcmp(key_str, "Age") == 0 || - strcmp(key_str, "TotalFriends") == 0) { - /* Certain fields get set as integers, instead of strings, for - * convenience. May not be the best way to do it, but having at least - * UserID as an integer is convenient...until it overflows! */ - purple_blist_node_set_int(&buddy->node, key_str, atol(value_str)); + if (!strcmp(key_str, "UserID")) { + purple_blist_node_set_int(&user->buddy->node, "UserID", atol(value_str)); + } else if (!strcmp(key_str, "Age")) { + user->age = atol(value_str); + } else if (!strcmp(key_str, "Gender")) { + user->gender = g_strdup(value_str); + } else if (!strcmp(key_str, "Location")) { + user->location = g_strdup(value_str); + } else if (!strcmp(key_str, "TotalFriends")) { + user->total_friends = atol(value_str); + } else if (!strcmp(key_str, "DisplayName")) { + user->display_name = g_strdup(value_str); + } else if (!strcmp(key_str, "BandName")) { + user->band_name = g_strdup(value_str); + } else if (!strcmp(key_str, "SongName")) { + user->song_name = g_strdup(value_str); + } else if (!strcmp(key_str, "UserName")) { + /* Ignore because PurpleBuddy knows this already */ + ; + } else if (!strcmp(key_str, "ImageURL")) { + user->image_url = g_strdup(value_str); } else { - purple_blist_node_set_string(&buddy->node, key_str, value_str); + /* TODO: other fields in MsimUser */ + gchar *msg; + + msg = g_strdup_printf("msim_store_user_info_each: unknown field %s=%s", + key_str, value_str); + + msim_unrecognized(NULL, NULL, msg); + + g_free(msg); } } @@ -2486,14 +2566,14 @@ * blist.xml. If the function has no buddy information, this function * is a no-op (and returns FALSE). * - * TODO: Store ephemeral information in MsimBuddy instead. + * TODO: Store ephemeral information in MsimUser instead. */ static gboolean -msim_store_buddy_info(MsimSession *session, MsimMessage *msg) +msim_store_user_info(MsimSession *session, MsimMessage *msg) { GHashTable *body; gchar *username, *body_str, *uid; - PurpleBuddy *buddy; + MsimUser *user; g_return_val_if_fail(MSIM_SESSION_VALID(session), FALSE); g_return_val_if_fail(msg != NULL, FALSE); @@ -2525,9 +2605,9 @@ purple_debug_info("msim", "associating uid %s with username %s\n", uid, username); - buddy = purple_find_buddy(session->account, username); - if (buddy) { - g_hash_table_foreach(body, msim_store_buddy_info_each, buddy); + user = msim_find_user(session, username); + if (user) { + g_hash_table_foreach(body, msim_store_user_info_each, user); } if (msim_msg_get_integer(msg, "dsn") == MG_OWN_IM_INFO_DSN && @@ -2617,7 +2697,7 @@ g_return_val_if_fail(MSIM_SESSION_VALID(session), FALSE); g_return_val_if_fail(msg != NULL, FALSE); - msim_store_buddy_info(session, msg); + msim_store_user_info(session, msg); rid = msim_msg_get_integer(msg, "rid"); cmd = msim_msg_get_integer(msg, "cmd"); @@ -2704,7 +2784,7 @@ msim_incoming_status(MsimSession *session, MsimMessage *msg) { PurpleBuddyList *blist; - PurpleBuddy *buddy; + MsimUser *user; GList *list; gchar *status_headline; gint status_code, purple_status_code; @@ -2742,23 +2822,26 @@ blist = purple_get_blist(); /* Add buddy if not found */ - buddy = purple_find_buddy(session->account, username); - if (!buddy) { + user = msim_find_user(session, username); + if (!user) { + PurpleBuddy *buddy; + purple_debug_info("msim", "msim_status: making new buddy for %s\n", username); buddy = purple_buddy_new(session->account, username, NULL); - purple_blist_add_buddy(buddy, NULL, NULL, NULL); + user = msim_get_user_from_buddy(buddy); + /* All buddies on list should have 'uid' integer associated with them. */ purple_blist_node_set_int(&buddy->node, "UserID", msim_msg_get_integer(msg, "f")); - msim_store_buddy_info(session, msg); + msim_store_user_info(session, msg); } else { purple_debug_info("msim", "msim_status: found buddy %s\n", username); } - purple_blist_node_set_string(&buddy->node, "Headline", status_headline); + user->headline = g_strdup(status_headline); /* Set user status */ switch (status_code) { @@ -3549,10 +3632,13 @@ msim_status_text(PurpleBuddy *buddy) { MsimSession *session; + MsimUser *user; const gchar *display_name, *headline; g_return_val_if_fail(buddy != NULL, NULL); + user = msim_get_user_from_buddy(buddy); + session = (MsimSession *)buddy->account->gc->proto_data; g_return_val_if_fail(MSIM_SESSION_VALID(session), NULL); @@ -3560,24 +3646,20 @@ /* Retrieve display name and/or headline, depending on user preference. */ if (purple_account_get_bool(session->account, "show_display_name", TRUE)) { - display_name = purple_blist_node_get_string(&buddy->node, "DisplayName"); + display_name = user->display_name; } if (purple_account_get_bool(session->account, "show_headline", FALSE)) { - headline = purple_blist_node_get_string(&buddy->node, "Headline"); + headline = user->headline; } /* Return appropriate combination of display name and/or headline, or neither. */ if (display_name && headline) { return g_strconcat(display_name, " ", headline, NULL); - } - - if (display_name) { + } else if (display_name) { return g_strdup(display_name); - } - - if (headline) { + } else if (headline) { return g_strdup(headline); } @@ -3596,12 +3678,14 @@ msim_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean full) { - const gchar *str, *str2; - gint n; + const gchar *str; + MsimUser *user; g_return_if_fail(buddy != NULL); g_return_if_fail(user_info != NULL); + user = msim_get_user_from_buddy(buddy); + if (PURPLE_BUDDY_IS_ONLINE(buddy)) { MsimSession *session; @@ -3609,51 +3693,41 @@ g_return_if_fail(MSIM_SESSION_VALID(session)); - /* TODO: if (full), do something different */ + /* TODO: if (full), do something different? */ /* Useful to identify the account the tooltip refers to. * Other prpls show this. */ - str = purple_blist_node_get_string(&buddy->node, "UserName"); - if (str) { - purple_notify_user_info_add_pair(user_info, _("User Name"), str); + if (user->username) { + purple_notify_user_info_add_pair(user_info, _("User Name"), user->username); } /* a/s/l...the vitals */ - n = purple_blist_node_get_int(&buddy->node, "Age"); - if (n) { + if (user->age) { purple_notify_user_info_add_pair(user_info, _("Age"), - g_strdup_printf("%d", n)); + g_strdup_printf("%d", user->age)); } - str = purple_blist_node_get_string(&buddy->node, "Gender"); - if (str) { - purple_notify_user_info_add_pair(user_info, _("Gender"), str); + if (user->gender) { + purple_notify_user_info_add_pair(user_info, _("Gender"), user->gender); } - str = purple_blist_node_get_string(&buddy->node, "Location"); - if (str) { - purple_notify_user_info_add_pair(user_info, _("Location"), str); + if (user->location) { + purple_notify_user_info_add_pair(user_info, _("Location"), user->location); } /* Other information */ - str = purple_blist_node_get_string(&buddy->node, "Headline"); - if (str) { - purple_notify_user_info_add_pair(user_info, _("Headline"), str); + if (user->headline) { + purple_notify_user_info_add_pair(user_info, _("Headline"), user->headline); } - str = purple_blist_node_get_string(&buddy->node, "BandName"); - str2 = purple_blist_node_get_string(&buddy->node, "SongName"); - if (str || str2) { - purple_notify_user_info_add_pair(user_info, _("Song"), - g_strdup_printf("%s - %s", - str ? str : _("Unknown Artist"), - str2 ? str2 : _("Unknown Song"))); + str = msim_format_now_playing(user->band_name, user->song_name); + if (str) { + purple_notify_user_info_add_pair(user_info, _("Song"), str); } - n = purple_blist_node_get_int(&buddy->node, "TotalFriends"); - if (n) { + if (user->total_friends) { purple_notify_user_info_add_pair(user_info, _("Total Friends"), - g_strdup_printf("%d", n)); + g_strdup_printf("%d", user->total_friends)); } }
--- a/libpurple/protocols/myspace/myspace.h Sun Aug 12 23:16:53 2007 +0000 +++ b/libpurple/protocols/myspace/myspace.h Sun Aug 12 23:20:07 2007 +0000 @@ -199,20 +199,24 @@ guint inbox_status; /**< Bit field of inbox notifications */ } MsimSession; -#if 0 /* Hold ephemeral information about buddies, for proto_data of PurpleBuddy. */ /* GHashTable? */ -typedef struct _MsimBuddy +typedef struct _MsimUser { + PurpleBuddy *buddy; guint client_cv; gchar *client_info; guint age; + gchar *gender; + gchar *location; guint total_friends; gchar *headline; gchar *display_name; + /* Note: uid is in &buddy->node (set_blist_node_int), since it never changes */ gchar *username; -} MsimBuddy; -#endif + gchar *band_name, *song_name; + gchar *image_url; +} MsimUser; /* Check if an MsimSession is valid */ #define MSIM_SESSION_VALID(s) (session != NULL && session->magic == MSIM_SESSION_STRUCT_MAGIC)