Statistics
| Revision:

root / trunk / base / nzbcreator.c @ 1833

History | View | Annotate | Download (21 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
#ifdef HAVE_SOUP
23
#include 
24
#endif
25
#ifdef HAVE_SOUP_GNOME
26
#include 
27
#endif
28
#include "nntpgrab_utils.h"
29
#include "nntpgrab_types.h"
30

                
31
#define URI "https://www.nntpgrab.nl/onlinesearch/search.php"
32

                
33
#ifdef HAVE_SOUP
34
static void authenticate_cb(SoupSession *session, SoupMessage *msg, SoupAuth *auth, gboolean retrying, gpointer user_data)
35
{
36
    soup_auth_authenticate(auth, "guest", "guest");
37
}
38
#endif
39

                
40
ngboolean
41
nntpgrab_utils_nzbcreator_check_api_version(ngboolean *api_okay, char **errmsg)
42
{
43
#ifdef HAVE_SOUP
44
    int result = 0;
45
    SoupSession *session;
46
    SoupMessage *msg;
47
    GError *err = NULL;
48
    NGList *list;
49

                
50
    g_return_val_if_fail(api_okay != NULL, FALSE);
51

                
52
    session = soup_session_sync_new();
53

                
54
#ifdef HAVE_SOUP_GNOME
55
    /* Enable proxy support when using GNOME 2.26.0 or higher */
56
    soup_session_add_feature_by_type(session, SOUP_TYPE_GNOME_FEATURES_2_26);
57
#endif
58

                
59
#ifdef HAVE_SOUP_GZIP
60
    /* Enable gzip compression */
61
    soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_DECODER);
62
#endif
63

                
64
    g_signal_connect (session, "authenticate", G_CALLBACK(authenticate_cb), NULL);
65

                
66
    msg = soup_xmlrpc_request_new(URI, "getProtocolVersion", G_TYPE_INVALID);
67
    soup_session_send_message(session, msg);
68

                
69
    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
70
        if (errmsg) {
71
            *errmsg = g_strdup(msg->reason_phrase);
72
        }
73

                
74
        g_object_unref(msg);
75
        g_object_unref(session);
76
        return FALSE;
77
    }
78

                
79
    if (!soup_xmlrpc_extract_method_response(msg->response_body->data, msg->response_body->length, &err, G_TYPE_INT, &result)) {
80
        if (err) {
81
            if (errmsg) {
82
                *errmsg = g_strdup(err->message);
83
            }
84

                
85
            g_error_free(err);
86
        }
87

                
88
        g_object_unref(msg);
89
        g_object_unref(session);
90

                
91
        return FALSE;
92
    }
93

                
94
    g_object_unref(msg);
95
    g_object_unref(session);
96

                
97
    if (result == 20110613) {
98
        *api_okay = TRUE;
99
    } else {
100
        *api_okay = FALSE;
101
    }
102

                
103
    return TRUE;
104
#else
105
    if (errmsg) {
106
        *errmsg = g_strdup(_("Support for the Online Search hasn't been enabled in this build. Please rebuild NNTPGrab to enable this feature"));
107
    }
108
    return FALSE;
109
#endif
110
}
111

                
112
void
113
nntpgrab_utils_nzbcreator_free_groups(NGList *groups)
114
{
115
    NGList *list = groups;
116
    while (list) {
117
        g_slice_free(NZBCreatorGroup, list->data);
118
        list = ng_list_next(list);
119
    }
120
    ng_list_free(groups);
121
}
122

                
123
NGList *
124
nntpgrab_utils_nzbcreator_get_all_groups(char **errmsg)
125
{
126
    NGList *ret = NULL;
127

                
128
#ifndef HAVE_SOUP
129
    if (errmsg) {
130
        *errmsg = g_strdup(_("Support for the Online Search hasn't been enabled in this build. Please rebuild NNTPGrab to enable this feature"));
131
    }
132
#else
133
    SoupSession *session = soup_session_sync_new();
134
    SoupMessage *msg = soup_xmlrpc_request_new(URI, "getListOfAvailableGroups", G_TYPE_INVALID);
135
    GError *err = NULL;
136
    int i;
137
    GValueArray *result = NULL;
138
    GHashTable *group_arr = NULL;
139

                
140
#ifdef SOUP_TYPE_GNOME_FEATURES_2_26
141
    /* Enable proxy support when using GNOME 2.26.0 or higher */
142
    soup_session_add_feature_by_type(session, SOUP_TYPE_GNOME_FEATURES_2_26);
143
#endif
144

                
145
#ifdef HAVE_SOUP_GZIP
146
    /* Enable gzip compression */
147
    soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_DECODER);
148
#endif
149

                
150
    g_signal_connect (session, "authenticate", G_CALLBACK(authenticate_cb), NULL);
151

                
152
    soup_session_send_message(session, msg);
153
    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
154
        if (errmsg) {
155
            *errmsg = g_strdup_printf("Server returned unknown error: %s (%i)", msg->reason_phrase, msg->status_code);
156
        }
157
        g_object_unref(msg);
158
        g_object_unref(session);
159
        return NULL;
160
    }
161

                
162
    if (!soup_xmlrpc_extract_method_response(msg->response_body->data, msg->response_body->length, &err, G_TYPE_VALUE_ARRAY, &result)) {
163
        if (errmsg) {
164
            if (err) {
165
                *errmsg = g_strdup_printf("Unable to parse reply: %s", err->message);
166
            } else {
167
                *errmsg = g_strdup_printf(__FILE__ ":%i Unable to parse reply from server. See the console for more details", __LINE__);
168
            }
169
        }
170

                
171
        if (err) {
172
            g_error_free(err);
173
        }
174

                
175
        g_object_unref(msg);
176
        g_object_unref(session);
177

                
178
        return NULL;
179
    }
180

                
181
    for (i = 0; i < result->n_values; i++) {
182
        NZBCreatorGroup *group;
183
        char *groupname = NULL;
184
        int group_id = -1;
185

                
186
        if (!soup_value_array_get_nth(result, i, G_TYPE_HASH_TABLE, &group_arr)) {
187
            g_warning(__FILE__ ":%i Unable to parse values", __LINE__);
188
            continue;
189
        }
190

                
191
        if (!soup_value_hash_lookup_vals(group_arr, "group_id", G_TYPE_INT, &group_id, "newsgroup", G_TYPE_STRING, &groupname, NULL)) {
192
            g_warning(__FILE__ ":%i Unable to parse values", __LINE__);
193
            g_hash_table_destroy(group_arr);
194
            continue;
195
        }
196

                
197
        group = g_slice_new0(NZBCreatorGroup);
198
        strncpy(group->newsgroup, groupname, sizeof(group->newsgroup) - 1);
199
        group->group_id = group_id;
200

                
201
        ret = ng_list_append(ret, group);
202
    }
203

                
204
    g_value_array_free(result);
205

                
206
    g_object_unref(msg);
207
    g_object_unref(session);
208
#endif
209

                
210
    return ret;
211
}
212

                
213
void
214
nntpgrab_utils_nzbcreator_free_result(NZBCreatorSearchResult *result)
215
{
216
    NGList *list;
217

                
218
    list = result->collections;
219
    while (list) {
220
        g_slice_free(NZBCreatorCollection, list->data);
221
        list = ng_list_next(list);
222
    }
223

                
224
    g_list_free((GList*) result->collections);
225
    g_slice_free(NZBCreatorSearchResult, result);
226
}
227

                
228
NZBCreatorSearchResult *
229
nntpgrab_utils_nzbcreator_perform_search(NZBCreatorSearchOpts opts, char **errmsg)
230
{
231
    NZBCreatorSearchResult *result = NULL;
232

                
233
#ifndef HAVE_SOUP
234
    if (errmsg) {
235
        *errmsg = g_strdup(_("Support for the Online Search hasn't been enabled in this build. Please rebuild NNTPGrab to enable this feature"));
236
    }
237
#else
238
    SoupSession *session;
239
    SoupMessage *msg;
240
    GHashTable *args;
241
    GError *err = NULL;
242
    GHashTable *rpc_result = NULL;
243
    GValueArray *matches = NULL;
244
    int i;
245

                
246
    g_return_val_if_fail(strlen(opts.query) > 0, FALSE);
247
    g_return_val_if_fail(opts.max_age <= 150, FALSE);
248
    g_return_val_if_fail(opts.percentage_complete <= 100, FALSE);
249

                
250
    session = soup_session_sync_new();
251

                
252
#ifdef SOUP_TYPE_GNOME_FEATURES_2_26
253
    /* Enable proxy support when using GNOME 2.26.0 or higher */
254
    soup_session_add_feature_by_type(session, SOUP_TYPE_GNOME_FEATURES_2_26);
255
#endif
256

                
257
#ifdef HAVE_SOUP_GZIP
258
    /* Enable gzip compression */
259
    soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_DECODER);
260
#endif
261

                
262
    g_signal_connect (session, "authenticate", G_CALLBACK(authenticate_cb), NULL);
263

                
264
    args = soup_value_hash_new_with_vals(   "query", G_TYPE_STRING, opts.query,
265
                                            "search_only_in", G_TYPE_INT, opts.search_only_in,
266
                                            "max_age", G_TYPE_INT, opts.max_age,
267
                                            NULL);
268

                
269
    if (strlen(opts.username) > 0 && strlen(opts.password) > 0) {
270
        soup_value_hash_insert(args, "username", G_TYPE_STRING, opts.username);
271
        soup_value_hash_insert(args, "password", G_TYPE_STRING, opts.password);
272
    }
273

                
274
    if (opts.minimal_file_size > 0) {
275
        /* Libsoup doesn't support 64bit integers as XML-RPC parameters */
276
        char *tmp = g_strdup_printf("%"G_GUINT64_FORMAT, opts.minimal_file_size);
277
        soup_value_hash_insert(args, "minimal_file_size", G_TYPE_STRING, tmp);
278
        g_free(tmp);
279
    }
280
    if (opts.maximal_file_size > 0) {
281
        char *tmp = g_strdup_printf("%"G_GUINT64_FORMAT, opts.maximal_file_size);
282
        soup_value_hash_insert(args, "maximal_file_size", G_TYPE_STRING, tmp);
283
        g_free(tmp);
284
    }
285
    if (opts.percentage_complete > 0) {
286
        soup_value_hash_insert(args, "percentage_complete", G_TYPE_INT, opts.percentage_complete);
287
    }
288
    if (opts.group_to_search > 0) {
289
        soup_value_hash_insert(args, "group_to_search", G_TYPE_INT, opts.group_to_search);
290
    }
291
    if (opts.file_type != NNTP_FILE_TYPE_UNKNOWN) {
292
        soup_value_hash_insert(args, "file_type", G_TYPE_INT, opts.file_type);
293
    }
294

                
295
    msg = soup_xmlrpc_request_new(URI, "performSearch", G_TYPE_HASH_TABLE, args, G_TYPE_INVALID);
296

                
297
    soup_session_send_message(session, msg);
298

                
299
    g_hash_table_destroy(args);
300

                
301
    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
302
        if (errmsg) {
303
            *errmsg = g_strdup_printf("Server returned unknown error: %s (%i)", msg->reason_phrase, msg->status_code);
304
        }
305
        g_object_unref(msg);
306
        g_object_unref(session);
307
        return NULL;
308
    }
309

                
310
    if (!soup_xmlrpc_extract_method_response(msg->response_body->data, msg->response_body->length, &err, G_TYPE_HASH_TABLE, &rpc_result)) {
311
        if (errmsg) {
312
            if (err) {
313
                *errmsg = g_strdup_printf("Unable to parse reply: %s", err->message);
314
            } else {
315
                *errmsg = g_strdup_printf(__FILE__ ":%i Unable to parse reply from server. See the console for more details", __LINE__);
316
            }
317
        }
318

                
319
        if (err) {
320
            g_error_free(err);
321
        }
322

                
323
        g_object_unref(msg);
324
        g_object_unref(session);
325

                
326
        return NULL;
327
    }
328

                
329
    result = g_slice_new0(NZBCreatorSearchResult);
330
    if (!soup_value_hash_lookup_vals(rpc_result,    "number_of_hits", G_TYPE_INT, &result->number_of_hits,
331
                                                    "number_of_results", G_TYPE_INT, &result->number_of_results,
332
                                                    "matches", G_TYPE_VALUE_ARRAY, &matches,
333
                                                    NULL)) {
334
        g_warning(__FILE__ ":%i Unable to parse values", __LINE__);
335
        g_slice_free(NZBCreatorSearchResult, result);
336
        g_hash_table_destroy(rpc_result);
337
        g_object_unref(msg);
338
        g_object_unref(session);
339
        return NULL;
340
    }
341

                
342
    for (i = 0; i < matches->n_values; i++) {
343
        NZBCreatorCollection *collection;
344
        GHashTable *hash_collection = NULL;
345
        int collection_id = 0;
346
        char *collection_name;
347
        char *short_collection_name;
348
        char *poster;
349
        char *newsgroup;
350
        int stamp = 0;
351
        int num_parts_found = -1;
352
        int num_parts_expected = -1;
353
        /* gint64 */guint total_size = -1;
354
        int complete_percentage = 0;
355
        int num_regular_files = 0;
356
        int num_par2_files = 0;
357
        int first_file_id = -1;
358

                
359
        if (!soup_value_array_get_nth(matches, i, G_TYPE_HASH_TABLE, &hash_collection)) {
360
            g_warning(__FILE__ ":%i Unable to parse values", __LINE__);
361
            continue;
362
        }
363

                
364
        if (!soup_value_hash_lookup_vals(hash_collection,   "collection_id", G_TYPE_INT, &collection_id,
365
                                                            "collection_name", G_TYPE_STRING, &collection_name,
366
                                                            "short_collection_name", G_TYPE_STRING, &short_collection_name,
367
                                                            "poster", G_TYPE_STRING, &poster,
368
                                                            "total_size", G_TYPE_INT, &total_size,       // FIXME: possible overflow!
369
                                                            "newsgroup", G_TYPE_STRING, &newsgroup,
370
                                                            "stamp", G_TYPE_INT, &stamp,
371
                                                            "num_parts_found", G_TYPE_INT, &num_parts_found,
372
                                                            "num_parts_expected", G_TYPE_INT, &num_parts_expected,
373
                                                            "complete_percentage", G_TYPE_INT, &complete_percentage,
374
                                                            "num_regular_files", G_TYPE_INT, &num_regular_files,
375
                                                            "num_par2_files", G_TYPE_INT, &num_par2_files,
376
                                                            "first_file_id", G_TYPE_INT, &first_file_id,
377
                                                            NULL)) {
378
            g_warning(__FILE__ ":%i Unable to parse values", __LINE__);
379
            g_hash_table_destroy(hash_collection);
380
            continue;
381
        }
382

                
383
        collection = g_slice_new0(NZBCreatorCollection);
384
        collection->collection_id = collection_id;
385
        strncpy(collection->collection_name, collection_name, sizeof(collection->collection_name) - 1);
386
        strncpy(collection->short_collection_name, short_collection_name, sizeof(collection->short_collection_name) - 1);
387
        strncpy(collection->poster, poster, sizeof(collection->poster) - 1);
388
        collection->total_size = total_size;
389
        strncpy(collection->newsgroup, newsgroup, sizeof(collection->newsgroup) - 1);
390
        collection->stamp = (time_t) stamp;
391
        collection->num_parts_found = num_parts_found;
392
        collection->num_parts_expected = num_parts_expected;
393
        collection->complete_percentage = complete_percentage;
394
        collection->num_regular_files = num_regular_files;
395
        collection->num_par2_files = num_par2_files;
396
        collection->first_file_id = first_file_id;
397

                
398
        result->collections = ng_list_append(result->collections, collection);
399
    }
400

                
401
    g_hash_table_destroy(rpc_result);
402
    g_object_unref(msg);
403
    g_object_unref(session);
404
#endif
405

                
406
    return result;
407
}
408

                
409
NGList *
410
nntpgrab_utils_nzbcreator_retrieve_collection_details(ngint64 collection_id, time_t stamp, char **errmsg)
411
{
412
    NGList *result = NULL;
413

                
414
#ifndef HAVE_SOUP
415
    if (errmsg) {
416
        *errmsg = g_strdup(_("Support for the Online Search hasn't been enabled in this build. Please rebuild NNTPGrab to enable this feature"));
417
    }
418
#else
419
    SoupSession *session;
420
    SoupMessage *msg;
421
    GHashTable *args;
422
    GError *err = NULL;
423
    GHashTable *rpc_result = NULL;
424
    GValueArray *matches = NULL;
425
    int i;
426

                
427
    g_return_val_if_fail(collection_id > 0, FALSE);
428

                
429
    session = soup_session_sync_new();
430

                
431
#ifdef SOUP_TYPE_GNOME_FEATURES_2_26
432
    /* Enable proxy support when using GNOME 2.26.0 or higher */
433
    soup_session_add_feature_by_type(session, SOUP_TYPE_GNOME_FEATURES_2_26);
434
#endif
435

                
436
#ifdef HAVE_SOUP_GZIP
437
    /* Enable gzip compression */
438
    soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_DECODER);
439
#endif
440

                
441
    g_signal_connect (session, "authenticate", G_CALLBACK(authenticate_cb), NULL);
442

                
443
    args = soup_value_hash_new_with_vals("collection_id", G_TYPE_INT, (int) collection_id,
444
                                         "stamp", G_TYPE_INT, (int) stamp,
445
                                         NULL);
446
    msg = soup_xmlrpc_request_new(URI, "retrieveCollectionDetails", G_TYPE_HASH_TABLE, args, G_TYPE_INVALID);
447

                
448
    soup_session_send_message(session, msg);
449

                
450
    g_hash_table_destroy(args);
451

                
452
    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
453
        if (errmsg) {
454
            *errmsg = g_strdup_printf("Server returned unknown error: %s (%i)", msg->reason_phrase, msg->status_code);
455
        }
456
        g_object_unref(msg);
457
        g_object_unref(session);
458
        return NULL;
459
    }
460

                
461
    if (!soup_xmlrpc_extract_method_response(msg->response_body->data, msg->response_body->length, &err, G_TYPE_VALUE_ARRAY, &matches)) {
462
        if (errmsg) {
463
            if (err) {
464
                *errmsg = g_strdup_printf("Unable to parse reply: %s", err->message);
465
            } else {
466
                *errmsg = g_strdup_printf(__FILE__ ":%i Unable to parse reply from server:\n%s", __LINE__, msg->response_body->data);
467
            }
468
        }
469

                
470
        if (err) {
471
            g_error_free(err);
472
        }
473

                
474
        g_object_unref(msg);
475
        g_object_unref(session);
476

                
477
        return NULL;
478
    }
479

                
480
    for (i = 0; i < matches->n_values; i++) {
481
        NZBCreatorFile *file;
482
        GHashTable *hash_file = NULL;
483
        /* gint64 */gint file_id = -1;
484
        char *subject = NULL;
485
        char *poster = NULL;
486
        int num_parts_found = -1;
487
        int num_parts_expected = -1;
488
        int file_type = NNTP_FILE_TYPE_UNKNOWN;
489
        /* gint64 */gint file_size = -1;
490
        int complete_percentage = 0;
491
        int stamp;
492

                
493
        if (!soup_value_array_get_nth(matches, i, G_TYPE_HASH_TABLE, &hash_file)) {
494
            g_warning(__FILE__ ":%i Unable to parse values", __LINE__);
495
            continue;
496
        }
497

                
498
        if (!soup_value_hash_lookup_vals(hash_file, "file_id", G_TYPE_INT, &file_id,            // FIXME: possible overflow!
499
                                                    "subject", G_TYPE_STRING, &subject,
500
                                                    "poster", G_TYPE_STRING, &poster,
501
                                                    "num_parts_found", G_TYPE_INT, &num_parts_found,
502
                                                    "num_parts_expected", G_TYPE_INT, &num_parts_expected,
503
                                                    "file_type", G_TYPE_INT, &file_type,
504
                                                    "file_size", G_TYPE_INT, &file_size,        // FIXME: possible overflow!
505
                                                    "stamp", G_TYPE_INT, &stamp,
506
                                                    "complete_percentage", G_TYPE_INT, &complete_percentage,
507
                                                    NULL)) {
508
            g_warning(__FILE__ ":%i Unable to parse values", __LINE__);
509
            continue;
510
        }
511

                
512
        file = g_slice_new0(NZBCreatorFile);
513
        file->file_id = file_id;
514
        strncpy(file->subject, subject, sizeof(file->subject) - 1);
515
        strncpy(file->poster, poster, sizeof(file->poster) - 1);
516
        file->num_parts_found = num_parts_found;
517
        file->num_parts_expected = num_parts_expected;
518
        file->file_type = (NNTPFileType) file_type;
519
        file->file_size = file_size;
520
        file->stamp = (time_t) stamp;
521
        file->complete_percentage = complete_percentage;
522

                
523
        result = ng_list_append(result, file);
524
    }
525

                
526
    g_object_unref(msg);
527
    g_object_unref(session);
528
#endif
529

                
530
    return result;
531
}
532

                
533
void nntpgrab_utils_nzbcreator_free_collection_details(NGList *files)
534
{
535
    NGList *list;
536

                
537
    list = files;
538
    while (list) {
539
        g_slice_free(NZBCreatorFile, list->data);
540
        list = ng_list_next(list);
541
    }
542

                
543
    g_list_free((GList*) files);
544
}
545

                
546
char *
547
nntpgrab_utils_nzbcreator_generate_NZB(NGList *file_ids, char **errmsg)
548
{
549
    char *result = NULL;
550

                
551
#ifndef HAVE_SOUP
552
    if (errmsg) {
553
        *errmsg = g_strdup(_("Support for the Online Search hasn't been enabled in this build. Please rebuild NNTPGrab to enable this feature"));
554
    }
555
#else
556
    SoupSession *session;
557
    SoupMessage *msg;
558
    GError *err = NULL;
559
    GValueArray *args = NULL;
560
    NGList *list;
561

                
562
    args = soup_value_array_new();
563
    list = file_ids;
564
    while (list) {
565
        soup_value_array_append(args, G_TYPE_INT, GPOINTER_TO_INT(list->data));
566
        list = ng_list_next(list);
567
    }
568

                
569
    session = soup_session_sync_new();
570

                
571
#ifdef HAVE_SOUP_GNOME
572
    /* Enable proxy support when using GNOME 2.26.0 or higher */
573
    soup_session_add_feature_by_type(session, SOUP_TYPE_GNOME_FEATURES_2_26);
574
#endif
575

                
576
#ifdef HAVE_SOUP_GZIP
577
    /* Enable gzip compression */
578
    soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_DECODER);
579
#endif
580

                
581
    g_signal_connect (session, "authenticate", G_CALLBACK(authenticate_cb), NULL);
582

                
583
    msg = soup_xmlrpc_request_new(URI, "generateNZB", G_TYPE_VALUE_ARRAY, args, G_TYPE_INVALID);
584
    soup_session_send_message(session, msg);
585

                
586
    g_value_array_free(args);
587

                
588
    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
589
        if (errmsg) {
590
            *errmsg = g_strdup_printf("Server returned unknown error: %s (%i)", msg->reason_phrase, msg->status_code);
591
        }
592
        g_object_unref(msg);
593
        g_object_unref(session);
594
        return NULL;
595
    }
596

                
597
    if (!soup_xmlrpc_extract_method_response(msg->response_body->data, msg->response_body->length, &err, G_TYPE_STRING, &result)) {
598
        if (errmsg) {
599
            if (err) {
600
                *errmsg = g_strdup_printf("Unable to parse reply: %s", err->message);
601
            } else {
602
                *errmsg = g_strdup_printf(__FILE__ ":%i Unable to parse reply from server. See the console for more details", __LINE__);
603
            }
604
        }
605

                
606
        if (err) {
607
            g_error_free(err);
608
        }
609

                
610
        g_object_unref(msg);
611
        g_object_unref(session);
612

                
613
        return NULL;
614
    }
615

                
616
    g_object_unref(msg);
617
    g_object_unref(session);
618
#endif
619

                
620
    return result;
621
}
622