1 // Copyright (C) 2012-2013 Petr Pavlu <setup@dagobah.cz>
3 // This file is part of CenterIM.
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.
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
31 #include <libpurple/purple.h>
32 #define DEFAULT_TEXT_DOMAIN PACKAGE_NAME
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') {
56 const char *protocol
= purple_account_get_protocol_name(account
);
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
;
63 // Get buddy alias and icon.
64 remote
= purple_buddy_get_alias(buddy
);
65 PurpleBuddyIcon
*icon
= purple_buddy_get_icon(buddy
);
68 gconstpointer data
= purple_buddy_icon_get_data(icon
, &len
);
69 icon_encoded
= g_base64_encode(data
, len
);
74 argv
[0] = g_strdup(command
);
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
);
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
);
97 // Free all resources.
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
,
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
,
125 on_new_message(account
, who
, message
);
128 static gboolean
plugin_load(PurplePlugin
*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
);
144 static gboolean
plugin_unload(PurplePlugin
*plugin
)
146 // Disconnect callbacks.
147 purple_signals_disconnect_by_handle(plugin
);
152 static PurplePluginPrefFrame
*plugin_get_pref_frame(PurplePlugin
*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
);
166 static PurplePluginUiInfo prefs_info
= {
167 plugin_get_pref_frame
,
176 static PurplePluginInfo info
= {
178 PURPLE_MAJOR_VERSION
,
179 PURPLE_MINOR_VERSION
,
180 PURPLE_PLUGIN_STANDARD
,
184 PURPLE_PRIORITY_DEFAULT
,
186 N_("External actions"),
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>",
207 static void init_plugin(PurplePlugin
*plugin
)
211 purple_prefs_add_none(PLUGIN_PREF
);
212 purple_prefs_add_path(PLUGIN_PREF_COMMAND
, "");
215 PURPLE_INIT_PLUGIN(extaction
, init_plugin
, info
)