Statistics
| Revision:

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

History | View | Annotate | Download (66.2 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 "collections.h"
29
#include 
30

                
31
static NGPlugin *plugin_data_global = NULL;
32

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

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

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

                
76
    plugin_data_global = plugin_data;
77

                
78
    if (been_here) {
79
        return;
80
    }
81

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

                
119
void
120
jsonrpc_methods_unregister_methods(void)
121
{
122
    plugin_data_global = NULL;
123
}
124

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

                
133
    if (errmsg) {
134
        json_object_object_add(response, "error", json_object_new_string((char*) errmsg));
135
    } else {
136
        json_object_object_add(response, "error", NULL);
137
    }
138
}
139

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

                
148
    if (!params) {
149
        params = json_object_object_get(request, "params");
150
    }
151

                
152
    if (!params) {
153
        json_prepare_response(request, response, "JSON request lacks a 'params' field");
154
        return FALSE;
155
    }
156

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

                
162
    if (json_object_array_length(params) != num_params_expected) {
163
        char msg[64];
164

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

                
171
    return TRUE;
172
}
173

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

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

                
186
    return TRUE;
187
}
188

                
189
static void
190
json_get_version_info(struct json_object *request, struct json_object *response, void *user_data)
191
{
192
    struct json_object *obj = json_object_new_object();
193

                
194
    json_object_object_add(obj, "api_version", json_object_new_int(NNTPGRAB_PLUGIN_API_VERSION));
195
    json_object_object_add(obj, "major_version", json_object_new_int(MAJOR_VERSION));
196
    json_object_object_add(obj, "minor_version", json_object_new_int(MINOR_VERSION));
197
    json_object_object_add(obj, "micro_version", json_object_new_int(MICRO_VERSION));
198
    json_object_object_add(obj, "version", json_object_new_string(PACKAGE_VERSION));
199

                
200
    json_object_object_add(response, "result", obj);
201

                
202
    json_prepare_response(request, response, NULL);
203
}
204

                
205
static void
206
json_server_request_quit(struct json_object *request, struct json_object *response, void *user_data)
207
{
208
    g_return_if_fail(plugin_data_global != NULL);
209

                
210
    plugin_data_global->core_funcs.server_request_quit();
211

                
212
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
213
    json_prepare_response(request, response, NULL);
214
}
215

                
216
static void
217
json_config_get_avail_servers(struct json_object *request, struct json_object *response, void *user_data)
218
{
219
    NGList *servers;
220
    NGList *list;
221
    struct json_object *arr;
222

                
223
    if (!json_verify_parameters(request, response, NULL, 0)) {
224
        return;
225
    }
226

                
227
    g_return_if_fail(plugin_data_global != NULL);
228

                
229
    servers = plugin_data_global->core_funcs.config_get_avail_servers();
230

                
231
    arr = json_object_new_array();
232
    json_object_object_add(response, "result", arr);
233

                
234
    list = servers;
235
    while (list) {
236
        const char *servername = list->data;
237

                
238
        json_object_array_add(arr, json_object_new_string((char*) servername));
239

                
240
        list = ng_list_next(list);
241
    }
242

                
243
    plugin_data_global->core_funcs.config_free_avail_servers(servers);
244

                
245
    json_prepare_response(request, response, NULL);
246
}
247

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

                
256
    params = json_object_object_get(request, "params");
257
    if (!json_verify_parameters(request, response, params, 1) ||
258
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
259

                
260
        return;
261
    }
262

                
263
    g_return_if_fail(plugin_data_global != NULL);
264

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

                
270
    servername = json_object_get_string(json_object_array_get_idx(params, 0));
271

                
272
    if (!servername) {
273
        json_prepare_response(request, response, "Invalid argument");
274
        return;
275
    }
276

                
277
    g_return_if_fail(servername != NULL);
278

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

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

                
296
    json_object_object_add(response, "result", ret);
297

                
298
    json_prepare_response(request, response, NULL);
299
}
300

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

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

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

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

                
352
    memset(&server, 0, sizeof(server));
353

                
354
    if (!json_verify_parameters(request, response, params, 1) ||
355
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
356

                
357
        return;
358
    }
359

                
360
    g_return_if_fail(plugin_data_global != NULL);
361

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

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

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

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

                
396
    return;
397

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

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

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

                
420
    if (!json_verify_parameters(request, response, params, 1) ||
421
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
422

                
423
        return;
424
    }
425

                
426
    g_return_if_fail(plugin_data_global != NULL);
427

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

                
434
    servername = json_object_get_string(param_server);
435

                
436
    g_return_if_fail(servername != NULL);
437

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

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

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

                
469
    memset(&server, 0, sizeof(server));
470

                
471
    if (!json_verify_parameters(request, response, params, 2) ||
472
        !test_if_required_argument_is_supplied(request, response, params, 0) ||
473
        !test_if_required_argument_is_supplied(request, response, params, 1)) {
474

                
475
        return;
476
    }
477

                
478
    g_return_if_fail(plugin_data_global != NULL);
479

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

                
486
    servername = json_object_get_string(param_server);
487

                
488
    g_return_if_fail(servername != NULL);
489

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

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

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

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

                
524
    return;
525

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

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

                
539
static void
540
json_config_get_opts(struct json_object *request, struct json_object *response, void *user_data)
541
{
542
    NGConfigOpts opts;
543
    struct json_object *ret;
544

                
545
    if(!json_verify_parameters(request, response, NULL, 0)) {
546
        return;
547
    }
548

                
549
    g_return_if_fail(plugin_data_global != NULL);
550

                
551
    opts = plugin_data_global->core_funcs.config_get_opts();
552

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

                
571
    json_object_object_add(response, "result", ret);
572

                
573
    json_prepare_response(request, response, NULL);
574
}
575

                
576
static void
577
json_config_set_opts(struct json_object *request, struct json_object *response, void *user_data)
578
{
579
    NGConfigOpts opts;
580
    struct json_object *params = json_object_object_get(request, "params");
581
    struct json_object *param_opts;
582
    const char *missing_param = NULL;
583
    const char *invalid_param = NULL;
584
    char msg[128];
585
    char *errmsg = NULL;
586

                
587
    memset(&opts, 0, sizeof(opts));
588

                
589
    if (!json_verify_parameters(request, response, params, 1) ||
590
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
591
        return;
592
    }
593

                
594
    g_return_if_fail(plugin_data_global != NULL);
595

                
596
    param_opts = json_object_array_get_idx(params, 0);
597
    if (json_object_get_type(param_opts) != json_type_object) {
598
        json_prepare_response(request, response, "Parameter 'opts' is of invalid type");
599
        return;
600
    }
601

                
602
    json_process_parameter_str (param_opts, "download_directory", opts.download_directory);
603
    json_process_parameter_str (param_opts, "temp_directory", opts.temp_directory);
604
    json_process_parameter_bool(param_opts, "enable_intelligent_par2_downloading", opts.enable_intelligent_par2_downloading);
605
    json_process_parameter_bool(param_opts, "enable_par2_repair", opts.enable_par2_repair);
606
    json_process_parameter_str (param_opts, "auto_import_directory", opts.auto_import_directory);
607
    json_process_parameter_bool(param_opts, "enable_auto_import", opts.enable_auto_import);
608
    json_process_parameter_bool(param_opts, "move_file_after_auto_import", opts.move_file_after_auto_import);
609
    json_process_parameter_bool(param_opts, "enable_auto_unpack", opts.enable_auto_unpack);
610
    json_process_parameter_bool(param_opts, "enable_bandwidth_shaping", opts.enable_bandwidth_shaping);
611
    json_process_parameter_int (param_opts, "max_bandwidth", opts.max_bandwidth);
612
    json_process_parameter_bool(param_opts, "enable_webserver", opts.enable_webserver);
613
    json_process_parameter_int (param_opts, "webserver_port", opts.webserver_port);
614
    json_process_parameter_bool(param_opts, "enable_logger", opts.enable_logger);
615
    json_process_parameter_bool(param_opts, "auto_remove_files_after_repair", opts.auto_remove_files_after_repair);
616
    json_process_parameter_bool(param_opts, "auto_remove_files_after_unpack", opts.auto_remove_files_after_unpack);
617
    json_process_parameter_bool(param_opts, "auto_remove_collections_after_download", opts.auto_remove_collections_after_download);
618

                
619
    plugin_data_global->core_funcs.config_set_opts(opts);
620

                
621
    if (!plugin_data_global->core_funcs.config_save(&errmsg)) {
622
        json_object_object_add(response, "result", json_object_new_boolean(FALSE));
623
        json_prepare_response(request, response, errmsg);
624
        g_free(errmsg);
625
    } else {
626
        json_object_object_add(response, "result", json_object_new_boolean(TRUE));
627
        json_prepare_response(request, response, NULL);
628
    }
629

                
630
    return;
631

                
632
missing_parameter:
633
    memset(&msg, 0, sizeof(msg));
634
    snprintf(msg, sizeof(msg), "Missing parameter in array: '%s'", missing_param);
635
    json_prepare_response(request, response, msg);
636
    return;
637

                
638
invalid_parameter:
639
    memset(&msg, 0, sizeof(msg));
640
    snprintf(msg, sizeof(msg), "Parameter '%s' is of the invalid type", invalid_param);
641
    json_prepare_response(request, response, msg);
642
    return;
643
}
644

                
645
static void
646
json_schedular_start(struct json_object *request, struct json_object *response, void *user_data)
647
{
648
    ngboolean ret;
649
    if(!json_verify_parameters(request, response, NULL, 0)) {
650
        return;
651
    }
652

                
653
    g_return_if_fail(plugin_data_global != NULL);
654

                
655
    ret = plugin_data_global->core_funcs.schedular_start();
656

                
657
    json_object_object_add(response, "result", json_object_new_boolean(ret));
658
    json_prepare_response(request, response, NULL);
659
}
660

                
661
static void
662
json_schedular_stop(struct json_object *request, struct json_object *response, void *user_data)
663
{
664
    struct json_object *params = json_object_object_get(request, "params");
665
    struct json_object *param_schedular;
666
    ngboolean ret;
667
    char *reason = NULL;
668

                
669
    if (!json_verify_parameters(request, response, params, 1) ||
670
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
671
        return;
672
    }
673

                
674
    g_return_if_fail(plugin_data_global != NULL);
675

                
676
    param_schedular = json_object_array_get_idx(params, 0);
677
    if (json_object_get_type(param_schedular) != json_type_boolean) {
678
        json_prepare_response(request, response, "Parameter 'wait' is of invalid type");
679
        return;
680
    }
681

                
682
    ret = json_object_get_boolean(param_schedular);
683

                
684
    if(!plugin_data_global->core_funcs.schedular_stop(reason, ret))
685
    {
686
        json_prepare_response(request, response, reason);
687
        return;
688
    }
689

                
690
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
691
    json_prepare_response(request, response, NULL);
692
}
693

                
694
static void
695
json_schedular_get_state(struct json_object *request, struct json_object *response, void *user_data)
696
{
697
    NGSchedularState state;
698

                
699
    if(!json_verify_parameters(request, response, NULL, 0)) {
700
            return;
701
    }
702

                
703
    g_return_if_fail(plugin_data_global != NULL);
704

                
705
    state = plugin_data_global->core_funcs.schedular_get_state();
706

                
707
    json_object_object_add(response, "result", json_object_new_int(state));
708
    json_prepare_response(request, response, NULL);
709
}
710

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

                
730
    if (!json_verify_parameters(request, response, NULL, 7) ||
731
        !test_if_required_argument_is_supplied(request, response, params, 0) ||
732
        !test_if_required_argument_is_supplied(request, response, params, 1) ||
733
        !test_if_required_argument_is_supplied(request, response, params, 2) ||
734
        !test_if_required_argument_is_supplied(request, response, params, 3) ||
735
        !test_if_required_argument_is_supplied(request, response, params, 4) ||
736
        !test_if_required_argument_is_supplied(request, response, params, 5) ||
737
        !test_if_required_argument_is_supplied(request, response, params, 6)) {
738

                
739
        return;
740
    }
741

                
742
    g_return_if_fail(plugin_data_global != NULL);
743

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

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

                
758
    obj = json_object_array_get_idx(params, 2);
759
    if (json_object_get_type(obj) != json_type_string) {
760
        json_prepare_response(request, response, "Parameter 'poster' is of invalid type");
761
        return;
762
    }
763
    poster = json_object_get_string(obj);
764

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

                
772
    obj = json_object_array_get_idx(params, 4);
773
    if (json_object_get_type(obj) != json_type_int) {
774
        json_prepare_response(request, response, "Parameter 'file_size' is of invalid type");
775
        return;
776
    }
777
    file_size = json_object_get_int(obj);
778

                
779
    obj = json_object_array_get_idx(params, 5);
780
    if (json_object_get_type(obj) != json_type_array) {
781
        json_prepare_response(request, response, "Parameter 'groups' is of invalid type");
782
        return;
783
    }
784

                
785
    len = json_object_array_length(obj);
786
    for (i = 0; i < len; i++) {
787
        struct json_object *group_obj = json_object_array_get_idx(obj, i);
788
        char *groupname;
789

                
790
        g_return_if_fail(group_obj != NULL);
791

                
792
        if (json_object_get_type(group_obj) != json_type_string) {
793
            char msg[1024];
794

                
795
            memset(&msg, 0, sizeof(msg));
796
            snprintf(msg, sizeof(msg) - 1, "Element %i of parameter 'groups' is of invalid type", i);
797
            json_prepare_response(request, response, msg);
798
            return;
799
        }
800

                
801
        groupname = json_object_get_string(group_obj);
802

                
803
        g_return_if_fail(groupname != NULL);
804

                
805
        groups = ng_list_append(groups, groupname);
806
    }
807

                
808
    obj = json_object_array_get_idx(params, 6);
809
    if (json_object_get_type(obj) != json_type_array) {
810
        json_prepare_response(request, response, "Parameter 'parts' is of invalid type");
811
        return;
812
    }
813

                
814
    len = json_object_array_length(obj);
815
    for (i = 0; i < len; i++) {
816
        struct json_object *part_obj = json_object_array_get_idx(obj, i);
817
        NNTPPart *part;
818

                
819
        g_return_if_fail(part_obj != NULL);
820

                
821
        if (json_object_get_type(part_obj) != json_type_object) {
822
            memset(&msg, 0, sizeof(msg));
823
            snprintf(msg, sizeof(msg) - 1, "Element %i of parameter 'parts' is of invalid type", i);
824
            json_prepare_response(request, response, msg);
825
            return;
826
        }
827

                
828
        part = g_slice_new0(NNTPPart);
829
        json_process_parameter_str(part_obj, "message_id", part->message_id);   /* NOTE: This line can give a compiler warning, but this is intentional! */
830
        json_process_parameter_int(part_obj, "part_num", part->part_num);
831
        json_process_parameter_int(part_obj, "size", part->size);
832

                
833
        parts = ng_list_append(parts, part);
834
    }
835

                
836
    if (!plugin_data_global->core_funcs.schedular_add_file_to_queue(collection_name, subject, poster, timestamp, file_size * 1024, groups, parts, &errmsg)) {
837
        json_prepare_response(request, response, errmsg);
838
        g_free(errmsg);
839
        return;
840
    }
841

                
842
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
843
    json_prepare_response(request, response, NULL);
844

                
845
    ng_list_free(groups);
846

                
847
    list = parts;
848
    while (list) {
849
        NNTPPart *part = list->data;
850

                
851
        g_slice_free(NNTPPart, part);
852

                
853
        list = ng_list_next(list);
854
    }
855
    ng_list_free(parts);
856

                
857
    return;
858

                
859
missing_parameter:
860
    memset(&msg, 0, sizeof(msg));
861
    snprintf(msg, sizeof(msg), "Missing parameter in array: '%s'", missing_param);
862
    json_prepare_response(request, response, msg);
863
    return;
864

                
865
invalid_parameter:
866
    memset(&msg, 0, sizeof(msg));
867
    snprintf(msg, sizeof(msg), "Parameter '%s' is of the invalid type", invalid_param);
868
    json_prepare_response(request, response, msg);
869
    return;
870
}
871

                
872
static void
873
json_schedular_del_file_from_queue(struct json_object *request, struct json_object *response, void *user_data)
874
{
875
    struct json_object *params = json_object_object_get(request, "params");
876
    struct json_object *param_collection;
877
    char *collection_name;
878
    char *subject = NULL;
879
    char *errmsg = NULL;
880

                
881
    if (!json_verify_parameters(request, response, NULL, 2) ||
882
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
883
        return;
884
    }
885

                
886
    g_return_if_fail(plugin_data_global != NULL);
887

                
888
    param_collection = json_object_array_get_idx(params, 0);
889
    if (json_object_get_type(param_collection) != json_type_string) {
890
        json_prepare_response(request, response, "Parameter 'collection_name' is of invalid type");
891
        return;
892
    }
893

                
894
    collection_name = json_object_get_string(param_collection);
895

                
896
    g_return_if_fail(collection_name != NULL);
897

                
898
    param_collection = json_object_array_get_idx(params, 1);
899

                
900
    if (test_if_required_argument_is_supplied(request, response, params, 1))
901
    {
902
        if(json_object_get_type(param_collection) != json_type_string)
903
        {
904
            json_prepare_response(request, response, "Parameter 'subject', is of invalid type");
905
            return;
906
        }
907
        else
908
        {
909
            subject = json_object_get_string(param_collection);
910
            g_return_if_fail(subject != NULL);
911
        }
912
    }
913

                
914
    if (!plugin_data_global->core_funcs.schedular_del_file_from_queue(collection_name, subject, &errmsg)) {
915
        json_prepare_response(request, response, errmsg);
916
        g_free(errmsg);
917
        return;
918
    }
919

                
920
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
921
    json_prepare_response(request, response, NULL);
922
}
923

                
924
static void
925
json_schedular_restart_file(struct json_object *request, struct json_object *response, void *user_data)
926
{
927

                
928
    struct json_object *params = json_object_object_get(request, "params");
929
    struct json_object *param_file;
930
    char *collection_name;
931
    char *subject = NULL;
932
    char *errmsg = NULL;
933

                
934
    if (!json_verify_parameters(request, response, NULL, 2) ||
935
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
936
        return;
937
    }
938

                
939
    g_return_if_fail(plugin_data_global != NULL);
940

                
941
    param_file = json_object_array_get_idx(params, 0);
942
    if (json_object_get_type(param_file) != json_type_string) {
943
        json_prepare_response(request, response, "Parameter 'collection_name' is of invalid type");
944
        return;
945
    }
946

                
947
    collection_name = json_object_get_string(param_file);
948

                
949
    g_return_if_fail(collection_name != NULL);
950

                
951
    param_file = json_object_array_get_idx(params, 1);
952

                
953
    if (test_if_required_argument_is_supplied(request, response, params, 1))
954
    {
955
        if(json_object_get_type(param_file) != json_type_string)
956
        {
957
            json_prepare_response(request, response, "Parameter 'subject', is of invalid type");
958
            return;
959
        }
960
        else
961
        {
962
            subject = json_object_get_string(param_file);
963
            g_return_if_fail(subject != NULL);
964
        }
965
    }
966

                
967
    if (!plugin_data_global->core_funcs.schedular_restart_file(collection_name, subject, &errmsg)) {
968
        json_prepare_response(request, response, errmsg);
969
        g_free(errmsg);
970
        return;
971
    }
972

                
973
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
974
    json_prepare_response(request, response, NULL);
975
}
976

                
977
static void
978
json_schedular_save_queue(struct json_object *request, struct json_object *response, void *user_data)
979
{
980
    char *errmsg = NULL;
981

                
982
    if (!json_verify_parameters(request, response, NULL, 0)) {
983
        return;
984
    }
985

                
986
    g_return_if_fail(plugin_data_global != NULL);
987

                
988
    if (!plugin_data_global->core_funcs.schedular_save_queue(&errmsg)) {
989
        json_prepare_response(request, response, errmsg);
990
        g_free(errmsg);
991
        return;
992
    }
993

                
994
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
995
    json_prepare_response(request, response, NULL);
996
}
997

                
998
struct _foreach_cb_data {
999
    struct json_object *collections;
1000
    struct json_object *collection;
1001
    struct json_object *files;
1002
    struct json_object *file;
1003
    struct json_object *groups;
1004

                
1005
    boolean only_emit;
1006
    void *connection;
1007
};
1008

                
1009
static void
1010
foreach_collection_func(const char *collection_name, const char *poster, nguint64 total_size, nguint64 total_size_remaining, int position, void *data)
1011
{
1012
    struct _foreach_cb_data *cb_data = data;
1013
    int i_total_size;
1014
    int i_total_size_remaining;
1015

                
1016
    total_size /= 1024;
1017
    total_size_remaining /= 1024;
1018

                
1019
    i_total_size = total_size;
1020
    i_total_size_remaining = total_size_remaining;
1021

                
1022
    cb_data->collection = json_object_new_object();
1023

                
1024
    json_object_object_add(cb_data->collection, "collection_name", json_object_new_string((char*) collection_name));
1025
    json_object_object_add(cb_data->collection, "poster", json_object_new_string((char*) poster));
1026

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

                
1032
    if (cb_data->only_emit) {
1033
        struct json_object *emit_event = json_object_new_object();
1034

                
1035
        json_object_object_add(cb_data->collection, "position", json_object_new_int(position));
1036

                
1037
        json_object_object_add(emit_event, "id", NULL);
1038
        json_object_object_add(emit_event, "method", json_object_new_string("foreach_collection_event"));
1039
        json_object_object_add(emit_event, "params", cb_data->collection);
1040

                
1041
        jsonrpc_tcp_emit_event_to_connection(json_object_to_json_string(emit_event), cb_data->connection);
1042

                
1043
        json_object_put(emit_event);
1044
        cb_data->collection = NULL;
1045

                
1046
        return;
1047
    }
1048

                
1049
    json_object_array_add(cb_data->collections, cb_data->collection);
1050

                
1051
    cb_data->files = json_object_new_array();
1052
    json_object_object_add(cb_data->collection, "files", cb_data->files);
1053
}
1054

                
1055
static void
1056
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)
1057
{
1058
    struct _foreach_cb_data *cb_data = data;
1059
    int i_file_size;
1060
    int i_file_size_remaining;
1061

                
1062
    file_size /= 1024;
1063
    file_size_remaining /= 1024;
1064

                
1065
    i_file_size = file_size;
1066
    i_file_size_remaining = file_size_remaining;
1067

                
1068
    cb_data->file = json_object_new_object();
1069

                
1070
    if (cb_data->only_emit) {
1071
        json_object_object_add(cb_data->file, "collection_name", json_object_new_string((char*) collection_name));
1072
    }
1073

                
1074
    json_object_object_add(cb_data->file, "subject", json_object_new_string((char*) subject));
1075
    json_object_object_add(cb_data->file, "poster", json_object_new_string((char*) poster));
1076
    json_object_object_add(cb_data->file, "stamp", json_object_new_int((int) stamp));
1077
    json_object_object_add(cb_data->file, "file_size", json_object_new_int(i_file_size));
1078
    json_object_object_add(cb_data->file, "file_size_remaining", json_object_new_int(i_file_size_remaining));
1079
    json_object_object_add(cb_data->file, "num_parts_total", json_object_new_int(num_parts_total));
1080
    json_object_object_add(cb_data->file, "num_parts_downloaded", json_object_new_int(num_parts_downloaded));
1081
    json_object_object_add(cb_data->file, "num_parts_failed", json_object_new_int(num_parts_failed));
1082
    json_object_object_add(cb_data->file, "status", json_object_new_int(status));
1083
    json_object_object_add(cb_data->file, "filename", json_object_new_string((char*) filename));
1084

                
1085
    if (cb_data->only_emit) {
1086
        struct json_object *emit_event = json_object_new_object();
1087

                
1088
        json_object_object_add(cb_data->file, "position", json_object_new_int(position));
1089

                
1090
        json_object_object_add(emit_event, "id", NULL);
1091
        json_object_object_add(emit_event, "method", json_object_new_string("foreach_file_event"));
1092
        json_object_object_add(emit_event, "params", cb_data->file);
1093

                
1094
        jsonrpc_tcp_emit_event_to_connection(json_object_to_json_string(emit_event), cb_data->connection);
1095

                
1096
        json_object_put(emit_event);
1097
        cb_data->file = NULL;
1098

                
1099
        return;
1100
    }
1101

                
1102
    json_object_array_add(cb_data->files, cb_data->file);
1103

                
1104
    cb_data->groups = json_object_new_array();
1105
    json_object_object_add(cb_data->file, "groups", cb_data->groups);
1106
}
1107

                
1108
static void
1109
foreach_group_func(const char *collection_name, const char *subject, const char *group, void *data)
1110
{
1111
    struct _foreach_cb_data *cb_data = data;
1112

                
1113
    if (cb_data->only_emit) {
1114
        struct json_object *obj = json_object_new_object();
1115
        struct json_object *emit_event = json_object_new_object();
1116

                
1117
        json_object_object_add(obj, "collection_name", json_object_new_string((char *) collection_name));
1118
        json_object_object_add(obj, "subject", json_object_new_string((char *) subject));
1119
        json_object_object_add(obj, "group", json_object_new_string((char *) group));
1120

                
1121
        json_object_object_add(emit_event, "id", NULL);
1122
        json_object_object_add(emit_event, "method", json_object_new_string("foreach_group_event"));
1123
        json_object_object_add(emit_event, "params", obj);
1124

                
1125
        jsonrpc_tcp_emit_event_to_connection(json_object_to_json_string(emit_event), cb_data->connection);
1126

                
1127
        json_object_put(emit_event);
1128

                
1129
        return;
1130
    }
1131

                
1132
    json_object_array_add(cb_data->groups, json_object_new_string((char *) group));
1133
}
1134

                
1135
static void
1136
json_schedular_get_all_tasks(struct json_object *request, struct json_object *response, void *user_data)
1137
{
1138
    struct _foreach_cb_data cb_data;
1139

                
1140
    if (!json_verify_parameters(request, response, NULL, 0)) {
1141
        return;
1142
    }
1143

                
1144
    g_return_if_fail(plugin_data_global != NULL);
1145

                
1146
    memset(&cb_data, 0, sizeof(cb_data));
1147
    cb_data.collections = json_object_new_array();
1148
    cb_data.only_emit = FALSE;
1149

                
1150
    plugin_data_global->core_funcs.schedular_foreach_file(foreach_collection_func, foreach_file_func, foreach_group_func, &cb_data);
1151

                
1152
    json_prepare_response(request, response, NULL);
1153
    json_object_object_add(response, "result", cb_data.collections);
1154
}
1155

                
1156
static void
1157
json_schedular_foreach_task(struct json_object *request, struct json_object *response, void *user_data)
1158
{
1159
    struct _foreach_cb_data cb_data;
1160

                
1161
    if (!json_verify_parameters(request, response, NULL, 0)) {
1162
        return;
1163
    }
1164

                
1165
    g_return_if_fail(plugin_data_global != NULL);
1166

                
1167
    memset(&cb_data, 0, sizeof(cb_data));
1168
    cb_data.only_emit = TRUE;
1169
    cb_data.connection = user_data;
1170

                
1171
    plugin_data_global->core_funcs.schedular_foreach_file(foreach_collection_func, foreach_file_func, foreach_group_func, &cb_data);
1172

                
1173
    json_prepare_response(request, response, NULL);
1174
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
1175
}
1176

                
1177
static void
1178
json_schedular_move_file(struct json_object *request, struct json_object *response, void *user_data)
1179
{
1180
    struct json_object *params = json_object_object_get(request, "params");
1181
    struct json_object *param_file;
1182
    char *collection_name_src;
1183
    char *subject;
1184
    char *collection_name_dest;
1185
    int position;
1186
    ngboolean ret;
1187

                
1188
    if (!json_verify_parameters(request, response, NULL, 4) ||
1189
        !test_if_required_argument_is_supplied(request, response, params, 0) ||
1190
        !test_if_required_argument_is_supplied(request, response, params, 1) ||
1191
        !test_if_required_argument_is_supplied(request, response, params, 2) ||
1192
        !test_if_required_argument_is_supplied(request, response, params, 3)) {
1193
        return;
1194
    }
1195

                
1196
    g_return_if_fail(plugin_data_global != NULL);
1197

                
1198

                
1199
    param_file = json_object_array_get_idx(params, 0);
1200
    if (json_object_get_type(param_file) != json_type_string) {
1201
        json_prepare_response(request, response, "Parameter 'collection_name_src' is of invalid type");
1202
        return;
1203
    }
1204

                
1205
    collection_name_src = json_object_get_string(param_file);
1206

                
1207
    g_return_if_fail(collection_name_src != NULL);
1208

                
1209
    param_file = json_object_array_get_idx(params, 1);
1210
    if (json_object_get_type(param_file) != json_type_string) {
1211
        json_prepare_response(request, response, "Parameter 'subject' is of invalid type");
1212
        return;
1213
    }
1214

                
1215
    subject = json_object_get_string(param_file);
1216

                
1217
    g_return_if_fail(subject != NULL);
1218

                
1219
    param_file = json_object_array_get_idx(params, 2);
1220
    if (json_object_get_type(param_file) != json_type_string) {
1221
        json_prepare_response(request, response, "Parameter 'collection_name_dest' is of invalid type");
1222
        return;
1223
    }
1224

                
1225
    collection_name_dest = json_object_get_string(param_file);
1226

                
1227
    g_return_if_fail(collection_name_dest != NULL);
1228

                
1229
    param_file = json_object_array_get_idx(params, 3);
1230
    if (json_object_get_type(param_file) != json_type_int) {
1231
        json_prepare_response(request, response, "Parameter 'position' is of invalid type");
1232
        return;
1233
    }
1234

                
1235
    position = json_object_get_int(param_file);
1236

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

                
1239
    json_object_object_add(response, "result", json_object_new_boolean(ret));
1240
    json_prepare_response(request, response, NULL);
1241

                
1242
}
1243

                
1244
static void
1245
json_schedular_move_collection(struct json_object *request, struct json_object *response, void *user_data)
1246
{
1247
    struct json_object *params = json_object_object_get(request, "params");
1248
    struct json_object *param_collection;
1249
    int new_pos;
1250
    char *collection_name = NULL;
1251
    ngboolean ret;
1252

                
1253
    if (!json_verify_parameters(request, response, NULL, 2) ||
1254
        !test_if_required_argument_is_supplied(request, response, params, 0) ||
1255
        !test_if_required_argument_is_supplied(request, response, params, 1)) {
1256
        return;
1257
    }
1258

                
1259
    g_return_if_fail(plugin_data_global != NULL);
1260

                
1261
    param_collection = json_object_array_get_idx(params, 0);
1262
    if (json_object_get_type(param_collection) != json_type_string) {
1263
        json_prepare_response(request, response, "Parameter 'collection_name' is of invalid type");
1264
        return;
1265
    }
1266

                
1267
    collection_name = json_object_get_string(param_collection);
1268

                
1269
    g_return_if_fail(collection_name != NULL);
1270

                
1271
    param_collection = json_object_array_get_idx(params, 1);
1272
    if (json_object_get_type(param_collection) != json_type_int) {
1273
        json_prepare_response(request, response, "Parameter 'new_position' is of invalid type");
1274
        return;
1275
    }
1276

                
1277
    new_pos = json_object_get_int(param_collection);
1278

                
1279
    ret = plugin_data_global->core_funcs.schedular_move_collection(collection_name, new_pos);
1280

                
1281
    json_object_object_add(response, "result", json_object_new_boolean(ret));
1282
    json_prepare_response(request, response, NULL);
1283
}
1284

                
1285
static void
1286
json_schedular_mark_task_optional(struct json_object *request, struct json_object *response, void *user_data)
1287
{
1288
    struct json_object *params = json_object_object_get(request, "params");
1289
    struct json_object *param;
1290
    char *collection_name = NULL;
1291
    char *subject = NULL;
1292
    gboolean is_optional;
1293
    ngboolean ret;
1294

                
1295
    if (!json_verify_parameters(request, response, NULL, 3) ||
1296
        !test_if_required_argument_is_supplied(request, response, params, 0) ||
1297
        !test_if_required_argument_is_supplied(request, response, params, 1) ||
1298
        !test_if_required_argument_is_supplied(request, response, params, 2)) {
1299
        return;
1300
    }
1301

                
1302
    g_return_if_fail(plugin_data_global != NULL);
1303

                
1304
    param = json_object_array_get_idx(params, 0);
1305
    if (json_object_get_type(param) != json_type_string) {
1306
        json_prepare_response(request, response, "Parameter 'collection_name' is of invalid type");
1307
        return;
1308
    }
1309

                
1310
    collection_name = json_object_get_string(param);
1311

                
1312
    g_return_if_fail(collection_name != NULL);
1313

                
1314
    param = json_object_array_get_idx(params, 1);
1315
    if (json_object_get_type(param) != json_type_string) {
1316
        json_prepare_response(request, response, "Parameter 'subject' is of invalid type");
1317
        return;
1318
    }
1319

                
1320
    subject = json_object_get_string(param);
1321

                
1322
    g_return_if_fail(collection_name != NULL);
1323

                
1324
    param = json_object_array_get_idx(params, 2);
1325
    if (json_object_get_type(param) != json_type_boolean) {
1326
        json_prepare_response(request, response, "Parameter 'is_optional' is of invalid type");
1327
        return;
1328
    }
1329

                
1330
    is_optional = json_object_get_boolean(param);
1331

                
1332
    ret = plugin_data_global->core_funcs.schedular_mark_task_optional(collection_name, subject, is_optional);
1333

                
1334
    json_object_object_add(response, "result", json_object_new_boolean(ret));
1335
    json_prepare_response(request, response, NULL);
1336
}
1337

                
1338
static void
1339
json_plugins_get_avail_plugins(struct json_object *request, struct json_object *response, void *user_data)
1340
{
1341
    NGList *plugins;
1342
    NGList *list;
1343
    struct json_object *arr;
1344

                
1345
    if (!json_verify_parameters(request, response, NULL, 0)) {
1346
        return;
1347
    }
1348

                
1349
    g_return_if_fail(plugin_data_global != NULL);
1350

                
1351
    plugins = plugin_data_global->core_funcs.plugins_get_avail_plugins();
1352

                
1353
    arr = json_object_new_array();
1354
    json_object_object_add(response, "result", arr);
1355

                
1356
    list = plugins;
1357
    while (list) {
1358
        const char *name = list->data;
1359
        json_object_array_add(arr, json_object_new_string((char*) name));
1360
        list = ng_list_next(list);
1361
    }
1362

                
1363
    plugin_data_global->core_funcs.plugins_free_avail_plugins(plugins);
1364

                
1365
    json_prepare_response(request, response, NULL);
1366
}
1367

                
1368
static void
1369
json_plugins_get_plugin_info(struct json_object *request, struct json_object *response, void *user_data)
1370
{
1371
    struct json_object *params = json_object_object_get(request, "params");
1372
    struct json_object *ret;
1373
    char *plugin_name = NULL;
1374
    NNTPGrabPluginInfo plugin_info;
1375

                
1376
    if (!json_verify_parameters(request, response, params, 1) ||
1377
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
1378
        return;
1379
    }
1380

                
1381
    g_return_if_fail(plugin_data_global != NULL);
1382

                
1383
    if (json_object_get_type(json_object_array_get_idx(params, 0)) != json_type_string) {
1384
        json_prepare_response(request, response, "Parameter is of invalid type");
1385
        return;
1386
    }
1387

                
1388
    plugin_name = json_object_get_string(json_object_array_get_idx(params, 0));
1389

                
1390
    g_return_if_fail(plugin_name != NULL);
1391

                
1392
    if (!plugin_data_global->core_funcs.plugins_get_plugin_info(plugin_name, &plugin_info)) {
1393
        json_prepare_response(request, response, "No plugin by that name found");
1394
        return;
1395
    }
1396

                
1397
    ret = json_object_new_object();
1398
    json_object_object_add(ret, "name", json_object_new_string((char*) plugin_info.name));
1399
    json_object_object_add(ret, "version", json_object_new_string((char*) plugin_info.version));
1400
    json_object_object_add(ret, "author", json_object_new_string((char*)plugin_info.author));
1401
    json_object_object_add(ret, "url", json_object_new_string((char*) plugin_info.url));
1402
    json_object_object_add(ret, "description", json_object_new_string((char*) plugin_info.description));
1403
    json_object_object_add(ret, "is_loaded", json_object_new_boolean(plugin_info.is_loaded));
1404
    json_object_object_add(ret, "is_persistent", json_object_new_boolean(plugin_info.is_persistent));
1405

                
1406
    json_object_object_add(response, "result", ret);
1407

                
1408
    json_prepare_response(request, response, NULL);
1409
}
1410

                
1411
static void
1412
json_plugins_load_plugin(struct json_object *request, struct json_object *response, void *user_data)
1413
{
1414
    struct json_object *params = json_object_object_get(request, "params");
1415
    struct json_object *param_plugin;
1416
    char *plugin_name = NULL;
1417

                
1418
    char *errmsg = NULL;
1419

                
1420
    if (!json_verify_parameters(request, response, NULL, 1) ||
1421
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
1422
        return;
1423
    }
1424

                
1425
    g_return_if_fail(plugin_data_global != NULL);
1426

                
1427
    param_plugin = json_object_array_get_idx(params, 0);
1428
    if (json_object_get_type(param_plugin) != json_type_string) {
1429
        json_prepare_response(request, response, "Parameter 'plugin_name' is of invalid type");
1430
        return;
1431
    }
1432

                
1433
    plugin_name = json_object_get_string(param_plugin);
1434

                
1435
    g_return_if_fail(plugin_name != NULL);
1436

                
1437
    if (!plugin_data_global->core_funcs.plugins_load_plugin(plugin_name, &errmsg)) {
1438
        json_prepare_response(request, response, errmsg);
1439
        g_free(errmsg);
1440
        return;
1441
    }
1442

                
1443
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
1444
    json_prepare_response(request, response, NULL);
1445
}
1446

                
1447
static void
1448
json_plugins_unload_plugin(struct json_object *request, struct json_object *response, void *user_data)
1449
{
1450
    struct json_object *params = json_object_object_get(request, "params");
1451
    struct json_object *param_plugin;
1452
    char *plugin_name = NULL;
1453

                
1454
    char *errmsg = NULL;
1455

                
1456
    if (!json_verify_parameters(request, response, NULL, 1) ||
1457
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
1458
        return;
1459
    }
1460

                
1461
    g_return_if_fail(plugin_data_global != NULL);
1462

                
1463
    param_plugin = json_object_array_get_idx(params, 0);
1464
    if (json_object_get_type(param_plugin) != json_type_string) {
1465
        json_prepare_response(request, response, "Parameter 'plugin_name' is of invalid type");
1466
        return;
1467
    }
1468

                
1469
    plugin_name = json_object_get_string(param_plugin);
1470

                
1471
    g_return_if_fail(plugin_name != NULL);
1472

                
1473
    if (!plugin_data_global->core_funcs.plugins_unload_plugin(plugin_name, &errmsg)) {
1474
        json_prepare_response(request, response, errmsg);
1475
        g_free(errmsg);
1476
        return;
1477
    }
1478

                
1479
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
1480
    json_prepare_response(request, response, NULL);
1481
}
1482

                
1483
static void
1484
json_plugins_set_persistent(struct json_object *request, struct json_object *response, void *user_data)
1485
{
1486
    struct json_object *params = json_object_object_get(request, "params");
1487
    struct json_object *param_plugin;
1488
    char *plugin_name = NULL;
1489
    ngboolean persistent;
1490

                
1491
    if (!json_verify_parameters(request, response, NULL, 2) ||
1492
        !test_if_required_argument_is_supplied(request, response, params, 0) ||
1493
        !test_if_required_argument_is_supplied(request, response, params, 1)) {
1494
        return;
1495
    }
1496

                
1497
    g_return_if_fail(plugin_data_global != NULL);
1498

                
1499
    param_plugin = json_object_array_get_idx(params, 0);
1500
    if (json_object_get_type(param_plugin) != json_type_string) {
1501
        json_prepare_response(request, response, "Parameter 'plugin_name' is of invalid type");
1502
        return;
1503
    }
1504

                
1505
    plugin_name = json_object_get_string(param_plugin);
1506

                
1507
    g_return_if_fail(plugin_name != NULL);
1508

                
1509
    param_plugin = json_object_array_get_idx(params, 1);
1510
    if (json_object_get_type(param_plugin) != json_type_string) {
1511
        json_prepare_response(request, response, "Parameter 'persistent' is of invalid type");
1512
        return;
1513
    }
1514

                
1515
    persistent = json_object_get_boolean(param_plugin);
1516

                
1517
    if (!plugin_data_global->core_funcs.plugins_set_persistent(plugin_name, persistent)) {
1518
        json_prepare_response(request, response, "No Plugin by that name found");
1519
        return;
1520
    }
1521

                
1522
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
1523
    json_prepare_response(request, response, NULL);
1524
}
1525

                
1526
static void
1527
json_plugins_call_plugin_method(struct json_object *request, struct json_object *response, void *user_data)
1528
{
1529
    struct json_object *params = json_object_object_get(request, "params");
1530
    struct json_object *param_plugin;
1531
    struct json_object *param_method;
1532
    struct json_object *param_params;
1533
    char *plugin_name;
1534
    char *method;
1535
    char *parameters;
1536
    GError *error = NULL;
1537
    char *errmsg = NULL;
1538
    NGVariant *params_variant;
1539
    NGVariant *result;
1540
    char *result_str;
1541

                
1542
    if (!json_verify_parameters(request, response, NULL, 3) ||
1543
        !test_if_required_argument_is_supplied(request, response, params, 0) ||
1544
        !test_if_required_argument_is_supplied(request, response, params, 1) ||
1545
        !test_if_required_argument_is_supplied(request, response, params, 2)) {
1546
        return;
1547
    }
1548

                
1549
    g_return_if_fail(plugin_data_global != NULL);
1550

                
1551
    param_plugin = json_object_array_get_idx(params, 0);
1552
    if (json_object_get_type(param_plugin) != json_type_string) {
1553
        json_prepare_response(request, response, "Parameter 'plugin_name' is of invalid type");
1554
        return;
1555
    }
1556

                
1557
    plugin_name = json_object_get_string(param_plugin);
1558
    g_return_if_fail(plugin_name != NULL);
1559

                
1560
    param_method = json_object_array_get_idx(params, 1);
1561
    if (json_object_get_type(param_method) != json_type_string) {
1562
        json_prepare_response(request, response, "Parameter 'method_name' is of invalid type");
1563
        return;
1564
    }
1565

                
1566
    method = json_object_get_string(param_method);
1567
    g_return_if_fail(method != NULL);
1568

                
1569
    param_params = json_object_array_get_idx(params, 2);
1570
    if (json_object_get_type(param_params) != json_type_string) {
1571
        json_prepare_response(request, response, "Parameter 'paramaters' is of invalid type");
1572
        return;
1573
    }
1574

                
1575
    parameters = json_object_get_string(param_params);
1576
    g_return_if_fail(parameters != NULL);
1577

                
1578
    params_variant = (NGVariant*) g_variant_parse(NULL, parameters, NULL, NULL, &error);
1579
    if (!params_variant) {
1580
        json_prepare_response(request, response, error->message);
1581
        g_error_free(error);
1582
        return;
1583
    }
1584

                
1585
    if (!(result = plugin_data_global->core_funcs.plugins_call_plugin_method(plugin_name, method, params_variant, &errmsg))) {
1586
        json_prepare_response(request, response, errmsg);
1587
        g_free(errmsg);
1588
        return;
1589
    }
1590

                
1591
    result_str = g_variant_print((GVariant*) result, TRUE);
1592

                
1593
    json_object_object_add(response, "result", json_object_new_string(result_str));
1594
    json_prepare_response(request, response, NULL);
1595

                
1596
    g_free(result_str);
1597
    g_variant_unref((GVariant*) result);
1598
}
1599

                
1600
static void
1601
json_set_emit_log_messages(struct json_object *request, struct json_object *response, void *user_data)
1602
{
1603
    struct json_object *params = json_object_object_get(request, "params");
1604
    struct json_object *param_val;
1605

                
1606
    if (!json_verify_parameters(request, response, NULL, 1) ||
1607
        !test_if_required_argument_is_supplied(request, response, params, 0)) {
1608
        return;
1609
    }
1610

                
1611
    g_return_if_fail(plugin_data_global != NULL);
1612

                
1613
    param_val = json_object_array_get_idx(params, 0);
1614
    if (json_object_get_type(param_val) != json_type_boolean) {
1615
        json_prepare_response(request, response, "Parameter 'val' is of invalid type");
1616
        return;
1617
    }
1618

                
1619
    plugin_data_global->core_funcs.set_emit_log_messages(json_object_get_boolean(param_val));
1620

                
1621
    json_object_object_add(response, "result", json_object_new_boolean(TRUE));
1622
    json_prepare_response(request, response, NULL);
1623
}
1624

                
1625
static void
1626
json_plugins_utils_strip_subject(struct json_object *request, struct json_object *response, void *user_data)
1627
{
1628
    json_prepare_response(request, response, "Not yet implemented");
1629
}
1630

                
1631
static void
1632
json_plugins_utils_calculate_file_size(struct json_object *request, struct json_object *response, void *user_data)
1633
{
1634
    json_prepare_response(request, response, "Not yet implemented");
1635
}
1636

                
1637
static void
1638
json_plugins_utils_calculate_estimated_time_remaining(struct json_object *request, struct json_object *response, void *user_data)
1639
{
1640
    json_prepare_response(request, response, "Not yet implemented");
1641
}
1642

                
1643
static void
1644
json_plugins_utils_get_readable_time_remaining(struct json_object *request, struct json_object *response, void *user_data)
1645
{
1646
    json_prepare_response(request, response, "Not yet implemented");
1647
}
1648

                
1649
static void
1650
json_plugins_utils_get_readable_finished_time(struct json_object *request, struct json_object *response, void *user_data)
1651
{
1652
    json_prepare_response(request, response, "Not yet implemented");
1653
}
1654

                
1655
static void
1656
json_plugins_utils_get_folder_listing(struct json_object *request, struct json_object *response, void *user_data)
1657
{
1658
    struct json_object *params = json_object_object_get(request, "params");
1659
    struct json_object *param_plugin;
1660
    char *parent = NULL;
1661
    struct json_object *response_folders;
1662
    NGList *folders = NULL;
1663
    NGList *list;
1664

                
1665
    if (!json_verify_parameters(request, response, NULL, 1)) {
1666
        return;
1667
    }
1668

                
1669
    g_return_if_fail(plugin_data_global != NULL);
1670

                
1671
    /* NOTE: parent can be NULL */
1672
    param_plugin = json_object_array_get_idx(params, 0);
1673
    if (param_plugin) {
1674
        if (json_object_get_type(param_plugin) != json_type_string) {
1675
            json_prepare_response(request, response, "Parameter 'parent' is of invalid type");
1676
            return;
1677
        }
1678

                
1679
        parent = json_object_get_string(param_plugin);
1680
    }
1681

                
1682
    if (!nntpgrab_utils_get_folder_listing(parent, &folders)) {
1683
        json_prepare_response(request, response, "Parent could not be found");
1684
        return;
1685
    }
1686

                
1687
    response_folders = json_object_new_array();
1688
    json_object_object_add(response, "result", response_folders);
1689

                
1690
    list = folders;
1691
    while (list) {
1692
        NNTPGrabFolder *folder = list->data;
1693
        struct json_object *folder_obj;
1694

                
1695
        folder_obj = json_object_new_object();
1696
        json_object_array_add(response_folders, folder_obj);
1697

                
1698
        json_object_object_add(folder_obj, "folder", json_object_new_string((char*) folder->folder));
1699
        json_object_object_add(folder_obj, "has_subfolders", json_object_new_boolean(folder->has_subfolders));
1700

                
1701
        list = ng_list_next(list);
1702
    }
1703

                
1704
    nntpgrab_utils_free_folder_listing(folders);
1705

                
1706
    json_prepare_response(request, response, NULL);
1707
}
1708