view pidgin-twitter.c @ 4:9ac8cea32513

now distclean erases aclocal.m4 too
author Yoshiki Yazawa <yaz@cc.rim.or.jp>
date Wed, 30 Apr 2008 15:47:33 +0900
parents 53ee194b5ff5
children 6ac1867d7e8e
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"
#include "sound.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 OPT_PLAYSOUND	OPT_PIDGINTWITTER "/playsound"
#define OPT_USERLIST	OPT_PIDGINTWITTER "/userlist"
#define TWITTER_FORMAT  "@<a href='http://twitter.com/%s'>%s</a>"

#define twitter_debug(fmt, ...)	purple_debug(PURPLE_DEBUG_INFO, PIDGINTWITTER_PLUGIN_ID, \
					fmt, ## __VA_ARGS__);
#define twitter_error(fmt, ...)	purple_debug(PURPLE_DEBUG_ERROR, PIDGINTWITTER_PLUGIN_ID, \
					fmt, ## __VA_ARGS__);

/* globals */
static GRegex *preg;

static gboolean
eval(const GMatchInfo *match_info, GString *result, gpointer user_data)
{
    gchar sub[128];
    gchar *match = g_match_info_fetch(match_info, 0);

    snprintf(sub, 128, TWITTER_FORMAT,
             match + 1, // +1 is to strip preceding '@'.
             match + 1);
	twitter_debug("sub = %s\n", sub);
    g_string_append(result, sub);
    g_free(match);

    return FALSE;
}

static void
translate(gchar **str)
{
    gchar *newstr;

    twitter_debug("*str = %s\n", *str);

    newstr = g_regex_replace_eval(
        preg,     // compiled regex
        *str,     // subject string
        -1,       // length of the subject string
        0,        // start position
        0,        // match options
        eval,     // function to call for each match
        NULL,     // user data (not used)
        NULL);    // error handler

    twitter_debug("newstr = %s\n", newstr);

    g_free(*str);
    *str = newstr;
}

static void
playsound(gchar **str)
{
    GMatchInfo *match_info;
    GList *list, *lp;

    list = purple_prefs_get_string_list(OPT_USERLIST);

    g_regex_match (preg, *str, 0, &match_info);
    while (g_match_info_matches (match_info))
    {
        gchar *user = g_match_info_fetch (match_info, 0);
        twitter_debug("user = %s\n", user);

        for(lp = list; lp; lp = g_list_next(lp)) {
            twitter_debug("lp->data = %s\n", (char *)lp->data);
            if(!strcmp(user, lp->data) || !strcmp(user+1, lp->data)) {
                twitter_debug("match. play sound\n");
                purple_sound_play_event(PURPLE_SOUND_POUNCE_DEFAULT, NULL);
            }
        }

        g_free (user);
        g_match_info_next (match_info, NULL);
    }

    g_match_info_free (match_info);
}


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

    /* check if the message is from twitter */
    proto = purple_account_get_protocol_id(account);
    twitter_debug("proto = %s\n", proto);
    twitter_debug("sender = %s\n", sender);

    if (!strcmp(proto, "prpl-jabber") &&
        !strcmp(sender, "twitter@twitter.com")) {
        if(purple_prefs_get_bool(OPT_PLAYSOUND)) {
            /* playsound */
            playsound(buffer);
        }
        if(purple_prefs_get_bool(OPT_TRANSLATE)) {
            /* translate */
            translate(buffer);
        }
    }
    return FALSE;
}

static gboolean
load_plugin(PurplePlugin *plugin)
{
	/* connect to signal */
	purple_signal_connect(purple_conversations_get_handle(), "writing-im-msg",
						plugin, PURPLE_CALLBACK(process_im_cb), NULL);

	return TRUE;
}

static gboolean
unload_plugin(PurplePlugin *plugin)
{
	twitter_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 the link to the user");
	purple_plugin_pref_frame_add(frame, pref);

	pref = purple_plugin_pref_new_with_name_and_label(OPT_PLAYSOUND,
			"Play sound if a reply to listed users arrives");
	purple_plugin_pref_frame_add(frame, pref);

    // xxx add pref field for OPT_USERLIST (gtk packing is needed) --yaz

	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	*/
	PIDGINTWITTER_PLUGIN_ID,    /**< id		*/
	"Pidgin-Twitter",			/**< name	*/
	"0.1.0",					/**< version	*/
	"replaces @username in a message with link to the user", /**  summary	*/
	"replaces @username in a message with link to the user", /**  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)
{
    GList *list;

	g_type_init();
    list = g_list_alloc();

	/* add plugin preferences */
	purple_prefs_add_none(OPT_PIDGINTWITTER);
	purple_prefs_add_bool(OPT_TRANSLATE, TRUE);
	purple_prefs_add_bool(OPT_PLAYSOUND, TRUE);
	purple_prefs_add_string_list(OPT_USERLIST, list);

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

}

PURPLE_INIT_PLUGIN(pidgin_twitter, init_plugin, info)