~ubuntu-branches/ubuntu/vivid/liferea/vivid-proposed

« back to all changes in this revision

Viewing changes to src/script.c

  • Committer: Package Import Robot
  • Author(s): bojo42
  • Date: 2012-03-29 14:17:21 UTC
  • mfrom: (1.5.1)
  • mto: This revision was merged to the branch mainline in revision 122.
  • Revision ID: package-import@ubuntu.com-20120329141721-qqj1hupcvhglekf1
ImportĀ upstreamĀ versionĀ 1.8.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * @file script.c generic scripting support implementation
3
 
 *
4
 
 * Copyright (C) 2006-2007 Lars Lindner <lars.lindner@gmail.com>
5
 
 *
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. 
10
 
 *
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.
15
 
 *
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
19
 
 */
20
 
 
21
 
#ifdef HAVE_CONFIG_H
22
 
#  include <config.h>
23
 
#endif
24
 
 
25
 
#include <glib.h>
26
 
#include "common.h"
27
 
#include "debug.h"
28
 
#include "plugin.h"
29
 
#include "script.h"
30
 
#include "xml.h"
31
 
 
32
 
/** hash of the scripts registered for different hooks */
33
 
static GHashTable *scripts = NULL;
34
 
static gboolean scriptConfigLoading = FALSE;
35
 
static scriptSupportImplPtr scriptImpl = NULL;
36
 
 
37
 
gboolean script_support_enabled(void) { return (scriptImpl != NULL); }
38
 
 
39
 
static gchar *script_get_name_for_hook (hookType hook)
40
 
{
41
 
        switch (hook)
42
 
        {
43
 
                case SCRIPT_HOOK_INVALID:
44
 
                        return NULL;
45
 
                        break;
46
 
 
47
 
                case SCRIPT_HOOK_STARTUP:
48
 
                        return g_strdup("startup");
49
 
                        break;
50
 
 
51
 
                case SCRIPT_HOOK_FEED_UPDATED:
52
 
                        return g_strdup("feed_updated");
53
 
                        break;
54
 
 
55
 
                case SCRIPT_HOOK_ITEM_SELECTED:
56
 
                        return g_strdup("item_selected");
57
 
                        break;
58
 
 
59
 
                case SCRIPT_HOOK_FEED_SELECTED:
60
 
                        return g_strdup("feed_selcted");
61
 
                        break;
62
 
 
63
 
                case SCRIPT_HOOK_ITEM_UNSELECT:
64
 
                        return g_strdup("item_unselect");
65
 
                        break;
66
 
 
67
 
                case SCRIPT_HOOK_FEED_UNSELECT:
68
 
                        return g_strdup("feed_unselect");
69
 
                        break;
70
 
 
71
 
                case SCRIPT_HOOK_SHUTDOWN:
72
 
                        return g_strdup("shutdown");
73
 
                        break;
74
 
 
75
 
                case SCRIPT_HOOK_NEW_SUBSCRIPTION:
76
 
                        return g_strdup("feed_added");
77
 
                        break;
78
 
        }
79
 
 
80
 
        return NULL;
81
 
}
82
 
 
83
 
static void script_config_load_hook_script(xmlNodePtr match, gpointer user_data) {
84
 
        gint    type = GPOINTER_TO_INT(user_data);
85
 
        gchar   *name;
86
 
        
87
 
        name = xmlNodeListGetString(match->doc, match->xmlChildrenNode, 1);
88
 
        if(name) {
89
 
                script_hook_add(type, name);
90
 
                g_free(name);
91
 
        }
92
 
}
93
 
 
94
 
static void
95
 
script_config_load_hook (xmlNodePtr match, gpointer user_data)
96
 
{
97
 
        gint    type;
98
 
        gchar   *tmp;
99
 
        
100
 
        tmp = xmlGetProp (match, BAD_CAST"type");
101
 
        type = atoi (tmp);
102
 
        g_free (tmp);
103
 
        if (!type)
104
 
                return;
105
 
        xpath_foreach_match (match, "script", script_config_load_hook_script, GINT_TO_POINTER (type));
106
 
}
107
 
 
108
 
static void
109
 
script_config_load (void)
110
 
{
111
 
        xmlDocPtr       doc;
112
 
        gchar           *filename, *data = NULL;
113
 
        gsize           len;
114
 
 
115
 
        scriptConfigLoading = TRUE;
116
 
        
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);
120
 
                if (doc) {
121
 
                        xpath_foreach_match (xmlDocGetRootElement (doc),
122
 
                                             "/scripts/hook",
123
 
                                             script_config_load_hook,
124
 
                                             NULL);
125
 
                        xmlFreeDoc (doc);
126
 
                }
127
 
        }
128
 
 
129
 
        g_free (data);
130
 
        g_free (filename);
131
 
        scriptConfigLoading = FALSE;
132
 
}
133
 
 
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;
137
 
        gchar           *tmp;
138
 
        
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);
142
 
        g_free(tmp);
143
 
         
144
 
        while(list) {
145
 
                xmlNewTextChild(hookNode, NULL, "script", (gchar *)list->data);
146
 
                list = g_slist_next(list);
147
 
        }
148
 
}
149
 
 
150
 
static void script_config_save(void) {
151
 
        xmlDocPtr       doc = NULL;
152
 
        xmlNodePtr      rootNode;
153
 
        gchar           *filename;
154
 
        
155
 
        if(scriptConfigLoading)
156
 
                return;
157
 
        
158
 
        doc = xmlNewDoc("1.0");
159
 
        rootNode = xmlDocGetRootElement(doc);
160
 
        rootNode = xmlNewDocNode(doc, NULL, "scripts", NULL);
161
 
        xmlDocSetRootElement(doc, rootNode);
162
 
        
163
 
        g_hash_table_foreach(scripts, script_config_save_hook, (gpointer)rootNode);
164
 
 
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);
168
 
                
169
 
        xmlFreeDoc(doc);
170
 
        g_free(filename);
171
 
}
172
 
 
173
 
void script_init(void) {
174
 
        GSList  *iter;
175
 
 
176
 
        scripts = g_hash_table_new(g_direct_hash, g_direct_equal);
177
 
        script_config_load();
178
 
 
179
 
        iter = plugin_mgmt_get_list();
180
 
        while(iter) {
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;
185
 
                        break;
186
 
                }                       
187
 
                iter = g_slist_next(iter);
188
 
        }
189
 
 
190
 
        if(scriptImpl)
191
 
                scriptImpl->init();
192
 
}
193
 
 
194
 
void script_run_cmd(const gchar *cmd) {
195
 
 
196
 
        if(scriptImpl)
197
 
                scriptImpl->run_cmd(cmd);
198
 
}
199
 
 
200
 
void script_run(const gchar *name, hookType hook) {
201
 
        
202
 
        if(scriptImpl) {
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);
206
 
                g_free(filename);
207
 
                g_free(hook_name);
208
 
        }
209
 
}
210
 
 
211
 
void script_run_for_hook(hookType type) {
212
 
        GSList  *hook;
213
 
 
214
 
        hook = g_hash_table_lookup(scripts, GINT_TO_POINTER(type));
215
 
        while(hook) {
216
 
                script_run((gchar *)hook->data, type);
217
 
                hook = g_slist_next(hook);
218
 
        }
219
 
}
220
 
 
221
 
void script_hook_add(hookType type, const gchar *scriptname) {
222
 
        GSList  *hook;
223
 
 
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();
228
 
}
229
 
 
230
 
void script_hook_remove(hookType type, gchar *scriptname) {
231
 
        GSList  *hook;
232
 
 
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();
237
 
        g_free(scriptname);
238
 
}
239
 
 
240
 
GSList *script_hook_get_list(hookType type) {
241
 
 
242
 
        return g_hash_table_lookup(scripts, GINT_TO_POINTER(type));
243
 
}
244
 
 
245
 
static void
246
 
script_hook_free (gpointer key, gpointer value, gpointer user_data)
247
 
{
248
 
        GSList  *iter, *list;
249
 
        
250
 
        iter = list = (GSList *) value;
251
 
        while (iter) {
252
 
                g_free (iter->data);    /* free script name */
253
 
                iter = g_slist_next (iter);
254
 
        }       
255
 
        g_slist_free (list);
256
 
}
257
 
 
258
 
void
259
 
script_deinit (void)
260
 
{
261
 
        if (scriptImpl)
262
 
                scriptImpl->deinit ();
263
 
 
264
 
        if (scripts) {
265
 
                g_hash_table_foreach (scripts, script_hook_free, NULL);
266
 
                // FIXME: foreach hook free script list
267
 
                g_hash_table_destroy (scripts);
268
 
                scripts = NULL;
269
 
        }
270
 
}