pygi-repository.c 12.4 KB
Newer Older
Simon van der Linden's avatar
Simon van der Linden committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* -*- Mode: C; c-basic-offset: 4 -*-
 * vim: tabstop=4 shiftwidth=4 expandtab
 *
 * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
 *
 *   pygi-repository.c: GIRepository wrapper.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Simon van der Linden's avatar
Simon van der Linden committed
20
21
 */

22
23
#include "pygi-repository.h"
#include "pygi-info.h"
24
#include "pygi-basictype.h"
Christoph Reiter's avatar
Christoph Reiter committed
25
#include "pygi-util.h"
26

Simon van der Linden's avatar
Simon van der Linden committed
27
28
PyObject *PyGIRepositoryError;

29
PYGI_DEFINE_TYPE("gi.Repository", PyGIRepository_Type, PyGIRepository);
Simon van der Linden's avatar
Simon van der Linden committed
30

31
static PyObject *
32
33
34
_wrap_g_irepository_enumerate_versions (PyGIRepository *self,
                                        PyObject       *args,
                                        PyObject       *kwargs)
35
36
37
38
39
40
{
    static char *kwlist[] = { "namespace", NULL };
    const char *namespace_;
    GList *versions, *item;
    PyObject *ret = NULL;

41
    if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s:Repository.enumerate_versions",
42
43
44
45
                                      kwlist, &namespace_)) {
        return NULL;
    }

46
    versions = g_irepository_enumerate_versions (self->repository, namespace_);
47
48
49
    ret = PyList_New(0);
    for (item = versions; item; item = item->next) {
        char *version = item->data;
50
        PyObject *py_version = pygi_utf8_to_py (version);
51
52
53
54
55
56
57
58
59
        PyList_Append(ret, py_version);
        Py_DECREF(py_version);
        g_free (version);
    }
    g_list_free(versions);

    return ret;
}

Simon van der Linden's avatar
Simon van der Linden committed
60
61
62
63
64
65
static PyObject *
_wrap_g_irepository_get_default (PyObject *self)
{
    static PyGIRepository *repository = NULL;

    if (!repository) {
66
        repository = (PyGIRepository *) PyObject_New (PyGIRepository, &PyGIRepository_Type);
Simon van der Linden's avatar
Simon van der Linden committed
67
68
69
70
71
72
73
        if (repository == NULL) {
            return NULL;
        }

        repository->repository = g_irepository_get_default();
    }

74
75
    Py_INCREF ( (PyObject *) repository);
    return (PyObject *) repository;
Simon van der Linden's avatar
Simon van der Linden committed
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
}

static PyObject *
_wrap_g_irepository_require (PyGIRepository *self,
                             PyObject       *args,
                             PyObject       *kwargs)
{
    static char *kwlist[] = { "namespace", "version", "lazy", NULL };

    const char *namespace_;
    const char *version = NULL;
    PyObject *lazy = NULL;
    GIRepositoryLoadFlags flags = 0;
    GError *error;

91
    if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s|zO:Repository.require",
92
                                      kwlist, &namespace_, &version, &lazy)) {
Simon van der Linden's avatar
Simon van der Linden committed
93
94
95
        return NULL;
    }

96
    if (lazy != NULL && PyObject_IsTrue (lazy)) {
Simon van der Linden's avatar
Simon van der Linden committed
97
98
99
100
        flags |= G_IREPOSITORY_LOAD_FLAG_LAZY;
    }

    error = NULL;
Martin Pitt's avatar
Martin Pitt committed
101
    g_irepository_require (self->repository, namespace_, version, flags, &error);
Simon van der Linden's avatar
Simon van der Linden committed
102
    if (error != NULL) {
103
104
        PyErr_SetString (PyGIRepositoryError, error->message);
        g_error_free (error);
Simon van der Linden's avatar
Simon van der Linden committed
105
106
107
108
109
110
        return NULL;
    }

    Py_RETURN_NONE;
}

111
112
113
114
115
116
117
118
119
120
121
122
123
124
static PyObject *
_wrap_g_irepository_is_registered (PyGIRepository *self,
                                   PyObject       *args,
                                   PyObject       *kwargs)
{
    static char *kwlist[] = { "namespace", "version", NULL };
    const char *namespace_;
    const char *version = NULL;

    if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s|z:Repository.is_registered",
                                      kwlist, &namespace_, &version)) {
        return NULL;
    }

125
126
    return pygi_gboolean_to_py (g_irepository_is_registered (self->repository,
                                                             namespace_, version));
127
128
}

Simon van der Linden's avatar
Simon van der Linden committed
129
130
131
132
133
134
135
136
137
138
139
static PyObject *
_wrap_g_irepository_find_by_name (PyGIRepository *self,
                                  PyObject       *args,
                                  PyObject       *kwargs)
{
    static char *kwlist[] = { "namespace", "name", NULL };

    const char *namespace_;
    const char *name;
    GIBaseInfo *info;
    PyObject *py_info;
140
141
    size_t len;
    char *trimmed_name = NULL;
Simon van der Linden's avatar
Simon van der Linden committed
142

143
144
    if (!PyArg_ParseTupleAndKeywords (args, kwargs,
                                      "ss:Repository.find_by_name", kwlist, &namespace_, &name)) {
Simon van der Linden's avatar
Simon van der Linden committed
145
146
147
        return NULL;
    }

148
149
150
151
152
153
154
155
156
157
158
159
    /* If the given name ends with an underscore, it might be due to usage
     * as an accessible replacement for something in GI with the same name
     * as a Python keyword. Test for this and trim it out if necessary.
     */
    len = strlen (name);
    if (len > 0 && name[len-1] == '_') {
        trimmed_name = g_strndup (name, len-1);
        if (_pygi_is_python_keyword (trimmed_name)) {
            name = trimmed_name;
        }
    }

160
    info = g_irepository_find_by_name (self->repository, namespace_, name);
161
162
    g_free (trimmed_name);

Simon van der Linden's avatar
Simon van der Linden committed
163
164
165
166
    if (info == NULL) {
        Py_RETURN_NONE;
    }

167
    py_info = _pygi_info_new (info);
Simon van der Linden's avatar
Simon van der Linden committed
168

169
    g_base_info_unref (info);
Simon van der Linden's avatar
Simon van der Linden committed
170
171
172
173
174
175
176
177
178
179
180
181
182
183

    return py_info;
}

static PyObject *
_wrap_g_irepository_get_infos (PyGIRepository *self,
                               PyObject       *args,
                               PyObject       *kwargs)
{
    static char *kwlist[] = { "namespace", NULL };

    const char *namespace_;
    gssize n_infos;
    PyObject *infos;
184
    gint i;
Simon van der Linden's avatar
Simon van der Linden committed
185

186
187
    if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s:Repository.get_infos",
                                      kwlist, &namespace_)) {
Simon van der Linden's avatar
Simon van der Linden committed
188
189
190
        return NULL;
    }

191
    n_infos = g_irepository_get_n_infos (self->repository, namespace_);
Simon van der Linden's avatar
Simon van der Linden committed
192
    if (n_infos < 0) {
193
        PyErr_Format (PyExc_RuntimeError, "Namespace '%s' not loaded", namespace_);
Simon van der Linden's avatar
Simon van der Linden committed
194
195
196
        return NULL;
    }

197
    infos = PyTuple_New (n_infos);
Simon van der Linden's avatar
Simon van der Linden committed
198
199
200
201
202

    for (i = 0; i < n_infos; i++) {
        GIBaseInfo *info;
        PyObject *py_info;

203
204
        info = g_irepository_get_info (self->repository, namespace_, i);
        g_assert (info != NULL);
Simon van der Linden's avatar
Simon van der Linden committed
205

206
        py_info = _pygi_info_new (info);
Simon van der Linden's avatar
Simon van der Linden committed
207

208
        g_base_info_unref (info);
Simon van der Linden's avatar
Simon van der Linden committed
209
210

        if (py_info == NULL) {
211
            Py_CLEAR (infos);
Simon van der Linden's avatar
Simon van der Linden committed
212
213
214
            break;
        }

215
        PyTuple_SET_ITEM (infos, i, py_info);
Simon van der Linden's avatar
Simon van der Linden committed
216
217
218
219
220
221
222
223
224
225
226
227
228
229
    }

    return infos;
}

static PyObject *
_wrap_g_irepository_get_typelib_path (PyGIRepository *self,
                                      PyObject       *args,
                                      PyObject       *kwargs)
{
    static char *kwlist[] = { "namespace", NULL };
    const char *namespace_;
    const gchar *typelib_path;

230
231
    if (!PyArg_ParseTupleAndKeywords (args, kwargs,
                                      "s:Repository.get_typelib_path", kwlist, &namespace_)) {
Simon van der Linden's avatar
Simon van der Linden committed
232
233
234
        return NULL;
    }

235
    typelib_path = g_irepository_get_typelib_path (self->repository, namespace_);
Simon van der Linden's avatar
Simon van der Linden committed
236
    if (typelib_path == NULL) {
237
        PyErr_Format (PyExc_RuntimeError, "Namespace '%s' not loaded", namespace_);
Simon van der Linden's avatar
Simon van der Linden committed
238
239
240
        return NULL;
    }

241
    return pygi_filename_to_py (typelib_path);
Simon van der Linden's avatar
Simon van der Linden committed
242
243
}

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
static PyObject *
_wrap_g_irepository_get_version (PyGIRepository *self,
                                 PyObject       *args,
                                 PyObject       *kwargs)
{
    static char *kwlist[] = { "namespace", NULL };
    const char *namespace_;
    const gchar *version;

    if (!PyArg_ParseTupleAndKeywords (args, kwargs,
                                      "s:Repository.get_version", kwlist, &namespace_)) {
        return NULL;
    }

    version = g_irepository_get_version (self->repository, namespace_);
    if (version == NULL) {
        PyErr_Format (PyExc_RuntimeError, "Namespace '%s' not loaded", namespace_);
        return NULL;
    }

264
    return pygi_utf8_to_py (version);
265
266
}

267
268
269
270
271
272
273
274
275
276
277
static PyObject *
_wrap_g_irepository_get_loaded_namespaces (PyGIRepository *self)
{
    char **namespaces;
    PyObject *py_namespaces;
    gssize i;

    namespaces = g_irepository_get_loaded_namespaces (self->repository);

    py_namespaces = PyList_New (0);
    for (i = 0; namespaces[i] != NULL; i++) {
278
        PyObject *py_namespace = pygi_utf8_to_py (namespaces[i]);
279
280
281
282
283
284
285
286
287
288
        PyList_Append (py_namespaces, py_namespace);
        Py_DECREF(py_namespace);
        g_free (namespaces[i]);
    }

    g_free (namespaces);

    return py_namespaces;
}

289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
static PyObject *
_wrap_g_irepository_get_dependencies (PyGIRepository *self,
                                      PyObject       *args,
                                      PyObject       *kwargs)
{
    static char *kwlist[] = { "namespace", NULL };
    const char *namespace_;
    char **namespaces;
    PyObject *py_namespaces;
    gssize i;

    if (!PyArg_ParseTupleAndKeywords (args, kwargs,
                                      "s:Repository.get_dependencies", kwlist, &namespace_)) {
        return NULL;
    }

    py_namespaces = PyList_New (0);
    /* Returns NULL in case of no dependencies */
    namespaces = g_irepository_get_dependencies (self->repository, namespace_);
    if (namespaces == NULL) {
        return py_namespaces;
    }

    for (i = 0; namespaces[i] != NULL; i++) {
313
        PyObject *py_namespace = pygi_utf8_to_py (namespaces[i]);
314
315
316
317
318
319
320
321
322
        PyList_Append (py_namespaces, py_namespace);
        Py_DECREF(py_namespace);
    }

    g_strfreev (namespaces);

    return py_namespaces;
}

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345

static PyObject *
_wrap_g_irepository_get_immediate_dependencies (PyGIRepository *self,
                                                PyObject       *args,
                                                PyObject       *kwargs)
{
    static char *kwlist[] = { "namespace", NULL };
    const char *namespace_;
    char **namespaces;
    PyObject *py_namespaces;
    gssize i;

    if (!PyArg_ParseTupleAndKeywords (args, kwargs,
                                      "s:Repository.get_immediate_dependencies",
                                      kwlist, &namespace_)) {
        return NULL;
    }

    py_namespaces = PyList_New (0);
    namespaces = g_irepository_get_immediate_dependencies (self->repository,
                                                           namespace_);

    for (i = 0; namespaces[i] != NULL; i++) {
346
        PyObject *py_namespace = pygi_utf8_to_py (namespaces[i]);
347
348
349
350
351
352
353
354
355
356
        PyList_Append (py_namespaces, py_namespace);
        Py_DECREF (py_namespace);
    }

    g_strfreev (namespaces);

    return py_namespaces;
}


Simon van der Linden's avatar
Simon van der Linden committed
357
static PyMethodDef _PyGIRepository_methods[] = {
358
    { "enumerate_versions", (PyCFunction) _wrap_g_irepository_enumerate_versions, METH_VARARGS | METH_KEYWORDS },
359
360
361
362
363
    { "get_default", (PyCFunction) _wrap_g_irepository_get_default, METH_STATIC | METH_NOARGS },
    { "require", (PyCFunction) _wrap_g_irepository_require, METH_VARARGS | METH_KEYWORDS },
    { "get_infos", (PyCFunction) _wrap_g_irepository_get_infos, METH_VARARGS | METH_KEYWORDS },
    { "find_by_name", (PyCFunction) _wrap_g_irepository_find_by_name, METH_VARARGS | METH_KEYWORDS },
    { "get_typelib_path", (PyCFunction) _wrap_g_irepository_get_typelib_path, METH_VARARGS | METH_KEYWORDS },
364
    { "get_version", (PyCFunction) _wrap_g_irepository_get_version, METH_VARARGS | METH_KEYWORDS },
365
    { "get_loaded_namespaces", (PyCFunction) _wrap_g_irepository_get_loaded_namespaces, METH_NOARGS },
366
    { "get_dependencies", (PyCFunction) _wrap_g_irepository_get_dependencies, METH_VARARGS | METH_KEYWORDS  },
367
    { "get_immediate_dependencies", (PyCFunction) _wrap_g_irepository_get_immediate_dependencies, METH_VARARGS | METH_KEYWORDS  },
368
    { "is_registered", (PyCFunction) _wrap_g_irepository_is_registered, METH_VARARGS | METH_KEYWORDS  },
Simon van der Linden's avatar
Simon van der Linden committed
369
370
371
    { NULL, NULL, 0 }
};

372
373
374
375
376
/**
 * Returns 0 on success, or -1 and sets an exception.
 */
int
pygi_repository_register_types (PyObject *m)
Simon van der Linden's avatar
Simon van der Linden committed
377
{
378
379
380
381
382
    Py_TYPE(&PyGIRepository_Type) = &PyType_Type;

    PyGIRepository_Type.tp_flags = Py_TPFLAGS_DEFAULT;
    PyGIRepository_Type.tp_methods = _PyGIRepository_methods;

383
384
    if (PyType_Ready (&PyGIRepository_Type) < 0)
        return -1;
385

386
387
388
389
    Py_INCREF ((PyObject *) &PyGIRepository_Type);
    if (PyModule_AddObject (m, "Repository", (PyObject *) &PyGIRepository_Type) < 0) {
        Py_DECREF ((PyObject *) &PyGIRepository_Type);
        return -1;
Simon van der Linden's avatar
Simon van der Linden committed
390
391
    }

392
    PyGIRepositoryError = PyErr_NewException ("gi.RepositoryError", NULL, NULL);
393
394
395
396
397
398
399
    if (PyGIRepositoryError == NULL)
        return -1;

    Py_INCREF (PyGIRepositoryError);
    if (PyModule_AddObject (m, "RepositoryError", PyGIRepositoryError) < 0) {
        Py_DECREF (PyGIRepositoryError);
        return -1;
Simon van der Linden's avatar
Simon van der Linden committed
400
    }
401
402

    return 0;
Simon van der Linden's avatar
Simon van der Linden committed
403
}