Mercurial > pidgin.yaz
diff libpurple/protocols/msn/user.c @ 31292:47b6eda87723
propagate from branch 'im.pidgin.pidgin' (head 07d0765c444a097af45c2650f54323afb900a07b)
to branch 'im.pidgin.soc.2010.msn-tlc' (head f3998422a4724ab424e4e2328f58fc0504856557)
author | masca@cpw.pidgin.im |
---|---|
date | Mon, 19 Jul 2010 21:11:32 +0000 |
parents | 56ef12440d52 |
children | 4445ae4215b8 |
line wrap: on
line diff
--- a/libpurple/protocols/msn/user.c Mon Jul 19 18:25:47 2010 +0000 +++ b/libpurple/protocols/msn/user.c Mon Jul 19 21:11:32 2010 +0000 @@ -21,10 +21,21 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#include "msn.h" + +#include "internal.h" +#include "debug.h" +#include "util.h" + #include "user.h" #include "slp.h" +static void free_user_endpoint(MsnUserEndpoint *data) +{ + g_free(data->id); + g_free(data->name); + g_free(data); +} + /*new a user object*/ MsnUser * msn_user_new(MsnUserList *userlist, const char *passport, @@ -39,15 +50,25 @@ msn_user_set_passport(user, passport); msn_user_set_friendly_name(user, friendly_name); - return user; + return msn_user_ref(user); } /*destroy a user object*/ -void +static void msn_user_destroy(MsnUser *user) { g_return_if_fail(user != NULL); + if (user->refcount > 1) { + msn_user_unref(user); + return; + } + + while (user->endpoints != NULL) { + free_user_endpoint(user->endpoints->data); + user->endpoints = g_slist_delete_link(user->endpoints, user->endpoints); + } + if (user->clientcaps != NULL) g_hash_table_destroy(user->clientcaps); @@ -82,6 +103,27 @@ g_free(user); } +MsnUser * +msn_user_ref(MsnUser *user) +{ + g_return_val_if_fail(user != NULL, NULL); + + user->refcount++; + + return user; +} + +void +msn_user_unref(MsnUser *user) +{ + g_return_if_fail(user != NULL); + + user->refcount--; + + if(user->refcount == 0) + msn_user_destroy(user); +} + void msn_user_update(MsnUser *user) { @@ -186,6 +228,9 @@ { g_return_val_if_fail(user != NULL, FALSE); + if (user == user->userlist->session->user) + return FALSE; + if (user->friendly_name && name && (!strcmp(user->friendly_name, name) || !strcmp(user->passport, name))) return FALSE; @@ -217,6 +262,47 @@ } void +msn_user_set_endpoint_data(MsnUser *user, const char *input, MsnUserEndpoint *newep) +{ + MsnUserEndpoint *ep; + char *endpoint; + GSList *l; + + g_return_if_fail(user != NULL); + g_return_if_fail(input != NULL); + + endpoint = g_ascii_strdown(input, -1); + + for (l = user->endpoints; l; l = l->next) { + ep = l->data; + if (g_str_equal(ep->id, endpoint)) { + /* We have info about this endpoint! */ + + g_free(endpoint); + + if (newep == NULL) { + /* Delete it and exit */ + user->endpoints = g_slist_delete_link(user->endpoints, l); + free_user_endpoint(ep); + return; + } + + /* Break out of our loop and update it */ + break; + } + } + if (l == NULL) { + /* Need to add a new endpoint */ + ep = g_new0(MsnUserEndpoint, 1); + ep->id = endpoint; + user->endpoints = g_slist_prepend(user->endpoints, ep); + } + + ep->clientid = newep->clientid; + ep->extcaps = newep->extcaps; +} + +void msn_user_set_op(MsnUser *user, MsnListOp list_op) { g_return_if_fail(user != NULL); @@ -406,6 +492,14 @@ } void +msn_user_set_extcaps(MsnUser *user, guint extcaps) +{ + g_return_if_fail(user != NULL); + + user->extcaps = extcaps; +} + +void msn_user_set_network(MsnUser *user, MsnNetwork network) { g_return_if_fail(user != NULL); @@ -413,6 +507,71 @@ user->networkid = network; } +static gboolean +buddy_icon_cached(PurpleConnection *gc, MsnObject *obj) +{ + PurpleAccount *account; + PurpleBuddy *buddy; + const char *old; + const char *new; + + g_return_val_if_fail(obj != NULL, FALSE); + + account = purple_connection_get_account(gc); + + buddy = purple_find_buddy(account, msn_object_get_creator(obj)); + if (buddy == NULL) + return FALSE; + + old = purple_buddy_icons_get_checksum_for_user(buddy); + new = msn_object_get_sha1(obj); + + if (new == NULL) + return FALSE; + + /* If the old and new checksums are the same, and the file actually exists, + * then return TRUE */ + if (old != NULL && !strcmp(old, new)) + return TRUE; + + return FALSE; +} + +static void +queue_buddy_icon_request(MsnUser *user) +{ + PurpleAccount *account; + MsnObject *obj; + GQueue *queue; + + g_return_if_fail(user != NULL); + + account = user->userlist->session->account; + + obj = msn_user_get_object(user); + + if (obj == NULL) { + purple_buddy_icons_set_for_user(account, user->passport, NULL, 0, NULL); + return; + } + + if (!buddy_icon_cached(account->gc, obj)) { + MsnUserList *userlist; + + userlist = user->userlist; + queue = userlist->buddy_icon_requests; + + if (purple_debug_is_verbose()) + purple_debug_info("msn", "Queueing buddy icon request for %s (buddy_icon_window = %i)\n", + user->passport, userlist->buddy_icon_window); + + g_queue_push_tail(queue, user); + + if (userlist->buddy_icon_window > 0) + msn_release_buddy_icon_request(userlist); + } +} + void msn_user_set_object(MsnUser *user, MsnObject *obj) { @@ -423,8 +582,8 @@ user->msnobj = obj; - if (user->list_op & MSN_LIST_FL_OP) - msn_queue_buddy_icon_request(user); + if (user != user->userlist->session->user && user->list_op & MSN_LIST_FL_OP) + queue_buddy_icon_request(user); } void @@ -496,6 +655,39 @@ return user->clientid; } +guint +msn_user_get_extcaps(const MsnUser *user) +{ + g_return_val_if_fail(user != NULL, 0); + + return user->extcaps; +} + +MsnUserEndpoint * +msn_user_get_endpoint_data(MsnUser *user, const char *input) +{ + char *endpoint; + GSList *l; + MsnUserEndpoint *ep; + + g_return_val_if_fail(user != NULL, NULL); + g_return_val_if_fail(input != NULL, NULL); + + endpoint = g_ascii_strdown(input, -1); + + for (l = user->endpoints; l; l = l->next) { + ep = l->data; + if (g_str_equal(ep->id, endpoint)) { + g_free(endpoint); + return ep; + } + } + + g_free(endpoint); + + return NULL; +} + MsnObject * msn_user_get_object(const MsnUser *user) { @@ -520,3 +712,54 @@ return user->invite_message; } +gboolean +msn_user_is_capable(MsnUser *user, char *endpoint, guint capability, guint extcap) +{ + g_return_val_if_fail(user != NULL, FALSE); + + if (endpoint != NULL) { + MsnUserEndpoint *ep = msn_user_get_endpoint_data(user, endpoint); + if (ep != NULL) + return (ep->clientid & capability) && (ep->extcaps & extcap); + else + return FALSE; + } + + return (user->clientid & capability) && (user->extcaps & extcap); +} + +/************************************************************************** + * Utility functions + **************************************************************************/ + +int +msn_user_passport_cmp(MsnUser *user, const char *passport) +{ + const char *pass; + + pass = msn_user_get_passport(user); + + return strcmp(pass, purple_normalize_nocase(NULL, passport)); +} + +gboolean +msn_user_is_in_group(MsnUser *user, const char * group_id) +{ + if (user == NULL) + return FALSE; + + if (group_id == NULL) + return FALSE; + + return (g_list_find_custom(user->group_ids, group_id, (GCompareFunc)strcmp)) != NULL; +} + +gboolean +msn_user_is_in_list(MsnUser *user, MsnListId list_id) +{ + if (user == NULL) + return FALSE; + + return (user->list_op & (1 << list_id)); +} +