Statistics
| Revision:

root / trunk / plugins / jsonrpc / jsonrpc_methods.c @ 1850

History | View | Annotate | Download (63.1 KB)

1
/* 
2
    Copyright (C) 2005-2010  Erik van Pienbroek
3

                
4
    This program is free software; you can redistribute it and/or modify
5
    it under the terms of the GNU General Public License as published by
6
    the Free Software Foundation; either version 2 of the License, or
7
    (at your option) any later version.
8

                
9
    This program is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU General Public License for more details.
13

                
14
    You should have received a copy of the GNU General Public License
15
    along with this program; if not, write to the Free Software
16
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
*/
18

                
19
#include 
20
#include 
21
#include 
22
#include 
23
#include "nntpgrab_plugin.h"
24
#include "nntpgrab_utils.h"
25
#include "json.h"
26
#include "jsonrpc.h"
27
#include "config.h"
28
#include 
29

                
30
static NGPlugin *plugin_data_global = NULL;
31

                
32
static void json_get_version_info(struct json_object *request, struct json_object *response, void *user_data);
33
static void json_server_request_quit(struct json_object *request, struct json_object *response, void *user_data);
34
static void json_config_get_avail_servers(struct json_object *request, struct json_object *response, void *user_data);
35
static void json_config_get_server_info(struct json_object *request, struct json_object *response, void *user_data);
36
static void json_config_add_server(struct json_object *request, struct json_object *response, void *user_data);
37
static void json_config_del_server(struct json_object *request, struct json_object *response, void *user_data);
38
static void json_config_edit_server(struct json_object *request, struct json_object *response, void *user_data);
39
static void json_config_get_opts(struct json_object *request, struct json_object *response, void *user_data);
40
static void json_config_set_opts(struct json_object *request, struct json_object *response, void *user_data);
41
static void json_schedular_start(struct json_object *request, struct json_object *response, void *user_data);
42
static void json_schedular_stop(struct json_object *request, struct json_object *response, void *user_data);
43
static void json_schedular_get_state(struct json_object *request, struct json_object *response, void *user_data);
44
static void json_schedular_add_file_to_queue(struct json_object *request, struct json_object *response, void *user_data);
45
static void json_schedular_del_file_from_queue(struct json_object *request, struct json_object *response, void *user_data);
46
static void json_schedular_restart_file(struct json_object *request, struct json_object *response, void *user_data);
47
static void json_schedular_save_queue(struct json_object *request, struct json_object *response, void *user_data);
48
static void json_schedular_get_all_tasks(struct json_object *request, struct json_object *response, void *user_data);
49
static void json_schedular_foreach_task(struct json_object *request, struct json_object *response, void *user_data);
50
static void json_schedular_move_file(struct json_object *request, struct json_object *response, void *user_data);
51
static void json_schedular_move_collection(struct json_object *request, struct json_object *response, void *user_data);
52
static void json_schedular_mark_task_optional(struct json_object *request, struct json_object *response, void *user_data);
53
static void json_plugins_get_avail_plugins(struct json_object *request, struct json_object *response, void *user_data);
54
static void json_plugins_get_plugin_info(struct json_object *request, struct json_object *response, void *user_data);
55
static void json_plugins_load_plugin(struct json_object *request, struct json_object *response, void *user_data);
56
static void json_plugins_unload_plugin(struct json_object *request, struct json_object *response, void *user_data);
57
static void json_plugins_set_persistent(struct json_object *request, struct json_object *response, void *user_data);
58
static void json_set_emit_log_messages(struct json_object *request, struct json_object *response, void *user_data);
59
static void json_plugins_utils_strip_subject(struct json_object *request, struct json_object *response, void *user_data);
60
static void json_plugins_utils_calculate_file_size(struct json_object *request, struct json_object *response, void *user_data);
61
static void json_plugins_utils_calculate_estimated_time_remaining(struct json_object *request, struct json_object *response, void *user_data);
62
static void json_plugins_utils_get_readable_time_remaining(struct json_object *request, struct json_object *response, void *user_data);
63
static void json_plugins_utils_get_readable_finished_time(struct json_object *request, struct json_object *response, void *user_data);
64
static void json_plugins_utils_get_folder_listing(struct json_object *request, struct json_object *response, void *user_data);
65

                
66
/* mongoose_hacks.c */
67
void jsonrpc_tcp_emit_event_to_connection(const char *json_data, void *conn);
68

                
69
void
70
jsonrpc_methods_register_methods(NGPlugin *plugin_data)
71
{
72
    static gboolean been_here = FALSE;
73

                
74
    plugin_data_global = plugin_data;
75

                
76
    if (been_here) {
77
        return;
78
    }
79

                
80
    been_here = TRUE;
81
    jsonrpc_add_method("nntpgrab_get_version_info", json_get_version_info);
82
    jsonrpc_add_method("nntpgrab_server_request_quit", json_server_request_quit);
83
    jsonrpc_add_method("nntpgrab_config_get_avail_servers", json_config_get_avail_servers);
84
    jsonrpc_add_method("nntpgrab_config_get_server_info", json_config_get_server_info);
85
    jsonrpc_add_method("nntpgrab_config_add_server", json_config_add_server);
86
    jsonrpc_add_method("nntpgrab_config_del_server", json_config_del_server);
87
    jsonrpc_add_method("nntpgrab_config_edit_server", json_config_edit_server);
88
    jsonrpc_add_method("nntpgrab_config_get_opts", json_config_get_opts);
89
    jsonrpc_add_method("nntpgrab_config_set_opts", json_config_set_opts);
90
    jsonrpc_add_method("nntpgrab_schedular_start", json_schedular_start);
91
    jsonrpc_add_method("nntpgrab_schedular_stop", json_schedular_stop);
92
    jsonrpc_add_method("nntpgrab_schedular_get_state", json_schedular_get_state);
93
    jsonrpc_add_method("nntpgrab_schedular_add_file_to_queue", json_schedular_add_file_to_queue);
94
    jsonrpc_add_method("nntpgrab_schedular_del_file_from_queue", json_schedular_del_file_from_queue);
95
    jsonrpc_add_method("nntpgrab_schedular_restart_file", json_schedular_restart_file);
96
    jsonrpc_add_method("nntpgrab_schedular_save_queue", json_schedular_save_queue);
97
    jsonrpc_add_method("nntpgrab_schedular_get_all_tasks", json_schedular_get_all_tasks);
98
    jsonrpc_add_method("nntpgrab_schedular_foreach_task", json_schedular_foreach_task);
99
    jsonrpc_add_method("nntpgrab_schedular_move_file", json_schedular_move_file);
100
    jsonrpc_add_method("nntpgrab_schedular_move_collection", json_schedular_move_collection);
101
    jsonrpc_add_method("nntpgrab_schedular_mark_task_optional", json_schedular_mark_task_optional);
102
    jsonrpc_add_method("nntpgrab_plugins_get_avail_plugins", json_plugins_get_avail_plugins);
103
    jsonrpc_add_method("nntpgrab_plugins_get_plugin_info", json_plugins_get_plugin_info);
104
    jsonrpc_add_method("nntpgrab_plugins_load_plugin", json_plugins_load_plugin);
105
    jsonrpc_add_method("nntpgrab_plugins_unload_plugin", json_plugins_unload_plugin);
106
    jsonrpc_add_method("nntpgrab_plugins_set_persistent", json_plugins_set_persistent);
107
    jsonrpc_add_method("nntpgrab_set_emit_log_messages", json_set_emit_log_messages);
108
    jsonrpc_add_method("nntpgrab_utils_strip_subject", json_plugins_utils_strip_subject);
109
    jsonrpc_add_method("nntpgrab_utils_calculate_file_size", json_plugins_utils_calculate_file_size);
110
    jsonrpc_add_method("nntpgrab_utils_calculate_estimated_time_remaining", json_plugins_utils_calculate_estimated_time_remaining);
111
    jsonrpc_add_method("nntpgrab_utils_get_readable_time_remaining", json_plugins_utils_get_readable_time_remaining);
112
    jsonrpc_add_method("nntpgrab_utils_get_readable_finished_time", json_plugins_utils_get_readable_finished_time);
113
    jsonrpc_add_method("nntpgrab_utils_get_folder_listing", json_plugins_utils_get_folder_listing);
114
}
115

                
116
void
117
jsonrpc_methods_unregister_methods(void)
118
{
119
    plugin_data_global = NULL;
120
}
121

                
122
/***********************************************************************/
123
/* JSON-RPC methods */
124
/***********************************************************************/
125
static void
126
json_prepare_response(struct json_object *request, struct json_object *response, const char *errmsg)
127
{
128
    json_object_object_add(response, "id", json_object_get(json_object_object_get(request, "id")));
129

                
130
    if (errmsg) {
131
        json_object_object_add(response, "error", json_object_new_string((char*) errmsg));
132
    } else {
133
        json_object_object_add(response, "error", NULL);
134
    }
135
}
136

                
137
static gboolean
138
json_verify_parameters(struct json_object *request, struct json_object *response, struct json_object *params, int num_params_expected)
139
{
140
    if (!plugin_data_global) {
141
        json_prepare_response(request, response, "Internal plugin error: plugin_data_global == NULL");
142
        return FALSE;
143
    }
144

                
145
    if (!params) {
146
        params = json_object_object_get(request, "params");
147
    }
148

                
149
    if (!params) {
150
        json_prepare_response(request, response, "JSON request lacks a 'params' field");
151
        return FALSE;
152
    }
153

                
154
    if (json_object_get_type(params) != json_type_array) {
155
        json_prepare_response(request, response, "Parameter is of invalid type");
156
        return FALSE;
157
    }
158

                
159
    if (json_object_array_length(params) != num_params_expected) {
160
        char msg[64];
161

                
162
        memset(&msg, 0, sizeof(msg));
163
        snprintf(msg, sizeof(msg) - 1, "Invalid number of arguments: %i (Expected: %i)", json_object_array_length(params), num_params_expected);
164
        json_prepare_response(request, response, msg);
165
        return FALSE;
166
    }
167

                
168
    return TRUE;
169
}
170

                
171
static gboolean
172
test_if_required_argument_is_supplied(struct json_object *request, struct json_object *response, struct json_object *params, int index)
173
{
174
    if (!json_object_array_get_idx(params, index)) {
175
        char msg[64];
176

                
177
        memset(&msg, 0, sizeof(msg));
178
        snprintf(msg, sizeof(msg) - 1, "Parameter %i is required but it wasn't supplied", index + 1);
179
        json_prepare_response(request, response, msg);
180
        return FALSE;
181
    }
182

                
183
    return TRUE;
184
}
185

                
186
static void
187
json_get_version_info(struct json_object *request, struct json_object *response, void *user_data)
188
{
189
    struct json_object *obj = json_object_new_object();
190

                
191
    json_object_object_add(obj, "api_version", json_object_new_int(NNTPGRAB_PLUGIN_API_VERSION));
192
    json_object_object_add(obj, "major_version", json_object_new_int(MAJOR_VERSION));
193
    json_object_object_add(obj, "minor_version", json_object_new_int(MINOR_VERSION));
194
    json_object_object_add(obj, "micro_version", json_object_new_int(MICRO_VERSION));
195
    json_object_object_add(obj, "version", json_object_new_string(PACKAGE_VERSION));
196

                
197
    json_object_object_add(response, "result", obj);
198

                
199
    json_prepare_response(request, response, NULL);
200
}
201

                
202
static void
203
json_server_request_quit(struct json_object *request, struct json_object *response, void *user_data)
204
{
205
    g_return_if_fail(plugin_data_global != NULL);
206

                
207
    plugin_data_global->core_funcs.server_request_quit();
208

                
209
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
210
    json_prepare_response(request, response, NULL);
211
}
212

                
213
static void
214
json_config_get_avail_servers(struct json_object *request, struct json_object *response, void *user_data)
215
{
216
    NGList *servers;
217
    NGList *list;
218
    struct json_object *arr;
219

                
220
    if (!json_verify_parameters(request, response, NULL, 0)) {
221
        return;
222
    }
223

                
224
    g_return_if_fail(plugin_data_global != NULL);
225

                
226
    servers = plugin_data_global->core_funcs.config_get_avail_servers();
227

                
228
    arr = json_object_new_array();
229
    json_object_object_add(response, "result", arr);
230

                
231
    list = servers;
232
    while (list) {
233
        const char *servername = list->data;
234

                
235
        json_object_array_add(arr, json_object_new_string((char*) servername));
236

                
237
        list = ng_list_next(list);
238
    }
239

                
240
    plugin_data_global->core_funcs.config_free_avail_servers(servers);
241

                
242
    json_prepare_response(request, response, NULL);
243
}
244

                
245
static void
246
json_config_get_server_info(struct json_object *request, struct json_object *response, void *user_data)
247
{
248
    const char *servername;
249
    NGConfigServer server;
250
    struct json_object *ret;
251
    struct json_object *params;
252

                
253
    params = json_object_object_get(request, "params");
254
    if (!json_verify_parameters(request, response, params, 1) ||
255
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
256

                
257
        return;
258
    }
259

                
260
    g_return_if_fail(plugin_data_global != NULL);
261

                
262
    if (json_object_get_type(json_object_array_get_idx(params, 0)) != json_type_string) {
263
        json_prepare_response(request, response, "Parameter is of invalid type");
264
        return;
265
    }
266

                
267
    servername = json_object_get_string(json_object_array_get_idx(params, 0));
268

                
269
    if (!servername) {
270
        json_prepare_response(request, response, "Invalid argument");
271
        return;
272
    }
273

                
274
    g_return_if_fail(servername != NULL);
275

                
276
    if (!plugin_data_global->core_funcs.config_get_server_info(servername, &server)) {
277
        json_prepare_response(request, response, "No server by that name found");
278
        return;
279
    }
280

                
281
    ret = json_object_new_object();
282
    json_object_object_add(ret, "servername", json_object_new_string((char*) server.servername));
283
    json_object_object_add(ret, "hostname", json_object_new_string((char*) server.hostname));
284
    json_object_object_add(ret, "port", json_object_new_int(server.port));
285
    json_object_object_add(ret, "username", json_object_new_string((char*) server.username));
286
    json_object_object_add(ret, "password", json_object_new_string((char*) server.password));
287
    json_object_object_add(ret, "max_threads", json_object_new_int(server.max_threads));
288
    json_object_object_add(ret, "priority", json_object_new_int(server.priority));
289
    json_object_object_add(ret, "send_group_command", json_object_new_boolean(server.send_group_command));
290
    json_object_object_add(ret, "use_ssl", json_object_new_boolean(server.use_ssl));
291
    json_object_object_add(ret, "enabled", json_object_new_boolean(server.enabled));
292

                
293
    json_object_object_add(response, "result", ret);
294

                
295
    json_prepare_response(request, response, NULL);
296
}
297

                
298
#define json_process_parameter_str(param_obj, param, dest)                  \
299
    {                                                                       \
300
        struct json_object *obj = json_object_object_get(param_obj, param); \
301
        if (!obj) {                                                         \
302
            missing_param = param;                                          \
303
            goto missing_parameter;                                         \
304
        } else if (json_object_get_type(obj) != json_type_string) {         \
305
            invalid_param = param;                                          \
306
            goto invalid_parameter;                                         \
307
        }                                                                   \
308
        strncpy(dest, json_object_get_string(obj), sizeof(dest) - 1);       \
309
    }
310

                
311
#define json_process_parameter_int(param_obj, param, dest)                  \
312
    {                                                                       \
313
        struct json_object *obj = json_object_object_get(param_obj, param); \
314
        if (!obj) {                                                         \
315
            missing_param = param;                                          \
316
            goto missing_parameter;                                         \
317
        } else if (json_object_get_type(obj) != json_type_int) {            \
318
            invalid_param = param;                                          \
319
            goto invalid_parameter;                                         \
320
        }                                                                   \
321
        dest = json_object_get_int(obj);                                    \
322
    }
323

                
324
#define json_process_parameter_bool(param_obj, param, dest)                 \
325
    {                                                                       \
326
        struct json_object *obj = json_object_object_get(param_obj, param); \
327
        if (!obj) {                                                         \
328
            missing_param = param;                                          \
329
            goto missing_parameter;                                         \
330
        } else if (json_object_get_type(obj) != json_type_boolean) {        \
331
            invalid_param = param;                                          \
332
            goto invalid_parameter;                                         \
333
        }                                                                   \
334
        dest = json_object_get_boolean(obj);                                \
335
    }
336

                
337
static void
338
json_config_add_server(struct json_object *request, struct json_object *response, void *user_data)
339
{
340
    NGConfigServer server;
341
    struct json_object *params = json_object_object_get(request, "params");
342
    struct json_object *param_server;
343
    const char *missing_param = NULL;
344
    const char *invalid_param = NULL;
345
    char msg[128];
346
    ngboolean ret;
347
    char *errmsg = NULL;
348

                
349
    memset(&server, 0, sizeof(server));
350

                
351
    if (!json_verify_parameters(request, response, params, 1) ||
352
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
353

                
354
        return;
355
    }
356

                
357
    g_return_if_fail(plugin_data_global != NULL);
358

                
359
    param_server = json_object_array_get_idx(params, 0);
360
    if (json_object_get_type(param_server) != json_type_object) {
361
        json_prepare_response(request, response, "Parameter is of invalid type");
362
        return;
363
    }
364

                
365
    json_process_parameter_str (param_server, "servername", server.servername);
366
    json_process_parameter_str (param_server, "hostname", server.hostname);
367
    json_process_parameter_int (param_server, "port", server.port);
368
    json_process_parameter_str (param_server, "username", server.username);
369
    json_process_parameter_str (param_server, "password", server.password);
370
    json_process_parameter_int (param_server, "max_threads", server.max_threads);
371
    json_process_parameter_int (param_server, "priority", server.priority);
372
    json_process_parameter_bool(param_server, "send_group_command", server.send_group_command);
373
    json_process_parameter_bool(param_server, "use_ssl", server.use_ssl);
374
    json_process_parameter_bool(param_server, "enabled", server.enabled);
375

                
376
    /* add the server */
377
    ret = plugin_data_global->core_funcs.config_add_server(server, &errmsg);
378
    if (!ret) {
379
        json_prepare_response(request, response, errmsg);
380
        g_free(errmsg);
381
        return;
382
    }
383

                
384
    if (!plugin_data_global->core_funcs.config_save(&errmsg)) {
385
        json_object_object_add(response, "result", json_object_new_boolean(FALSE));
386
        json_prepare_response(request, response, errmsg);
387
        g_free(errmsg);
388
    } else {
389
        json_object_object_add(response, "result", json_object_new_boolean(TRUE));
390
        json_prepare_response(request, response, NULL);
391
    }
392

                
393
    return;
394

                
395
missing_parameter:
396
    memset(&msg, 0, sizeof(msg));
397
    snprintf(msg, sizeof(msg), "Missing parameter in array: '%s'", missing_param);
398
    json_prepare_response(request, response, msg);
399
    return;
400

                
401
invalid_parameter:
402
    memset(&msg, 0, sizeof(msg));
403
    snprintf(msg, sizeof(msg), "Parameter '%s' is of the invalid type", invalid_param);
404
    json_prepare_response(request, response, msg);
405
    return;
406
}
407

                
408
static void
409
json_config_del_server(struct json_object *request, struct json_object *response, void *user_data)
410
{
411
    struct json_object *params = json_object_object_get(request, "params");
412
    struct json_object *param_server;
413
    const char *servername;
414
    ngboolean ret;
415
    char *errmsg = NULL;
416

                
417
    if (!json_verify_parameters(request, response, params, 1) ||
418
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
419

                
420
        return;
421
    }
422

                
423
    g_return_if_fail(plugin_data_global != NULL);
424

                
425
    param_server = json_object_array_get_idx(params, 0);
426
    if (json_object_get_type(param_server) != json_type_string) {
427
        json_prepare_response(request, response, "Parameter 'servername' is of invalid type");
428
        return;
429
    }
430

                
431
    servername = json_object_get_string(param_server);
432

                
433
    g_return_if_fail(servername != NULL);
434

                
435
    /* delete the server */
436
    ret = plugin_data_global->core_funcs.config_del_server(servername, &errmsg);
437
    if (!ret) {
438
        json_prepare_response(request, response, errmsg);
439
        g_free(errmsg);
440
        return;
441
    }
442

                
443
    if (!plugin_data_global->core_funcs.config_save(&errmsg)) {
444
        json_object_object_add(response, "result", json_object_new_boolean(FALSE));
445
        json_prepare_response(request, response, errmsg);
446
        g_free(errmsg);
447
    } else {
448
        json_object_object_add(response, "result", json_object_new_boolean(TRUE));
449
        json_prepare_response(request, response, NULL);
450
    }
451
}
452

                
453
static void
454
json_config_edit_server(struct json_object *request, struct json_object *response, void *user_data)
455
{
456
    NGConfigServer server;
457
    struct json_object *params = json_object_object_get(request, "params");
458
    struct json_object *param_server;
459
    const char *missing_param = NULL;
460
    const char *invalid_param = NULL;
461
    const char *servername;
462
    char msg[128];
463
    ngboolean ret;
464
    char *errmsg = NULL;
465

                
466
    memset(&server, 0, sizeof(server));
467

                
468
    if (!json_verify_parameters(request, response, params, 2) ||
469
        !test_if_required_argument_is_supplied(request, response, params, 0) ||
470
        !test_if_required_argument_is_supplied(request, response, params, 1)) {
471

                
472
        return;
473
    }
474

                
475
    g_return_if_fail(plugin_data_global != NULL);
476

                
477
    param_server = json_object_array_get_idx(params, 0);
478
    if (json_object_get_type(param_server) != json_type_string) {
479
        json_prepare_response(request, response, "Parameter 'servername_old' is of invalid type");
480
        return;
481
    }
482

                
483
    servername = json_object_get_string(param_server);
484

                
485
    g_return_if_fail(servername != NULL);
486

                
487
    param_server = json_object_array_get_idx(params, 1);
488
    if (json_object_get_type(param_server) != json_type_object) {
489
        json_prepare_response(request, response, "Parameter 'server', is of invalid type");
490
        return;
491
    }
492

                
493
    json_process_parameter_str (param_server, "servername", server.servername);
494
    json_process_parameter_str (param_server, "hostname", server.hostname);
495
    json_process_parameter_int (param_server, "port", server.port);
496
    json_process_parameter_str (param_server, "username", server.username);
497
    json_process_parameter_str (param_server, "password", server.password);
498
    json_process_parameter_int (param_server, "max_threads", server.max_threads);
499
    json_process_parameter_int (param_server, "priority", server.priority);
500
    json_process_parameter_bool(param_server, "send_group_command", server.send_group_command);
501
    json_process_parameter_bool(param_server, "use_ssl", server.use_ssl);
502
    json_process_parameter_bool(param_server, "enabled", server.enabled);
503

                
504
    /* edit the server */
505
    ret = plugin_data_global->core_funcs.config_edit_server(servername, server, &errmsg);
506
    if (!ret) {
507
        json_prepare_response(request, response, errmsg);
508
        g_free(errmsg);
509
        return;
510
    }
511

                
512
    if (!plugin_data_global->core_funcs.config_save(&errmsg)) {
513
        json_object_object_add(response, "result", json_object_new_boolean(FALSE));
514
        json_prepare_response(request, response, errmsg);
515
        g_free(errmsg);
516
    } else {
517
        json_object_object_add(response, "result", json_object_new_boolean(TRUE));
518
        json_prepare_response(request, response, NULL);
519
    }
520

                
521
    return;
522

                
523
missing_parameter:
524
    memset(&msg, 0, sizeof(msg));
525
    snprintf(msg, sizeof(msg), "Missing parameter in array: '%s'", missing_param);
526
    json_prepare_response(request, response, msg);
527
    return;
528

                
529
invalid_parameter:
530
    memset(&msg, 0, sizeof(msg));
531
    snprintf(msg, sizeof(msg), "Parameter '%s' is of the invalid type", invalid_param);
532
    json_prepare_response(request, response, msg);
533
    return;
534
}
535

                
536
static void
537
json_config_get_opts(struct json_object *request, struct json_object *response, void *user_data)
538
{
539
    NGConfigOpts opts;
540
    struct json_object *ret;
541

                
542
    if(!json_verify_parameters(request, response, NULL, 0)) {
543
        return;
544
    }
545

                
546
    g_return_if_fail(plugin_data_global != NULL);
547

                
548
    opts = plugin_data_global->core_funcs.config_get_opts();
549

                
550
    ret = json_object_new_object();
551
    json_object_object_add(ret, "download_directory", json_object_new_string((char*) opts.download_directory));
552
    json_object_object_add(ret, "temp_directory", json_object_new_string((char*) opts.temp_directory));
553
    json_object_object_add(ret, "enable_intelligent_par2_downloading", json_object_new_boolean(opts.enable_intelligent_par2_downloading));
554
    json_object_object_add(ret, "enable_par2_repair", json_object_new_boolean(opts.enable_par2_repair));
555
    json_object_object_add(ret, "auto_import_directory", json_object_new_string((char*) opts.auto_import_directory));
556
    json_object_object_add(ret, "enable_auto_import", json_object_new_boolean(opts.enable_auto_import));
557
    json_object_object_add(ret, "move_file_after_auto_import", json_object_new_boolean(opts.move_file_after_auto_import));
558
    json_object_object_add(ret, "enable_auto_unpack", json_object_new_boolean(opts.enable_auto_unpack));
559
    json_object_object_add(ret, "enable_bandwidth_shaping", json_object_new_boolean(opts.enable_bandwidth_shaping));
560
    json_object_object_add(ret, "max_bandwidth", json_object_new_int(opts.max_bandwidth));
561
    json_object_object_add(ret, "enable_webserver", json_object_new_boolean(opts.enable_webserver));
562
    json_object_object_add(ret, "webserver_port", json_object_new_int(opts.webserver_port));
563
    json_object_object_add(ret, "enable_logger", json_object_new_boolean(opts.enable_logger));
564
    json_object_object_add(ret, "auto_remove_files_after_repair", json_object_new_boolean(opts.auto_remove_files_after_repair));
565
    json_object_object_add(ret, "auto_remove_files_after_unpack", json_object_new_boolean(opts.auto_remove_files_after_unpack));
566
    json_object_object_add(response, "result", ret);
567

                
568
    json_prepare_response(request, response, NULL);
569
}
570

                
571
static void
572
json_config_set_opts(struct json_object *request, struct json_object *response, void *user_data)
573
{
574
    NGConfigOpts opts;
575
    struct json_object *params = json_object_object_get(request, "params");
576
    struct json_object *param_opts;
577
    const char *missing_param = NULL;
578
    const char *invalid_param = NULL;
579
    char msg[128];
580
    char *errmsg = NULL;
581

                
582
    memset(&opts, 0, sizeof(opts));
583

                
584
    if (!json_verify_parameters(request, response, params, 1) ||
585
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
586
        return;
587
    }
588

                
589
    g_return_if_fail(plugin_data_global != NULL);
590

                
591
    param_opts = json_object_array_get_idx(params, 0);
592
    if (json_object_get_type(param_opts) != json_type_object) {
593
        json_prepare_response(request, response, "Parameter 'opts' is of invalid type");
594
        return;
595
    }
596

                
597
    json_process_parameter_str (param_opts, "download_directory", opts.download_directory);
598
    json_process_parameter_str (param_opts, "temp_directory", opts.temp_directory);
599
    json_process_parameter_bool(param_opts, "enable_intelligent_par2_downloading", opts.enable_intelligent_par2_downloading);
600
    json_process_parameter_bool(param_opts, "enable_par2_repair", opts.enable_par2_repair);
601
    json_process_parameter_str (param_opts, "auto_import_directory", opts.auto_import_directory);
602
    json_process_parameter_bool(param_opts, "enable_auto_import", opts.enable_auto_import);
603
    json_process_parameter_bool(param_opts, "move_file_after_auto_import", opts.move_file_after_auto_import);
604
    json_process_parameter_bool(param_opts, "enable_auto_unpack", opts.enable_auto_unpack);
605
    json_process_parameter_bool(param_opts, "enable_bandwidth_shaping", opts.enable_bandwidth_shaping);
606
    json_process_parameter_int (param_opts, "max_bandwidth", opts.max_bandwidth);
607
    json_process_parameter_bool(param_opts, "enable_webserver", opts.enable_webserver);
608
    json_process_parameter_int (param_opts, "webserver_port", opts.webserver_port);
609
    json_process_parameter_bool(param_opts, "enable_logger", opts.enable_logger);
610
    json_process_parameter_bool(param_opts, "auto_remove_files_after_repair", opts.auto_remove_files_after_repair);
611
    json_process_parameter_bool(param_opts, "auto_remove_files_after_unpack", opts.auto_remove_files_after_unpack);
612

                
613
    plugin_data_global->core_funcs.config_set_opts(opts);
614

                
615
    if (!plugin_data_global->core_funcs.config_save(&errmsg)) {
616
        json_object_object_add(response, "result", json_object_new_boolean(FALSE));
617
        json_prepare_response(request, response, errmsg);
618
        g_free(errmsg);
619
    } else {
620
        json_object_object_add(response, "result", json_object_new_boolean(TRUE));
621
        json_prepare_response(request, response, NULL);
622
    }
623

                
624
    return;
625

                
626
missing_parameter:
627
    memset(&msg, 0, sizeof(msg));
628
    snprintf(msg, sizeof(msg), "Missing parameter in array: '%s'", missing_param);
629
    json_prepare_response(request, response, msg);
630
    return;
631

                
632
invalid_parameter:
633
    memset(&msg, 0, sizeof(msg));
634
    snprintf(msg, sizeof(msg), "Parameter '%s' is of the invalid type", invalid_param);
635
    json_prepare_response(request, response, msg);
636
    return;
637
}
638

                
639
static void
640
json_schedular_start(struct json_object *request, struct json_object *response, void *user_data)
641
{
642
    ngboolean ret;
643
    if(!json_verify_parameters(request, response, NULL, 0)) {
644
        return;
645
    }
646

                
647
    g_return_if_fail(plugin_data_global != NULL);
648

                
649
    ret = plugin_data_global->core_funcs.schedular_start();
650

                
651
    json_object_object_add(response, "result", json_object_new_boolean(ret));
652
    json_prepare_response(request, response, NULL);
653
}
654

                
655
static void
656
json_schedular_stop(struct json_object *request, struct json_object *response, void *user_data)
657
{
658
    struct json_object *params = json_object_object_get(request, "params");
659
    struct json_object *param_schedular;
660
    ngboolean ret;
661
    char *reason = NULL;
662

                
663
    if (!json_verify_parameters(request, response, params, 1) ||
664
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
665
        return;
666
    }
667

                
668
    g_return_if_fail(plugin_data_global != NULL);
669

                
670
    param_schedular = json_object_array_get_idx(params, 0);
671
    if (json_object_get_type(param_schedular) != json_type_boolean) {
672
        json_prepare_response(request, response, "Parameter 'wait' is of invalid type");
673
        return;
674
    }
675

                
676
    ret = json_object_get_boolean(param_schedular);
677

                
678
    if(!plugin_data_global->core_funcs.schedular_stop(reason, ret))
679
    {
680
        json_prepare_response(request, response, reason);
681
        return;
682
    }
683

                
684
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
685
    json_prepare_response(request, response, NULL);
686
}
687

                
688
static void
689
json_schedular_get_state(struct json_object *request, struct json_object *response, void *user_data)
690
{
691
    NGSchedularState state;
692

                
693
    if(!json_verify_parameters(request, response, NULL, 0)) {
694
            return;
695
    }
696

                
697
    g_return_if_fail(plugin_data_global != NULL);
698

                
699
    state = plugin_data_global->core_funcs.schedular_get_state();
700

                
701
    json_object_object_add(response, "result", json_object_new_int(state));
702
    json_prepare_response(request, response, NULL);
703
}
704

                
705
static void
706
json_schedular_add_file_to_queue(struct json_object *request, struct json_object *response, void *user_data)
707
{
708
    struct json_object *params = json_object_object_get(request, "params");
709
    struct json_object *obj;
710
    char *collection_name;
711
    char *subject;
712
    char *poster;
713
    time_t timestamp;
714
    guint64 file_size;
715
    NGList *groups = NULL;
716
    NGList *parts = NULL;
717
    NGList *list;
718
    int i, len;
719
    const char *missing_param = NULL;
720
    const char *invalid_param = NULL;
721
    char *errmsg = NULL;
722
    char msg[1024];
723

                
724
    if (!json_verify_parameters(request, response, NULL, 7) ||
725
        !test_if_required_argument_is_supplied(request, response, params, 0) ||
726
        !test_if_required_argument_is_supplied(request, response, params, 1) ||
727
        !test_if_required_argument_is_supplied(request, response, params, 2) ||
728
        !test_if_required_argument_is_supplied(request, response, params, 3) ||
729
        !test_if_required_argument_is_supplied(request, response, params, 4) ||
730
        !test_if_required_argument_is_supplied(request, response, params, 5) ||
731
        !test_if_required_argument_is_supplied(request, response, params, 6)) {
732

                
733
        return;
734
    }
735

                
736
    g_return_if_fail(plugin_data_global != NULL);
737

                
738
    obj = json_object_array_get_idx(params, 0);
739
    if (json_object_get_type(obj) != json_type_string) {
740
        json_prepare_response(request, response, "Parameter 'collection_name' is of invalid type");
741
        return;
742
    }
743
    collection_name = json_object_get_string(obj);
744

                
745
    obj = json_object_array_get_idx(params, 1);
746
    if (json_object_get_type(obj) != json_type_string) {
747
        json_prepare_response(request, response, "Parameter 'subject' is of invalid type");
748
        return;
749
    }
750
    subject = json_object_get_string(obj);
751

                
752
    obj = json_object_array_get_idx(params, 2);
753
    if (json_object_get_type(obj) != json_type_string) {
754
        json_prepare_response(request, response, "Parameter 'poster' is of invalid type");
755
        return;
756
    }
757
    poster = json_object_get_string(obj);
758

                
759
    obj = json_object_array_get_idx(params, 3);
760
    if (json_object_get_type(obj) != json_type_int) {
761
        json_prepare_response(request, response, "Parameter 'timestamp' is of invalid type");
762
        return;
763
    }
764
    timestamp = json_object_get_int(obj);
765

                
766
    obj = json_object_array_get_idx(params, 4);
767
    if (json_object_get_type(obj) != json_type_int) {
768
        json_prepare_response(request, response, "Parameter 'file_size' is of invalid type");
769
        return;
770
    }
771
    file_size = json_object_get_int(obj);
772

                
773
    obj = json_object_array_get_idx(params, 5);
774
    if (json_object_get_type(obj) != json_type_array) {
775
        json_prepare_response(request, response, "Parameter 'groups' is of invalid type");
776
        return;
777
    }
778

                
779
    len = json_object_array_length(obj);
780
    for (i = 0; i < len; i++) {
781
        struct json_object *group_obj = json_object_array_get_idx(obj, i);
782
        char *groupname;
783

                
784
        g_return_if_fail(group_obj != NULL);
785

                
786
        if (json_object_get_type(group_obj) != json_type_string) {
787
            char msg[1024];
788

                
789
            memset(&msg, 0, sizeof(msg));
790
            snprintf(msg, sizeof(msg) - 1, "Element %i of parameter 'groups' is of invalid type", i);
791
            json_prepare_response(request, response, msg);
792
            return;
793
        }
794

                
795
        groupname = json_object_get_string(group_obj);
796

                
797
        g_return_if_fail(groupname != NULL);
798

                
799
        groups = ng_list_append(groups, groupname);
800
    }
801

                
802
    obj = json_object_array_get_idx(params, 6);
803
    if (json_object_get_type(obj) != json_type_array) {
804
        json_prepare_response(request, response, "Parameter 'parts' is of invalid type");
805
        return;
806
    }
807

                
808
    len = json_object_array_length(obj);
809
    for (i = 0; i < len; i++) {
810
        struct json_object *part_obj = json_object_array_get_idx(obj, i);
811
        NNTPPart *part;
812

                
813
        g_return_if_fail(part_obj != NULL);
814

                
815
        if (json_object_get_type(part_obj) != json_type_object) {
816
            memset(&msg, 0, sizeof(msg));
817
            snprintf(msg, sizeof(msg) - 1, "Element %i of parameter 'parts' is of invalid type", i);
818
            json_prepare_response(request, response, msg);
819
            return;
820
        }
821

                
822
        part = g_slice_new0(NNTPPart);
823
        json_process_parameter_str(part_obj, "message_id", part->message_id);   /* NOTE: This line can give a compiler warning, but this is intentional! */
824
        json_process_parameter_int(part_obj, "part_num", part->part_num);
825
        json_process_parameter_int(part_obj, "size", part->size);
826

                
827
        parts = ng_list_append(parts, part);
828
    }
829

                
830
    if (!plugin_data_global->core_funcs.schedular_add_file_to_queue(collection_name, subject, poster, timestamp, file_size * 1024, groups, parts, &errmsg)) {
831
        json_prepare_response(request, response, errmsg);
832
        g_free(errmsg);
833
        return;
834
    }
835

                
836
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
837
    json_prepare_response(request, response, NULL);
838

                
839
    ng_list_free(groups);
840

                
841
    list = parts;
842
    while (list) {
843
        NNTPPart *part = list->data;
844

                
845
        g_slice_free(NNTPPart, part);
846

                
847
        list = ng_list_next(list);
848
    }
849
    ng_list_free(parts);
850

                
851
    return;
852

                
853
missing_parameter:
854
    memset(&msg, 0, sizeof(msg));
855
    snprintf(msg, sizeof(msg), "Missing parameter in array: '%s'", missing_param);
856
    json_prepare_response(request, response, msg);
857
    return;
858

                
859
invalid_parameter:
860
    memset(&msg, 0, sizeof(msg));
861
    snprintf(msg, sizeof(msg), "Parameter '%s' is of the invalid type", invalid_param);
862
    json_prepare_response(request, response, msg);
863
    return;
864
}
865

                
866
static void
867
json_schedular_del_file_from_queue(struct json_object *request, struct json_object *response, void *user_data)
868
{
869
    struct json_object *params = json_object_object_get(request, "params");
870
    struct json_object *param_collection;
871
    char *collection_name;
872
    char *subject = NULL;
873
    char *errmsg = NULL;
874

                
875
    if (!json_verify_parameters(request, response, NULL, 2) ||
876
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
877
        return;
878
    }
879

                
880
    g_return_if_fail(plugin_data_global != NULL);
881

                
882
    param_collection = json_object_array_get_idx(params, 0);
883
    if (json_object_get_type(param_collection) != json_type_string) {
884
        json_prepare_response(request, response, "Parameter 'collection_name' is of invalid type");
885
        return;
886
    }
887

                
888
    collection_name = json_object_get_string(param_collection);
889

                
890
    g_return_if_fail(collection_name != NULL);
891

                
892
    param_collection = json_object_array_get_idx(params, 1);
893

                
894
    if (test_if_required_argument_is_supplied(request, response, params, 1))
895
    {
896
        if(json_object_get_type(param_collection) != json_type_string)
897
        {
898
            json_prepare_response(request, response, "Parameter 'subject', is of invalid type");
899
            return;
900
        }
901
        else
902
        {
903
            subject = json_object_get_string(param_collection);
904
            g_return_if_fail(subject != NULL);
905
        }
906
    }
907

                
908
    if (!plugin_data_global->core_funcs.schedular_del_file_from_queue(collection_name, subject, &errmsg)) {
909
        json_prepare_response(request, response, errmsg);
910
        g_free(errmsg);
911
        return;
912
    }
913

                
914
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
915
    json_prepare_response(request, response, NULL);
916
}
917

                
918
static void
919
json_schedular_restart_file(struct json_object *request, struct json_object *response, void *user_data)
920
{
921

                
922
    struct json_object *params = json_object_object_get(request, "params");
923
    struct json_object *param_file;
924
    char *collection_name;
925
    char *subject = NULL;
926
    char *errmsg = NULL;
927

                
928
    if (!json_verify_parameters(request, response, NULL, 2) ||
929
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
930
        return;
931
    }
932

                
933
    g_return_if_fail(plugin_data_global != NULL);
934

                
935
    param_file = json_object_array_get_idx(params, 0);
936
    if (json_object_get_type(param_file) != json_type_string) {
937
        json_prepare_response(request, response, "Parameter 'collection_name' is of invalid type");
938
        return;
939
    }
940

                
941
    collection_name = json_object_get_string(param_file);
942

                
943
    g_return_if_fail(collection_name != NULL);
944

                
945
    param_file = json_object_array_get_idx(params, 1);
946

                
947
    if (test_if_required_argument_is_supplied(request, response, params, 1))
948
    {
949
        if(json_object_get_type(param_file) != json_type_string)
950
        {
951
            json_prepare_response(request, response, "Parameter 'subject', is of invalid type");
952
            return;
953
        }
954
        else
955
        {
956
            subject = json_object_get_string(param_file);
957
            g_return_if_fail(subject != NULL);
958
        }
959
    }
960

                
961
    if (!plugin_data_global->core_funcs.schedular_restart_file(collection_name, subject, &errmsg)) {
962
        json_prepare_response(request, response, errmsg);
963
        g_free(errmsg);
964
        return;
965
    }
966

                
967
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
968
    json_prepare_response(request, response, NULL);
969
}
970

                
971
static void
972
json_schedular_save_queue(struct json_object *request, struct json_object *response, void *user_data)
973
{
974
    char *errmsg = NULL;
975

                
976
    if (!json_verify_parameters(request, response, NULL, 0)) {
977
        return;
978
    }
979

                
980
    g_return_if_fail(plugin_data_global != NULL);
981

                
982
    if (!plugin_data_global->core_funcs.schedular_save_queue(&errmsg)) {
983
        json_prepare_response(request, response, errmsg);
984
        g_free(errmsg);
985
        return;
986
    }
987

                
988
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
989
    json_prepare_response(request, response, NULL);
990
}
991

                
992
struct _foreach_cb_data {
993
    struct json_object *collections;
994
    struct json_object *collection;
995
    struct json_object *files;
996
    struct json_object *file;
997
    struct json_object *groups;
998

                
999
    boolean only_emit;
1000
    void *connection;
1001
};
1002

                
1003
static void
1004
foreach_collection_func(const char *collection_name, const char *poster, nguint64 total_size, nguint64 total_size_remaining, int position, void *data)
1005
{
1006
    struct _foreach_cb_data *cb_data = data;
1007
    int i_total_size;
1008
    int i_total_size_remaining;
1009

                
1010
    total_size /= 1024;
1011
    total_size_remaining /= 1024;
1012

                
1013
    i_total_size = total_size;
1014
    i_total_size_remaining = total_size_remaining;
1015

                
1016
    cb_data->collection = json_object_new_object();
1017

                
1018
    json_object_object_add(cb_data->collection, "collection_name", json_object_new_string((char*) collection_name));
1019
    json_object_object_add(cb_data->collection, "poster", json_object_new_string((char*) poster));
1020

                
1021
    /* The total size needs to be divided by 1024 as JSON doesn't 
1022
     * know 64bit long integers, so we keep the size in KB here */
1023
    json_object_object_add(cb_data->collection, "total_size", json_object_new_int(i_total_size));
1024
    json_object_object_add(cb_data->collection, "total_size_remaining", json_object_new_int(i_total_size_remaining));
1025

                
1026
    if (cb_data->only_emit) {
1027
        struct json_object *emit_event = json_object_new_object();
1028

                
1029
        json_object_object_add(cb_data->collection, "position", json_object_new_int(position));
1030

                
1031
        json_object_object_add(emit_event, "id", NULL);
1032
        json_object_object_add(emit_event, "method", json_object_new_string("foreach_collection_event"));
1033
        json_object_object_add(emit_event, "params", cb_data->collection);
1034

                
1035
        jsonrpc_tcp_emit_event_to_connection(json_object_to_json_string(emit_event), cb_data->connection);
1036

                
1037
        json_object_put(emit_event);
1038
        cb_data->collection = NULL;
1039

                
1040
        return;
1041
    }
1042

                
1043
    json_object_array_add(cb_data->collections, cb_data->collection);
1044

                
1045
    cb_data->files = json_object_new_array();
1046
    json_object_object_add(cb_data->collection, "files", cb_data->files);
1047
}
1048

                
1049
static void
1050
foreach_file_func(const char *collection_name, const char *subject, const char *poster, ngint64 stamp, nguint64 file_size, nguint64 file_size_remaining, int position, int num_parts_total, int num_parts_downloaded, int num_parts_failed, NGTaskState status, const char *filename, void *data)
1051
{
1052
    struct _foreach_cb_data *cb_data = data;
1053
    int i_file_size;
1054
    int i_file_size_remaining;
1055

                
1056
    file_size /= 1024;
1057
    file_size_remaining /= 1024;
1058

                
1059
    i_file_size = file_size;
1060
    i_file_size_remaining = file_size_remaining;
1061

                
1062
    cb_data->file = json_object_new_object();
1063

                
1064
    if (cb_data->only_emit) {
1065
        json_object_object_add(cb_data->file, "collection_name", json_object_new_string((char*) collection_name));
1066
    }
1067

                
1068
    json_object_object_add(cb_data->file, "subject", json_object_new_string((char*) subject));
1069
    json_object_object_add(cb_data->file, "poster", json_object_new_string((char*) poster));
1070
    json_object_object_add(cb_data->file, "stamp", json_object_new_int((int) stamp));
1071
    json_object_object_add(cb_data->file, "file_size", json_object_new_int(i_file_size));
1072
    json_object_object_add(cb_data->file, "file_size_remaining", json_object_new_int(i_file_size_remaining));
1073
    json_object_object_add(cb_data->file, "num_parts_total", json_object_new_int(num_parts_total));
1074
    json_object_object_add(cb_data->file, "num_parts_downloaded", json_object_new_int(num_parts_downloaded));
1075
    json_object_object_add(cb_data->file, "num_parts_failed", json_object_new_int(num_parts_failed));
1076
    json_object_object_add(cb_data->file, "status", json_object_new_int(status));
1077
    json_object_object_add(cb_data->file, "filename", json_object_new_string((char*) filename));
1078

                
1079
    if (cb_data->only_emit) {
1080
        struct json_object *emit_event = json_object_new_object();
1081

                
1082
        json_object_object_add(cb_data->file, "position", json_object_new_int(position));
1083

                
1084
        json_object_object_add(emit_event, "id", NULL);
1085
        json_object_object_add(emit_event, "method", json_object_new_string("foreach_file_event"));
1086
        json_object_object_add(emit_event, "params", cb_data->file);
1087

                
1088
        jsonrpc_tcp_emit_event_to_connection(json_object_to_json_string(emit_event), cb_data->connection);
1089

                
1090
        json_object_put(emit_event);
1091
        cb_data->file = NULL;
1092

                
1093
        return;
1094
    }
1095

                
1096
    json_object_array_add(cb_data->files, cb_data->file);
1097

                
1098
    cb_data->groups = json_object_new_array();
1099
    json_object_object_add(cb_data->file, "groups", cb_data->groups);
1100
}
1101

                
1102
static void
1103
foreach_group_func(const char *collection_name, const char *subject, const char *group, void *data)
1104
{
1105
    struct _foreach_cb_data *cb_data = data;
1106

                
1107
    if (cb_data->only_emit) {
1108
        struct json_object *obj = json_object_new_object();
1109
        struct json_object *emit_event = json_object_new_object();
1110

                
1111
        json_object_object_add(obj, "collection_name", json_object_new_string((char *) collection_name));
1112
        json_object_object_add(obj, "subject", json_object_new_string((char *) subject));
1113
        json_object_object_add(obj, "group", json_object_new_string((char *) group));
1114

                
1115
        json_object_object_add(emit_event, "id", NULL);
1116
        json_object_object_add(emit_event, "method", json_object_new_string("foreach_group_event"));
1117
        json_object_object_add(emit_event, "params", obj);
1118

                
1119
        jsonrpc_tcp_emit_event_to_connection(json_object_to_json_string(emit_event), cb_data->connection);
1120

                
1121
        json_object_put(emit_event);
1122

                
1123
        return;
1124
    }
1125

                
1126
    json_object_array_add(cb_data->groups, json_object_new_string((char *) group));
1127
}
1128

                
1129
static void
1130
json_schedular_get_all_tasks(struct json_object *request, struct json_object *response, void *user_data)
1131
{
1132
    struct _foreach_cb_data cb_data;
1133

                
1134
    if (!json_verify_parameters(request, response, NULL, 0)) {
1135
        return;
1136
    }
1137

                
1138
    g_return_if_fail(plugin_data_global != NULL);
1139

                
1140
    memset(&cb_data, 0, sizeof(cb_data));
1141
    cb_data.collections = json_object_new_array();
1142
    cb_data.only_emit = FALSE;
1143

                
1144
    plugin_data_global->core_funcs.schedular_foreach_file(foreach_collection_func, foreach_file_func, foreach_group_func, &cb_data);
1145

                
1146
    json_prepare_response(request, response, NULL);
1147
    json_object_object_add(response, "result", cb_data.collections);
1148
}
1149

                
1150
static void
1151
json_schedular_foreach_task(struct json_object *request, struct json_object *response, void *user_data)
1152
{
1153
    struct _foreach_cb_data cb_data;
1154

                
1155
    if (!json_verify_parameters(request, response, NULL, 0)) {
1156
        return;
1157
    }
1158

                
1159
    g_return_if_fail(plugin_data_global != NULL);
1160

                
1161
    memset(&cb_data, 0, sizeof(cb_data));
1162
    cb_data.only_emit = TRUE;
1163
    cb_data.connection = user_data;
1164

                
1165
    plugin_data_global->core_funcs.schedular_foreach_file(foreach_collection_func, foreach_file_func, foreach_group_func, &cb_data);
1166

                
1167
    json_prepare_response(request, response, NULL);
1168
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
1169
}
1170

                
1171
static void
1172
json_schedular_move_file(struct json_object *request, struct json_object *response, void *user_data)
1173
{
1174
    struct json_object *params = json_object_object_get(request, "params");
1175
    struct json_object *param_file;
1176
    char *collection_name_src;
1177
    char *subject;
1178
    char *collection_name_dest;
1179
    int position;
1180
    ngboolean ret;
1181

                
1182
    if (!json_verify_parameters(request, response, NULL, 4) ||
1183
        !test_if_required_argument_is_supplied(request, response, params, 0) ||
1184
        !test_if_required_argument_is_supplied(request, response, params, 1) ||
1185
        !test_if_required_argument_is_supplied(request, response, params, 2) ||
1186
        !test_if_required_argument_is_supplied(request, response, params, 3)) {
1187
        return;
1188
    }
1189

                
1190
    g_return_if_fail(plugin_data_global != NULL);
1191

                
1192

                
1193
    param_file = json_object_array_get_idx(params, 0);
1194
    if (json_object_get_type(param_file) != json_type_string) {
1195
        json_prepare_response(request, response, "Parameter 'collection_name_src' is of invalid type");
1196
        return;
1197
    }
1198

                
1199
    collection_name_src = json_object_get_string(param_file);
1200

                
1201
    g_return_if_fail(collection_name_src != NULL);
1202

                
1203
    param_file = json_object_array_get_idx(params, 1);
1204
    if (json_object_get_type(param_file) != json_type_string) {
1205
        json_prepare_response(request, response, "Parameter 'subject' is of invalid type");
1206
        return;
1207
    }
1208

                
1209
    subject = json_object_get_string(param_file);
1210

                
1211
    g_return_if_fail(subject != NULL);
1212

                
1213
    param_file = json_object_array_get_idx(params, 2);
1214
    if (json_object_get_type(param_file) != json_type_string) {
1215
        json_prepare_response(request, response, "Parameter 'collection_name_dest' is of invalid type");
1216
        return;
1217
    }
1218

                
1219
    collection_name_dest = json_object_get_string(param_file);
1220

                
1221
    g_return_if_fail(collection_name_dest != NULL);
1222

                
1223
    param_file = json_object_array_get_idx(params, 3);
1224
    if (json_object_get_type(param_file) != json_type_int) {
1225
        json_prepare_response(request, response, "Parameter 'position' is of invalid type");
1226
        return;
1227
    }
1228

                
1229
    position = json_object_get_int(param_file);
1230

                
1231
    ret = plugin_data_global->core_funcs.schedular_move_file(collection_name_src, subject, collection_name_dest, position);
1232

                
1233
    json_object_object_add(response, "result", json_object_new_boolean(ret));
1234
    json_prepare_response(request, response, NULL);
1235

                
1236
}
1237

                
1238
static void
1239
json_schedular_move_collection(struct json_object *request, struct json_object *response, void *user_data)
1240
{
1241
    struct json_object *params = json_object_object_get(request, "params");
1242
    struct json_object *param_collection;
1243
    int new_pos;
1244
    char *collection_name = NULL;
1245
    ngboolean ret;
1246

                
1247
    if (!json_verify_parameters(request, response, NULL, 2) ||
1248
        !test_if_required_argument_is_supplied(request, response, params, 0) ||
1249
        !test_if_required_argument_is_supplied(request, response, params, 1)) {
1250
        return;
1251
    }
1252

                
1253
    g_return_if_fail(plugin_data_global != NULL);
1254

                
1255
    param_collection = json_object_array_get_idx(params, 0);
1256
    if (json_object_get_type(param_collection) != json_type_string) {
1257
        json_prepare_response(request, response, "Parameter 'collection_name' is of invalid type");
1258
        return;
1259
    }
1260

                
1261
    collection_name = json_object_get_string(param_collection);
1262

                
1263
    g_return_if_fail(collection_name != NULL);
1264

                
1265
    param_collection = json_object_array_get_idx(params, 1);
1266
    if (json_object_get_type(param_collection) != json_type_int) {
1267
        json_prepare_response(request, response, "Parameter 'new_position' is of invalid type");
1268
        return;
1269
    }
1270

                
1271
    new_pos = json_object_get_int(param_collection);
1272

                
1273
    ret = plugin_data_global->core_funcs.schedular_move_collection(collection_name, new_pos);
1274

                
1275
    json_object_object_add(response, "result", json_object_new_boolean(ret));
1276
    json_prepare_response(request, response, NULL);
1277
}
1278

                
1279
static void
1280
json_schedular_mark_task_optional(struct json_object *request, struct json_object *response, void *user_data)
1281
{
1282
    struct json_object *params = json_object_object_get(request, "params");
1283
    struct json_object *param;
1284
    char *collection_name = NULL;
1285
    char *subject = NULL;
1286
    gboolean is_optional;
1287
    ngboolean ret;
1288

                
1289
    if (!json_verify_parameters(request, response, NULL, 3) ||
1290
        !test_if_required_argument_is_supplied(request, response, params, 0) ||
1291
        !test_if_required_argument_is_supplied(request, response, params, 1) ||
1292
        !test_if_required_argument_is_supplied(request, response, params, 2)) {
1293
        return;
1294
    }
1295

                
1296
    g_return_if_fail(plugin_data_global != NULL);
1297

                
1298
    param = json_object_array_get_idx(params, 0);
1299
    if (json_object_get_type(param) != json_type_string) {
1300
        json_prepare_response(request, response, "Parameter 'collection_name' is of invalid type");
1301
        return;
1302
    }
1303

                
1304
    collection_name = json_object_get_string(param);
1305

                
1306
    g_return_if_fail(collection_name != NULL);
1307

                
1308
    param = json_object_array_get_idx(params, 1);
1309
    if (json_object_get_type(param) != json_type_string) {
1310
        json_prepare_response(request, response, "Parameter 'subject' is of invalid type");
1311
        return;
1312
    }
1313

                
1314
    subject = json_object_get_string(param);
1315

                
1316
    g_return_if_fail(collection_name != NULL);
1317

                
1318
    param = json_object_array_get_idx(params, 2);
1319
    if (json_object_get_type(param) != json_type_boolean) {
1320
        json_prepare_response(request, response, "Parameter 'is_optional' is of invalid type");
1321
        return;
1322
    }
1323

                
1324
    is_optional = json_object_get_boolean(param);
1325

                
1326
    ret = plugin_data_global->core_funcs.schedular_mark_task_optional(collection_name, subject, is_optional);
1327

                
1328
    json_object_object_add(response, "result", json_object_new_boolean(ret));
1329
    json_prepare_response(request, response, NULL);
1330
}
1331

                
1332
static void
1333
json_plugins_get_avail_plugins(struct json_object *request, struct json_object *response, void *user_data)
1334
{
1335
    NGList *plugins;
1336
    NGList *list;
1337
    struct json_object *arr;
1338

                
1339
    if (!json_verify_parameters(request, response, NULL, 0)) {
1340
        return;
1341
    }
1342

                
1343
    g_return_if_fail(plugin_data_global != NULL);
1344

                
1345
    plugins = plugin_data_global->core_funcs.plugins_get_avail_plugins();
1346

                
1347
    arr = json_object_new_array();
1348
    json_object_object_add(response, "result", arr);
1349

                
1350
    list = plugins;
1351
    while (list) {
1352
        const char *name = list->data;
1353
        json_object_array_add(arr, json_object_new_string((char*) name));
1354
        list = ng_list_next(list);
1355
    }
1356

                
1357
    plugin_data_global->core_funcs.plugins_free_avail_plugins(plugins);
1358

                
1359
    json_prepare_response(request, response, NULL);
1360
}
1361

                
1362
static void
1363
json_plugins_get_plugin_info(struct json_object *request, struct json_object *response, void *user_data)
1364
{
1365
    struct json_object *params = json_object_object_get(request, "params");
1366
    struct json_object *ret;
1367
    char *plugin_name = NULL;
1368
    NNTPGrabPluginInfo plugin_info;
1369

                
1370
    if (!json_verify_parameters(request, response, params, 1) ||
1371
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
1372
        return;
1373
    }
1374

                
1375
    g_return_if_fail(plugin_data_global != NULL);
1376

                
1377
    if (json_object_get_type(json_object_array_get_idx(params, 0)) != json_type_string) {
1378
        json_prepare_response(request, response, "Parameter is of invalid type");
1379
        return;
1380
    }
1381

                
1382
    plugin_name = json_object_get_string(json_object_array_get_idx(params, 0));
1383

                
1384
    g_return_if_fail(plugin_name != NULL);
1385

                
1386
    if (!plugin_data_global->core_funcs.plugins_get_plugin_info(plugin_name, &plugin_info)) {
1387
        json_prepare_response(request, response, "No plugin by that name found");
1388
        return;
1389
    }
1390

                
1391
    ret = json_object_new_object();
1392
    json_object_object_add(ret, "name", json_object_new_string((char*) plugin_info.name));
1393
    json_object_object_add(ret, "version", json_object_new_string((char*) plugin_info.version));
1394
    json_object_object_add(ret, "author", json_object_new_string((char*)plugin_info.author));
1395
    json_object_object_add(ret, "url", json_object_new_string((char*) plugin_info.url));
1396
    json_object_object_add(ret, "description", json_object_new_string((char*) plugin_info.description));
1397
    json_object_object_add(ret, "is_loaded", json_object_new_boolean(plugin_info.is_loaded));
1398
    json_object_object_add(ret, "is_persistent", json_object_new_boolean(plugin_info.is_persistent));
1399

                
1400
    json_object_object_add(response, "result", ret);
1401

                
1402
    json_prepare_response(request, response, NULL);
1403
}
1404

                
1405
static void
1406
json_plugins_load_plugin(struct json_object *request, struct json_object *response, void *user_data)
1407
{
1408
    struct json_object *params = json_object_object_get(request, "params");
1409
    struct json_object *param_plugin;
1410
    char *plugin_name = NULL;
1411

                
1412
    char *errmsg = NULL;
1413

                
1414
    if (!json_verify_parameters(request, response, NULL, 1) ||
1415
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
1416
        return;
1417
    }
1418

                
1419
    g_return_if_fail(plugin_data_global != NULL);
1420

                
1421
    param_plugin = json_object_array_get_idx(params, 0);
1422
    if (json_object_get_type(param_plugin) != json_type_string) {
1423
        json_prepare_response(request, response, "Parameter 'plugin_name' is of invalid type");
1424
        return;
1425
    }
1426

                
1427
    plugin_name = json_object_get_string(param_plugin);
1428

                
1429
    g_return_if_fail(plugin_name != NULL);
1430

                
1431
    if (!plugin_data_global->core_funcs.plugins_load_plugin(plugin_name, &errmsg)) {
1432
        json_prepare_response(request, response, errmsg);
1433
        g_free(errmsg);
1434
        return;
1435
    }
1436

                
1437
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
1438
    json_prepare_response(request, response, NULL);
1439
}
1440

                
1441
static void
1442
json_plugins_unload_plugin(struct json_object *request, struct json_object *response, void *user_data)
1443
{
1444
    struct json_object *params = json_object_object_get(request, "params");
1445
    struct json_object *param_plugin;
1446
    char *plugin_name = NULL;
1447

                
1448
    char *errmsg = NULL;
1449

                
1450
    if (!json_verify_parameters(request, response, NULL, 1) ||
1451
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
1452
        return;
1453
    }
1454

                
1455
    g_return_if_fail(plugin_data_global != NULL);
1456

                
1457
    param_plugin = json_object_array_get_idx(params, 0);
1458
    if (json_object_get_type(param_plugin) != json_type_string) {
1459
        json_prepare_response(request, response, "Parameter 'plugin_name' is of invalid type");
1460
        return;
1461
    }
1462

                
1463
    plugin_name = json_object_get_string(param_plugin);
1464

                
1465
    g_return_if_fail(plugin_name != NULL);
1466

                
1467
    if (!plugin_data_global->core_funcs.plugins_unload_plugin(plugin_name, &errmsg)) {
1468
        json_prepare_response(request, response, errmsg);
1469
        g_free(errmsg);
1470
        return;
1471
    }
1472

                
1473
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
1474
    json_prepare_response(request, response, NULL);
1475
}
1476

                
1477
static void
1478
json_plugins_set_persistent(struct json_object *request, struct json_object *response, void *user_data)
1479
{
1480
    struct json_object *params = json_object_object_get(request, "params");
1481
    struct json_object *param_plugin;
1482
    char *plugin_name = NULL;
1483
    ngboolean persistent;
1484

                
1485
    if (!json_verify_parameters(request, response, NULL, 2) ||
1486
        !test_if_required_argument_is_supplied(request, response, params, 0) ||
1487
        !test_if_required_argument_is_supplied(request, response, params, 1)) {
1488
        return;
1489
    }
1490

                
1491
    g_return_if_fail(plugin_data_global != NULL);
1492

                
1493
    param_plugin = json_object_array_get_idx(params, 0);
1494
    if (json_object_get_type(param_plugin) != json_type_string) {
1495
        json_prepare_response(request, response, "Parameter 'plugin_name' is of invalid type");
1496
        return;
1497
    }
1498

                
1499
    plugin_name = json_object_get_string(param_plugin);
1500

                
1501
    g_return_if_fail(plugin_name != NULL);
1502

                
1503
    param_plugin = json_object_array_get_idx(params, 1);
1504
    if (json_object_get_type(param_plugin) != json_type_string) {
1505
        json_prepare_response(request, response, "Parameter 'persistent' is of invalid type");
1506
        return;
1507
    }
1508

                
1509
    persistent = json_object_get_boolean(param_plugin);
1510

                
1511
    if (!plugin_data_global->core_funcs.plugins_set_persistent(plugin_name, persistent)) {
1512
        json_prepare_response(request, response, "No Plugin by that name found");
1513
        return;
1514
    }
1515

                
1516
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
1517
    json_prepare_response(request, response, NULL);
1518
}
1519

                
1520
static void
1521
json_set_emit_log_messages(struct json_object *request, struct json_object *response, void *user_data)
1522
{
1523
    struct json_object *params = json_object_object_get(request, "params");
1524
    struct json_object *param_val;
1525

                
1526
    if (!json_verify_parameters(request, response, NULL, 1) ||
1527
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
1528
        return;
1529
    }
1530

                
1531
    g_return_if_fail(plugin_data_global != NULL);
1532

                
1533
    param_val = json_object_array_get_idx(params, 0);
1534
    if (json_object_get_type(param_val) != json_type_boolean) {
1535
        json_prepare_response(request, response, "Parameter 'val' is of invalid type");
1536
        return;
1537
    }
1538

                
1539
    plugin_data_global->core_funcs.set_emit_log_messages(json_object_get_boolean(param_val));
1540

                
1541
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
1542
    json_prepare_response(request, response, NULL);
1543
}
1544

                
1545
static void
1546
json_plugins_utils_strip_subject(struct json_object *request, struct json_object *response, void *user_data)
1547
{
1548
    json_prepare_response(request, response, "Not yet implemented");
1549
}
1550

                
1551
static void
1552
json_plugins_utils_calculate_file_size(struct json_object *request, struct json_object *response, void *user_data)
1553
{
1554
    json_prepare_response(request, response, "Not yet implemented");
1555
}
1556

                
1557
static void
1558
json_plugins_utils_calculate_estimated_time_remaining(struct json_object *request, struct json_object *response, void *user_data)
1559
{
1560
    json_prepare_response(request, response, "Not yet implemented");
1561
}
1562

                
1563
static void
1564
json_plugins_utils_get_readable_time_remaining(struct json_object *request, struct json_object *response, void *user_data)
1565
{
1566
    json_prepare_response(request, response, "Not yet implemented");
1567
}
1568

                
1569
static void
1570
json_plugins_utils_get_readable_finished_time(struct json_object *request, struct json_object *response, void *user_data)
1571
{
1572
    json_prepare_response(request, response, "Not yet implemented");
1573
}
1574

                
1575
static void
1576
json_plugins_utils_get_folder_listing(struct json_object *request, struct json_object *response, void *user_data)
1577
{
1578
    struct json_object *params = json_object_object_get(request, "params");
1579
    struct json_object *param_plugin;
1580
    char *parent = NULL;
1581
    struct json_object *response_folders;
1582
    NGList *folders = NULL;
1583
    NGList *list;
1584

                
1585
    if (!json_verify_parameters(request, response, NULL, 1)) {
1586
        return;
1587
    }
1588

                
1589
    g_return_if_fail(plugin_data_global != NULL);
1590

                
1591
    /* NOTE: parent can be NULL */
1592
    param_plugin = json_object_array_get_idx(params, 0);
1593
    if (param_plugin) {
1594
        if (json_object_get_type(param_plugin) != json_type_string) {
1595
            json_prepare_response(request, response, "Parameter 'parent' is of invalid type");
1596
            return;
1597
        }
1598

                
1599
        parent = json_object_get_string(param_plugin);
1600
    }
1601

                
1602
    if (!nntpgrab_utils_get_folder_listing(parent, &folders)) {
1603
        json_prepare_response(request, response, "Parent could not be found");
1604
        return;
1605
    }
1606

                
1607
    response_folders = json_object_new_array();
1608
    json_object_object_add(response, "result", response_folders);
1609

                
1610
    list = folders;
1611
    while (list) {
1612
        NNTPGrabFolder *folder = list->data;
1613
        struct json_object *folder_obj;
1614

                
1615
        folder_obj = json_object_new_object();
1616
        json_object_array_add(response_folders, folder_obj);
1617

                
1618
        json_object_object_add(folder_obj, "folder", json_object_new_string((char*) folder->folder));
1619
        json_object_object_add(folder_obj, "has_subfolders", json_object_new_boolean(folder->has_subfolders));
1620

                
1621
        list = ng_list_next(list);
1622
    }
1623

                
1624
    nntpgrab_utils_free_folder_listing(folders);
1625

                
1626
    json_prepare_response(request, response, NULL);
1627
}
1628