2
* @file script.c generic scripting support implementation
4
* Copyright (C) 2006-2007 Lars Lindner <lars.lindner@gmail.com>
6
* This program 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
* This program 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 this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32
/** hash of the scripts registered for different hooks */
33
static GHashTable *scripts = NULL;
34
static gboolean scriptConfigLoading = FALSE;
35
static scriptSupportImplPtr scriptImpl = NULL;
37
gboolean script_support_enabled(void) { return (scriptImpl != NULL); }
39
static gchar *script_get_name_for_hook (hookType hook)
43
case SCRIPT_HOOK_INVALID:
47
case SCRIPT_HOOK_STARTUP:
48
return g_strdup("startup");
51
case SCRIPT_HOOK_FEED_UPDATED:
52
return g_strdup("feed_updated");
55
case SCRIPT_HOOK_ITEM_SELECTED:
56
return g_strdup("item_selected");
59
case SCRIPT_HOOK_FEED_SELECTED:
60
return g_strdup("feed_selcted");
63
case SCRIPT_HOOK_ITEM_UNSELECT:
64
return g_strdup("item_unselect");
67
case SCRIPT_HOOK_FEED_UNSELECT:
68
return g_strdup("feed_unselect");
71
case SCRIPT_HOOK_SHUTDOWN:
72
return g_strdup("shutdown");
75
case SCRIPT_HOOK_NEW_SUBSCRIPTION:
76
return g_strdup("feed_added");
83
static void script_config_load_hook_script(xmlNodePtr match, gpointer user_data) {
84
gint type = GPOINTER_TO_INT(user_data);
87
name = xmlNodeListGetString(match->doc, match->xmlChildrenNode, 1);
89
script_hook_add(type, name);
95
script_config_load_hook (xmlNodePtr match, gpointer user_data)
100
tmp = xmlGetProp (match, BAD_CAST"type");
105
xpath_foreach_match (match, "script", script_config_load_hook_script, GINT_TO_POINTER (type));
109
script_config_load (void)
112
gchar *filename, *data = NULL;
115
scriptConfigLoading = TRUE;
117
filename = common_create_cache_filename (NULL, "scripts", "xml");
118
if (g_file_get_contents (filename, &data, &len, NULL)) {
119
doc = xml_parse (data, len, FALSE, NULL);
121
xpath_foreach_match (xmlDocGetRootElement (doc),
123
script_config_load_hook,
131
scriptConfigLoading = FALSE;
134
static void script_config_save_hook(gpointer key, gpointer value, gpointer user_data) {
135
xmlNodePtr hookNode, rootNode = (xmlNodePtr)user_data;
136
GSList *list = (GSList *)value;
139
tmp = g_strdup_printf("%d", GPOINTER_TO_INT(key));
140
hookNode = xmlNewChild(rootNode, NULL, "hook", NULL);
141
xmlNewProp(hookNode, BAD_CAST"type", BAD_CAST tmp);
145
xmlNewTextChild(hookNode, NULL, "script", (gchar *)list->data);
146
list = g_slist_next(list);
150
static void script_config_save(void) {
151
xmlDocPtr doc = NULL;
155
if(scriptConfigLoading)
158
doc = xmlNewDoc("1.0");
159
rootNode = xmlDocGetRootElement(doc);
160
rootNode = xmlNewDocNode(doc, NULL, "scripts", NULL);
161
xmlDocSetRootElement(doc, rootNode);
163
g_hash_table_foreach(scripts, script_config_save_hook, (gpointer)rootNode);
165
filename = common_create_cache_filename(NULL, "scripts", "xml");
166
if(-1 == xmlSaveFormatFileEnc(filename, doc, NULL, 1))
167
g_warning("Could save script config %s!", filename);
173
void script_init(void) {
176
scripts = g_hash_table_new(g_direct_hash, g_direct_equal);
177
script_config_load();
179
iter = plugin_mgmt_get_list();
181
pluginPtr plugin = (pluginPtr)(iter->data);
182
if(PLUGIN_TYPE_SCRIPT_SUPPORT == plugin->type) {
183
debug1(DEBUG_PLUGINS, "using \"%s\" for scripting...", plugin->name);
184
scriptImpl = plugin->symbols;
187
iter = g_slist_next(iter);
194
void script_run_cmd(const gchar *cmd) {
197
scriptImpl->run_cmd(cmd);
200
void script_run(const gchar *name, hookType hook) {
203
gchar *filename = common_create_cache_filename("cache" G_DIR_SEPARATOR_S "scripts", name, "lua");
204
gchar *hook_name = script_get_name_for_hook(hook);
205
scriptImpl->run_script(filename, hook_name);
211
void script_run_for_hook(hookType type) {
214
hook = g_hash_table_lookup(scripts, GINT_TO_POINTER(type));
216
script_run((gchar *)hook->data, type);
217
hook = g_slist_next(hook);
221
void script_hook_add(hookType type, const gchar *scriptname) {
224
hook = g_hash_table_lookup(scripts, GINT_TO_POINTER(type));
225
hook = g_slist_append(hook, g_strdup(scriptname));
226
g_hash_table_insert(scripts, GINT_TO_POINTER(type), hook);
227
script_config_save();
230
void script_hook_remove(hookType type, gchar *scriptname) {
233
hook = g_hash_table_lookup(scripts, GINT_TO_POINTER(type));
234
hook = g_slist_remove(hook, scriptname);
235
g_hash_table_insert(scripts, GINT_TO_POINTER(type), hook);
236
script_config_save();
240
GSList *script_hook_get_list(hookType type) {
242
return g_hash_table_lookup(scripts, GINT_TO_POINTER(type));
246
script_hook_free (gpointer key, gpointer value, gpointer user_data)
250
iter = list = (GSList *) value;
252
g_free (iter->data); /* free script name */
253
iter = g_slist_next (iter);
262
scriptImpl->deinit ();
265
g_hash_table_foreach (scripts, script_hook_free, NULL);
266
// FIXME: foreach hook free script list
267
g_hash_table_destroy (scripts);