Add logic to run termex tests during build
[centerim5.git] / plugins / extaction.c
bloba5edbf0cacdf82cc0f20117286bc3ad22e5a6378
1 /*
2 * Copyright (C) 2012-2013 Petr Pavlu <setup@dagobah.cz>
4 * This file is part of CenterIM.
6 * CenterIM is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * CenterIM is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with CenterIM. If not, see <http://www.gnu.org/licenses/>.
21 * Plugin to support external-action functionality in CenterIM5.
23 * When an event such as received-im-msg, or buddy-signed-on occurs this
24 * plugin asynchronously executes a user-defined external program.
26 * An example how to use this plugin can be found in contrib/extnotify.py.
28 * TODO Add support for more kinds of events, currently only received-im-msg
29 * and received-chat-msg actions are supported.
31 * Note: This plugin requires glib 2.32 because it relies on the
32 * g_environ_setenv() function which isn't available in earlier glib versions.
35 #define PURPLE_PLUGINS
37 #include <glib.h>
38 #include <libpurple/purple.h>
39 #define DEFAULT_TEXT_DOMAIN PACKAGE_NAME
40 #include "gettext.h"
42 #define PLUGIN_ID "core-cim_pack-ext_action"
43 #define PLUGIN_PREF "/plugins/core/cim_pack-extaction"
44 #define PLUGIN_PREF_COMMAND PLUGIN_PREF "/command"
46 #define UNUSED(x) (void)(x)
48 static PurplePlugin *ea_plugin = NULL;
50 static void on_new_message(
51 PurpleAccount *account, const char *remote, const char *message)
53 const char *command = purple_prefs_get_path(PLUGIN_PREF_COMMAND);
55 // The command should be never NULL.
56 g_return_if_fail(command);
58 if (!command[0]) {
59 // No command is set.
60 return;
63 const char *protocol = purple_account_get_protocol_name(account);
64 char *local =
65 g_strdup(purple_normalize(account, purple_account_get_username(account)));
66 char *nohtml = purple_markup_strip_html(message);
67 PurpleBuddy *buddy = purple_find_buddy(account, remote);
68 char *icon_encoded = NULL;
69 if (buddy) {
70 // get buddy alias and icon
71 remote = purple_buddy_get_alias(buddy);
72 PurpleBuddyIcon *icon = purple_buddy_get_icon(buddy);
73 if (icon) {
74 size_t len;
75 gconstpointer data = purple_buddy_icon_get_data(icon, &len);
76 icon_encoded = g_base64_encode(data, len);
80 char *argv[2];
81 argv[0] = g_strdup(command);
82 argv[1] = NULL;
84 // Prepare child's environment variables.
85 char **envp = g_get_environ();
86 envp = g_environ_setenv(envp, "EVENT_TYPE", "msg", TRUE);
87 envp = g_environ_setenv(envp, "EVENT_NETWORK", protocol, TRUE);
88 envp = g_environ_setenv(envp, "EVENT_LOCAL_USER", local, TRUE);
89 envp = g_environ_setenv(envp, "EVENT_REMOTE_USER", remote, TRUE);
90 if (icon_encoded)
91 envp = g_environ_setenv(envp, "EVENT_REMOTE_USER_ICON", icon_encoded, TRUE);
92 envp = g_environ_setenv(envp, "EVENT_MESSAGE", nohtml, TRUE);
93 envp = g_environ_setenv(envp, "EVENT_MESSAGE_HTML", message, TRUE);
95 // Spawn the command.
96 GError *err = NULL;
97 if (!g_spawn_async(NULL, argv, envp, G_SPAWN_SEARCH_PATH |
98 G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
99 NULL, NULL, NULL, &err)) {
100 purple_debug_error("extaction", "%s", err->message);
101 g_clear_error(&err);
104 // Free all resources.
105 g_free(argv[0]);
106 g_strfreev(envp);
108 g_free(local);
109 g_free(nohtml);
110 g_free(icon_encoded);
113 static void on_new_im_message(PurpleAccount *account, const char *name,
114 const char *message, PurpleConversation *conv, PurpleMessageFlags flags,
115 gpointer data)
117 UNUSED(conv);
118 UNUSED(flags);
119 UNUSED(data);
121 on_new_message(account, name, message);
124 static void on_new_chat_message(PurpleAccount *account, const char *who,
125 const char *message, PurpleConversation *conv, PurpleMessageFlags flags,
126 gpointer data)
128 UNUSED(conv);
129 UNUSED(flags);
130 UNUSED(data);
132 on_new_message(account, who, message);
135 static gboolean plugin_load(PurplePlugin *plugin)
137 ea_plugin = plugin;
139 void *conv_handle = purple_conversations_get_handle();
141 // Connect callbacks.
142 purple_signal_connect(conv_handle, "received-im-msg", plugin,
143 PURPLE_CALLBACK(on_new_im_message), NULL);
145 purple_signal_connect(conv_handle, "received-chat-msg", plugin,
146 PURPLE_CALLBACK(on_new_chat_message), NULL);
148 return TRUE;
151 static gboolean plugin_unload(PurplePlugin *plugin)
153 // Disconnect callbacks.
154 purple_signals_disconnect_by_handle(plugin);
155 return TRUE;
158 // UI
159 static PurplePluginPrefFrame *plugin_get_pref_frame(PurplePlugin *plugin)
161 UNUSED(plugin);
163 PurplePluginPrefFrame *frame = purple_plugin_pref_frame_new();
165 PurplePluginPref *pref = purple_plugin_pref_new_with_name_and_label(
166 PLUGIN_PREF_COMMAND, _("Command"));
167 purple_plugin_pref_frame_add(frame, pref);
169 return frame;
172 // clang-format off
173 static PurplePluginUiInfo prefs_info = {
174 plugin_get_pref_frame,
176 NULL,
177 NULL,
178 NULL,
179 NULL,
180 NULL
183 static PurplePluginInfo info = {
184 PURPLE_PLUGIN_MAGIC,
185 PURPLE_MAJOR_VERSION,
186 PURPLE_MINOR_VERSION,
187 PURPLE_PLUGIN_STANDARD,
188 NULL,
190 NULL,
191 PURPLE_PRIORITY_DEFAULT,
192 PLUGIN_ID,
193 N_("External actions"),
194 "1.0",
195 N_("Executes an external program when a specific event occurs."),
196 N_("When an event such as received-im-msg, or buddy-signed-on occurs this "
197 "plugin executes a user-defined external program."),
198 "Petr Pavlu <setup@dagobah.cz>",
199 PACKAGE_URL,
200 plugin_load,
201 plugin_unload,
202 NULL,
203 NULL,
204 NULL,
205 &prefs_info,
206 NULL,
207 NULL,
208 NULL,
209 NULL,
210 NULL
212 // clang-format on
214 static void init_plugin(PurplePlugin *plugin)
216 UNUSED(plugin);
218 purple_prefs_add_none(PLUGIN_PREF);
219 purple_prefs_add_path(PLUGIN_PREF_COMMAND, "");
222 PURPLE_INIT_PLUGIN(extaction, init_plugin, info)