# HG changeset patch # User Yoshiki Yazawa # Date 1260789271 -32400 # Node ID 33d2551727ba8fb429cd426c0644fe5c14653f7f # Parent dbebabe99035409e78f0c8b04d9103c0233116cc embed "in reply to foo" link to each reply message diff -r dbebabe99035 -r 33d2551727ba main.c --- a/main.c Mon Dec 14 15:07:52 2009 +0900 +++ b/main.c Mon Dec 14 20:14:31 2009 +0900 @@ -1261,7 +1261,7 @@ 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); - regp[MESSAGE_ID] = g_regex_new(P_MESSAGE_ID, 0, 0, NULL); + regp[PTTAG_TWITTER] = g_regex_new(P_PTTAG_TWITTER, 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, diff -r dbebabe99035 -r 33d2551727ba pidgin-twitter.h --- a/pidgin-twitter.h Mon Dec 14 15:07:52 2009 +0900 +++ b/pidgin-twitter.h Mon Dec 14 20:14:31 2009 +0900 @@ -51,7 +51,7 @@ SIZE_128_WASSR, EXCESS_LF, TRAIL_HASH, - MESSAGE_ID + PTTAG_TWITTER }; /* service id */ @@ -95,6 +95,8 @@ gchar *profile_image_url; time_t time; guint64 id; + guint64 in_reply_to_status_id; + gchar *in_reply_to_screen_name; } status_t; typedef struct _source { @@ -173,6 +175,8 @@ #define TAG_FORMAT_IDENTICA "#%s" #define GROUP_FORMAT_IDENTICA "!%s" #define LINK_FORMAT_TWITTER " RE FV RT QT" +#define IN_REPLY_TO_FORMAT_TWITTER " in reply to %s" + #define DEFAULT_LIST "(list of users: separated with ' ,:;')" #define OOPS_MESSAGE "Oops! Your update was over 140 characters. We sent the short version to your friends (they can view the entire update on the web).
" @@ -197,7 +201,8 @@ #define P_SIZE_128_WASSR "\\.128\\." #define P_EXCESS_LF "([\\r|\\n]{2,})" #define P_TRAIL_HASH "( #\\s+$)" -#define P_MESSAGE_ID " ptmsgid=([0-9]+)$" +/* pttag=msgid:in_reply_to_status_id:in_reply_to_screen_name */ +#define P_PTTAG_TWITTER " pttag=([0-9]+):([0-9]+):([-A-Za-z0-9_]*)$" /* twitter API specific macros */ #define TWITTER_BASE_URL "http://twitter.com" diff -r dbebabe99035 -r 33d2551727ba twitter_api.c --- a/twitter_api.c Mon Dec 14 15:07:52 2009 +0900 +++ b/twitter_api.c Mon Dec 14 20:14:31 2009 +0900 @@ -152,6 +152,18 @@ else if(!xmlStrcmp(nptr->name, (xmlChar *)"user")) { parse_user(nptr, st); } + else if(!xmlStrcmp(nptr->name, (xmlChar *)"in_reply_to_status_id")) { + gchar *str = (gchar *)xmlNodeGetContent(nptr); + st->in_reply_to_status_id = atoll(str); + twitter_debug("in_reply_to_status_id=%llu\n", (long long unsigned int)st->in_reply_to_status_id); + xmlFree(str); + } + else if(!xmlStrcmp(nptr->name, (xmlChar *)"in_reply_to_screen_name")) { + gchar *str = (gchar *)xmlNodeGetContent(nptr); + st->in_reply_to_screen_name = g_strdup(str); + twitter_debug("in_reply_to_screen_name=%s\n", st->in_reply_to_screen_name); + xmlFree(str); + } } } } @@ -163,6 +175,7 @@ g_free(st->text); g_free(st->screen_name); g_free(st->profile_image_url); + g_free(st->in_reply_to_screen_name); } static gboolean @@ -264,9 +277,11 @@ PurpleMessageFlags flag = PURPLE_MESSAGE_RECV; - msg = g_strdup_printf("%s: %s ptmsgid=%llu", + msg = g_strdup_printf("%s: %s pttag=%llu:%llu:%s", st->screen_name, st->text, - (long long unsigned int)st->id); + (long long unsigned int)st->id, + (long long unsigned int)st->in_reply_to_status_id, + st->in_reply_to_screen_name ? st->in_reply_to_screen_name : ""); /* apply filter */ if(purple_prefs_get_bool(OPT_FILTER)) { @@ -456,7 +471,7 @@ xmlFreeDoc(doc); xmlCleanupParser(); - m = g_strdup_printf("%s ptmsgid=%llu", + m = g_strdup_printf("%s pttag=%llu:0:", tm->status, (long long unsigned int)st->id); diff -r dbebabe99035 -r 33d2551727ba util.c --- a/util.c Mon Dec 14 15:07:52 2009 +0900 +++ b/util.c Mon Dec 14 20:14:31 2009 +0900 @@ -529,23 +529,22 @@ twitter_rip_link_string(gchar **str) { GMatchInfo *match_info = NULL; - gchar *boddy0 = NULL, *boddy = NULL; + gchar *body0 = NULL, *body = NULL; gchar *newstr = NULL, *linkstr = NULL; - gchar *match = NULL; - gchar *idstr = NULL, *user = NULL; + gchar *user = NULL; twitter_debug("called\n"); - /* buffer without ptmsgid=123 */ - boddy0 = g_regex_replace(regp[SENDER], *str, -1, 0, "", 0, NULL); - boddy = g_regex_replace(regp[MESSAGE_ID], boddy0, -1, 0, "", 0, NULL); - g_free(boddy0); - boddy0 = NULL; - twitter_debug("boddy = %s\n", boddy); + /* buffer without pttag= */ + body0 = g_regex_replace(regp[SENDER], *str, -1, 0, "", 0, NULL); + body = g_regex_replace(regp[PTTAG_TWITTER], body0, -1, 0, "", 0, NULL); + g_free(body0); + body0 = NULL; + twitter_debug("body = %s\n", body); - boddy0 = g_uri_escape_string(boddy, " !$()*,;:@/?#[]", TRUE); - g_free(boddy); - boddy = boddy0; + body0 = g_uri_escape_string(body, " !$()*,;:@/?#[]", TRUE); + g_free(body); + body = body0; /* sender */ g_regex_match(regp[SENDER], *str, 0, &match_info); @@ -557,36 +556,60 @@ } /* link string */ - g_regex_match(regp[MESSAGE_ID], *str, 0, &match_info); + g_regex_match(regp[PTTAG_TWITTER], *str, 0, &match_info); if(match_info) { - match = g_match_info_fetch(match_info, 1); - idstr = match ? match : "0"; - linkstr = g_strdup_printf(LINK_FORMAT_TWITTER, - idstr, user, /* Reply */ - idstr, /* Favorite */ - idstr, /* Retweet */ - idstr, user, boddy); /* Quotetweet */ + gchar *msg_id_str = NULL; + gchar *in_reply_to_status_id_str = NULL; + long long unsigned int in_reply_to_status_id = 0; + + msg_id_str = g_match_info_fetch(match_info, 1); + in_reply_to_status_id_str = g_match_info_fetch(match_info, 2); + in_reply_to_status_id = strtoull(in_reply_to_status_id_str, NULL, 10); + g_free(in_reply_to_status_id_str); + in_reply_to_status_id_str = NULL; + + if(in_reply_to_status_id) { + gchar *in_reply_to_screen_name; + + in_reply_to_screen_name = g_match_info_fetch(match_info, 3); + linkstr = g_strdup_printf(IN_REPLY_TO_FORMAT_TWITTER LINK_FORMAT_TWITTER, + in_reply_to_screen_name, + in_reply_to_status_id, + in_reply_to_screen_name, + msg_id_str, user, /* Reply */ + msg_id_str, /* Favorite */ + msg_id_str, /* Retweet */ + msg_id_str, user, body); /* Quotetweet */ + + g_free(in_reply_to_screen_name); + in_reply_to_screen_name = NULL; + } + else { + linkstr = g_strdup_printf(LINK_FORMAT_TWITTER, + msg_id_str, user, /* Reply */ + msg_id_str, /* Favorite */ + msg_id_str, /* Retweet */ + msg_id_str, user, body); /* Quotetweet */ + } twitter_debug("linkstr = %s\n", linkstr); - newstr = g_regex_replace(regp[MESSAGE_ID], *str, -1, 0, - "", - 0, NULL); + newstr = g_regex_replace(regp[PTTAG_TWITTER], *str, -1, 0, "", 0, NULL); twitter_debug("newstr = %s\n", newstr); g_free(*str); *str = newstr; - g_free(match); - match = NULL; + g_free(msg_id_str); + msg_id_str = NULL; g_match_info_free(match_info); match_info = NULL; } g_free(user); - g_free(boddy); + g_free(body); return linkstr; }