Mercurial > pidgin-twitter
view util.c @ 332:227852ee649c
do not append "in_reply_to_status_id" when msdid is 0.
author | Yoshiki Yazawa <[email protected]> |
---|---|
date | Tue, 13 Oct 2009 03:10:32 +0900 |
parents | b4c846870b3c |
children | 9f78fb6bfc76 |
line wrap: on
line source
#include "pidgin-twitter.h" extern GRegex *regp[]; extern guint64 reply_to_msgid; extern PurpleAccount *account_for_twitter; /* prototypes */ static gchar *twitter_memrchr(const gchar *s, int c, size_t n); void fav_with_api(guint64 id); /* functions */ /* this function has been taken from autoaccept plugin */ gboolean ensure_path_exists(const char *dir) { if (!g_file_test(dir, G_FILE_TEST_IS_DIR)) { if (purple_build_dir(dir, S_IRUSR | S_IWUSR | S_IXUSR)) return FALSE; } return TRUE; } static gchar * twitter_memrchr(const gchar *s, int c, size_t n) { int nn = n; g_return_val_if_fail(s != NULL, NULL); while(nn+1) { if((int)*(s+nn) == c) return (gchar *)(s+nn); nn--; } return NULL; } static gchar *html_tags[] = { "<a ", "</a>", "<b>", "</b>", "<p>", "</p>", "<div ", "</div>", "<span ", "</span>", "<body>", "<body ", "</body>", "<i>", "</i>", "<font ", "</font>", "<br>", "<br/>", "<img ", "<html>", "<html ", "</html>", NULL }; gchar * strip_html_markup(const gchar *src) { gchar *head, *tail; /* head and tail of html */ gchar *begin, *end; /* begin:< end:> */ gchar *html, *str; /* copied src and string to be returned */ /* gchar *vis1, *vis2; */ /* begin and end of address part */ gchar *startp; /* starting point marker */ gchar **tagp; /* tag iterator */ gchar *tmp, *tmp2; /* scratches */ g_return_val_if_fail(src != NULL, NULL); const gchar *ptr, *ent; gchar *ptr2; gint srclen; gint entlen; /* unescape &x; */ srclen = strlen(src); html = g_malloc0(srclen + 1); ptr2 = html; for(ptr = src; *ptr; ) { if(*ptr == '&') { ent = purple_markup_unescape_entity(ptr, &entlen); if(ent != NULL) { while(*ent) { if(ptr2 - html < srclen) *ptr2++ = *ent++; else ent++; } ptr += entlen; } else { if(ptr2 - html < srclen) *ptr2++ = *ptr++; else ptr++; } } else { if(ptr2 - html < srclen) *ptr2++ = *ptr++; else ptr++; } } /* for */ str = g_strdup("\0"); head = html; tail = head + strlen(html); startp = head; loop: begin = NULL; end = NULL; if(startp >= tail) { g_free(html); return str; } end = strchr(startp, '>'); if(end) { begin = twitter_memrchr(startp, '<', end - startp); if(begin < startp) begin = NULL; if(!begin) { /* '>' found but no corresponding '<' */ tmp = g_strndup(startp, end - startp + 1); /* concat until '>' */ tmp2 = g_strconcat(str, tmp, NULL); g_free(str); g_free(tmp); str = tmp2; startp = end + 1; goto loop; } } else { /* neither '>' nor '<' were found */ tmp = g_strconcat(str, startp, NULL); /* concat the rest */ g_free(str); str = tmp; g_free(html); return str; } /* here, both < and > are found */ /* concatenate leading part to dest */ tmp = g_strndup(startp, begin - startp); tmp2 = g_strconcat(str, tmp, NULL); g_free(tmp); g_free(str); str = tmp2; /* find tag */ for(tagp = html_tags; *tagp; tagp++) { if(!g_ascii_strncasecmp(begin, *tagp, strlen(*tagp))) { /* we found a valid tag */ /* if tag is <a href=, extract address. */ #if 0 if(!strcmp(*tagp, "<a href=")) { vis1 = NULL; vis2 = NULL; vis1 = strchr(begin, '\''); if(vis1) vis2 = strchr(vis1+1, '\''); if(!vis1) { vis1 = strchr(begin, '\"'); if(vis1) vis2 = strchr(vis1+1, '\"'); } if(vis1 && vis2) { *vis2 = '\0'; /* generate "[ http://example.com/ ] anchor " */ tmp = g_strconcat(str, "[ ", vis1+1, " ]", " ", NULL); g_free(str); str = tmp; } startp = end + 1; goto loop; } /* <a href= */ else { /* anything else: discard whole <>. */ startp = end + 1; goto loop; } #else /* anything else: discard whole <>. */ startp = end + 1; goto loop; #endif } /* valid tag */ } /* no valid tag was found: copy <brabra> */ tmp = g_strndup(begin, end - begin + 1); tmp2 = g_strconcat(str, tmp, NULL); g_free(tmp); g_free(str); str = tmp2; startp = end + 1; goto loop; } /* string utilities */ void escape(gchar **str) { GMatchInfo *match_info = NULL; gchar *newstr = NULL, *match = NULL; gboolean flag = FALSE; /* search genuine command */ g_regex_match(regp[COMMAND], *str, 0, &match_info); while(g_match_info_matches(match_info)) { match = g_match_info_fetch(match_info, 1); twitter_debug("command = %s\n", match); g_free(match); g_match_info_next(match_info, NULL); flag = TRUE; } g_match_info_free(match_info); match_info = NULL; if(flag) return; /* if not found, check pseudo command */ g_regex_match(regp[PSEUDO], *str, 0, &match_info); while(g_match_info_matches(match_info)) { match = g_match_info_fetch(match_info, 1); twitter_debug("pseudo = %s\n", match); g_free(match); g_match_info_next(match_info, NULL); flag = TRUE; } g_match_info_free(match_info); match_info = NULL; /* if there is pseudo one, escape it */ if(flag) { /* put ". " to the beginning of buffer */ newstr = g_strdup_printf(". %s", *str); twitter_debug("*str = %s newstr = %s\n", *str, newstr); g_free(*str); *str = newstr; } } void strip_markup(gchar **str, gboolean escape) { gchar *plain; plain = strip_html_markup(*str); g_free(*str); if(escape) { *str = g_markup_escape_text(plain, -1); g_free(plain); } else { *str = plain; } twitter_debug("result=%s\n", *str); } gboolean is_twitter_account(PurpleAccount *account, const char *name) { const gchar *proto = purple_account_get_protocol_id(account); if(g_strstr_len(name, 19, "[email protected]") && g_strstr_len(proto, 11, "prpl-jabber")) { return TRUE; } return FALSE; } gboolean is_twitter_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_twitter_account(account, name); } gboolean is_wassr_account(PurpleAccount *account, const char *name) { const gchar *proto = purple_account_get_protocol_id(account); if(g_strstr_len(name, 18, "[email protected]") && g_strstr_len(proto, 11, "prpl-jabber")) { return TRUE; } return FALSE; } gboolean is_wassr_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_wassr_account(account, name); } gboolean is_identica_account(PurpleAccount *account, const char *name) { const gchar *proto = purple_account_get_protocol_id(account); if(g_strstr_len(name, 16, "[email protected]") && g_strstr_len(proto, 11, "prpl-jabber")) { return TRUE; } return FALSE; } gboolean is_identica_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_identica_account(account, name); } gboolean is_jisko_account(PurpleAccount *account, const char *name) { const gchar *proto = purple_account_get_protocol_id(account); if(g_strstr_len(name, 16, "[email protected]") && g_strstr_len(proto, 11, "prpl-jabber")) { return TRUE; } return FALSE; } gboolean is_jisko_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_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, "[email protected]") && 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) { gint service = unknown_service; g_return_val_if_fail(account != NULL, unknown_service); g_return_val_if_fail(sender != NULL, unknown_service); if(is_twitter_account(account, sender)) service = twitter_service; else if(is_wassr_account(account, sender)) service = wassr_service; else if(is_identica_account(account, sender)) 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; } gint get_service_type(PurpleConversation *conv) { gint service = unknown_service; g_return_val_if_fail(conv != NULL, unknown_service); if(is_twitter_conv(conv)) service = twitter_service; else if(is_wassr_conv(conv)) service = wassr_service; else if(is_identica_conv(conv)) service = identica_service; else if(is_jisko_conv(conv)) service = jisko_service; else if(is_ffeed_conv(conv)) service = ffeed_service; return service; } gboolean pt_uri_handler(const char *proto, const char *cmd, GHashTable *params) { char *idstr = NULL; const char *acct_id = NULL; PurpleConversation *conv = NULL; PidginConversation *gtkconv = NULL; guint64 msgid = 0; gchar *sender = NULL, *recipient = NULL, *msg = NULL; if(g_ascii_strcasecmp(proto, "pt")) return FALSE; twitter_debug("params=%p\n", params); acct_id = purple_prefs_get_string(OPT_SCREEN_NAME_TWITTER); twitter_debug("acct_id=%s\n", acct_id); if(strstr(cmd, "reply-twitter")) { sender = g_hash_table_lookup(params, "user"); idstr = g_hash_table_lookup(params, "id"); if(idstr) msgid = strtoull(idstr, NULL, 10); /* find conv */ conv = purple_find_conversation_with_account( PURPLE_CONV_TYPE_ANY, "[email protected]", account_for_twitter); /* xxx */ twitter_debug("conv = %p\n", conv); gtkconv = PIDGIN_CONVERSATION(conv); twitter_debug("sender = %s, id = %llu\n", sender, (unsigned long long)msgid); recipient = g_strdup_printf("@%s ", sender); gtk_text_buffer_insert_at_cursor(gtkconv->entry_buffer, recipient, -1); gtk_widget_grab_focus(GTK_WIDGET(gtkconv->entry)); g_free(recipient); reply_to_msgid = msgid; /* xxx */ return TRUE; } else if(strstr(cmd, "fav-twitter")) { idstr = g_hash_table_lookup(params, "id"); fav_with_api(strtoull(idstr, NULL, 10)); return TRUE; } else if(strstr(cmd, "retweet-twitter")) { gchar *msg0; sender = g_hash_table_lookup(params, "user"); idstr = g_hash_table_lookup(params, "id"); msg0 = g_hash_table_lookup(params, "msg"); msg = g_uri_unescape_string(msg0, NULL); if(idstr) msgid = strtoull(idstr, NULL, 10); /* find conv */ conv = purple_find_conversation_with_account( PURPLE_CONV_TYPE_ANY, "[email protected]", account_for_twitter); /* xxx */ twitter_debug("conv = %p\n", conv); gtkconv = PIDGIN_CONVERSATION(conv); twitter_debug("sender = %s, id = %llu\n", sender, (unsigned long long)msgid); recipient = g_strdup_printf("RT @%s: %s", sender, msg); g_free(msg); gtk_text_buffer_insert_at_cursor(gtkconv->entry_buffer, recipient, -1); GtkTextIter iter; gtk_text_buffer_get_start_iter(gtkconv->entry_buffer, &iter); gtk_text_buffer_place_cursor(gtkconv->entry_buffer, &iter); gtk_widget_grab_focus(GTK_WIDGET(gtkconv->entry)); g_free(recipient); return TRUE; } return FALSE; } gchar * twitter_make_link_string(gchar **str) { GMatchInfo *match_info = NULL; gchar *boddy0 = NULL, *boddy = NULL; gchar *newstr = NULL, *linkstr = NULL; gchar *match = NULL; gchar *idstr = NULL, *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); boddy0 = g_uri_escape_string(boddy, " !$()*,;:@/?#[]", TRUE); g_free(boddy); boddy = boddy0; /* sender */ g_regex_match(regp[SENDER], *str, 0, &match_info); if(g_match_info_matches(match_info)) { user = g_match_info_fetch(match_info, 2); twitter_debug("user = %s\n", user); g_match_info_free(match_info); match_info = NULL; } /* link string */ g_regex_match(regp[MESSAGE_ID], *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, user, boddy); /* Retweet */ twitter_debug("linkstr = %s\n", linkstr); newstr = g_regex_replace(regp[MESSAGE_ID], *str, -1, 0, "", 0, NULL); twitter_debug("newstr = %s\n", newstr); g_free(*str); *str = newstr; g_free(match); match = NULL; g_match_info_free(match_info); match_info = NULL; } g_free(user); g_free(boddy); return linkstr; }