diff libpurple/protocols/yahoo/yahoo.c @ 15623:71af5b6209d5

uri-handler support for AIM/ICQ, Yahoo and MSN
author Daniel Atallah <daniel.atallah@gmail.com>
date Sun, 11 Feb 2007 21:58:50 +0000
parents 2193394fd427
children 12778e2f7282
line wrap: on
line diff
--- a/libpurple/protocols/yahoo/yahoo.c	Sun Feb 11 19:34:43 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo.c	Sun Feb 11 21:58:50 2007 +0000
@@ -28,6 +28,7 @@
 #include "blist.h"
 #include "cipher.h"
 #include "cmds.h"
+#include "core.h"
 #include "debug.h"
 #include "notify.h"
 #include "privacy.h"
@@ -3794,6 +3795,107 @@
 	                 _("doodle: Request user to start a Doodle session"), NULL);
 }
 
+static GaimAccount *find_acct(const char *prpl, const char *acct_id)
+{
+	GaimAccount *acct = NULL;
+
+	/* If we have a specific acct, use it */
+	if (acct_id) {
+		acct = gaim_accounts_find(acct_id, prpl);
+		if (acct && !gaim_account_is_connected(acct))
+			acct = NULL;
+	} else { /* Otherwise find an active account for the protocol */
+		GList *l = gaim_accounts_get_all();
+		while (l) {
+			if (!strcmp(prpl, gaim_account_get_protocol_id(l->data))
+					&& gaim_account_is_connected(l->data)) {
+				acct = l->data;
+				break;
+			}
+			l = l->next;
+		}
+	}
+
+	return acct;
+}
+
+/* This may not be the best way to do this, but we find the first key w/o a value
+ * and assume it is the screenname */
+static void yahoo_find_uri_novalue_param(gpointer key, gpointer value, gpointer user_data)
+{
+	char **retval = user_data;
+
+	if (value == NULL && *retval == NULL) {
+		*retval = key;
+	}
+}
+
+static gboolean yahoo_uri_handler(const char *proto, const char *cmd, GHashTable *params)
+{
+	char *acct_id = g_hash_table_lookup(params, "account");
+	GaimAccount *acct;
+
+	if (g_ascii_strcasecmp(proto, "ymsgr"))
+		return FALSE;
+
+	acct = find_acct(gaim_plugin_get_id(my_protocol), acct_id);
+
+	if (!acct)
+		return FALSE;
+
+	/* ymsgr:SendIM?screename&m=The+Message */
+	if (!g_ascii_strcasecmp(cmd, "SendIM")) {
+		char *sname = NULL;
+		g_hash_table_foreach(params, yahoo_find_uri_novalue_param, &sname);
+		if (sname) {
+			char *message = g_hash_table_lookup(params, "m");
+
+			GaimConversation *conv = gaim_find_conversation_with_account(
+				GAIM_CONV_TYPE_IM, sname, acct);
+			if (conv == NULL)
+				conv = gaim_conversation_new(GAIM_CONV_TYPE_IM, acct, sname);
+			gaim_conversation_present(conv);
+
+			if (message) {
+				/* Spaces are encoded as '+' */
+				g_strdelimit(message, "+", ' ');
+				gaim_conv_im_send(GAIM_CONV_IM(conv), message);
+			}
+		}
+		/*else
+			**If pidgindialogs_im() was in the core, we could use it here.
+			 * It is all gaim_request_* based, but I'm not sure it really belongs in the core
+			pidgindialogs_im();*/
+
+		return TRUE;
+	}
+	/* ymsgr:Chat?roomname */
+	else if (!g_ascii_strcasecmp(cmd, "Chat")) {
+		char *rname = NULL;
+		g_hash_table_foreach(params, yahoo_find_uri_novalue_param, &rname);
+		if (rname) {
+			/* This is somewhat hacky, but the params aren't useful after this command */
+			g_hash_table_insert(params, g_strdup("room"), g_strdup(rname));
+			g_hash_table_insert(params, g_strdup("type"), g_strdup("Chat"));
+			serv_join_chat(gaim_account_get_connection(acct), params);
+		}
+		/*else
+			** Same as above (except that this would have to be re-written using gaim_request_*)
+			pidgin_blist_joinchat_show(); */
+
+		return TRUE;
+	}
+	/* ymsgr:AddFriend?name */
+	else if (!g_ascii_strcasecmp(cmd, "AddFriend")) {
+		char *name = NULL;
+		g_hash_table_foreach(params, yahoo_find_uri_novalue_param, &name);
+		gaim_blist_request_add_buddy(acct, name, NULL, NULL);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
 static GaimWhiteboardPrplOps yahoo_whiteboard_prpl_ops =
 {
 	yahoo_doodle_start,
@@ -3950,6 +4052,9 @@
 	my_protocol = plugin;
 	yahoogaim_register_commands();
 	yahoo_init_colorht();
+
+	gaim_signal_connect(gaim_get_core(), "uri-handler", plugin,
+		GAIM_CALLBACK(yahoo_uri_handler), NULL);
 }
 
 GAIM_INIT_PLUGIN(yahoo, init_plugin, info);