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
38 #include <libpurple/purple.h>
39 #define DEFAULT_TEXT_DOMAIN PACKAGE_NAME
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
);
63 const char *protocol
= purple_account_get_protocol_name(account
);
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
;
70 // get buddy alias and icon
71 remote
= purple_buddy_get_alias(buddy
);
72 PurpleBuddyIcon
*icon
= purple_buddy_get_icon(buddy
);
75 gconstpointer data
= purple_buddy_icon_get_data(icon
, &len
);
76 icon_encoded
= g_base64_encode(data
, len
);
81 argv
[0] = g_strdup(command
);
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
);
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
);
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
);
104 // Free all resources.
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
,
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
,
132 on_new_message(account
, who
, message
);
135 static gboolean
plugin_load(PurplePlugin
*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
);
151 static gboolean
plugin_unload(PurplePlugin
*plugin
)
153 // Disconnect callbacks.
154 purple_signals_disconnect_by_handle(plugin
);
159 static PurplePluginPrefFrame
*plugin_get_pref_frame(PurplePlugin
*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
);
173 static PurplePluginUiInfo prefs_info
= {
174 plugin_get_pref_frame
,
183 static PurplePluginInfo info
= {
185 PURPLE_MAJOR_VERSION
,
186 PURPLE_MINOR_VERSION
,
187 PURPLE_PLUGIN_STANDARD
,
191 PURPLE_PRIORITY_DEFAULT
,
193 N_("External actions"),
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>",
214 static void init_plugin(PurplePlugin
*plugin
)
218 purple_prefs_add_none(PLUGIN_PREF
);
219 purple_prefs_add_path(PLUGIN_PREF_COMMAND
, "");
222 PURPLE_INIT_PLUGIN(extaction
, init_plugin
, info
)