void qq_update_buddy_icon(PurpleAccount *account, const gchar *who, gint face) { PurpleBuddy *buddy; const gchar *icon_name_prev = NULL; gchar *icon_name; gchar *icon_path; gchar *icon_file_content; gsize icon_file_size; g_return_if_fail(account != NULL && who != NULL); /* purple_debug_info("QQ", "Update %s icon to %d\n", who, face); */ icon_name = qq_get_icon_name(face); g_return_if_fail(icon_name != NULL); /* purple_debug_info("QQ", "icon file name is %s\n", icon_name); */ if ((buddy = purple_find_buddy(account, who))) { icon_name_prev = purple_buddy_icons_get_checksum_for_user(buddy); /* purple_debug_info("QQ", "Previous icon is %s\n", icon_name_prev != NULL ? icon_name_prev : "(NULL)"); */ } if (icon_name_prev != NULL && !strcmp(icon_name, icon_name_prev)) { /* purple_debug_info("QQ", "Icon is not changed\n"); */ g_free(icon_name); return; } icon_path = qq_get_icon_path(icon_name); if (icon_path == NULL) { g_free(icon_name); return; } if (!g_file_get_contents(icon_path, &icon_file_content, &icon_file_size, NULL)) { purple_debug_error("QQ", "Failed reading icon file %s\n", icon_path); } else { purple_debug_info("QQ", "Update %s icon to %d (%s)\n", who, face, icon_path); purple_buddy_icons_set_for_user(account, who, icon_file_content, icon_file_size, icon_name); } g_free(icon_name); g_free(icon_path); }
void CheckPortrait(struct fetion_account_data *sip, const gchar * who, const gchar * crc) { PurpleBuddy *buddy = NULL; struct fetion_buddy *f_buddy; const gchar *old_crc = NULL; buddy = purple_find_buddy(sip->account, who); g_return_if_fail(buddy != NULL); old_crc = purple_buddy_icons_get_checksum_for_user(buddy); if (old_crc != NULL && (strcmp(old_crc, crc) == 0)) return; f_buddy = g_hash_table_lookup(sip->buddies, who); g_return_if_fail(f_buddy != NULL); f_buddy->icon_crc = g_strdup(crc); GetPortrait(sip, f_buddy, NULL); }
static void spin_sync_photo(SpinData* spin,PurpleBuddy* buddy,const gchar* url) { PurpleAccount* account = purple_connection_get_account(spin->gc); const gchar* old_url = purple_buddy_icons_get_checksum_for_user(buddy); if(g_strcmp0(url,old_url) == 0) return; if(!url) purple_buddy_icons_set_for_user(account,purple_buddy_get_name(buddy), NULL,0,NULL); else { FetchPhotoData* user = g_new(FetchPhotoData,1); user->url = g_strdup(url); user->user = g_strdup(purple_buddy_get_name(buddy)); user->gc = spin->gc; spin_fetch_url_request(spin,url,fetch_photo_cb,user); } }
static void pb_set_base64_icon_for_buddy(const gchar *base64_icon, PurpleBuddy *buddy) { PurpleBuddyIcon *icon; guchar *icon_data; gsize icon_len; gchar *checksum; const gchar *old_checksum; checksum = g_strdup_printf("%ud", g_str_hash(base64_icon)); old_checksum = purple_buddy_icons_get_checksum_for_user(buddy); if (old_checksum && purple_strequal(old_checksum, checksum)) { g_free(checksum); return; } icon_data = purple_base64_decode(base64_icon, &icon_len); icon = purple_buddy_icon_new(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy), icon_data, icon_len, checksum); g_free(icon_data); g_free(checksum); }
static gboolean handle_presence_contact(JabberStream *js, JabberPresence *presence) { JabberBuddyResource *jbr; PurpleAccount *account; PurpleBuddy *b; char *buddy_name; PurpleConversation *conv; buddy_name = jabber_id_get_bare_jid(presence->jid_from); account = purple_connection_get_account(js->gc); b = purple_find_buddy(account, buddy_name); /* * Unbind/unlock from sending messages to a specific resource on * presence changes. This is locked to a specific resource when * receiving a message (in message.c). */ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy_name, account); if (conv) { purple_debug_info("jabber", "Changed conversation binding from %s to %s\n", purple_conversation_get_name(conv), buddy_name); purple_conversation_set_name(conv, buddy_name); } if (b == NULL) { if (presence->jb != js->user_jb) { purple_debug_warning("jabber", "Got presence for unknown buddy %s on account %s (%p)\n", buddy_name, purple_account_get_username(account), account); g_free(buddy_name); return FALSE; } else { /* this is a different resource of our own account. Resume even when this account isn't on our blist */ } } if (b && presence->vcard_avatar_hash) { const char *ah = presence->vcard_avatar_hash[0] != '\0' ? presence->vcard_avatar_hash : NULL; const char *ah2 = purple_buddy_icons_get_checksum_for_user(b); if (!purple_strequal(ah, ah2)) { /* XXX this is a crappy way of trying to prevent * someone from spamming us with presence packets * and causing us to DoS ourselves...what we really * need is a queue system that can throttle itself, * but i'm too tired to write that right now */ if(!g_slist_find(js->pending_avatar_requests, presence->jb)) { JabberIq *iq; xmlnode *vcard; js->pending_avatar_requests = g_slist_prepend(js->pending_avatar_requests, presence->jb); iq = jabber_iq_new(js, JABBER_IQ_GET); xmlnode_set_attrib(iq->node, "to", buddy_name); vcard = xmlnode_new_child(iq->node, "vCard"); xmlnode_set_namespace(vcard, "vcard-temp"); jabber_iq_set_callback(iq, jabber_vcard_parse_avatar, NULL); jabber_iq_send(iq); } } } if (presence->state == JABBER_BUDDY_STATE_ERROR || presence->type == JABBER_PRESENCE_UNAVAILABLE || presence->type == JABBER_PRESENCE_UNSUBSCRIBED) { jabber_buddy_remove_resource(presence->jb, presence->jid_from->resource); } else { jbr = jabber_buddy_track_resource(presence->jb, presence->jid_from->resource, presence->priority, presence->state, presence->status); jbr->idle = presence->idle ? time(NULL) - presence->idle : 0; } jbr = jabber_buddy_find_resource(presence->jb, NULL); if (jbr) { jabber_google_presence_incoming(js, buddy_name, jbr); purple_prpl_got_user_status(account, buddy_name, jabber_buddy_state_get_status_id(jbr->state), "priority", jbr->priority, "message", jbr->status, NULL); purple_prpl_got_user_idle(account, buddy_name, jbr->idle, jbr->idle); if (presence->nickname) serv_got_alias(js->gc, buddy_name, presence->nickname); } else { purple_prpl_got_user_status(account, buddy_name, jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_UNAVAILABLE), presence->status ? "message" : NULL, presence->status, NULL); } g_free(buddy_name); return TRUE; }
/** * If the buddy does not yet exist, then create it and add it to * our buddy list. In either case we set the correct status for * the buddy. */ void bonjour_buddy_add_to_purple(BonjourBuddy *bonjour_buddy) { PurpleBuddy *buddy; PurpleGroup *group; PurpleAccount *account = bonjour_buddy->account; const char *status_id, *old_hash, *new_hash; /* Translate between the Bonjour status and the Purple status */ if (bonjour_buddy->status != NULL && g_ascii_strcasecmp("dnd", bonjour_buddy->status) == 0) status_id = BONJOUR_STATUS_ID_AWAY; else status_id = BONJOUR_STATUS_ID_AVAILABLE; /* * TODO: Figure out the idle time by getting the "away" * field from the DNS SD. */ /* Make sure the Bonjour group exists in our buddy list */ group = purple_find_group(BONJOUR_GROUP_NAME); /* Use the buddy's domain, instead? */ if (group == NULL) { group = purple_group_new(BONJOUR_GROUP_NAME); purple_blist_add_group(group, NULL); } /* Make sure the buddy exists in our buddy list */ buddy = purple_find_buddy(account, bonjour_buddy->name); if (buddy == NULL) { buddy = purple_buddy_new(account, bonjour_buddy->name, NULL); buddy->proto_data = bonjour_buddy; purple_blist_node_set_flags((PurpleBlistNode *)buddy, PURPLE_BLIST_NODE_FLAG_NO_SAVE); purple_blist_add_buddy(buddy, NULL, group, NULL); } /* Create the alias for the buddy using the first and the last name */ if (bonjour_buddy->nick) serv_got_alias(purple_account_get_connection(account), buddy->name, bonjour_buddy->nick); else { gchar *alias = NULL; const char *first, *last; first = bonjour_buddy->first; last = bonjour_buddy->last; if ((first && *first) || (last && *last)) alias = g_strdup_printf("%s%s%s", (first && *first ? first : ""), (first && *first && last && *last ? " " : ""), (last && *last ? last : "")); serv_got_alias(purple_account_get_connection(account), buddy->name, alias); g_free(alias); } /* Set the user's status */ if (bonjour_buddy->msg != NULL) purple_prpl_got_user_status(account, buddy->name, status_id, "message", bonjour_buddy->msg, NULL); else purple_prpl_got_user_status(account, buddy->name, status_id, NULL); purple_prpl_got_user_idle(account, buddy->name, FALSE, 0); /* TODO: Because we don't save Bonjour buddies in blist.xml, * we will always have to look up the buddy icon at login time. * I think we should figure out a way to do something about this. */ /* Deal with the buddy icon */ old_hash = purple_buddy_icons_get_checksum_for_user(buddy); new_hash = (bonjour_buddy->phsh && *(bonjour_buddy->phsh)) ? bonjour_buddy->phsh : NULL; if (new_hash && (!old_hash || strcmp(old_hash, new_hash) != 0)) { /* Look up the new icon data */ /* TODO: Make sure the hash assigned to the retrieved buddy icon is the same * as what we looked up. */ bonjour_dns_sd_retrieve_buddy_icon(bonjour_buddy); } else if (!new_hash) purple_buddy_icons_set_for_user(account, buddy->name, NULL, 0, NULL); }
/* return TRUE if avatar update was performed or there is no new requests, FALSE if we can request another one immediately */ static gboolean ggp_avatar_buddy_update_next(PurpleConnection *gc) { PurpleHttpRequest *req; ggp_avatar_session_data *avdata = ggp_avatar_get_avdata(gc); GList *pending_update_it; ggp_avatar_buddy_update_req *pending_update; PurpleBuddy *buddy; PurpleAccount *account = purple_connection_get_account(gc); time_t old_timestamp; const char *old_timestamp_str; pending_update_it = g_list_first(avdata->pending_updates); if (pending_update_it == NULL) return TRUE; pending_update = pending_update_it->data; avdata->pending_updates = g_list_remove(avdata->pending_updates, pending_update); buddy = purple_blist_find_buddy(account, ggp_uin_to_str(pending_update->uin)); if (!buddy) { if (ggp_str_to_uin(purple_account_get_username(account)) == pending_update->uin) { purple_debug_misc("gg", "ggp_avatar_buddy_update_next(%p): own " "avatar update requested, but we don't have " "ourselves on buddy list\n", gc); } else { purple_debug_warning("gg", "ggp_avatar_buddy_update_next(%p): " "%u update requested, but he's not on buddy " "list\n", gc, pending_update->uin); } return FALSE; } old_timestamp_str = purple_buddy_icons_get_checksum_for_user(buddy); old_timestamp = old_timestamp_str ? g_ascii_strtoull( old_timestamp_str, NULL, 10) : 0; if (old_timestamp == pending_update->timestamp) { if (purple_debug_is_verbose()) { purple_debug_misc("gg", "ggp_avatar_buddy_update_next(%p): " "%u have up to date avatar with ts=%lu\n", gc, pending_update->uin, pending_update->timestamp); } return FALSE; } if (old_timestamp > pending_update->timestamp) { purple_debug_warning("gg", "ggp_avatar_buddy_update_next(%p): " "saved timestamp for %u is newer than received " "(%lu > %lu)\n", gc, pending_update->uin, old_timestamp, pending_update->timestamp); } purple_debug_info("gg", "ggp_avatar_buddy_update_next(%p): " "updating %u with ts=%lu...\n", gc, pending_update->uin, pending_update->timestamp); pending_update->gc = gc; avdata->current_update = pending_update; req = purple_http_request_new(NULL); purple_http_request_set_url_printf(req, GGP_AVATAR_BUDDY_URL, pending_update->uin); purple_http_request_header_set(req, "User-Agent", GGP_AVATAR_USERAGENT); purple_http_request_set_max_len(req, GGP_AVATAR_SIZE_MAX); pending_update->request = purple_http_request(gc, req, ggp_avatar_buddy_update_received, pending_update); purple_http_request_unref(req); return TRUE; }
static void skypeweb_get_friend_list_cb(SkypeWebAccount *sa, JsonNode *node, gpointer user_data) { JsonObject *obj; JsonArray *contacts; PurpleGroup *group = NULL; GSList *users_to_fetch = NULL; guint index, length; obj = json_node_get_object(node); contacts = json_object_get_array_member(obj, "contacts"); length = json_array_get_length(contacts); for(index = 0; index < length; index++) { JsonObject *contact = json_array_get_object_element(contacts, index); const gchar *id = json_object_get_string_member(contact, "id"); const gchar *display_name = json_object_get_string_member(contact, "display_name"); const gchar *avatar_url = NULL; gboolean authorized = json_object_get_boolean_member(contact, "authorized"); gboolean blocked = json_object_get_boolean_member(contact, "blocked"); const gchar *type = json_object_get_string_member(contact, "type"); JsonObject *name = json_object_get_object_member(contact, "name"); const gchar *firstname = json_object_get_string_member(name, "first"); const gchar *surname = NULL; PurpleBuddy *buddy; //TODO make this work for "pstn" if (!g_str_equal(type, "skype") && !g_str_equal(type, "msn")) continue; if (json_object_has_member(contact, "suggested") && json_object_get_boolean_member(contact, "suggested") && !authorized) { // suggested buddies wtf? some kind of advertising? continue; } buddy = purple_find_buddy(sa->account, id); if (!buddy) { if (!group) { group = purple_blist_find_group("Skype"); if (!group) { group = purple_group_new("Skype"); purple_blist_add_group(group, NULL); } } buddy = purple_buddy_new(sa->account, id, display_name); purple_blist_add_buddy(buddy, NULL, group, NULL); } if (json_object_has_member(name, "surname")) surname = json_object_get_string_member(name, "surname"); // try to free the sbuddy here. no-op if it's not set before, otherwise prevents a leak. skypeweb_buddy_free(buddy); SkypeWebBuddy *sbuddy = g_new0(SkypeWebBuddy, 1); sbuddy->skypename = g_strdup(id); sbuddy->sa = sa; sbuddy->fullname = g_strconcat(firstname, (surname ? " " : NULL), surname, NULL); sbuddy->display_name = g_strdup(display_name); sbuddy->authorized = authorized; sbuddy->blocked = blocked; sbuddy->avatar_url = g_strdup(purple_buddy_icons_get_checksum_for_user(buddy)); sbuddy->buddy = buddy; purple_buddy_set_protocol_data(buddy, sbuddy); purple_serv_got_alias(sa->pc, id, sbuddy->display_name); purple_blist_server_alias_buddy(buddy, sbuddy->fullname); if (json_object_has_member(contact, "avatar_url")) { avatar_url = json_object_get_string_member(contact, "avatar_url"); if (avatar_url && *avatar_url && (!sbuddy->avatar_url || !g_str_equal(sbuddy->avatar_url, avatar_url))) { g_free(sbuddy->avatar_url); sbuddy->avatar_url = g_strdup(avatar_url); skypeweb_get_icon(buddy); } } if (blocked == TRUE) { purple_privacy_deny_add(sa->account, id, TRUE); } else { users_to_fetch = g_slist_prepend(users_to_fetch, sbuddy->skypename); } } if (users_to_fetch) { //skypeweb_get_friend_profiles(sa, users_to_fetch); skypeweb_subscribe_to_contact_status(sa, users_to_fetch); g_slist_free(users_to_fetch); } }
/** * Store a field of information about a buddy. * * @param key_str Key to store. * @param value_str Value string, either user takes ownership of this string * or it is freed if MsimUser doesn't store the string. * @param user User to store data in. Existing data will be replaced. */ static void msim_store_user_info_each(const gchar *key_str, gchar *value_str, MsimUser *user) { if (g_str_equal(key_str, "UserID") || g_str_equal(key_str, "ContactID")) { /* Save to buddy list, if it exists, for quick cached uid lookup with msim_uid2username_from_blist(). */ user->id = atol(value_str); g_free(value_str); if (user->buddy) { purple_debug_info("msim", "associating uid %s with username %s\n", key_str, user->buddy->name); purple_blist_node_set_int(&user->buddy->node, "UserID", user->id); } /* Need to store in MsimUser, too? What if not on blist? */ } else if (g_str_equal(key_str, "Age")) { user->age = atol(value_str); g_free(value_str); } else if (g_str_equal(key_str, "Gender")) { g_free(user->gender); user->gender = value_str; } else if (g_str_equal(key_str, "Location")) { g_free(user->location); user->location = value_str; } else if (g_str_equal(key_str, "TotalFriends")) { user->total_friends = atol(value_str); g_free(value_str); } else if (g_str_equal(key_str, "DisplayName")) { g_free(user->display_name); user->display_name = value_str; } else if (g_str_equal(key_str, "BandName")) { msim_set_artist_or_title(user, value_str, NULL); g_free(value_str); } else if (g_str_equal(key_str, "SongName")) { msim_set_artist_or_title(user, NULL, value_str); g_free(value_str); } else if (g_str_equal(key_str, "UserName") || g_str_equal(key_str, "IMName") || g_str_equal(key_str, "NickName")) { /* Ignore because PurpleBuddy knows this already */ g_free(value_str); } else if (g_str_equal(key_str, "ImageURL") || g_str_equal(key_str, "AvatarURL")) { const gchar *previous_url; if (user->temporary_user) { /* This user will be destroyed soon; don't try to look up its image or avatar, * since that won't return immediately and we will end up accessing freed data. */ g_free(value_str); return; } if (user->temporary_user) { /* This user will be destroyed soon; don't try to look up its image or avatar, * since that won't return immediately and we will end up accessing freed data. */ g_free(value_str); return; } g_free(user->image_url); user->image_url = value_str; /* Instead of showing 'no photo' picture, show nothing. */ if (g_str_equal(user->image_url, "http://x.myspace.com/images/no_pic.gif")) { purple_buddy_icons_set_for_user(user->buddy->account, user->buddy->name, NULL, 0, NULL); return; } /* TODO: use ETag for checksum */ previous_url = purple_buddy_icons_get_checksum_for_user(user->buddy); /* Only download if URL changed */ if (!previous_url || !g_str_equal(previous_url, user->image_url)) { purple_util_fetch_url(user->image_url, TRUE, NULL, TRUE, msim_downloaded_buddy_icon, (gpointer)user); } } else if (g_str_equal(key_str, "LastImageUpdated")) { /* TODO: use somewhere */ user->last_image_updated = atol(value_str); g_free(value_str); } else if (g_str_equal(key_str, "Headline")) { g_free(user->headline); user->headline = value_str; } else { /* TODO: other fields in MsimUser */ gchar *msg; msg = g_strdup_printf("msim_store_user_info_each: unknown field %s=%s", key_str, value_str); g_free(value_str); msim_unrecognized(NULL, NULL, msg); g_free(msg); } }