changeset 28309:7eaf2561b6dd

Extend the TinyURL plugin. TinyURL has its own notify_uri function to show a shorter URL. This will help with opening inboxes on yahoo/msn etc. In a conversation, long URLs in a system message are also tinyurl-ed. This will help with, for example, Yahoo chat-room captchas.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Wed, 30 Sep 2009 15:20:25 +0000
parents a501f14e6961
children a45d9f5fea69 f22eadbdc5d1
files ChangeLog finch/plugins/gnttinyurl.c
diffstat 2 files changed, 109 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Sep 29 16:19:47 2009 +0000
+++ b/ChangeLog	Wed Sep 30 15:20:25 2009 +0000
@@ -13,6 +13,11 @@
 	* Fix a crash when performing DNS queries on Unixes that use the
 	  blocking DNS lookups.  (Brian Lu)
 
+	Finch:
+	* The TinyURL plugin now creates shorter URLs for long non-conversation
+	  URLs, e.g. URLs to open Inbox in Yahoo/MSN protocols, or the Yahoo
+	  Captcha when joining chat rooms.
+
 version 2.6.2 (09/05/2009):
 	libpurple:
 	* Fix --disable-avahi to actually disable it in configure, as opposed
--- a/finch/plugins/gnttinyurl.c	Tue Sep 29 16:19:47 2009 +0000
+++ b/finch/plugins/gnttinyurl.c	Wed Sep 30 15:20:25 2009 +0000
@@ -41,7 +41,10 @@
 #include <gntconv.h>
 
 #include <gntplugin.h>
+
+#include <gntlabel.h>
 #include <gnttextview.h>
+#include <gntwindow.h>
 
 static int tag_num = 0;
 
@@ -52,6 +55,8 @@
 	int num;
 } CbInfo;
 
+static void process_urls(PurpleConversation *conv, GList *urls);
+
 /* 3 functions from util.c */
 static gboolean
 badchar(char c)
@@ -83,7 +88,8 @@
 	return FALSE;
 }
 
-static GList *extract_urls(char *text) {
+static GList *extract_urls(const char *text)
+{
 	const char *t, *c, *q = NULL;
 	char *url_buf;
 	GList *ret = NULL;
@@ -207,10 +213,12 @@
 			gnt_text_view_tag_change(tv, data->tag, str, FALSE);
 			g_free(str);
 			g_free(data->tag);
+			g_free(data);
 			return;
 		}
 	}
 	g_free(data->tag);
+	g_free(data);
 	purple_debug_info("TinyURL", "Conversation no longer exists... :(\n");
 }
 
@@ -219,13 +227,14 @@
 	g_free(data);
 }
 
-static gboolean receiving_msg(PurpleAccount *account, char **sender, char **message,
-				PurpleConversation *conv, PurpleMessageFlags *flags) {
+static gboolean writing_msg(PurpleAccount *account, char *sender, char **message,
+				PurpleConversation *conv, PurpleMessageFlags flags)
+{
 	GString *t;
 	GList *iter, *urls;
 	int c = 0;
 
-	if (!(*flags & PURPLE_MESSAGE_RECV) || *flags & PURPLE_MESSAGE_INVISIBLE)
+	if ((flags & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_INVISIBLE)))
 		return FALSE;
 
 	urls = purple_conversation_get_data(conv, "TinyURLs");
@@ -270,22 +279,33 @@
 	*message = t->str;
 	g_string_free(t, FALSE);
 	if (conv == NULL)
-		conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, *sender);
+		conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender);
 	purple_conversation_set_data(conv, "TinyURLs", urls);
 	return FALSE;
 }
 
-static void received_msg(PurpleAccount *account, char *sender, char *message,
-				PurpleConversation *conv, PurpleMessageFlags flags) {
+static void wrote_msg(PurpleAccount *account, char *sender, char *message,
+				PurpleConversation *conv, PurpleMessageFlags flags)
+{
+	GList *urls;
+
+	urls = purple_conversation_get_data(conv, "TinyURLs");
+	if ((flags & PURPLE_MESSAGE_SEND) || urls == NULL)
+		return;
+
+	process_urls(conv, urls);
+	purple_conversation_set_data(conv, "TinyURLs", NULL);
+}
+
+/* Frees 'urls' */
+static void
+process_urls(PurpleConversation *conv, GList *urls)
+{
+	GList *iter;
 	int c;
-	GList *urls, *iter;
 	FinchConv *fconv = FINCH_CONV(conv);
 	GntTextView *tv = GNT_TEXT_VIEW(fconv->tv);
 
-	urls = purple_conversation_get_data(conv, "TinyURLs");
-	if (!(flags & PURPLE_MESSAGE_RECV) || urls == NULL)
-		return;
-
 	for (iter = urls, c = 0; iter; iter = iter->next) {
 		int i;
 		CbInfo *cbdata;
@@ -312,7 +332,6 @@
 		g_free(url);
 	}
 	g_list_free(urls);
-	purple_conversation_set_data(conv, "TinyURLs", NULL);
 }
 
 static void
@@ -324,20 +343,75 @@
 	g_list_free(urls);
 }
 
+static void tinyurl_notify_fetch_cb(PurpleUtilFetchUrlData *urldata, gpointer cbdata,
+		const gchar *urltext, gsize len, const gchar *error)
+{
+	GntWidget *win = cbdata;
+	GntWidget *label = g_object_get_data(G_OBJECT(win), "info-widget");
+	char *message;
+
+	message = g_strdup_printf(_("TinyURL for above: %s"), urltext);
+	gnt_label_set_text(GNT_LABEL(label), message);
+	g_free(message);
+
+	g_signal_handlers_disconnect_matched(G_OBJECT(win), G_SIGNAL_MATCH_FUNC,
+			0, 0, NULL,
+			G_CALLBACK(purple_util_fetch_url_cancel), NULL);
+}
+
+static void *
+tinyurl_notify_uri(const char *uri)
+{
+	char *fullurl = NULL;
+	GntWidget *win;
+	PurpleUtilFetchUrlData *urlcb;
+
+	/* XXX: The following expects that finch_notify_message gets called. This
+	 * may not always happen, e.g. when another plugin sets its own
+	 * notify_message. So tread carefully. */
+	win = purple_notify_message(NULL, PURPLE_NOTIFY_URI, _("URI"), uri,
+			_("Please wait while TinyURL fetches a shorter URL ..."), NULL, NULL);
+	if (!GNT_IS_WINDOW(win) || !g_object_get_data(G_OBJECT(win), "info-widget"))
+		return win;
+
+	if (g_ascii_strncasecmp(uri, "http://", 7) && g_ascii_strncasecmp(uri, "https://", 8)) {
+		fullurl = g_strdup_printf("%shttp%%3A%%2F%%2F%s",
+				purple_prefs_get_string(PREF_URL), purple_url_encode(uri));
+	} else {
+		fullurl = g_strdup_printf("%s%s", purple_prefs_get_string(PREF_URL),
+				purple_url_encode(uri));
+	}
+
+	/* Store the return value of _fetch_url and destroy that when win is
+	   destroyed, so that the callback for _fetch_url does not try to molest a
+	   non-existent window */
+	urlcb = purple_util_fetch_url(fullurl, TRUE, "finch", FALSE, tinyurl_notify_fetch_cb, win);
+	g_free(fullurl);
+	g_signal_connect_swapped(G_OBJECT(win), "destroy",
+			G_CALLBACK(purple_util_fetch_url_cancel), urlcb);
+
+	return win;
+}
+
 static gboolean
-plugin_load(PurplePlugin *plugin) {
+plugin_load(PurplePlugin *plugin)
+{
+	PurpleNotifyUiOps *ops = purple_notify_get_ui_ops();
+	plugin->extra = ops->notify_uri;
+	ops->notify_uri = tinyurl_notify_uri;
+
 	purple_signal_connect(purple_conversations_get_handle(),
 			"wrote-im-msg",
-			plugin, PURPLE_CALLBACK(received_msg), NULL);
+			plugin, PURPLE_CALLBACK(wrote_msg), NULL);
 	purple_signal_connect(purple_conversations_get_handle(),
 			"wrote-chat-msg",
-			plugin, PURPLE_CALLBACK(received_msg), NULL);
+			plugin, PURPLE_CALLBACK(wrote_msg), NULL);
 	purple_signal_connect(purple_conversations_get_handle(),
-			"receiving-im-msg",
-			plugin, PURPLE_CALLBACK(receiving_msg), NULL);
+			"writing-im-msg",
+			plugin, PURPLE_CALLBACK(writing_msg), NULL);
 	purple_signal_connect(purple_conversations_get_handle(),
-			"receiving-chat-msg",
-			plugin, PURPLE_CALLBACK(receiving_msg), NULL);
+			"writing-chat-msg",
+			plugin, PURPLE_CALLBACK(writing_msg), NULL);
 	purple_signal_connect(purple_conversations_get_handle(),
 			"deleting-conversation",
 			plugin, PURPLE_CALLBACK(free_conv_urls), NULL);
@@ -345,6 +419,15 @@
 	return TRUE;
 }
 
+static gboolean
+plugin_unload(PurplePlugin *plugin)
+{
+	PurpleNotifyUiOps *ops = purple_notify_get_ui_ops();
+	if (ops->notify_uri == tinyurl_notify_uri)
+		ops->notify_uri = plugin->extra;
+	return TRUE;
+}
+
 static PurplePluginPrefFrame *
 get_plugin_pref_frame(PurplePlugin *plugin) {
 
@@ -394,7 +477,7 @@
 	"Richard Nelson <wabz@whatsbeef.net>",
 	PURPLE_WEBSITE,
 	plugin_load,
-	NULL,
+	plugin_unload,
 	NULL,
 	NULL,
 	NULL,