Mercurial > pidgin-twitter
view util.c @ 352:f60ee22c1ac8
shows a silly confirmation dialog before posting retweet. it is only for gathering feedbacks.
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Fri, 16 Apr 2010 12:22:30 +0900 |
parents | 059e962ee26a |
children | 29084c253e68 |
line wrap: on
line source
#include "pidgin-twitter.h" #include <gtkutils.h> #include <pidginstock.h> #include <gtkblist.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); /* 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, "twitter@twitter.com") && 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, "wassr-bot@wassr.jp") && 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, "update@identi.ca") && 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, "bot@jisko.net") && 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, "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) { 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; } void cancel_retweet(void *data) { /* do nothing */ } void do_retweet(void *data) { guint64 msgid = *(guint64 *)data; twitter_debug("msgid=%llu\n", msgid); retweet_with_api(msgid); } 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, "twitter@twitter.com", 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; 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")) { GtkWidget *retweet_dialog; static guint64 retweet_msgid = 0; idstr = g_hash_table_lookup(params, "id"); retweet_msgid = strtoull(idstr, NULL, 10); twitter_debug("retweet_msgid=%llu\n", retweet_msgid); retweet_dialog = pidgin_make_mini_dialog( NULL, PIDGIN_STOCK_DIALOG_INFO, "Are you sure to retweet this message?", NULL, /* secondary */ (void *)&retweet_msgid, /* user data */ "Cancel", PURPLE_CALLBACK(cancel_retweet), "Retweet", PURPLE_CALLBACK(do_retweet), NULL); pidgin_blist_add_alert(retweet_dialog); return TRUE; } else if(strstr(cmd, "quotetweet-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, "twitter@twitter.com", 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("QT @%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); reply_to_msgid = msgid; return TRUE; } return FALSE; } gchar * twitter_rip_link_string(gchar **str) { GMatchInfo *match_info = NULL; gchar *body0 = NULL, *body = NULL; gchar *newstr = NULL, *linkstr = NULL; gchar *user = NULL; twitter_debug("called\n"); /* 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); body0 = g_uri_escape_string(body, " !$()*,;:@/?#[]", TRUE); g_free(body); body = body0; /* 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[PTTAG_TWITTER], *str, 0, &match_info); if(match_info) { 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); if(in_reply_to_status_id_str) 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[PTTAG_TWITTER], *str, -1, 0, "", 0, NULL); twitter_debug("newstr = %s\n", newstr); g_free(*str); *str = newstr; g_free(msg_id_str); msg_id_str = NULL; g_match_info_free(match_info); match_info = NULL; } g_free(user); g_free(body); return linkstr; }