changeset 24081:119d85c40d75

2008.10.07 - ccpaging <ccpaging(at)gmail.com> * Update buddy icon
author SHiNE CsyFeK <csyfek@gmail.com>
date Wed, 22 Oct 2008 15:00:47 +0000
parents 818ab62006f5
children 4edf36682236
files libpurple/protocols/qq/ChangeLog libpurple/protocols/qq/buddy_info.c libpurple/protocols/qq/buddy_info.h libpurple/protocols/qq/qq.c libpurple/protocols/qq/utils.c libpurple/protocols/qq/utils.h
diffstat 6 files changed, 114 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/qq/ChangeLog	Wed Oct 22 14:59:55 2008 +0000
+++ b/libpurple/protocols/qq/ChangeLog	Wed Oct 22 15:00:47 2008 +0000
@@ -1,3 +1,6 @@
+2008.10.07 - ccpaging <ccpaging(at)gmail.com>
+	* Update buddy icon
+
 2008.10.07 - ccpaging <ccpaging(at)gmail.com>
 	* Update qq_buddy
 
--- a/libpurple/protocols/qq/buddy_info.c	Wed Oct 22 14:59:55 2008 +0000
+++ b/libpurple/protocols/qq/buddy_info.c	Wed Oct 22 15:00:47 2008 +0000
@@ -127,7 +127,7 @@
 	{ QQ_FIELD_BASE, 		QQ_FIELD_BOOL, 	"auth", 				N_("Authorize adding"), NULL, 0 },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "unknow1",	"Unknow1", NULL, 0 },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "unknow2",	"Unknow2", NULL, 0 },
-	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "face",				"Face", NULL, 0 },
+	{ QQ_FIELD_BASE, 		QQ_FIELD_STRING, "face",				"Face", NULL, 0 },
 	{ QQ_FIELD_CONTACT, QQ_FIELD_STRING, "mobile",		N_("Cellphone Number"), NULL, 0 },
 	{ QQ_FIELD_UNUSED, 	QQ_FIELD_STRING, "mobile_type","Cellphone Type", NULL, 0 },
 	{ QQ_FIELD_BASE, 		QQ_FIELD_MULTI, 	"intro", 		N_("Personal Introduction"), NULL, 0 },
@@ -478,33 +478,35 @@
 	qq_request_buddy_info(gc, qd->uid, 0, QQ_BUDDY_INFO_SET_ICON);
 }
 
-static void buddy_local_icon_set(PurpleAccount *account, const gchar *who, const gchar *icon_num, const gchar *iconfile)
+/* return the location of the buddy icon dir
+ * any application using libpurple but not installing the QQ buddy icons
+ * under datadir needs to set the pref below, or buddy icons won't work */
+static const char *get_icon_dir(void)
 {
-	gchar *data;
-	gsize len;
-
-	if (!g_file_get_contents(iconfile, &data, &len, NULL)) {
-		g_return_if_reached();
-	} else {
-		purple_buddy_icons_set_for_user(account, who, data, len, icon_num);
-	}
+	if (purple_prefs_exists("/plugins/prpl/qq/icon_dir"))
+		return purple_prefs_get_string("/plugins/prpl/qq/icon_dir");
+	else
+		return NULL;
 }
 
 /* TODO: custom faces for QQ members and users with level >= 16 */
-void qq_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img)
+void qq_set_buddy_icon_old(PurpleConnection *gc, PurpleStoredImage *img)
 {
 	gchar *icon;
 	gint icon_num;
 	gint icon_len;
 	PurpleAccount *account = purple_connection_get_account(gc);
 	const gchar *icon_path = purple_account_get_buddy_icon_path(account);
-	const gchar *buddy_icon_dir = qq_buddy_icon_dir();
+	const gchar *buddy_icon_dir = get_icon_dir();
 	gint prefix_len = strlen(QQ_ICON_PREFIX);
 	gint suffix_len = strlen(QQ_ICON_SUFFIX);
 	gint dir_len = buddy_icon_dir ? strlen(buddy_icon_dir) : 0;
 	gchar *errmsg = g_strdup_printf(_("Setting custom faces is not currently supported. Please choose an image from %s."), buddy_icon_dir ? buddy_icon_dir : "(null)");
 	gboolean icon_global = purple_account_get_bool(gc->account, "use-global-buddyicon", TRUE);
 
+	gchar *icon_file_content;
+	gsize icon_file_size;
+
 	if (!icon_path)
 		icon_path = "";
 
@@ -539,37 +541,85 @@
 	g_free(errmsg);
 	/* tell server my icon changed */
 	request_set_buddy_icon(gc, icon_num);
+
 	/* display in blist */
-	buddy_local_icon_set(account, account->username, icon, icon_path);
+	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);
+		return;
+	}
+	purple_buddy_icons_set_for_user(account, account->username,
+			icon_file_content, icon_file_size, icon);
 }
 
+void qq_set_custom_icon(PurpleConnection *gc, PurpleStoredImage *img)
+{
+	PurpleAccount *account = purple_connection_get_account(gc);
+	const gchar *icon_path = purple_account_get_buddy_icon_path(account);
+	gchar **segments;
+	gint index;
 
-static void buddy_local_icon_upate(PurpleAccount *account, const gchar *name, gint face)
+	g_return_if_fail(icon_path != NULL);
+
+	/* Fixme:
+	 *  icon_path is always null
+	 *  purple_imgstore_get_filename is always new file
+	 *  QQ buddy may set custom icon if level is over 16 */
+	purple_debug_info("QQ", "Change my icon to %s\n", icon_path);
+	segments = g_strsplit_set(icon_path, G_DIR_SEPARATOR_S, 0);
+	for (index = 0; segments[index] != NULL; index++) {
+		purple_debug_info("QQ", "Split to %s\n", segments[index]);
+	}
+
+	g_strfreev(segments);
+}
+
+static void update_buddy_icon(PurpleAccount *account, const gchar *who, gint face)
 {
 	PurpleBuddy *buddy;
-	gchar *icon_num_str = face_to_icon_str(face);
-	const gchar *old_icon_num = NULL;
+	const gchar *icon_name_prev = NULL;
+	gchar *icon_name;
+	const gchar *icon_dir;
+	gchar *icon_path;
+	gchar *icon_file_content;
+	gsize icon_file_size;
 
-	if ((buddy = purple_find_buddy(account, name)))
-		old_icon_num = purple_buddy_icons_get_checksum_for_user(buddy);
+	purple_debug_info("QQ", "Update %s icon to %d\n", who, face);
 
-	if ((old_icon_num == NULL ||
-			strcmp(icon_num_str, old_icon_num)) && (qq_buddy_icon_dir() != NULL))
-	{
-		gchar *icon_path;
+	icon_name = g_strdup_printf("%d", face);
+	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);
+	}
+	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_dir = NULL;
+	if ( purple_prefs_exists("/plugins/prpl/qq/icon_dir") ) {
+		icon_dir = purple_prefs_get_string("/plugins/prpl/qq/icon_dir");
+	}
+	if ( icon_dir == NULL) {
+		purple_debug_info("QQ", "Icon dir is not defined in prefs '/plugins/prpl/qq/icon_dir'\n");
+		g_free(icon_name);
+		return;
+	}
 
-		icon_path = g_strconcat(qq_buddy_icon_dir(), G_DIR_SEPARATOR_S,
-				QQ_ICON_PREFIX, icon_num_str,
-				QQ_ICON_SUFFIX, NULL);
+	icon_path = g_strconcat(icon_dir, G_DIR_SEPARATOR_S,
+			QQ_ICON_PREFIX, icon_name, QQ_ICON_SUFFIX, NULL);
 
-		buddy_local_icon_set(account, name, icon_num_str, icon_path);
-		g_free(icon_path);
+	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_buddy_icons_set_for_user(account, who,
+				icon_file_content, icon_file_size, icon_name);
 	}
-	g_free(icon_num_str);
+	g_free(icon_name);
+	g_free(icon_path);
 }
 
 /* after getting info or modify myself, refresh the buddy list accordingly */
-static void qq_update_buddy_info(PurpleConnection *gc, gchar **segments)
+static void update_buddy_info(PurpleConnection *gc, gchar **segments)
 {
 	PurpleBuddy *buddy;
 	qq_data *qd;
@@ -584,6 +634,7 @@
 	uid = strtol(segments[QQ_INFO_UID], NULL, 10);
 	who = uid_to_purple_name(uid);
 
+	qq_filter_str(segments[QQ_INFO_NICK]);
 	alias_utf8 = qq_to_utf8(segments[QQ_INFO_NICK], QQ_CHARSET_DEFAULT);
 	if (uid == qd->uid) {	/* it is me */
 		purple_debug_info("QQ", "Got my info\n");
@@ -597,7 +648,7 @@
 		buddy = purple_find_buddy(gc->account, who);
 	}
 
-	if (buddy == NULL && buddy->proto_data == NULL) {
+	if (buddy == NULL || buddy->proto_data == NULL) {
 		g_free(who);
 		g_free(alias_utf8);
 		return;
@@ -616,7 +667,9 @@
 	bd->last_update = time(NULL);
 
 	purple_blist_server_alias_buddy(buddy, bd->nickname);
-	buddy_local_icon_upate(gc->account, who, bd->face);
+
+	/* convert face num from packet (0-299) to local face (1-100) */
+	update_buddy_icon(gc->account, who, (bd->face / 3 + 1));
 
 	g_free(who);
 	g_free(alias_utf8);
@@ -628,6 +681,7 @@
 	qq_data *qd;
 	gchar **segments;
 	gint field_count;
+	gchar *icon_name;
 
 	g_return_if_fail(data != NULL && data_len != 0);
 
@@ -646,25 +700,25 @@
 #endif
 
 	if (action == QQ_BUDDY_INFO_SET_ICON) {
+		/* send new face to server */
 		if (strtol(segments[QQ_INFO_FACE], NULL, 10) != qd->my_icon) {
-			gchar *icon = g_strdup_printf("%d", qd->my_icon);
-
+			icon_name = g_strdup_printf("%d", qd->my_icon);
 			g_free(segments[QQ_INFO_FACE]);
-			segments[QQ_INFO_FACE] = icon;
+			segments[QQ_INFO_FACE] = icon_name;
 
 			request_modify_info(gc, segments);
-			qq_update_buddy_info(gc, segments);
 		}
 		g_strfreev(segments);
 		return;
 	}
 
-	qq_update_buddy_info(gc, segments);
+	update_buddy_info(gc, segments);
 	switch (action) {
 		case QQ_BUDDY_INFO_DISPLAY:
 			info_display_only(gc, segments);
 			break;
 		case QQ_BUDDY_INFO_SET_ICON:
+			/* never reached */
 			break;
 		case QQ_BUDDY_INFO_MODIFY_BASE:
 			info_modify_dialogue(gc, segments, QQ_FIELD_BASE);
--- a/libpurple/protocols/qq/buddy_info.h	Wed Oct 22 14:59:55 2008 +0000
+++ b/libpurple/protocols/qq/buddy_info.h	Wed Oct 22 15:00:47 2008 +0000
@@ -79,7 +79,7 @@
 
 void qq_request_buddy_info(PurpleConnection *gc, guint32 uid,
 		gint update_class, int action);
-void qq_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img);
+void qq_set_custom_icon(PurpleConnection *gc, PurpleStoredImage *img);
 void qq_process_modify_info_reply(guint8 *data, gint data_len, PurpleConnection *gc);
 void qq_process_get_buddy_info(guint8 *data, gint data_len, guint32 action, PurpleConnection *gc);
 
--- a/libpurple/protocols/qq/qq.c	Wed Oct 22 14:59:55 2008 +0000
+++ b/libpurple/protocols/qq/qq.c	Wed Oct 22 15:00:47 2008 +0000
@@ -530,6 +530,19 @@
 	qq_update_all_rooms(gc, 0, 0);
 }
 
+static void action_change_icon(PurplePluginAction *action)
+{
+	PurpleConnection *gc = (PurpleConnection *) action->context;
+
+	g_return_if_fail(NULL != gc && NULL != gc->proto_data);
+
+	purple_request_file(action, _("Select icon..."), NULL,
+			FALSE,
+			NULL, NULL,
+			purple_connection_get_account(gc), NULL, NULL,
+			gc);
+}
+
 static void action_modify_info_base(PurplePluginAction *action)
 {
 	PurpleConnection *gc = (PurpleConnection *) action->context;
@@ -778,6 +791,9 @@
 	PurplePluginAction *act;
 
 	m = NULL;
+	act = purple_plugin_action_new(_("Change icon"), action_change_icon);
+	m = g_list_append(m, act);
+
 	act = purple_plugin_action_new(_("Modify Information"), action_modify_info_base);
 	m = g_list_append(m, act);
 
@@ -940,7 +956,7 @@
 	NULL,							/* buddy_free */
 	NULL,							/* convo_closed */
 	NULL,							/* normalize */
-	qq_set_buddy_icon,					/* set_buddy_icon */
+	qq_set_custom_icon,
 	NULL,							/* remove_group */
 	qq_get_chat_buddy_real_name,				/* get_cb_real_name */
 	NULL,							/* set_chat_topic */
@@ -1074,6 +1090,7 @@
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
 
 	purple_prefs_add_none("/plugins/prpl/qq");
+	purple_prefs_add_string("/plugins/prpl/qq/icon_dir", "");
 	purple_prefs_add_bool("/plugins/prpl/qq/show_status_by_icon", TRUE);
 	purple_prefs_add_bool("/plugins/prpl/qq/show_fake_video", FALSE);
 	purple_prefs_add_bool("/plugins/prpl/qq/show_room_when_newin", TRUE);
--- a/libpurple/protocols/qq/utils.c	Wed Oct 22 14:59:55 2008 +0000
+++ b/libpurple/protocols/qq/utils.c	Wed Oct 22 15:00:47 2008 +0000
@@ -118,8 +118,7 @@
 	if (expected_fields <= 0)
 		return segments;
 
-	for (count = 0; segments[count] != NULL; count++) {;
-	}
+	count = g_strv_length(segments);
 	if (count < expected_fields) {	/* not enough fields */
 		purple_debug_error("QQ", "Less fields %d then %d\n", count, expected_fields);
 		return NULL;
@@ -366,22 +365,3 @@
 	qq_hex_dump(PURPLE_DEBUG_INFO, "QQ", buf, len, desc);
 }
 
-/* convert face num from packet (0-299) to local face (1-100) */
-gchar *face_to_icon_str(gint face)
-{
-	gchar *icon_num_str;
-	gint icon_num = face / 3 + 1;
-	icon_num_str = g_strdup_printf("%d", icon_num);
-	return icon_num_str;
-}
-
-/* return the location of the buddy icon dir
- * any application using libpurple but not installing the QQ buddy icons
- * under datadir needs to set the pref below, or buddy icons won't work */
-const char *qq_buddy_icon_dir(void)
-{
-	if (purple_prefs_exists("/prpl/qq/buddy_icon_dir"))
-		return purple_prefs_get_string("/prpl/qq/buddy_icon_dir");
-	else
-		return NULL;
-}
--- a/libpurple/protocols/qq/utils.h	Wed Oct 22 14:59:55 2008 +0000
+++ b/libpurple/protocols/qq/utils.h	Wed Oct 22 15:00:47 2008 +0000
@@ -45,16 +45,12 @@
 gchar *uid_to_purple_name(guint32 uid);
 gchar *chat_name_to_purple_name(const gchar *const name);
 
-gchar *face_to_icon_str(gint face);
-
 gchar *try_dump_as_gbk(const guint8 *const data, gint len);
 
 void qq_show_packet(const gchar *desc, const guint8 *buf, gint len);
 void qq_hex_dump(PurpleDebugLevel level, const char *category,
-		const guint8 *pdata, gint bytes,	
+		const guint8 *pdata, gint bytes,
 		const char *format, ...);
 guint8 *hex_str_to_bytes(const gchar *buf, gint *out_len);
 
-const gchar *qq_buddy_icon_dir(void);
-
 #endif