# HG changeset patch # User Yoshiki Yazawa # Date 1215259843 -32400 # Node ID 0c1f63882b8a200694212d17ea855509c0205651 # Parent 15f4886720e40892720586593fef59d2a753e312 preliminary wassr icon support. not yet completed. diff -r 15f4886720e4 -r 0c1f63882b8a pidgin-twitter.c --- a/pidgin-twitter.c Sat Jul 05 16:35:28 2008 +0900 +++ b/pidgin-twitter.c Sat Jul 05 21:10:43 2008 +0900 @@ -24,9 +24,10 @@ static GRegex *regp[7]; static gboolean suppress_oops = FALSE; static GHashTable *icon_data_by_user = NULL; +static GHashTable *icon_data_by_user2 = NULL; #define WASSR_POST_LEN (255 * 4) -static gchar wassr_post[WASSR_POST_LEN + 1]; +static gchar *wassr_post = NULL; typedef struct icon_data { gint icon_id; // image id @@ -45,6 +46,11 @@ int service; } eval_data; +typedef struct _got_icon_data { + gchar *user_name; + gint service; +} got_icon_data; + /* this function is a modified clone of purple_markup_strip_html() */ static char * strip_html_markup(const char *str) @@ -807,14 +813,13 @@ } static void -delete_requested_icon_marks(PidginConversation *conv) { +delete_requested_icon_marks(PidginConversation *conv, GHashTable *table) { GtkTextBuffer *text_buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(conv->imhtml)); - g_hash_table_foreach(icon_data_by_user, + g_hash_table_foreach(table, (GHFunc)remove_marks_func, (gpointer)text_buffer); - } static void @@ -964,11 +969,10 @@ /* only attach to twitter conversation window */ if(is_twitter_conv(conv)) - delete_requested_icon_marks(gtkconv); -#if 0 + delete_requested_icon_marks(gtkconv, icon_data_by_user); + if(is_wassr_conv(conv)) - delete_requested_icon_marks(gtkconv); -#endif + delete_requested_icon_marks(gtkconv, icon_data_by_user2); } static gboolean @@ -991,8 +995,8 @@ g_free(*buffer); *buffer = NULL; } /* fix for parrot problem during post to a channel */ - else if(strstr(*buffer, wassr_post)) { - twitter_debug("parrot clearing: %s\n", *buffer); + else if(strlen(wassr_post) && strstr(*buffer, wassr_post)) { + twitter_debug("parrot clearing: buf = %s post = %s\n", *buffer, wassr_post); g_free(*sender); *sender = NULL; g_free(*buffer); *buffer = NULL; } @@ -1020,15 +1024,20 @@ } static void -insert_icon_at_mark(GtkTextMark *requested_mark, const gchar *user_name) +insert_icon_at_mark(GtkTextMark *requested_mark, gpointer user_data) { + got_icon_data *gotdata = (got_icon_data *)user_data; + + gchar *user_name = gotdata->user_name; + int service = gotdata->service; + GList *win_list; GtkIMHtml *target_imhtml = NULL; GtkTextBuffer *target_buffer = NULL; GtkTextIter inserting_point; int icon_id; - twitter_debug("called\n"); + twitter_debug("called: service = %d\n", service); /* find the conversation that contains the mark */ for(win_list = pidgin_conv_windows_get_list(); win_list; @@ -1064,7 +1073,12 @@ &inserting_point, requested_mark); /* insert icon */ - icon_data *data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name); + icon_data *data = NULL; + if(service == TWITTER_SERVICE) + data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name); + else if(service == WASSR_SERVICE) + data = (icon_data *)g_hash_table_lookup(icon_data_by_user2, user_name); + if(data) icon_id = data->icon_id; else @@ -1078,37 +1092,55 @@ gtk_imhtml_insert_image_at_iter(target_imhtml, icon_id, &inserting_point); gtk_text_buffer_delete_mark(target_buffer, requested_mark); requested_mark = NULL; - } static void -insert_requested_icon(const gchar *user_name) +insert_requested_icon(const gchar *user_name, int service) { - icon_data *data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name); + icon_data *data = NULL; GList *mark_list = NULL; - if(data) - mark_list = data->request_list; + if(service == TWITTER_SERVICE) + data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name); + else if(service == WASSR_SERVICE) + data = (icon_data *)g_hash_table_lookup(icon_data_by_user2, user_name); + + if(!data) + return; + + mark_list = data->request_list; + + got_icon_data *gotdata = g_new0(got_icon_data, 1); + gotdata->user_name = g_strdup(user_name); + gotdata->service = service; if(mark_list) { - g_list_foreach(mark_list, (GFunc) insert_icon_at_mark, (gchar *)user_name); + g_list_foreach(mark_list, (GFunc) insert_icon_at_mark, gotdata); mark_list = g_list_remove_all(mark_list, NULL); g_list_free(mark_list); data->request_list = NULL; } + g_free(gotdata->user_name); + g_free(gotdata); } static void got_icon_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { - gchar *user_name = (gchar *)user_data; + got_icon_data *gotdata = (got_icon_data *)user_data; + gchar *user_name = gotdata->user_name; + int service = gotdata->service; + int icon_id; icon_data *data = NULL; - twitter_debug("called\n"); + twitter_debug("called: service = %d\n", service); - data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name); + if (service == TWITTER_SERVICE) + data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name); + else if (service == WASSR_SERVICE) + data = (icon_data *)g_hash_table_lookup(icon_data_by_user2, user_name); if(data && data->fetch_data) { data->fetch_data = NULL; @@ -1118,7 +1150,7 @@ * the download is failure. */ if((data && data->icon_id) || !url_text) { //xxx if(!url_text) { - twitter_debug("downloading %s's icon was failure : %s\n", + twitter_debug("downloading %s's icon failed : %s\n", user_name, error_message); } else { @@ -1129,6 +1161,7 @@ g_free(user_name); + g_free(data); return; } @@ -1138,8 +1171,12 @@ data = g_new0(icon_data, 1); } data->icon_id = icon_id; - g_hash_table_insert(icon_data_by_user, - g_strdup(user_name), data); + if (service == TWITTER_SERVICE) + g_hash_table_insert(icon_data_by_user, + g_strdup(user_name), data); + if (service == WASSR_SERVICE) + g_hash_table_insert(icon_data_by_user2, + g_strdup(user_name), data); const gchar *dirname = purple_prefs_get_string(OPT_ICON_DIR); @@ -1148,7 +1185,11 @@ gchar *filename = NULL; gchar *path = NULL; FILE *fp = NULL; - filename = g_strdup_printf("%s.gif", user_name); + + if(service == TWITTER_SERVICE) + filename = g_strdup_printf("%s.gif", user_name); + else if(service == WASSR_SERVICE) + filename = g_strdup_printf("%s_wassr.png", user_name); path = g_build_filename(dirname, filename, NULL); g_free(filename); filename = NULL; @@ -1168,12 +1209,13 @@ user_name, icon_id); /* Insert the icon to messages that had been received. */ - insert_requested_icon(user_name); + insert_requested_icon(user_name, service); g_free(user_name); + g_free(data); } static void -request_icon(const char *user_name) +request_icon(const char *user_name, int service) { gchar *url = NULL; @@ -1182,12 +1224,19 @@ gchar *path = NULL; icon_data *data = NULL; - data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name); + if(service == TWITTER_SERVICE) + data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name); + else if(service == WASSR_SERVICE) + data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name); if(!data) { data = g_new0(icon_data, 1); - g_hash_table_insert(icon_data_by_user, - g_strdup(user_name), data); + if(service == TWITTER_SERVICE) + g_hash_table_insert(icon_data_by_user, + g_strdup(user_name), data); + else if(service == WASSR_SERVICE) + g_hash_table_insert(icon_data_by_user2, + g_strdup(user_name), data); } /* if img has been registerd, just return */ @@ -1195,16 +1244,31 @@ return; /* check if saved file exists */ - filename = g_strdup_printf("%s.gif", user_name); - path = g_build_filename( - purple_prefs_get_string(OPT_ICON_DIR), filename, NULL); + if (service == TWITTER_SERVICE) { + filename = g_strdup_printf("%s.gif", user_name); + path = g_build_filename( + purple_prefs_get_string(OPT_ICON_DIR), filename, NULL); - if(!g_file_test(path, G_FILE_TEST_EXISTS)) { - g_free(path); - filename = g_strdup_printf("%s.png", user_name); + if(!g_file_test(path, G_FILE_TEST_EXISTS)) { + g_free(path); + filename = g_strdup_printf("%s.png", user_name); path = g_build_filename( + purple_prefs_get_string(OPT_ICON_DIR), filename, NULL); + } + } + else if (service == WASSR_SERVICE) { + filename = g_strdup_printf("%s_wassr.gif", user_name); + path = g_build_filename( purple_prefs_get_string(OPT_ICON_DIR), filename, NULL); + + if(!g_file_test(path, G_FILE_TEST_EXISTS)) { + g_free(path); + filename = g_strdup_printf("%s_wassr.png", user_name); + path = g_build_filename( + purple_prefs_get_string(OPT_ICON_DIR), filename, NULL); + } } + /* build image from file, if file exists */ if(g_file_test(path, G_FILE_TEST_EXISTS)) { gchar *imgdata = NULL; @@ -1223,7 +1287,7 @@ twitter_debug("icon data has been loaded from file\n"); - insert_requested_icon(user_name); + insert_requested_icon(user_name, service); return; } @@ -1237,31 +1301,48 @@ /* Create the URL of the user's icon. * See http://twitter.g.hatena.ne.jp/ikko615/20080107/1199703400 */ - url = g_strdup_printf("http://img.twitty.jp/twitter/user/%s/m.gif", - user_name); + if (service == TWITTER_SERVICE) + url = g_strdup_printf("http://img.twitty.jp/twitter/user/%s/m.gif", + user_name); + else if (service == WASSR_SERVICE) + url = g_strdup_printf("http://wassr.jp/user/%s/profile_img.png.64", + user_name); + got_icon_data *gotdata = g_new0(got_icon_data, 1); + gotdata->user_name = g_strdup(user_name); + gotdata->service = service; + + /* gotdata will be released in got_icon_cb */ data->fetch_data = purple_util_fetch_url(url, TRUE, NULL, TRUE, - got_icon_cb, g_strdup(user_name)); + got_icon_cb, gotdata); g_free(url); url = NULL; twitter_debug("request %s's icon\n", user_name); } static void -mark_icon_for_user(GtkTextMark *mark, const gchar *user_name) +mark_icon_for_user(GtkTextMark *mark, const gchar *user_name, int service) { icon_data *data = NULL; - data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name); + + twitter_debug("called\n"); + + if(service == TWITTER_SERVICE) + data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name); + else if(service == WASSR_SERVICE) + data = (icon_data *)g_hash_table_lookup(icon_data_by_user2, user_name); if(!data) { data = g_new0(icon_data, 1); - g_hash_table_insert(icon_data_by_user, - g_strdup(user_name), data); + if(service == TWITTER_SERVICE) + g_hash_table_insert(icon_data_by_user, + g_strdup(user_name), data); + else if(service == WASSR_SERVICE) + g_hash_table_insert(icon_data_by_user2, + g_strdup(user_name), data); } - GList *mark_list = data->request_list; - mark_list = g_list_append(mark_list, mark); - data->request_list = mark_list; + data->request_list = g_list_append(data->request_list, mark); } static void @@ -1275,8 +1356,8 @@ GtkTextIter inserting_point; int icon_id; - if(!is_twitter_conv(conv)) { - twitter_debug("not twitter conv\n"); + if(!is_twitter_conv(conv) && !is_wassr_conv(conv)) { + twitter_debug("neither twitter or wassr conv\n"); return; } @@ -1291,8 +1372,8 @@ user_name = g_match_info_fetch(match_info, 1); g_match_info_free(match_info); + /* insert icon */ - imhtml = GTK_IMHTML(PIDGIN_CONVERSATION(conv)->imhtml); text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(imhtml)); @@ -1301,7 +1382,11 @@ gtk_text_buffer_get_line_count(text_buffer) - 1); icon_data *data = NULL; - data = g_hash_table_lookup(icon_data_by_user, user_name); + if(is_twitter_conv(conv)) + data = g_hash_table_lookup(icon_data_by_user, user_name); + else if(is_wassr_conv(conv)) + data = g_hash_table_lookup(icon_data_by_user2, user_name); + if(data) icon_id = data->icon_id; else @@ -1311,11 +1396,17 @@ * mark the message and request the icon. */ if(!icon_id) { twitter_debug("%s's icon is not in memory.\n", user_name); + int service = 0; + if(is_twitter_conv(conv)) + service = TWITTER_SERVICE; + else if(is_wassr_conv(conv)) + service = WASSR_SERVICE; + mark_icon_for_user(gtk_text_buffer_create_mark( text_buffer, NULL, &inserting_point, FALSE), - user_name); + user_name, service); /* request to attach icon to the buffer */ - request_icon(user_name); + request_icon(user_name, service); g_free(user_name); user_name = NULL; return; } @@ -1356,12 +1447,17 @@ icon_data_by_user = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + icon_data_by_user2 = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, NULL); /* attach counter to the existing twitter window */ if(purple_prefs_get_bool(OPT_COUNTER)) { attach_to_window(); } + /* allocate wassr_post */ + wassr_post = g_new0(gchar, WASSR_POST_LEN + 1); + return TRUE; } @@ -1421,16 +1517,23 @@ /* remove mark list in each hash entry */ g_hash_table_foreach(icon_data_by_user, (GHFunc)remove_marks_func, NULL); + g_hash_table_foreach(icon_data_by_user2, (GHFunc)remove_marks_func, NULL); /* cancel request that has not been finished yet */ g_hash_table_foreach(icon_data_by_user, (GHFunc)cancel_fetch_func, NULL); + g_hash_table_foreach(icon_data_by_user2, (GHFunc)cancel_fetch_func, NULL); /* destroy hash table for icon_data */ g_hash_table_destroy(icon_data_by_user); //XXX all memory freed? --yaz + g_hash_table_destroy(icon_data_by_user2); //XXX all memory freed? --yaz /* detach from twitter window */ detach_from_window(); + /* free wassr_post */ + g_free(wassr_post); + wassr_post = NULL; + return TRUE; } @@ -1610,10 +1713,10 @@ PURPLE_PRIORITY_DEFAULT, /**< priority */ PLUGIN_ID, /**< id */ "Pidgin-Twitter", /**< name */ - "0.7.0 alpha1", /**< version */ + "0.7.0 alpha2d1", /**< version */ "provides useful features for twitter", /** summary */ "provides useful features for twitter", /** desc */ - "Yoshiki Yazawa, mikanbako, \nKonosuke Watanabe, IWATA Ray, \nthe pidging-twitter team", /**< author */ + "Yoshiki Yazawa, mikanbako, \nKonosuke Watanabe, IWATA Ray, mojin, \nthe pidging-twitter team", /**< author */ "http://www.honeyplanet.jp/", /**< homepage */ load_plugin, /**< load */ unload_plugin, /**< unload */ diff -r 15f4886720e4 -r 0c1f63882b8a pidgin-twitter.h --- a/pidgin-twitter.h Sat Jul 05 16:35:28 2008 +0900 +++ b/pidgin-twitter.h Sat Jul 05 21:10:43 2008 +0900 @@ -80,7 +80,7 @@ static void delete_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *start_pos, GtkTextIter *end_pos, gpointer user_data); static void detach_from_window(void); static void detach_from_conv(PurpleConversation *conv, gpointer null); -static void delete_requested_icon_marks(PidginConversation *gtkconv); +static void delete_requested_icon_marks(PidginConversation *gtkconv, GHashTable *table); static void attach_to_window(void); static void attach_to_conv(PurpleConversation *conv, gpointer null); static gboolean is_twitter_account(PurpleAccount *account, const char *name); @@ -90,11 +90,11 @@ static void conv_created_cb(PurpleConversation *conv, gpointer null); static void deleting_conv_cb(PurpleConversation *conv); static gboolean receiving_im_cb(PurpleAccount *account, char **sender, char **buffer, PurpleConversation *conv, PurpleMessageFlags *flags, void *data); -static void insert_icon_at_mark(GtkTextMark *requested_mark, const gchar *user_name); -static void insert_requested_icon(const gchar *user_name); +static void insert_icon_at_mark(GtkTextMark *requested_mark, gpointer user_data); +static void insert_requested_icon(const gchar *user_name, int service); static void got_icon_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message); -static void request_icon(const char *user_name); -static void mark_icon_for_user(GtkTextMark *mark, const gchar *user_name); +static void request_icon(const char *user_name, int service); +static void mark_icon_for_user(GtkTextMark *mark, const gchar *user_name, int service); static void displayed_im_cb(PurpleAccount *account, const char *who, char *message, PurpleConversation *conv, PurpleMessageFlags flags); static gboolean load_plugin(PurplePlugin *plugin); static gboolean unload_plugin(PurplePlugin *plugin);