0
|
1 /*
|
|
2 * Pidgin-Twitter plugin.
|
|
3 *
|
|
4 * This program is free software; you can redistribute it and/or
|
|
5 * modify it under the terms of the GNU General Public License as
|
|
6 * published by the Free Software Foundation; either version 2 of the
|
|
7 * License, or (at your option) any later version.
|
|
8 *
|
|
9 * This program is distributed in the hope that it will be useful, but
|
|
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12 * General Public License for more details.
|
|
13 *
|
|
14 * You should have received a copy of the GNU General Public License
|
|
15 * along with this program; if not, write to the Free Software
|
|
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
17 * 02111-1307, USA.
|
|
18 */
|
|
19 #define PURPLE_PLUGINS 1
|
|
20
|
|
21 #include <stdio.h>
|
|
22 #include <stdlib.h>
|
|
23 #include <string.h>
|
|
24 #include <glib.h>
|
|
25
|
|
26 #include "gtkplugin.h"
|
|
27 #include "util.h"
|
|
28 #include "debug.h"
|
|
29 #include "connection.h"
|
|
30 #include "version.h"
|
1
|
31 #include "sound.h"
|
0
|
32
|
|
33 extern gchar *botch_utf(const gchar *msg, gsize len, gsize *newlen) __attribute__ ((weak));
|
|
34
|
|
35 #define PIDGINTWITTER_PLUGIN_ID "pidgin_twitter"
|
|
36 #define OPT_PIDGINTWITTER "/plugins/pidgin_twitter"
|
|
37 #define OPT_TRANSLATE OPT_PIDGINTWITTER "/translate"
|
1
|
38 #define OPT_PLAYSOUND OPT_PIDGINTWITTER "/playsound"
|
|
39 #define OPT_USERLIST OPT_PIDGINTWITTER "/userlist"
|
2
|
40 #define TWITTER_FORMAT "@<a href='http://twitter.com/%s'>%s</a>"
|
0
|
41
|
2
|
42 #define twitter_debug(fmt, ...) purple_debug(PURPLE_DEBUG_INFO, PIDGINTWITTER_PLUGIN_ID, \
|
0
|
43 fmt, ## __VA_ARGS__);
|
2
|
44 #define twitter_error(fmt, ...) purple_debug(PURPLE_DEBUG_ERROR, PIDGINTWITTER_PLUGIN_ID, \
|
0
|
45 fmt, ## __VA_ARGS__);
|
|
46
|
|
47 /* globals */
|
|
48 static GRegex *preg;
|
|
49
|
1
|
50 static gboolean
|
|
51 eval(const GMatchInfo *match_info, GString *result, gpointer user_data)
|
|
52 {
|
|
53 gchar sub[128];
|
|
54 gchar *match = g_match_info_fetch(match_info, 0);
|
|
55
|
2
|
56 snprintf(sub, 128, TWITTER_FORMAT,
|
|
57 match + 1, // +1 is to strip preceding '@'.
|
1
|
58 match + 1);
|
|
59 twitter_debug("sub = %s\n", sub);
|
|
60 g_string_append(result, sub);
|
|
61 g_free(match);
|
|
62
|
|
63 return FALSE;
|
|
64 }
|
0
|
65
|
|
66 static void
|
1
|
67 translate(gchar **str)
|
0
|
68 {
|
1
|
69 gchar *newstr;
|
|
70
|
|
71 twitter_debug("*str = %s\n", *str);
|
0
|
72
|
1
|
73 newstr = g_regex_replace_eval(
|
|
74 preg, // compiled regex
|
|
75 *str, // subject string
|
|
76 -1, // length of the subject string
|
|
77 0, // start position
|
|
78 0, // match options
|
|
79 eval, // function to call for each match
|
|
80 NULL, // user data (not used)
|
|
81 NULL); // error handler
|
|
82
|
|
83 twitter_debug("newstr = %s\n", newstr);
|
|
84
|
|
85 g_free(*str);
|
|
86 *str = newstr;
|
|
87 }
|
0
|
88
|
1
|
89 static void
|
|
90 playsound(gchar **str)
|
|
91 {
|
|
92 GMatchInfo *match_info;
|
|
93 GList *list, *lp;
|
0
|
94
|
1
|
95 list = purple_prefs_get_string_list(OPT_USERLIST);
|
|
96
|
|
97 g_regex_match (preg, *str, 0, &match_info);
|
|
98 while (g_match_info_matches (match_info))
|
|
99 {
|
|
100 gchar *user = g_match_info_fetch (match_info, 0);
|
|
101 twitter_debug("user = %s\n", user);
|
0
|
102
|
1
|
103 for(lp = list; lp; lp = g_list_next(lp)) {
|
|
104 twitter_debug("lp->data = %s\n", (char *)lp->data);
|
|
105 if(!strcmp(user, lp->data) || !strcmp(user+1, lp->data)) {
|
|
106 twitter_debug("match. play sound\n");
|
|
107 purple_sound_play_event(PURPLE_SOUND_POUNCE_DEFAULT, NULL);
|
|
108 }
|
|
109 }
|
0
|
110
|
1
|
111 g_free (user);
|
|
112 g_match_info_next (match_info, NULL);
|
|
113 }
|
|
114
|
|
115 g_match_info_free (match_info);
|
0
|
116 }
|
|
117
|
|
118
|
1
|
119 static gboolean
|
|
120 process_im_cb(PurpleAccount *account, char *sender, char **buffer,
|
|
121 PurpleConversation *conv, int *flags, void *data)
|
0
|
122 {
|
|
123 const gchar *proto;
|
|
124
|
1
|
125 /* check if the message is from twitter */
|
0
|
126 proto = purple_account_get_protocol_id(account);
|
1
|
127 twitter_debug("proto = %s\n", proto);
|
|
128 twitter_debug("sender = %s\n", sender);
|
0
|
129
|
1
|
130 if (!strcmp(proto, "prpl-jabber") &&
|
|
131 !strcmp(sender, "twitter@twitter.com")) {
|
|
132 if(purple_prefs_get_bool(OPT_PLAYSOUND)) {
|
|
133 /* playsound */
|
|
134 playsound(buffer);
|
|
135 }
|
|
136 if(purple_prefs_get_bool(OPT_TRANSLATE)) {
|
|
137 /* translate */
|
|
138 translate(buffer);
|
|
139 }
|
0
|
140 }
|
1
|
141 return FALSE;
|
0
|
142 }
|
|
143
|
|
144 static gboolean
|
|
145 load_plugin(PurplePlugin *plugin)
|
|
146 {
|
1
|
147 /* connect to signal */
|
|
148 purple_signal_connect(purple_conversations_get_handle(), "writing-im-msg",
|
|
149 plugin, PURPLE_CALLBACK(process_im_cb), NULL);
|
0
|
150
|
|
151 return TRUE;
|
|
152 }
|
|
153
|
|
154 static gboolean
|
|
155 unload_plugin(PurplePlugin *plugin)
|
|
156 {
|
1
|
157 twitter_debug("pidgin-twitter unload called\n");
|
0
|
158
|
|
159 g_regex_unref(preg);
|
|
160 preg = NULL;
|
|
161 return TRUE;
|
|
162 }
|
|
163
|
|
164 static PurplePluginPrefFrame *
|
|
165 get_plugin_pref_frame(PurplePlugin *plugin)
|
|
166 {
|
|
167 PurplePluginPref *pref;
|
|
168 PurplePluginPrefFrame *frame = purple_plugin_pref_frame_new();
|
|
169
|
|
170 /* create gtk elements for the plugin preferences */
|
|
171 pref = purple_plugin_pref_new_with_label("Pidgin-Twitter Configuration");
|
|
172 purple_plugin_pref_frame_add(frame, pref);
|
|
173
|
|
174 pref = purple_plugin_pref_new_with_name_and_label(OPT_TRANSLATE,
|
1
|
175 "Translate @username to the link to the user");
|
0
|
176 purple_plugin_pref_frame_add(frame, pref);
|
|
177
|
1
|
178 pref = purple_plugin_pref_new_with_name_and_label(OPT_PLAYSOUND,
|
|
179 "Play sound if a reply to listed users arrives");
|
|
180 purple_plugin_pref_frame_add(frame, pref);
|
|
181
|
|
182 // xxx add pref field for OPT_USERLIST (gtk packing is needed) --yaz
|
|
183
|
0
|
184 return frame;
|
|
185 }
|
|
186
|
|
187 static PurplePluginUiInfo pref_info =
|
|
188 {
|
|
189 get_plugin_pref_frame
|
|
190 };
|
|
191
|
|
192 static PurplePluginInfo info =
|
|
193 {
|
|
194 PURPLE_PLUGIN_MAGIC,
|
|
195 PURPLE_MAJOR_VERSION,
|
|
196 PURPLE_MINOR_VERSION,
|
|
197 PURPLE_PLUGIN_STANDARD, /**< type */
|
|
198 NULL, /**< ui_req */
|
1
|
199 0, /**< flags */
|
|
200 NULL, /**< deps */
|
|
201 PURPLE_PRIORITY_DEFAULT, /**< priority */
|
|
202 PIDGINTWITTER_PLUGIN_ID, /**< id */
|
0
|
203 "Pidgin-Twitter", /**< name */
|
|
204 "0.1.0", /**< version */
|
1
|
205 "replaces @username in a message with link to the user", /** summary */
|
|
206 "replaces @username in a message with link to the user", /** desc */
|
0
|
207 "Yoshiki Yazawa (yaz@honeyplanet.jp)", /**< author */
|
|
208 "http://www.honeyplanet.jp/", /**< homepage */
|
|
209 load_plugin, /**< load */
|
|
210 unload_plugin, /**< unload */
|
|
211 NULL, /**< destroy */
|
|
212 NULL, /**< ui_info */
|
|
213 NULL, /**< extra_info */
|
|
214 &pref_info, /**< pref info */
|
|
215 NULL
|
|
216 };
|
|
217
|
|
218 static void
|
|
219 init_plugin(PurplePlugin *plugin)
|
|
220 {
|
1
|
221 GList *list;
|
|
222
|
0
|
223 g_type_init();
|
1
|
224 list = g_list_alloc();
|
0
|
225
|
|
226 /* add plugin preferences */
|
|
227 purple_prefs_add_none(OPT_PIDGINTWITTER);
|
|
228 purple_prefs_add_bool(OPT_TRANSLATE, TRUE);
|
1
|
229 purple_prefs_add_bool(OPT_PLAYSOUND, TRUE);
|
|
230 purple_prefs_add_string_list(OPT_USERLIST, list);
|
0
|
231
|
1
|
232 /* compile regex */
|
0
|
233 preg = g_regex_new("@[A-Za-z0-9-_]+", 0, 0, NULL);
|
1
|
234
|
0
|
235 }
|
|
236
|
|
237 PURPLE_INIT_PLUGIN(pidgin_twitter, init_plugin, info)
|