changeset 300:42cdddf0f747

added preliminary support for friendfeed.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Mon, 25 May 2009 22:47:44 +0900
parents d68ed289ef69
children 3b2b68c8babd
files icon.c main.c pidgin-twitter.h prefs.c prefs.ui util.c
diffstat 6 files changed, 232 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/icon.c	Sat Apr 25 22:27:13 2009 +0900
+++ b/icon.c	Mon May 25 22:47:44 2009 +0900
@@ -70,6 +70,7 @@
     case wassr_service:
     case identica_service:
     case jisko_service:
+    case ffeed_service:
         hash = icon_hash[service];
         break;
     default:
@@ -112,6 +113,7 @@
     case wassr_service:
     case identica_service:
     case jisko_service:
+    case ffeed_service:
         hash = icon_hash[service];
         break;
     default:
@@ -179,6 +181,11 @@
             icon_hash[service], user_name);
         regp_id = IMAGE_JISKO;
     }
+    else if(service == ffeed_service) {
+        data = (icon_data *)g_hash_table_lookup(
+            icon_hash[service], user_name);
+        regp_id = IMAGE_FFEED;
+    }
 
     /* retrieved nothing or got a bad response */
     if(!url_text ||
@@ -213,6 +220,11 @@
                           gotdata->user_name);
             url = g_strdup(JISKO_DEFAULT_ICON_URL);
         }
+        else if(service == ffeed_service) {
+            twitter_debug("fall back to ffeed default icon: %s\n",
+                          gotdata->user_name);
+            url = g_strdup(FFEED_DEFAULT_ICON_URL);
+        }
         else {
             twitter_debug("no image url found\n");
             if(data) {
@@ -356,6 +368,7 @@
     case wassr_service:
     case identica_service:
     case jisko_service:
+    case ffeed_service:
         hash = icon_hash[service];
         break;
     default:
@@ -412,6 +425,8 @@
             break;
         case jisko_service:
             url = JISKO_DEFAULT_ICON_URL;
+        case ffeed_service:
+            url = FFEED_DEFAULT_ICON_URL;
             break;
         }
 
@@ -470,6 +485,9 @@
         case jisko_service:
             suffix = "jisko";
             break;
+        case ffeed_service:
+            suffix = "ffeed";
+            break;
         default:
             twitter_debug("unknown service\n");
             break;
@@ -538,6 +556,10 @@
         hash = icon_hash[service];
         suffix = "jisko";
         break;
+    case ffeed_service:
+        hash = icon_hash[service];
+        suffix = "ffeed";
+        break;
     default:
         twitter_debug("unknown service\n");
         break;
@@ -630,6 +652,9 @@
     case jisko_service:
         url = g_strdup_printf("http://jisko.net/%s", user_name);
         break;
+    case ffeed_service:
+        url = g_strdup_printf("http://friendfeed.com/%s", user_name);
+        break;
     default:
         twitter_debug("unknown service\n");
         break;
@@ -643,7 +668,8 @@
         /* gotdata will be released in got_icon_cb */
         if(service == twitter_service ||
            service == wassr_service ||
-           service == jisko_service) {
+           service == jisko_service ||
+           service == ffeed_service) {
             data->fetch_data =
                 purple_util_fetch_url_request(url, TRUE, NULL, TRUE, NULL,
                                               TRUE, got_page_cb, gotdata);
@@ -680,6 +706,9 @@
     case jisko_service:
         hash = icon_hash[jisko_service];
         break;
+    case ffeed_service:
+        hash = icon_hash[ffeed_service];
+        break;
     default:
         twitter_debug("unknown service\n");
         break;
--- a/main.c	Sat Apr 25 22:27:13 2009 +0900
+++ b/main.c	Mon May 25 22:47:44 2009 +0900
@@ -170,6 +170,9 @@
         case jisko_service:
             format = RECIPIENT_FORMAT_JISKO;
             break;
+        case ffeed_service:
+            format = RECIPIENT_FORMAT_FFEED;
+            break;
         default:
             twitter_debug("unknown service\n");
             break;
@@ -179,7 +182,7 @@
         g_free(match2);
     }
     else if(which == SENDER) {
-        gchar *match1 = g_match_info_fetch(match_info, 1); /*preceding CR|LF*/
+        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;
 
@@ -206,6 +209,17 @@
         g_free(match1);
         g_free(match2);
     }
+    else if(which == SENDER_FFEED) {
+        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;
+
+        format = SENDER_FORMAT_FFEED;
+        g_snprintf(sub, SUBST_BUF_SIZE, format, match1 ? match1: "", match2, match2);
+
+        g_free(match1);
+        g_free(match2);
+    }
     else if(which == CHANNEL_WASSR && service == wassr_service) {
         gchar *match1 = g_match_info_fetch(match_info, 1); /* before channel */
         gchar *match2 = g_match_info_fetch(match_info, 2); /* channel */
@@ -245,6 +259,9 @@
     else if(which == EXCESS_LF) {
         g_snprintf(sub, SUBST_BUF_SIZE, "%s", "\n");
     }
+    else if(which == TRAIL_HASH) {
+        g_snprintf(sub, SUBST_BUF_SIZE, "%s", ""); /* xxx --yaz */
+    }
 
     g_string_append(result, sub);
     twitter_debug("sub = %s\n", sub);
@@ -352,6 +369,9 @@
         case jisko_service:
             screen_name = purple_prefs_get_string(OPT_SCREEN_NAME_JISKO);
             break;
+        case ffeed_service:
+            screen_name = purple_prefs_get_string(OPT_SCREEN_NAME_FFEED);
+            break;
         }
 
         if (screen_name) {
@@ -374,7 +394,10 @@
 
     /* translate */
     if(purple_prefs_get_bool(OPT_TRANSLATE_SENDER)) {
-        translate(buffer, SENDER, service);
+        if(service == ffeed_service)
+            translate(buffer, SENDER_FFEED, service);
+        else
+            translate(buffer, SENDER, service);
     }
     if(purple_prefs_get_bool(OPT_TRANSLATE_RECIPIENT)) {
         translate(buffer, RECIPIENT, service);
@@ -406,6 +429,10 @@
         translate(buffer, EXCESS_LF, service);
     }
 
+    if(service == ffeed_service) {
+        translate(buffer, TRAIL_HASH, service);
+    }
+
     return FALSE;
 }
 
@@ -427,6 +454,7 @@
     case twitter_service:
     case identica_service:
     case jisko_service:
+    case ffeed_service:
         count = gtk_text_buffer_get_char_count(textbuffer) +
             (unsigned int)g_utf8_strlen(new_text, -1);
         markup = g_markup_printf_escaped("<span color=\"%s\">%u</span>",
@@ -468,6 +496,7 @@
     case twitter_service:
     case identica_service:
     case jisko_service:
+    case ffeed_service:
         count= gtk_text_buffer_get_char_count(textbuffer) -
             (gtk_text_iter_get_offset(end_pos) -
              gtk_text_iter_get_offset(start_pos));
@@ -510,6 +539,7 @@
         case wassr_service:
         case identica_service:
         case jisko_service:
+        case ffeed_service:
             detach_from_conv(conv, NULL);
             break;
         default:
@@ -628,6 +658,7 @@
         case wassr_service:
         case identica_service:
         case jisko_service:
+        case ffeed_service:
             attach_to_conv(conv, NULL);
             break;
         default:
@@ -720,6 +751,7 @@
     case wassr_service:
     case identica_service:
     case jisko_service:
+    case ffeed_service:
         attach_to_conv(conv, NULL);
         break;
     default:
@@ -753,6 +785,7 @@
     case wassr_service:
     case identica_service:
     case jisko_service:
+    case ffeed_service:
         hash = icon_hash[service];
         break;
     default:
@@ -794,6 +827,9 @@
     case jisko_service:
         list = purple_prefs_get_string(OPT_FILTER_JISKO);
         screen_name = g_strdup_printf("@%s", purple_prefs_get_string(OPT_SCREEN_NAME_JISKO));
+    case ffeed_service:
+        list = purple_prefs_get_string(OPT_FILTER_FFEED);
+        screen_name = g_strdup_printf("@%s", purple_prefs_get_string(OPT_SCREEN_NAME_FFEED));
         break;
     }
     g_return_if_fail(list != NULL);
@@ -1037,6 +1073,7 @@
     case wassr_service:
     case identica_service:
     case jisko_service:
+    case ffeed_service:
         hash = icon_hash[service];
         break;
     default:
@@ -1123,6 +1160,7 @@
     /* compile regex */
     regp[RECIPIENT] = g_regex_new(P_RECIPIENT, 0, 0, NULL);
     regp[SENDER]    = g_regex_new(P_SENDER,    0, 0, NULL);
+    regp[SENDER_FFEED] = g_regex_new(P_SENDER_FFEED, 0, 0, NULL);
     regp[COMMAND]   = g_regex_new(P_COMMAND, G_REGEX_RAW, 0, NULL);
     regp[PSEUDO]    = g_regex_new(P_PSEUDO,  G_REGEX_RAW, 0, NULL);
     regp[USER]      = g_regex_new(P_USER, 0, 0, NULL);
@@ -1134,8 +1172,10 @@
     regp[IMAGE_WASSR]    = g_regex_new(P_IMAGE_WASSR, 0, 0, NULL);
     regp[IMAGE_IDENTICA] = g_regex_new(P_IMAGE_IDENTICA, 0, 0, NULL);
     regp[IMAGE_JISKO]    = g_regex_new(P_IMAGE_JISKO, 0, 0, NULL);
+    regp[IMAGE_FFEED]    = g_regex_new(P_IMAGE_FFEED, 0, 0, NULL);
     regp[SIZE_128_WASSR] = g_regex_new(P_SIZE_128_WASSR, 0, 0, NULL);
     regp[EXCESS_LF] = g_regex_new(P_EXCESS_LF, 0, 0, NULL);
+    regp[TRAIL_HASH] = g_regex_new(P_TRAIL_HASH, 0, 0, NULL);
 
     for(i = twitter_service; i < NUM_SERVICES; i++) {
         icon_hash[i] = g_hash_table_new_full(g_str_hash, g_str_equal,
@@ -1339,6 +1379,7 @@
     purple_prefs_add_string(OPT_SCREEN_NAME_WASSR, EMPTY);
     purple_prefs_add_string(OPT_SCREEN_NAME_IDENTICA, EMPTY);
     purple_prefs_add_string(OPT_SCREEN_NAME_JISKO, EMPTY);
+    purple_prefs_add_string(OPT_SCREEN_NAME_FFEED, EMPTY);
 
     purple_prefs_add_bool(OPT_SHOW_ICON, TRUE);
     purple_prefs_add_int(OPT_ICON_SIZE, DEFAULT_ICON_SIZE);
@@ -1353,6 +1394,7 @@
     purple_prefs_add_string(OPT_FILTER_WASSR, DEFAULT_LIST);
     purple_prefs_add_string(OPT_FILTER_IDENTICA, DEFAULT_LIST);
     purple_prefs_add_string(OPT_FILTER_JISKO, DEFAULT_LIST);
+    purple_prefs_add_string(OPT_FILTER_FFEED, DEFAULT_LIST);
 }
 
 PURPLE_INIT_PLUGIN(pidgin_twitter, init_plugin, info)
--- a/pidgin-twitter.h	Sat Apr 25 22:27:13 2009 +0900
+++ b/pidgin-twitter.h	Mon May 25 22:47:44 2009 +0900
@@ -34,6 +34,7 @@
 enum {
     RECIPIENT = 0,
     SENDER,
+    SENDER_FFEED,
     COMMAND,
     PSEUDO,
     USER,
@@ -45,8 +46,10 @@
     IMAGE_WASSR,
     IMAGE_IDENTICA,
     IMAGE_JISKO,
+    IMAGE_FFEED,
     SIZE_128_WASSR,
-    EXCESS_LF
+    EXCESS_LF,
+    TRAIL_HASH
 };
 
 /* service id */
@@ -55,7 +58,8 @@
     twitter_service,
     wassr_service,
     identica_service,
-    jisko_service
+    jisko_service,
+    ffeed_service
 };
 
 /* container to hold icon data */
@@ -128,6 +132,7 @@
 #define OPT_SCREEN_NAME_WASSR   OPT_PIDGINTWITTER "/screen_name_wassr"
 #define OPT_SCREEN_NAME_IDENTICA OPT_PIDGINTWITTER "/screen_name_identica"
 #define OPT_SCREEN_NAME_JISKO   OPT_PIDGINTWITTER "/screen_name_jisko"
+#define OPT_SCREEN_NAME_FFEED   OPT_PIDGINTWITTER "/screen_name_ffeed"
 #define OPT_PASSWORD_TWITTER    OPT_PIDGINTWITTER "/password_twitter"
 #define OPT_SHOW_ICON           OPT_PIDGINTWITTER "/show_icon"
 #define OPT_ICON_SIZE           OPT_PIDGINTWITTER "/icon_size"
@@ -142,6 +147,7 @@
 #define OPT_FILTER_WASSR        OPT_PIDGINTWITTER "/filter_wassr"
 #define OPT_FILTER_IDENTICA     OPT_PIDGINTWITTER "/filter_identica"
 #define OPT_FILTER_JISKO        OPT_PIDGINTWITTER "/filter_jisko"
+#define OPT_FILTER_FFEED        OPT_PIDGINTWITTER "/filter_ffeed"
 #define OPT_STRIP_EXCESS_LF     OPT_PIDGINTWITTER "/strip_excess_lf"
 #define OPT_RETRIEVE_COUNT      OPT_PIDGINTWITTER "/retrieve_count"
 
@@ -158,6 +164,8 @@
 #define SENDER_FORMAT_IDENTICA  "%s<a href='http://identi.ca/%s'>%s</a>: "
 #define RECIPIENT_FORMAT_JISKO  "%s@<a href='http://jisko.net/%s'>%s</a>"
 #define SENDER_FORMAT_JISKO     "%s<a href='http://jisko.net/%s'>%s</a>: "
+#define RECIPIENT_FORMAT_FFEED  "%s@<a href='http://friendfeed.com/%s'>%s</a>"
+#define SENDER_FORMAT_FFEED     "%s<a href='http://friendfeed.com/%s'>%s</a>: "
 #define CHANNEL_FORMAT_WASSR    "%s<a href='http://wassr.jp/channel/%s'>%s</a> "
 #define CHANNEL_FORMAT_IDENTICA "%s<a href='http://identi.ca/tag/%s'>%s</a> "
 #define TAG_FORMAT_TWITTER      "%s<a href='http://twitter.com/search?q=%%23%s'>#%s</a>"
@@ -171,6 +179,7 @@
 /* patterns */
 #define P_RECIPIENT         "(^|\\s+|[.[:^print:]])@([-A-Za-z0-9_]+)"
 #define P_SENDER            "^(\\r?\\n?)\\s*([-A-Za-z0-9_]+)(?:\\s*\\(.+\\))?: "
+#define P_SENDER_FFEED      "^(\\r?\\n?)\\s*@[0-9]\\s*([-A-Za-z0-9_]+)\\s*(?:posted)"
 #define P_COMMAND           "^(?:\\s*)([dDfFgGlLmMnNtTwW]{1}\\s+[A-Za-z0-9_]+)(?:\\s*\\Z)"
 #define P_PSEUDO            "^\\s*(?:[\"#$%&'()*+,\\-./:;<=>?\\[\\\\\\]_`{|}~]|[^\\s\\x21-\\x7E])*([dDfFgGlLmMnNtTwW]{1})(?:\\Z|\\s+|[^\\x21-\\x7E]+\\Z)"
 #define P_USER              "^.*?(?:<a .+?>)?([-A-Za-z0-9_]+)(?:</a>)?:"
@@ -182,8 +191,10 @@
 #define P_IMAGE_WASSR       "<div class=\"image\"><a href=\".+\"><img src=\"(.+)\" width=\".+?\" /></a></div>"
 #define P_IMAGE_IDENTICA    "<img src=\"(https?://.+.identi.ca/.+)\" class=\"avatar profile photo\" width=\"96\" height=\"96\" alt=\"[A-Za-z0-9_]+\"/>"
 #define P_IMAGE_JISKO       "<img src=\"(https?://jisko.net/users/.+/img/avatar/thumb_side\\..+)\" alt=\"Avatar\" />"
+#define P_IMAGE_FFEED       "<img src=\"(https?://i.friendfeed.com/.+)\" alt=\""
 #define P_SIZE_128_WASSR    "\\.128\\."
 #define P_EXCESS_LF         "([\\r|\\n]{2,})"
+#define P_TRAIL_HASH        "( #\\s+$)"
 
 /* twitter API specific macros */
 #define TWITTER_BASE_URL "http://twitter.com"
@@ -211,6 +222,9 @@
 /* jisko specific macro */
 #define JISKO_DEFAULT_ICON_URL "http://jisko.net/static/img/avatar/default_note.png"
 
+/* ffeed specific macro */
+#define FFEED_DEFAULT_ICON_URL "http://friendfeed.com/static/images/nomugshot-large.png"
+
 /* size of substitution buffer */
 #define SUBST_BUF_SIZE (32 * 1024)
 
@@ -219,8 +233,8 @@
 #define DEFAULT_ICON_MAX_COUNT (50)
 #define DEFAULT_ICON_MAX_DAYS (7)
 #define DAYS_TO_SECONDS(d) ((d) * 86400)
-#define NUM_REGPS (15)
-#define NUM_SERVICES (4)          /* twitter, wassr, identica, jisko. */
+#define NUM_REGPS (18)
+#define NUM_SERVICES (5)          /* twitter, wassr, identica, jisko, ffeed. */
 
 /* debug macros */
 #define twitter_debug(fmt, ...)	do { if(purple_prefs_get_bool(OPT_LOG_OUTPUT)) purple_debug(PURPLE_DEBUG_INFO, PLUGIN_NAME, "%s: %s():%4d:  " fmt, __FILE__, __FUNCTION__, (int)__LINE__, ## __VA_ARGS__); } while(0);
--- a/prefs.c	Sat Apr 25 22:27:13 2009 +0900
+++ b/prefs.c	Mon May 25 22:47:44 2009 +0900
@@ -189,6 +189,13 @@
     g_signal_connect(e, "changed",
                      G_CALLBACK(text_changed_cb), &e);
 
+    e = GTK_WIDGET(gtk_builder_get_object (builder, "account_ffeed"));
+    g_object_set_data(G_OBJECT(e), "pref", OPT_SCREEN_NAME_FFEED);
+    text = purple_prefs_get_string(OPT_SCREEN_NAME_FFEED);
+    gtk_entry_set_text(GTK_ENTRY(e), text);
+    g_signal_connect(e, "changed",
+                     G_CALLBACK(text_changed_cb), &e);
+
     e = GTK_WIDGET(gtk_builder_get_object (builder, "account_api"));
     g_object_set_data(G_OBJECT(e), "pref", OPT_API_BASE_POST);
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(e),
@@ -330,6 +337,13 @@
     g_signal_connect(e, "changed",
                      G_CALLBACK(text_changed_cb), &e);
 
+    e = GTK_WIDGET(gtk_builder_get_object (builder, "filter_ffeed"));
+    g_object_set_data(G_OBJECT(e), "pref", OPT_FILTER_FFEED);
+    text = purple_prefs_get_string(OPT_FILTER_FFEED);
+    gtk_entry_set_text(GTK_ENTRY(e), text);
+    g_signal_connect(e, "changed",
+                     G_CALLBACK(text_changed_cb), &e);
+
 
 
     /*************/
--- a/prefs.ui	Sat Apr 25 22:27:13 2009 +0900
+++ b/prefs.ui	Mon May 25 22:47:44 2009 +0900
@@ -246,6 +246,50 @@
               </packing>
             </child>
             <child>
+              <object class="GtkHBox" id="hbox17">
+                <property name="visible">True</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment74">
+                    <property name="visible">True</property>
+                    <property name="left_padding">20</property>
+                    <child>
+                      <object class="GtkLabel" id="label42">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">friend feed</property>
+                        <property name="max_width_chars">10</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkAlignment" id="alignment75">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="right_padding">4</property>
+                    <child>
+                      <object class="GtkEntry" id="account_ffeed">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="width_chars">20</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">5</property>
+              </packing>
+            </child>
+            <child>
               <object class="GtkAlignment" id="alignment8">
                 <property name="visible">True</property>
                 <property name="top_padding">8</property>
@@ -262,7 +306,7 @@
                 </child>
               </object>
               <packing>
-                <property name="position">5</property>
+                <property name="position">6</property>
               </packing>
             </child>
             <child>
@@ -281,7 +325,7 @@
                 </child>
               </object>
               <packing>
-                <property name="position">6</property>
+                <property name="position">7</property>
               </packing>
             </child>
             <child>
@@ -314,6 +358,7 @@
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="width_chars">20</property>
+                        <property name="invisible_char_set">True</property>
                       </object>
                     </child>
                   </object>
@@ -325,7 +370,7 @@
                 </child>
               </object>
               <packing>
-                <property name="position">7</property>
+                <property name="position">8</property>
               </packing>
             </child>
             <child>
@@ -391,7 +436,7 @@
               </object>
               <packing>
                 <property name="expand">False</property>
-                <property name="position">8</property>
+                <property name="position">9</property>
               </packing>
             </child>
             <child>
@@ -461,7 +506,7 @@
               </object>
               <packing>
                 <property name="expand">False</property>
-                <property name="position">9</property>
+                <property name="position">10</property>
               </packing>
             </child>
           </object>
@@ -856,6 +901,54 @@
                 <property name="position">7</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkHBox" id="hbox16">
+                <property name="visible">True</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment72">
+                    <property name="visible">True</property>
+                    <property name="left_padding">20</property>
+                    <child>
+                      <object class="GtkLabel" id="label41">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">friend feed</property>
+                        <property name="max_width_chars">10</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkAlignment" id="alignment73">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="right_padding">4</property>
+                    <child>
+                      <object class="GtkEntry" id="filter_ffeed">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">&#x25CF;</property>
+                        <property name="width_chars">35</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="padding">2</property>
+                <property name="position">8</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="position">2</property>
--- a/util.c	Sat Apr 25 22:27:13 2009 +0900
+++ b/util.c	Mon May 25 22:47:44 2009 +0900
@@ -355,6 +355,30 @@
     return is_jisko_account(account, name);
 }
 
+gboolean
+is_ffeed_account(PurpleAccount *account, const char *name)
+{
+    const gchar *proto = purple_account_get_protocol_id(account);
+
+    if(g_strstr_len(name,  22, "ff@chat.friendfeed.com") &&
+       g_strstr_len(proto, 11, "prpl-jabber")) {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+gboolean
+is_ffeed_conv(PurpleConversation *conv)
+{
+    g_return_val_if_fail(conv != NULL, FALSE);
+
+    const char *name = purple_conversation_get_name(conv);
+    PurpleAccount *account = purple_conversation_get_account(conv);
+
+    return is_ffeed_account(account, name);
+}
+
 gint
 get_service_type_by_account(PurpleAccount *account, const char *sender)
 {
@@ -371,6 +395,8 @@
         service = identica_service;
     else if(is_jisko_account(account, sender))
         service = jisko_service;
+    else if(is_ffeed_account(account, sender))
+        service = ffeed_service;
 
     return service;
 }
@@ -390,6 +416,8 @@
         service = identica_service;
     else if(is_jisko_conv(conv))
         service = jisko_service;
+    else if(is_ffeed_conv(conv))
+        service = ffeed_service;
 
     return service;
 }