/pidgin-2.7.3/libpurple/protocols/qq/group_internal.c
C | 434 lines | 332 code | 70 blank | 32 comment | 95 complexity | 3cac2badcb95b617774f28a296a0e5af MD5 | raw file
- /**
- * @file group_internal.c
- *
- * purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
- #include "internal.h"
- #include "blist.h"
- #include "debug.h"
- #include "buddy_opt.h"
- #include "group_internal.h"
- #include "utils.h"
- static qq_room_data *room_data_new(guint32 id, guint32 ext_id, const gchar *title)
- {
- qq_room_data *rmd;
- purple_debug_info("QQ", "Created room data: %s, ext id %u, id %u\n",
- title == NULL ? "(NULL)" : title,
- ext_id, id);
- rmd = g_new0(qq_room_data, 1);
- rmd->my_role = QQ_ROOM_ROLE_NO;
- rmd->id = id;
- rmd->ext_id = ext_id;
- rmd->type8 = 0x01; /* assume permanent Qun */
- rmd->creator_uid = 10000; /* assume by QQ admin */
- rmd->category = 0x01;
- rmd->auth_type = 0x02; /* assume need auth */
- rmd->title_utf8 = g_strdup(title == NULL ? "" : title);
- rmd->desc_utf8 = g_strdup("");
- rmd->notice_utf8 = g_strdup("");
- rmd->members = NULL;
- rmd->is_got_buddies = FALSE;
- return rmd;
- }
- /* create a qq_room_data from hashtable */
- static qq_room_data *room_data_new_by_hashtable(PurpleConnection *gc, GHashTable *data)
- {
- qq_room_data *rmd;
- guint32 id, ext_id;
- gchar *value;
- value = g_hash_table_lookup(data, QQ_ROOM_KEY_INTERNAL_ID);
- id = value ? strtoul(value, NULL, 10) : 0;
- value = g_hash_table_lookup(data, QQ_ROOM_KEY_EXTERNAL_ID);
- ext_id = value ? strtoul(value, NULL, 10) : 0;
- value = g_hash_table_lookup(data, QQ_ROOM_KEY_TITLE_UTF8);
- rmd = room_data_new(id, ext_id, value);
- rmd->my_role = QQ_ROOM_ROLE_YES;
- return rmd;
- }
- /* gracefully free all members in a room */
- static void room_buddies_free(qq_room_data *rmd)
- {
- gint i;
- GList *list;
- qq_buddy_data *bd;
- g_return_if_fail(rmd != NULL);
- i = 0;
- while (NULL != (list = rmd->members)) {
- bd = (qq_buddy_data *) list->data;
- i++;
- rmd->members = g_list_remove(rmd->members, bd);
- qq_buddy_data_free(bd);
- }
- rmd->members = NULL;
- }
- /* gracefully free the memory for one qq_room_data */
- static void room_data_free(qq_room_data *rmd)
- {
- g_return_if_fail(rmd != NULL);
- room_buddies_free(rmd);
- g_free(rmd->title_utf8);
- g_free(rmd->desc_utf8);
- g_free(rmd->notice_utf8);
- g_free(rmd);
- }
- void qq_room_update_chat_info(PurpleChat *chat, qq_room_data *rmd)
- {
- GHashTable *components;
- if (rmd->title_utf8 != NULL && strlen(rmd->title_utf8) > 0) {
- purple_blist_alias_chat(chat, rmd->title_utf8);
- }
- components = purple_chat_get_components(chat);
- g_hash_table_replace(components,
- g_strdup(QQ_ROOM_KEY_INTERNAL_ID),
- g_strdup_printf("%u", rmd->id));
- g_hash_table_replace(components,
- g_strdup(QQ_ROOM_KEY_EXTERNAL_ID),
- g_strdup_printf("%u", rmd->ext_id));
- g_hash_table_replace(components,
- g_strdup(QQ_ROOM_KEY_TITLE_UTF8), g_strdup(rmd->title_utf8));
- }
- static PurpleChat *chat_new(PurpleConnection *gc, qq_room_data *rmd)
- {
- GHashTable *components;
- PurpleGroup *g;
- PurpleChat *chat;
- purple_debug_info("QQ", "Add new chat: id %u, ext id %u, title %s\n",
- rmd->id, rmd->ext_id,
- rmd->title_utf8 == NULL ? "(NULL)" : rmd->title_utf8);
- components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- g_hash_table_insert(components,
- g_strdup(QQ_ROOM_KEY_INTERNAL_ID), g_strdup_printf("%u", rmd->id));
- g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_EXTERNAL_ID),
- g_strdup_printf("%u", rmd->ext_id));
- g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_TITLE_UTF8), g_strdup(rmd->title_utf8));
- chat = purple_chat_new(purple_connection_get_account(gc), rmd->title_utf8, components);
- g = qq_group_find_or_new(PURPLE_GROUP_QQ_QUN);
- purple_blist_add_chat(chat, g, NULL);
- return chat;
- }
- PurpleChat *qq_room_find_or_new(PurpleConnection *gc, guint32 id, guint32 ext_id)
- {
- qq_data *qd;
- qq_room_data *rmd;
- PurpleChat *chat;
- gchar *num_str;
- g_return_val_if_fail (gc != NULL && gc->proto_data != NULL, NULL);
- qd = (qq_data *) gc->proto_data;
- g_return_val_if_fail(id != 0 && ext_id != 0, NULL);
- purple_debug_info("QQ", "Find or add new room: id %u, ext id %u\n", id, ext_id);
- rmd = qq_room_data_find(gc, id);
- if (rmd == NULL) {
- rmd = room_data_new(id, ext_id, NULL);
- g_return_val_if_fail(rmd != NULL, NULL);
- rmd->my_role = QQ_ROOM_ROLE_YES;
- qd->groups = g_list_append(qd->groups, rmd);
- }
- num_str = g_strdup_printf("%u", ext_id);
- chat = purple_blist_find_chat(purple_connection_get_account(gc), num_str);
- g_free(num_str);
- if (chat) {
- return chat;
- }
- return chat_new(gc, rmd);
- }
- void qq_room_remove(PurpleConnection *gc, guint32 id)
- {
- qq_data *qd;
- PurpleChat *chat;
- qq_room_data *rmd;
- gchar *num_str;
- guint32 ext_id;
- g_return_if_fail (gc != NULL && gc->proto_data != NULL);
- qd = (qq_data *) gc->proto_data;
- purple_debug_info("QQ", "Find and remove room data, id %u\n", id);
- rmd = qq_room_data_find(gc, id);
- g_return_if_fail (rmd != NULL);
- ext_id = rmd->ext_id;
- qd->groups = g_list_remove(qd->groups, rmd);
- room_data_free(rmd);
- purple_debug_info("QQ", "Find and remove chat, ext_id %u\n", ext_id);
- num_str = g_strdup_printf("%u", ext_id);
- chat = purple_blist_find_chat(purple_connection_get_account(gc), num_str);
- g_free(num_str);
- g_return_if_fail (chat != NULL);
- purple_blist_remove_chat(chat);
- }
- /* find a qq_buddy_data by uid, called by im.c */
- qq_buddy_data *qq_room_buddy_find(qq_room_data *rmd, guint32 uid)
- {
- GList *list;
- qq_buddy_data *bd;
- g_return_val_if_fail(rmd != NULL && uid > 0, NULL);
- list = rmd->members;
- while (list != NULL) {
- bd = (qq_buddy_data *) list->data;
- if (bd->uid == uid)
- return bd;
- else
- list = list->next;
- }
- return NULL;
- }
- /* remove a qq_buddy_data by uid, called by qq_group_opt.c */
- void qq_room_buddy_remove(qq_room_data *rmd, guint32 uid)
- {
- GList *list;
- qq_buddy_data *bd;
- g_return_if_fail(rmd != NULL && uid > 0);
- list = rmd->members;
- while (list != NULL) {
- bd = (qq_buddy_data *) list->data;
- if (bd->uid == uid) {
- rmd->members = g_list_remove(rmd->members, bd);
- return;
- } else {
- list = list->next;
- }
- }
- }
- qq_buddy_data *qq_room_buddy_find_or_new(PurpleConnection *gc, qq_room_data *rmd, guint32 member_uid)
- {
- qq_buddy_data *member, *bd;
- PurpleBuddy *buddy;
- g_return_val_if_fail(rmd != NULL && member_uid > 0, NULL);
- member = qq_room_buddy_find(rmd, member_uid);
- if (member == NULL) { /* first appear during my session */
- member = g_new0(qq_buddy_data, 1);
- member->uid = member_uid;
- buddy = purple_find_buddy(purple_connection_get_account(gc), uid_to_purple_name(member_uid));
- if (buddy != NULL) {
- const gchar *alias = NULL;
- bd = purple_buddy_get_protocol_data(buddy);
- if (bd != NULL && bd->nickname != NULL)
- member->nickname = g_strdup(bd->nickname);
- else if ((alias = purple_buddy_get_alias(buddy)) != NULL)
- member->nickname = g_strdup(alias);
- }
- rmd->members = g_list_append(rmd->members, member);
- }
- return member;
- }
- qq_room_data *qq_room_data_find(PurpleConnection *gc, guint32 room_id)
- {
- GList *list;
- qq_room_data *rmd;
- qq_data *qd;
- qd = (qq_data *) gc->proto_data;
- if (qd->groups == NULL || room_id <= 0)
- return 0;
- list = qd->groups;
- while (list != NULL) {
- rmd = (qq_room_data *) list->data;
- if (rmd->id == room_id) {
- return rmd;
- }
- list = list->next;
- }
- return NULL;
- }
- guint32 qq_room_get_next(PurpleConnection *gc, guint32 room_id)
- {
- GList *list;
- qq_room_data *rmd;
- qq_data *qd;
- gboolean is_find = FALSE;
- qd = (qq_data *) gc->proto_data;
- if (qd->groups == NULL) {
- return 0;
- }
- if (room_id <= 0) {
- rmd = (qq_room_data *) qd->groups->data;
- return rmd->id;
- }
- list = qd->groups;
- while (list != NULL) {
- rmd = (qq_room_data *) list->data;
- list = list->next;
- if (rmd->id == room_id) {
- is_find = TRUE;
- break;
- }
- }
- g_return_val_if_fail(is_find, 0);
- if (list == NULL) return 0; /* be the end */
- rmd = (qq_room_data *) list->data;
- g_return_val_if_fail(rmd != NULL, 0);
- return rmd->id;
- }
- guint32 qq_room_get_next_conv(PurpleConnection *gc, guint32 room_id)
- {
- GList *list;
- qq_room_data *rmd;
- qq_data *qd;
- gboolean is_find;
- qd = (qq_data *) gc->proto_data;
- list = qd->groups;
- if (room_id > 0) {
- /* search next room */
- is_find = FALSE;
- while (list != NULL) {
- rmd = (qq_room_data *) list->data;
- list = list->next;
- if (rmd->id == room_id) {
- is_find = TRUE;
- break;
- }
- }
- g_return_val_if_fail(is_find, 0);
- }
- while (list != NULL) {
- rmd = (qq_room_data *) list->data;
- g_return_val_if_fail(rmd != NULL, 0);
- if (rmd->my_role == QQ_ROOM_ROLE_YES || rmd->my_role == QQ_ROOM_ROLE_ADMIN) {
- if (NULL != purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_CHAT,rmd->title_utf8, purple_connection_get_account(gc))) {
- /* In convseration*/
- return rmd->id;
- }
- }
- list = list->next;
- }
- return 0;
- }
- /* this should be called upon signin, even when we did not open group chat window */
- void qq_room_data_initial(PurpleConnection *gc)
- {
- PurpleAccount *account;
- PurpleChat *chat;
- PurpleGroup *purple_group;
- PurpleBlistNode *node;
- qq_data *qd;
- qq_room_data *rmd;
- gint count;
- account = purple_connection_get_account(gc);
- qd = (qq_data *) gc->proto_data;
- purple_debug_info("QQ", "Initial QQ Qun configurations\n");
- purple_group = purple_find_group(PURPLE_GROUP_QQ_QUN);
- if (purple_group == NULL) {
- purple_debug_info("QQ", "We have no QQ Qun\n");
- return;
- }
- count = 0;
- for (node = purple_blist_node_get_first_child((PurpleBlistNode *)purple_group);
- node != NULL;
- node = purple_blist_node_get_sibling_next(node))
- {
- if ( !PURPLE_BLIST_NODE_IS_CHAT(node)) {
- continue;
- }
- /* got one */
- chat = (PurpleChat *) node;
- if (account != purple_chat_get_account(chat)) /* not qq account*/
- continue;
- rmd = room_data_new_by_hashtable(gc, purple_chat_get_components(chat));
- qd->groups = g_list_append(qd->groups, rmd);
- count++;
- }
- purple_debug_info("QQ", "Load %d QQ Qun configurations\n", count);
- }
- void qq_room_data_free_all(PurpleConnection *gc)
- {
- qq_data *qd;
- qq_room_data *rmd;
- gint count;
- g_return_if_fail (gc != NULL && gc->proto_data != NULL);
- qd = (qq_data *) gc->proto_data;
- count = 0;
- while (qd->groups != NULL) {
- rmd = (qq_room_data *) qd->groups->data;
- qd->groups = g_list_remove(qd->groups, rmd);
- room_data_free(rmd);
- count++;
- }
- if (count > 0) {
- purple_debug_info("QQ", "%d rooms are freed\n", count);
- }
- }