changeset 95:ab612180e7d0

- added identica support. linkfy and character counter work. icon support has not implemented yet. - put common code together.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Thu, 10 Jul 2008 00:12:03 +0900
parents 31cddb2c2acc
children 987607b5ba32
files pidgin-twitter.c pidgin-twitter.h
diffstat 2 files changed, 186 insertions(+), 123 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin-twitter.c	Wed Jul 09 16:13:02 2008 +0900
+++ b/pidgin-twitter.c	Thu Jul 10 00:12:03 2008 +0900
@@ -25,6 +25,7 @@
 static gboolean suppress_oops = FALSE;
 static GHashTable *icon_data_by_user = NULL;
 static GHashTable *icon_data_by_user2 = NULL;
+static GHashTable *icon_data_by_user3 = NULL;
 static GHashTable *conv_hash = NULL;
 
 #define WASSR_POST_LEN (255 * 4)
@@ -40,7 +41,8 @@
 enum {
     unknown_service = 0,
     twitter_service,
-    wassr_service
+    wassr_service,
+    identica_service
 };
 
 typedef struct _eval_data {
@@ -511,38 +513,45 @@
 
     if(which == RECIPIENT) {
         gchar *match = g_match_info_fetch(match_info, 1);
+        const gchar *format = NULL;
+        switch(service) {
+        case twitter_service:
+            format = RECIPIENT_FORMAT_TWITTER;
+            break;
+        case wassr_service:
+            format = RECIPIENT_FORMAT_WASSR;
+            break;
+        case identica_service:
+            format = RECIPIENT_FORMAT_IDENTICA;
+            break;
+        default:
+            twitter_debug("unknown service\n");
+            break;
+        }
+        snprintf(sub, 128, format, match, match);
+        g_free(match);
+    }
+    else if(which == SENDER) {
+        gchar *match1 = g_match_info_fetch(match_info, 1); //preceding CR|LF
+        gchar *match2 = g_match_info_fetch(match_info, 2); //sender
+        const gchar *format = NULL;
 
         switch(service) {
         case twitter_service:
-            snprintf(sub, 128, RECIPIENT_FORMAT, match, match);
+            format = SENDER_FORMAT_TWITTER;
             break;
         case wassr_service:
-            snprintf(sub, 128, RECIPIENT_FORMAT_WASSR, match, match);
+            format = SENDER_FORMAT_WASSR;
+            break;
+        case identica_service:
+            format = SENDER_FORMAT_IDENTICA;
             break;
         default:
             twitter_debug("unknown service\n");
             break;
         }
 
-        g_free(match);
-    }
-    else if(which == SENDER) {
-        gchar *match1 = g_match_info_fetch(match_info, 1); //preceding CR|LF
-        gchar *match2 = g_match_info_fetch(match_info, 2); //sender
-
-        switch(service) {
-        case twitter_service:
-            snprintf(sub, 128, SENDER_FORMAT, match1 ? match1: "",
-                     match2, match2);
-            break;
-        case wassr_service:
-            snprintf(sub, 128, SENDER_FORMAT_WASSR, match1 ? match1: "",
-                     match2, match2);
-            break;
-        default:
-            twitter_debug("unknown service\n");
-            break;
-        }
+        snprintf(sub, 128, format, match1 ? match1: "", match2, match2);
 
         g_free(match1);
         g_free(match2);
@@ -695,6 +704,7 @@
 
     switch(service) {
     case twitter_service:
+    case identica_service:
         markup = g_markup_printf_escaped("<span color=\"%s\">%u</span>",
                                          count <= 140 ? "black" : "red", count);
         break;
@@ -733,6 +743,7 @@
 
     switch(service) {
     case twitter_service:
+    case identica_service:
         markup = g_markup_printf_escaped("<span color=\"%s\">%u</span>",
                                          count <= 140 ? "black" : "red", count);
         break;
@@ -766,9 +777,8 @@
         gint service = get_service_type(conv);
         switch(service) {
         case twitter_service:
-            detach_from_conv(conv, NULL);
-            break;
         case wassr_service:
+        case identica_service:
             detach_from_conv(conv, NULL);
             break;
         default:
@@ -874,6 +884,7 @@
         switch(service) {
         case twitter_service:
         case wassr_service:
+        case identica_service:
             attach_to_conv(conv, NULL);
             break;
         default:
@@ -950,8 +961,8 @@
 
     twitter_debug("name  = %s proto = %s\n", name, proto);
 
-    if(!strcmp(name, "twitter@twitter.com") &&
-       !strcmp(proto, "prpl-jabber")) {
+    if(g_strstr_len(name,  19, "twitter@twitter.com") &&
+       g_strstr_len(proto, 11, "prpl-jabber")) {
         return TRUE;
     }
 
@@ -974,8 +985,8 @@
 
     twitter_debug("name  = %s proto = %s\n", name, proto);
 
-    if(strstr(name, "wassr-bot@wassr.jp") &&
-       !strcmp(proto, "prpl-jabber")) {
+    if(g_strstr_len(name,  18, "wassr-bot@wassr.jp") &&
+       g_strstr_len(proto, 11, "prpl-jabber")) {
         return TRUE;
     }
 
@@ -991,6 +1002,30 @@
     return is_wassr_account(account, name);
 }
 
+static gboolean
+is_identica_account(PurpleAccount *account, const char *name)
+{
+    const gchar *proto = purple_account_get_protocol_id(account);
+
+    twitter_debug("name  = %s proto = %s\n", name, proto);
+
+    if(g_strstr_len(name,  16, "update@identi.ca") &&
+       g_strstr_len(proto, 11, "prpl-jabber")) {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static gboolean
+is_identica_conv(PurpleConversation *conv)
+{
+    const char *name = purple_conversation_get_name(conv);
+    PurpleAccount *account = purple_conversation_get_account(conv);
+
+    return is_identica_account(account, name);
+}
+
 static gint
 get_service_type(PurpleConversation *conv)
 {
@@ -1002,6 +1037,8 @@
         service = twitter_service;
     else if(is_wassr_conv(conv))
         service = wassr_service;
+    else if(is_identica_conv(conv))
+        service = identica_service;
 
     return service;
 }
@@ -1017,6 +1054,7 @@
     switch(service) {
     case twitter_service:
     case wassr_service:
+    case identica_service:
         attach_to_conv(conv, NULL);
         break;
     default:
@@ -1029,21 +1067,30 @@
 deleting_conv_cb(PurpleConversation *conv)
 {
     PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
+
     g_return_if_fail(gtkconv != NULL);
 
     gint service = get_service_type(conv);
+    GHashTable *hash = NULL;
+
     /* only attach to twitter conversation window */
     switch(service) {
     case twitter_service:
-        delete_requested_icon_marks(gtkconv, icon_data_by_user);
+        hash = icon_data_by_user;
         break;
     case wassr_service:
-        delete_requested_icon_marks(gtkconv, icon_data_by_user2);
+        hash = icon_data_by_user2;
+        break;
+    case identica_service:
+        hash = icon_data_by_user3;
         break;
     default:
         twitter_debug("unknown service\n");
         break;
     }
+
+    if(hash)
+        delete_requested_icon_marks(gtkconv, hash);
 }
 
 static gboolean
@@ -1108,6 +1155,7 @@
     GtkTextIter insertion_point;
     gint icon_id;
     icon_data *data = NULL;
+    GHashTable *hash = NULL;
 
     twitter_debug("called: service = %d\n", service);
 
@@ -1149,15 +1197,21 @@
     /* insert icon */
     switch(service) {
     case twitter_service:
-        data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name);
+        hash = icon_data_by_user;
         break;
     case wassr_service:
-        data = (icon_data *)g_hash_table_lookup(icon_data_by_user2, user_name);
+        hash = icon_data_by_user2;
+        break;
+    case identica_service:
+        hash = icon_data_by_user3;
         break;
     default:
         twitter_debug("unknown service\n");
     }
 
+    if(hash)
+        data = (icon_data *)g_hash_table_lookup(hash, user_name);
+
     if(data)
         icon_id = data->icon_id;
     else
@@ -1178,19 +1232,28 @@
 {
     icon_data *data = NULL;
     GList *mark_list = NULL;
+    GHashTable *hash = NULL;
+
+    twitter_debug("called\n");
 
     switch(service) {
     case twitter_service:
-        data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name);
+        hash = icon_data_by_user;
         break;
     case wassr_service:
-        data = (icon_data *)g_hash_table_lookup(icon_data_by_user2, user_name);
+        hash = icon_data_by_user2;
+        break;
+    case identica_service:
+        hash = icon_data_by_user3;
         break;
     default:
         twitter_debug("unknown service\n");
         break;
     }
 
+    if(hash)
+        data = (icon_data *)g_hash_table_lookup(hash, user_name);
+
     if(!data)
         return;
 
@@ -1200,6 +1263,8 @@
     gotdata->user_name = g_strdup(user_name);
     gotdata->service = service;
 
+    twitter_debug("about to insert icon\n");
+
     if(mark_list) {
         g_list_foreach(mark_list, (GFunc) insert_icon_at_mark, gotdata);
         mark_list = g_list_remove_all(mark_list, NULL);
@@ -1220,20 +1285,27 @@
 
     gint icon_id;
     icon_data *data = NULL;
+    GHashTable *hash = NULL;
 
     twitter_debug("called: service = %d\n", service);
 
     switch(service) {
     case twitter_service:
-        data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name);
+        hash = icon_data_by_user;
         break;
     case wassr_service:
-        data = (icon_data *)g_hash_table_lookup(icon_data_by_user2, user_name);
+        hash = icon_data_by_user2;
+        break;
+    case identica_service:
+        hash = icon_data_by_user3;
         break;
     default:
         twitter_debug("unknown service\n");
     }
 
+    if(hash)
+        data = (icon_data *)g_hash_table_lookup(hash, user_name);
+
     /* return if download failed */
     if(!url_text) {
         twitter_debug("downloading %s's icon failed : %s\n",
@@ -1269,19 +1341,8 @@
 
     data->icon_id = icon_id;
 
-    switch(service) {
-    case twitter_service:
-        g_hash_table_insert(icon_data_by_user,
-                            g_strdup(user_name), data);
-        break;
-    case wassr_service:
-        g_hash_table_insert(icon_data_by_user2,
-                            g_strdup(user_name), data);
-        break;
-    default:
-        twitter_debug("unknown service\n");
-        break;
-    }
+    if(hash)
+        g_hash_table_insert(hash, g_strdup(user_name), data);
 
     const gchar *dirname = purple_prefs_get_string(OPT_ICON_DIR);
 
@@ -1293,11 +1354,14 @@
 
         switch(service) {
         case twitter_service:
-            filename = g_strdup_printf("%s.gif", user_name);
+            filename = g_strdup_printf("%s_twitter.gif", user_name);
             break;
         case wassr_service:
             filename = g_strdup_printf("%s_wassr.png", user_name);
             break;
+        case identica_service:
+            filename = g_strdup_printf("%s_identica.png", user_name);
+            break;
         default:
             twitter_debug("unknown service\n");
             break;
@@ -1335,72 +1399,54 @@
     gchar *filename = NULL;
     gchar *path = NULL;
     icon_data *data = NULL;
+    GHashTable *hash = NULL;
+    const gchar *suffix = NULL;
 
     switch(service) {
     case twitter_service:
-        data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name);
+        hash = icon_data_by_user;
+        suffix = "twitter";
         break;
     case wassr_service:
-        data = (icon_data *)g_hash_table_lookup(icon_data_by_user2, user_name);
+        hash = icon_data_by_user2;
+        suffix = "wassr";
+        break;
+    case identica_service:
+        suffix = "identica";
+        hash = icon_data_by_user3;
         break;
     default:
         twitter_debug("unknown service\n");
-        return;
         break;
     }
 
-    if(!data) {
-        data = g_new0(icon_data, 1);
-        switch(service) {
-        case twitter_service:
-            g_hash_table_insert(icon_data_by_user,
-                                g_strdup(user_name), data);
-            break;
-        case wassr_service:
-            g_hash_table_insert(icon_data_by_user2,
-                                g_strdup(user_name), data);
-            break;
-        default:
-            twitter_debug("unknown service\n");
-            return;
-            break;
-        }
-    }
+    if(!hash)
+        return;
+
+    /* since this function is called after mark_icon_for_user(), data
+     * must exist here. */
+    data = (icon_data *)g_hash_table_lookup(hash, user_name);
+    g_hash_table_insert(hash, g_strdup(user_name), data);
 
     /* if img has been registerd, just return */
-    if(data->icon_id)
+    if(data->icon_id > 0)
         return;
 
     /* check if saved file exists */
-    switch(service) {
-    case twitter_service:
-        filename = g_strdup_printf("%s.gif", user_name);
+    if(suffix) {
+        filename = g_strdup_printf("%s_%s.gif", user_name, suffix);
         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);
+            filename = g_strdup_printf("%s_%s.png", user_name, suffix);
             path = g_build_filename(
                 purple_prefs_get_string(OPT_ICON_DIR), filename, NULL);
         }
-        break;
-    case 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);
-        }
-        break;
-    default:
-        twitter_debug("unknown service\n");
-        break;
-    }
+    twitter_debug("path = %s\n", path);
 
     /* build image from file, if file exists */
     if(g_file_test(path, G_FILE_TEST_EXISTS)) {
@@ -1443,57 +1489,57 @@
         url = g_strdup_printf("http://wassr.jp/user/%s/profile_img.png.64",
                               user_name);
         break;
+    case identica_service:
+        twitter_debug("identica icon support has not implemented yet.\n");
+        break;
     default:
         twitter_debug("unknown service\n");
         break;
     }
 
-    got_icon_data *gotdata = g_new0(got_icon_data, 1);
-    gotdata->user_name = g_strdup(user_name);
-    gotdata->service = service;
+    if(url) {
+        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, gotdata);
-    g_free(url); url = NULL;
+        /* gotdata will be released in got_icon_cb */
+        data->fetch_data = purple_util_fetch_url(url, TRUE, NULL, TRUE,
+                                                 got_icon_cb, gotdata);
+        g_free(url); url = NULL;
 
-    twitter_debug("request %s's icon\n", user_name);
+        twitter_debug("request %s's icon\n", user_name);
+    }
 }
 
 static void
 mark_icon_for_user(GtkTextMark *mark, const gchar *user_name, gint service)
 {
     icon_data *data = NULL;
+    GHashTable *hash = NULL;
 
     twitter_debug("called\n");
 
     switch(service) {
     case twitter_service:
-        data = (icon_data *)g_hash_table_lookup(icon_data_by_user, user_name);
+        hash = icon_data_by_user;
         break;
     case wassr_service:
-        data = (icon_data *)g_hash_table_lookup(icon_data_by_user2, user_name);
+        hash = icon_data_by_user2;
+        break;
+    case identica_service:
+        hash = icon_data_by_user3;
         break;
     default:
         twitter_debug("unknown service\n");
         break;
     }
 
+    if(hash)
+        data = (icon_data *)g_hash_table_lookup(hash, user_name);
+
     if(!data) {
         data = g_new0(icon_data, 1);
-        switch(service) {
-        case twitter_service:
-            g_hash_table_insert(icon_data_by_user,
-                                g_strdup(user_name), data);
-            break;
-        case wassr_service:
-            g_hash_table_insert(icon_data_by_user2,
-                                g_strdup(user_name), data);
-            break;
-        default:
-            twitter_debug("unknown service\n");
-            break;
-        }
+        g_hash_table_insert(hash, g_strdup(user_name), data);
     }
 
     data->request_list = g_list_append(data->request_list, mark);
@@ -1515,7 +1561,6 @@
         return FALSE;
     }
 
-
     /* get text buffer */
     imhtml = GTK_IMHTML(PIDGIN_CONVERSATION(conv)->imhtml);
     text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(imhtml));
@@ -1541,11 +1586,12 @@
     gint service = get_service_type(conv);
     icon_data *data = NULL;
     gint linenumber;
+    GHashTable *hash = NULL;
 
     twitter_debug("called\n");
 
     if(service == unknown_service) {
-        twitter_debug("neither twitter or wassr conv\n");
+        twitter_debug("unknown service\n");
         return;
     }
 
@@ -1570,16 +1616,24 @@
                                      &insertion_point,
                                      linenumber);
 
-
     switch(service) {
     case twitter_service:
-        data = g_hash_table_lookup(icon_data_by_user, user_name);
+        hash = icon_data_by_user;
         break;
     case wassr_service:
-        data = g_hash_table_lookup(icon_data_by_user2, user_name);
+        hash = icon_data_by_user2;
+        break;
+    case identica_service:
+        hash = icon_data_by_user3;
+        break;
+    default:
+        twitter_debug("unknown service\n");
         break;
     }
 
+    if(hash)
+        data = g_hash_table_lookup(hash, user_name);
+
     if(data)
         icon_id = data->icon_id;
 
@@ -1588,7 +1642,7 @@
     if(!icon_id) {
         twitter_debug("%s's icon is not in memory.\n", user_name);
         mark_icon_for_user(gtk_text_buffer_create_mark(
-                                text_buffer, NULL, &insertion_point, FALSE),
+                               text_buffer, NULL, &insertion_point, FALSE),
                            user_name, service);
         /* request to attach icon to the buffer */
         request_icon(user_name, service);
@@ -1638,6 +1692,8 @@
                                               g_free, NULL);
     icon_data_by_user2 = g_hash_table_new_full(g_str_hash, g_str_equal,
                                               g_free, NULL);
+    icon_data_by_user3 = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                              g_free, NULL);
     conv_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
                                               NULL, NULL);
 
@@ -1709,14 +1765,17 @@
     /* 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);
+    g_hash_table_foreach(icon_data_by_user3, (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);
+    g_hash_table_foreach(icon_data_by_user3, (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
+    g_hash_table_destroy(icon_data_by_user2);
+    g_hash_table_destroy(icon_data_by_user3);
     g_hash_table_destroy(conv_hash);
 
     /* detach from twitter window */
--- a/pidgin-twitter.h	Wed Jul 09 16:13:02 2008 +0900
+++ b/pidgin-twitter.h	Thu Jul 10 00:12:03 2008 +0900
@@ -48,10 +48,12 @@
 #define OPT_PASSWORD            OPT_PIDGINTWITTER "/password"
 
 /* formats and templates */
-#define RECIPIENT_FORMAT        "@<a href='http://twitter.com/%s'>%s</a>"
-#define SENDER_FORMAT           "%s<a href='http://twitter.com/%s'>%s</a>: "
+#define RECIPIENT_FORMAT_TWITTER "@<a href='http://twitter.com/%s'>%s</a>"
+#define SENDER_FORMAT_TWITTER   "%s<a href='http://twitter.com/%s'>%s</a>: "
 #define RECIPIENT_FORMAT_WASSR  "@<a href='http://wassr.jp/user/%s'>%s</a>"
 #define SENDER_FORMAT_WASSR     "%s<a href='http://wassr.jp/user/%s'>%s</a>: "
+#define RECIPIENT_FORMAT_IDENTICA "@<a href='http://identi.ca/%s'>%s</a>"
+#define SENDER_FORMAT_IDENTICA  "%s<a href='http://identi.ca/%s'>%s</a>: "
 #define DEFAULT_LIST            "(list of users: separated with ' ,:;')"
 #define OOPS_MESSAGE            "<body>Oops! Your update was over 140 characters. We sent the short version to your friends (they can view the entire update on the web).<BR></body>"
 #define EMPTY                   ""
@@ -87,6 +89,8 @@
 static gboolean is_twitter_conv(PurpleConversation *conv);
 static gboolean is_wassr_account(PurpleAccount *account, const char *name);
 static gboolean is_wassr_conv(PurpleConversation *conv);
+static gboolean is_identica_account(PurpleAccount *account, const char *name);
+static gboolean is_identica_conv(PurpleConversation *conv);
 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);