Update list of wide characters
[centerim5.git] / plugins / extaction.c
blob44734c3714a8f6530de5419585ce4944d05e8afb
1 // Copyright (C) 2012-2013 Petr Pavlu <setup@dagobah.cz>
2 //
3 // This file is part of CenterIM.
4 //
5 // CenterIM is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // CenterIM is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with CenterIM. If not, see <http://www.gnu.org/licenses/>.
18 // Plugin to support external-action functionality in CenterIM5.
20 // When an event such as received-im-msg, or buddy-signed-on occurs this plugin
21 // asynchronously executes a user-defined external program.
23 // An example how to use this plugin can be found in contrib/extnotify.py.
25 // TODO Add support for more kinds of events, currently only received-im-msg and
26 // received-chat-msg actions are supported.
28 #define PURPLE_PLUGINS
30 #include <glib.h>
31 #include <libpurple/purple.h>
32 #define DEFAULT_TEXT_DOMAIN PACKAGE_NAME
33 #include "gettext.h"
35 #define PLUGIN_ID "core-cim_pack-ext_action"
36 #define PLUGIN_PREF "/plugins/core/cim_pack-extaction"
37 #define PLUGIN_PREF_COMMAND PLUGIN_PREF "/command"
39 #define UNUSED(x) (void)(x)
41 static PurplePlugin *ea_plugin = NULL;
43 static void on_new_message(
44 PurpleAccount *account, const char *remote, const char *message)
46 const char *command = purple_prefs_get_path(PLUGIN_PREF_COMMAND);
48 // The command should be never NULL.
49 g_return_if_fail(command != NULL);
51 if (command[0] == '\0') {
52 // No command is set.
53 return;
56 const char *protocol = purple_account_get_protocol_name(account);
57 char *local =
58 g_strdup(purple_normalize(account, purple_account_get_username(account)));
59 char *nohtml = purple_markup_strip_html(message);
60 PurpleBuddy *buddy = purple_find_buddy(account, remote);
61 char *icon_encoded = NULL;
62 if (buddy != NULL) {
63 // Get buddy alias and icon.
64 remote = purple_buddy_get_alias(buddy);
65 PurpleBuddyIcon *icon = purple_buddy_get_icon(buddy);
66 if (icon != NULL) {
67 size_t len;
68 gconstpointer data = purple_buddy_icon_get_data(icon, &len);
69 icon_encoded = g_base64_encode(data, len);
73 char *argv[2];
74 argv[0] = g_strdup(command);
75 argv[1] = NULL;
77 // Prepare child's environment variables.
78 char **envp = g_get_environ();
79 envp = g_environ_setenv(envp, "EVENT_TYPE", "msg", TRUE);
80 envp = g_environ_setenv(envp, "EVENT_NETWORK", protocol, TRUE);
81 envp = g_environ_setenv(envp, "EVENT_LOCAL_USER", local, TRUE);
82 envp = g_environ_setenv(envp, "EVENT_REMOTE_USER", remote, TRUE);
83 if (icon_encoded != NULL)
84 envp = g_environ_setenv(envp, "EVENT_REMOTE_USER_ICON", icon_encoded, TRUE);
85 envp = g_environ_setenv(envp, "EVENT_MESSAGE", nohtml, TRUE);
86 envp = g_environ_setenv(envp, "EVENT_MESSAGE_HTML", message, TRUE);
88 // Spawn the command.
89 GError *err = NULL;
90 if (!g_spawn_async(NULL, argv, envp, G_SPAWN_SEARCH_PATH |
91 G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
92 NULL, NULL, NULL, &err)) {
93 purple_debug_error("extaction", "%s", err->message);
94 g_clear_error(&err);
97 // Free all resources.
98 g_free(argv[0]);
99 g_strfreev(envp);
101 g_free(local);
102 g_free(nohtml);
103 g_free(icon_encoded);
106 static void on_new_im_message(PurpleAccount *account, const char *name,
107 const char *message, PurpleConversation *conv, PurpleMessageFlags flags,
108 gpointer data)
110 UNUSED(conv);
111 UNUSED(flags);
112 UNUSED(data);
114 on_new_message(account, name, message);
117 static void on_new_chat_message(PurpleAccount *account, const char *who,
118 const char *message, PurpleConversation *conv, PurpleMessageFlags flags,
119 gpointer data)
121 UNUSED(conv);
122 UNUSED(flags);
123 UNUSED(data);
125 on_new_message(account, who, message);
128 static gboolean plugin_load(PurplePlugin *plugin)
130 ea_plugin = plugin;
132 void *conv_handle = purple_conversations_get_handle();
134 // Connect callbacks.
135 purple_signal_connect(conv_handle, "received-im-msg", plugin,
136 PURPLE_CALLBACK(on_new_im_message), NULL);
138 purple_signal_connect(conv_handle, "received-chat-msg", plugin,
139 PURPLE_CALLBACK(on_new_chat_message), NULL);
141 return TRUE;
144 static gboolean plugin_unload(PurplePlugin *plugin)
146 // Disconnect callbacks.
147 purple_signals_disconnect_by_handle(plugin);
148 return TRUE;
151 // UI
152 static PurplePluginPrefFrame *plugin_get_pref_frame(PurplePlugin *plugin)
154 UNUSED(plugin);
156 PurplePluginPrefFrame *frame = purple_plugin_pref_frame_new();
158 PurplePluginPref *pref = purple_plugin_pref_new_with_name_and_label(
159 PLUGIN_PREF_COMMAND, _("Command"));
160 purple_plugin_pref_frame_add(frame, pref);
162 return frame;
165 // clang-format off
166 static PurplePluginUiInfo prefs_info = {
167 plugin_get_pref_frame,
169 NULL,
170 NULL,
171 NULL,
172 NULL,
173 NULL
176 static PurplePluginInfo info = {
177 PURPLE_PLUGIN_MAGIC,
178 PURPLE_MAJOR_VERSION,
179 PURPLE_MINOR_VERSION,
180 PURPLE_PLUGIN_STANDARD,
181 NULL,
183 NULL,
184 PURPLE_PRIORITY_DEFAULT,
185 PLUGIN_ID,
186 N_("External actions"),
187 "1.0",
188 N_("Executes an external program when a specific event occurs."),
189 N_("When an event such as received-im-msg, or buddy-signed-on occurs this "
190 "plugin executes a user-defined external program."),
191 "Petr Pavlu <setup@dagobah.cz>",
192 PACKAGE_URL,
193 plugin_load,
194 plugin_unload,
195 NULL,
196 NULL,
197 NULL,
198 &prefs_info,
199 NULL,
200 NULL,
201 NULL,
202 NULL,
203 NULL
205 // clang-format on
207 static void init_plugin(PurplePlugin *plugin)
209 UNUSED(plugin);
211 purple_prefs_add_none(PLUGIN_PREF);
212 purple_prefs_add_path(PLUGIN_PREF_COMMAND, "");
215 PURPLE_INIT_PLUGIN(extaction, init_plugin, info)