view pidgin-twitter.c @ 0:2413369d1b01

initial import
author Yoshiki Yazawa <yaz@cc.rim.or.jp>
date Tue, 29 Apr 2008 14:35:36 +0900
parents
children 799955af57ad
line wrap: on
line source

/*
 * Pidgin-Twitter plugin.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */
#define PURPLE_PLUGINS 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

#include "gtkplugin.h"
#include "util.h"
#include "debug.h"
#include "connection.h"
#include "version.h"

extern gchar *botch_utf(const gchar *msg, gsize len, gsize *newlen) __attribute__ ((weak));

#define PIDGINTWITTER_PLUGIN_ID	"pidgin_twitter"
#define OPT_PIDGINTWITTER 		"/plugins/pidgin_twitter"
#define OPT_TRANSLATE	OPT_PIDGINTWITTER "/translate"

#define twitter_debug(fmt, ...)	purple_debug(PURPLE_DEBUG_INFO, "Pidgin-Twitter", \
					fmt, ## __VA_ARGS__);
#define twitter_error(fmt, ...)	purple_debug(PURPLE_DEBUG_ERROR, "Pidgin-Twitter", \
					fmt, ## __VA_ARGS__);

/* globals */
static GRegex *preg;


static void
do_translate(char *str)
{
    int i;
    int rc;
    int ovector[30];
    int soffset = 0;    //start offset in str
    int boffset = 0;    //tail of buf
    int len = strlen(str);
    char *buf = calloc(1, strlen(str) + 1024); /* XXX should be reasonable size */

    do {
        rc = pcre_exec(
            re,             /* result of pcre_compile() */
            NULL,           /* we didn't study the pattern */
            str,            /* the subject string */
            len,            /* the length of the subject string */
            soffset,            /* start at offset 0 in the subject */
            0,              /* default options */
            ovector,        /* vector of integers for substring information */
            30);            /* number of elements (NOT size in bytes) */

        printf("rc=%d\n",rc);
        if(rc <= 0) {
            printf("no match\n");
            break;
        } else {
            char *sub;

            /* copy until precedings */
            strncpy(buf+boffset, str+soffset, ovector[0]-soffset);
            boffset = boffset + ovector[0]-soffset;

            sub = (char *)malloc(128);
            /* concatenate replacement substr */
            snprintf(sub, 128, "<a href=\"http://twitter.com/%s\"</a>", str+ovector[0]+1); //+1 is to strip preceding @.
            strncat(buf, sub, strlen(sub));
            boffset += strlen(sub);
            free(sub);

            soffset = ovector[1];
        }
    } while(soffset < len);
}


static void
translate(PurpleAccount *account, char *sender, char *buffer,
          PurpleConversation *conv, PurpleMessageFlags flags, void *data)
{
    const gchar *proto;

    /* check if the message is from twitter? */
    proto = purple_account_get_protocol_id(account);
    if (!g_utf8_collate(proto, "xmpp") && 
        !g_utf8_collate(sender, "twitter@twitter.com") &&
        purple_prefs_get_bool(OPT_TRANSLATE)) {

        /* translate */
        do_translate(buffer);

    }

}

static gboolean
load_plugin(PurplePlugin *plugin)
{

	/* connect to signing-off signal */
	purple_signal_connect(purple_connections_get_handle(), "received-im-msg",
                          plugin, PURPLE_CALLBACK(translate), NULL);

	return TRUE;
}

static gboolean
unload_plugin(PurplePlugin *plugin)
{
	aud_debug("pidgin-twitter unload called\n");

    g_regex_unref(preg);
    preg = NULL;
	return TRUE;
}

static PurplePluginPrefFrame *
get_plugin_pref_frame(PurplePlugin *plugin)
{
	PurplePluginPref *pref;
	PurplePluginPrefFrame *frame = purple_plugin_pref_frame_new();

	/* create gtk elements for the plugin preferences */
	pref = purple_plugin_pref_new_with_label("Pidgin-Twitter Configuration");
	purple_plugin_pref_frame_add(frame, pref);

	pref = purple_plugin_pref_new_with_name_and_label(OPT_TRANSLATE,
			"Translate @username to link");
	purple_plugin_pref_frame_add(frame, pref);

	return frame;
}

static PurplePluginUiInfo pref_info =
{
	get_plugin_pref_frame
};

static PurplePluginInfo info =
{
	PURPLE_PLUGIN_MAGIC,
	PURPLE_MAJOR_VERSION,
	PURPLE_MINOR_VERSION,
	PURPLE_PLUGIN_STANDARD,		/**< type	*/
    NULL,				        /**< ui_req	*/
	0,						    /**< flags	*/
	NULL,						/**< deps	*/
	PURPLE_PRIORITY_DEFAULT,	/**< priority	*/
	PIDGINAUD_PLUGIN_ID,		/**< id		*/
	"Pidgin-Twitter",			/**< name	*/
	"0.1.0",					/**< version	*/
	"replaces @someone in incoming message with link to someone", /**  summary	*/
	"replaces @someone in incoming message with link to someone", /**  desc	*/
	"Yoshiki Yazawa (yaz@honeyplanet.jp)", /**< author	*/
	"http://www.honeyplanet.jp/",	/**< homepage	*/
	load_plugin,					/**< load	*/
	unload_plugin,					/**< unload	*/
	NULL,						/**< destroy	*/
	NULL,						/**< ui_info	*/
	NULL,						/**< extra_info	*/
	&pref_info,					/**< pref info	*/
	NULL
};

static void
init_plugin(PurplePlugin *plugin)
{
	g_type_init();

	/* add plugin preferences */
	purple_prefs_add_none(OPT_PIDGINTWITTER);
	purple_prefs_add_bool(OPT_TRANSLATE, TRUE);

    preg = g_regex_new("@[A-Za-z0-9-_]+", 0, 0, NULL);
}

PURPLE_INIT_PLUGIN(pidgin_twitter, init_plugin, info)