Mercurial > pidgin-twitter
view pidgin-twitter.c @ 29:ea1aef67c97d
Added tag 0.5.1 for changeset 73e817be3267
author | Yoshiki Yazawa <yaz@cc.rim.or.jp> |
---|---|
date | Mon, 05 May 2008 23:32:39 +0900 |
parents | 73e817be3267 |
children | e740ceed9337 |
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" #define RECIPIENT 0 #define SENDER 1 #define COMMAND 2 #define PSEUDO 3 #define PIDGINTWITTER_PLUGIN_ID "pidgin_twitter" #define OPT_PIDGINTWITTER "/plugins/pidgin_twitter" #define OPT_TRANSLATE_RECIPIENT OPT_PIDGINTWITTER "/translate_recipient" #define OPT_TRANSLATE_SENDER OPT_PIDGINTWITTER "/translate_sender" #define OPT_PLAYSOUND_RECIPIENT OPT_PIDGINTWITTER "/playsound_recipient" #define OPT_PLAYSOUND_SENDER OPT_PIDGINTWITTER "/playsound_sender" #define OPT_SOUNDID_RECIPIENT OPT_PIDGINTWITTER "/soundid_recipient" #define OPT_SOUNDID_SENDER OPT_PIDGINTWITTER "/soundid_sender" #define OPT_ESCAPE_PSEUDO OPT_PIDGINTWITTER "/escape_pseudo" #define OPT_USERLIST_RECIPIENT OPT_PIDGINTWITTER "/userlist_recipient" #define OPT_USERLIST_SENDER OPT_PIDGINTWITTER "/userlist_sender" #define RECIPIENT_FORMAT "@<a href='http://twitter.com/%s'>%s</a>" #define SENDER_FORMAT "<a href='http://twitter.com/%s'>%s</a>: " #define DEFAULT_LIST "(list of users: separated with ' ,:;')" #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, \ /* globals */ static GRegex *regp[4]; static 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\n", *str); twitter_debug("newstr = %s\n", newstr); g_free(*str); *str = newstr; } } static gboolean sending_im_cb(PurpleAccount * account, char *recipient, char **buffer, void *data) { const gchar *proto; /* check if the message is from twitter */ proto = purple_account_get_protocol_id(account); twitter_debug("sending_im_cb\n"); twitter_debug("proto = %s\n", proto); twitter_debug("recipient = %s\n", recipient); if(!strcmp(proto, "prpl-jabber") && !strcmp(recipient, "twitter@twitter.com")) { /* escape */ if(purple_prefs_get_bool(OPT_ESCAPE_PSEUDO)) { escape(buffer); } } return FALSE; } static gboolean eval(const GMatchInfo * match_info, GString * result, gpointer user_data) { gchar sub[128]; gchar *match = g_match_info_fetch(match_info, 1); int which = *(int *)user_data; snprintf(sub, 128, which ? SENDER_FORMAT : RECIPIENT_FORMAT, match, match); twitter_debug("sub = %s\n", sub); g_string_append(result, sub); g_free(match); return FALSE; } static void translate(gchar **str, int which) { gchar *newstr; twitter_debug("*str = %s\n", *str); newstr = g_regex_replace_eval(regp[which], // compiled regex *str, // subject string -1, // length of the subject string 0, // start position 0, // match options eval, // function to call for each match &which, // user data NULL); // error handler twitter_debug("newstr = %s\n", newstr); g_free(*str); *str = newstr; } static void playsound(gchar **str, int which) { GMatchInfo *match_info; const gchar *list; gchar **candidates = NULL, **candidate = NULL; list = purple_prefs_get_string(which ? OPT_USERLIST_SENDER : OPT_USERLIST_RECIPIENT); g_return_if_fail(list != NULL); if(!strcmp(list, DEFAULT_LIST)) return; candidates = g_strsplit_set(list, " ,:;", 0); g_return_if_fail(candidates != NULL); g_regex_match(regp[which], *str, 0, &match_info); while(g_match_info_matches(match_info)) { gchar *user = g_match_info_fetch(match_info, 1); twitter_debug("user = %s\n", user); for(candidate = candidates; *candidate ; candidate++) { if(!strcmp(*candidate, "")) continue; twitter_debug("candidate = %s\n", *candidate); if(!strcmp(user, *candidate)) { twitter_debug("match. play sound\n"); purple_sound_play_event( purple_prefs_get_int(which ? OPT_SOUNDID_SENDER : OPT_SOUNDID_RECIPIENT), NULL); break; } } g_free(user); g_match_info_next(match_info, NULL); } g_strfreev(candidates); g_match_info_free(match_info); } static gboolean writing_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("writing_im_cb\n"); twitter_debug("proto = %s\n", proto); twitter_debug("sender = %s\n", sender); if(!strcmp(sender, "twitter@twitter.com") && !strcmp(proto, "prpl-jabber")) { /* playsound */ if(purple_prefs_get_bool(OPT_PLAYSOUND_SENDER)) { playsound(buffer, SENDER); } if(purple_prefs_get_bool(OPT_PLAYSOUND_RECIPIENT)) { playsound(buffer, RECIPIENT); } /* translate */ if(purple_prefs_get_bool(OPT_TRANSLATE_SENDER)) { translate(buffer, SENDER); } if(purple_prefs_get_bool(OPT_TRANSLATE_RECIPIENT)) { translate(buffer, RECIPIENT); } /* escape */ if(purple_prefs_get_bool(OPT_ESCAPE_PSEUDO)) { escape(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(writing_im_cb), NULL); purple_signal_connect(purple_conversations_get_handle(), "sending-im-msg", plugin, PURPLE_CALLBACK(sending_im_cb), NULL); /* compile regex */ regp[RECIPIENT] = g_regex_new("@([A-Za-z0-9_]+)", 0, 0, NULL); regp[SENDER] = g_regex_new("<body>([A-Za-z0-9_]+): ", 0, 0, NULL); regp[COMMAND] = g_regex_new( "^(?:\\s*)([dDfFgGlLmMnNtTwW]{1}\\s+[A-Za-z0-9_]+\\Z)", G_REGEX_RAW, 0, NULL); regp[PSEUDO] = g_regex_new( "^\\s*(?:[\"#$%&'()*+,\\-./:;<=>?\\[\\\\\\]_`{|}~]|[^\\s\\x21-\\x7E])*([dDfFgGlLmMnNtTwW]{1})(?:\\Z|\\s+|[^\\x21-\\x7E]+\\Z)", G_REGEX_RAW, 0, NULL); return TRUE; } static gboolean unload_plugin(PurplePlugin * plugin) { twitter_debug("pidgin-twitter unload called\n"); g_regex_unref(regp[RECIPIENT]); g_regex_unref(regp[SENDER]); g_regex_unref(regp[COMMAND]); g_regex_unref(regp[PSEUDO]); return TRUE; } static PurplePluginPrefFrame * get_plugin_pref_frame(PurplePlugin * plugin) { /* create gtk elements for the plugin preferences */ PurplePluginPref *pref; PurplePluginPrefFrame *frame = purple_plugin_pref_frame_new(); /* frame title */ pref = purple_plugin_pref_new_with_label("Pidgin-Twitter Configuration"); purple_plugin_pref_frame_add(frame, pref); /* translation settings */ pref = purple_plugin_pref_new_with_name_and_label( OPT_TRANSLATE_RECIPIENT, "Translate @username to link"); purple_plugin_pref_frame_add(frame, pref); pref = purple_plugin_pref_new_with_name_and_label( OPT_TRANSLATE_SENDER, "Translate sender name to link"); purple_plugin_pref_frame_add(frame, pref); /* escape pseudo command settings */ pref = purple_plugin_pref_new_with_name_and_label( OPT_ESCAPE_PSEUDO, "Escape pseudo command string"); purple_plugin_pref_frame_add(frame, pref); /* sound settings for recipient */ pref = purple_plugin_pref_new_with_name_and_label( OPT_PLAYSOUND_RECIPIENT, "Play sound on a reply to the user in the recipient list"); purple_plugin_pref_frame_add(frame, pref); /* recipient list */ pref = purple_plugin_pref_new_with_name_and_label( OPT_USERLIST_RECIPIENT, "Recipient List"); purple_plugin_pref_frame_add(frame, pref); /* sound id selector */ pref = purple_plugin_pref_new_with_name_and_label(OPT_SOUNDID_RECIPIENT, "Recipient Sound"); purple_plugin_pref_set_type(pref, PURPLE_PLUGIN_PREF_CHOICE); purple_plugin_pref_add_choice(pref, "Arrive", GINT_TO_POINTER(0)); purple_plugin_pref_add_choice(pref, "Leave", GINT_TO_POINTER(1)); purple_plugin_pref_add_choice(pref, "Receive", GINT_TO_POINTER(2)); purple_plugin_pref_add_choice(pref, "Fist Receive", GINT_TO_POINTER(3)); purple_plugin_pref_add_choice(pref, "Send", GINT_TO_POINTER(4)); purple_plugin_pref_add_choice(pref, "Chat Join", GINT_TO_POINTER(5)); purple_plugin_pref_add_choice(pref, "Chat Leave", GINT_TO_POINTER(6)); purple_plugin_pref_add_choice(pref, "Chat You Say", GINT_TO_POINTER(7)); purple_plugin_pref_add_choice(pref, "Chat Someone Say", GINT_TO_POINTER(8)); purple_plugin_pref_add_choice(pref, "Pounce Default", GINT_TO_POINTER(9)); purple_plugin_pref_add_choice(pref, "Chat Nick Said", GINT_TO_POINTER(10)); purple_plugin_pref_frame_add(frame, pref); /* sound settings for sender */ pref = purple_plugin_pref_new_with_name_and_label( OPT_PLAYSOUND_SENDER, "Play sound if sender of a message is in the sender list"); purple_plugin_pref_frame_add(frame, pref); /* sender list */ pref = purple_plugin_pref_new_with_name_and_label( OPT_USERLIST_SENDER, "Sender List"); purple_plugin_pref_frame_add(frame, pref); /* sound id selector */ pref = purple_plugin_pref_new_with_name_and_label(OPT_SOUNDID_SENDER, "Sender Sound"); purple_plugin_pref_set_type(pref, PURPLE_PLUGIN_PREF_CHOICE); purple_plugin_pref_add_choice(pref, "Arrive", GINT_TO_POINTER(0)); purple_plugin_pref_add_choice(pref, "Leave", GINT_TO_POINTER(1)); purple_plugin_pref_add_choice(pref, "Receive", GINT_TO_POINTER(2)); purple_plugin_pref_add_choice(pref, "Fist Receive", GINT_TO_POINTER(3)); purple_plugin_pref_add_choice(pref, "Send", GINT_TO_POINTER(4)); purple_plugin_pref_add_choice(pref, "Chat Join", GINT_TO_POINTER(5)); purple_plugin_pref_add_choice(pref, "Chat Leave", GINT_TO_POINTER(6)); purple_plugin_pref_add_choice(pref, "Chat You Say", GINT_TO_POINTER(7)); purple_plugin_pref_add_choice(pref, "Chat Someone Say", GINT_TO_POINTER(8)); purple_plugin_pref_add_choice(pref, "Pounce Default", GINT_TO_POINTER(9)); purple_plugin_pref_add_choice(pref, "Chat Nick Said", GINT_TO_POINTER(10)); 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 */ PIDGINTWITTER_PLUGIN_ID, /**< id */ "Pidgin-Twitter", /**< name */ "0.5.1", /**< version */ "replaces @username to a link and play sound", /** summary */ "replaces @username in a link and play sound", /** 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_RECIPIENT, TRUE); purple_prefs_add_bool(OPT_TRANSLATE_SENDER, TRUE); purple_prefs_add_bool(OPT_ESCAPE_PSEUDO, TRUE); purple_prefs_add_bool(OPT_PLAYSOUND_RECIPIENT, TRUE); purple_prefs_add_bool(OPT_PLAYSOUND_SENDER, TRUE); purple_prefs_add_int(OPT_SOUNDID_RECIPIENT, PURPLE_SOUND_POUNCE_DEFAULT); purple_prefs_add_string(OPT_USERLIST_RECIPIENT, DEFAULT_LIST); purple_prefs_add_int(OPT_SOUNDID_SENDER, PURPLE_SOUND_POUNCE_DEFAULT); purple_prefs_add_string(OPT_USERLIST_SENDER, DEFAULT_LIST); } PURPLE_INIT_PLUGIN(pidgin_twitter, init_plugin, info)