16356f9ac5b3e2ec0e90949c5b6a258d55602d3e
[platform/upstream/python-gobject.git] / gi / pygi-repository.c
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * vim: tabstop=4 shiftwidth=4 expandtab
3  *
4  * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
5  *
6  *   pygi-repository.c: GIRepository wrapper.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * 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/>.
20  */
21
22 #include "pygi-private.h"
23
24 #include <pyglib-python-compat.h>
25
26 PyObject *PyGIRepositoryError;
27
28 PYGLIB_DEFINE_TYPE("gi.Repository", PyGIRepository_Type, PyGIRepository);
29
30 static PyObject *
31 _wrap_g_irepository_enumerate_versions (PyGIRepository *self,
32                                         PyObject       *args,
33                                         PyObject       *kwargs)
34 {
35     static char *kwlist[] = { "namespace", NULL };
36     const char *namespace_;
37     GList *versions, *item;
38     PyObject *ret = NULL;
39
40     if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s:Repository.enumerate_versions",
41                                       kwlist, &namespace_)) {
42         return NULL;
43     }
44
45     versions = g_irepository_enumerate_versions (self->repository, namespace_);
46     ret = PyList_New(0);
47     for (item = versions; item; item = item->next) {
48         char *version = item->data;
49         PyObject *py_version = PYGLIB_PyUnicode_FromString (version);
50         PyList_Append(ret, py_version);
51         Py_DECREF(py_version);
52         g_free (version);
53     }
54     g_list_free(versions);
55
56     return ret;
57 }
58
59 static PyObject *
60 _wrap_g_irepository_get_default (PyObject *self)
61 {
62     static PyGIRepository *repository = NULL;
63
64     if (!repository) {
65         repository = (PyGIRepository *) PyObject_New (PyGIRepository, &PyGIRepository_Type);
66         if (repository == NULL) {
67             return NULL;
68         }
69
70         repository->repository = g_irepository_get_default();
71     }
72
73     Py_INCREF ( (PyObject *) repository);
74     return (PyObject *) repository;
75 }
76
77 static PyObject *
78 _wrap_g_irepository_require (PyGIRepository *self,
79                              PyObject       *args,
80                              PyObject       *kwargs)
81 {
82     static char *kwlist[] = { "namespace", "version", "lazy", NULL };
83
84     const char *namespace_;
85     const char *version = NULL;
86     PyObject *lazy = NULL;
87     GIRepositoryLoadFlags flags = 0;
88     GError *error;
89
90     if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s|zO:Repository.require",
91                                       kwlist, &namespace_, &version, &lazy)) {
92         return NULL;
93     }
94
95     if (lazy != NULL && PyObject_IsTrue (lazy)) {
96         flags |= G_IREPOSITORY_LOAD_FLAG_LAZY;
97     }
98
99     error = NULL;
100     g_irepository_require (self->repository, namespace_, version, flags, &error);
101     if (error != NULL) {
102         PyErr_SetString (PyGIRepositoryError, error->message);
103         g_error_free (error);
104         return NULL;
105     }
106
107     Py_RETURN_NONE;
108 }
109
110 static PyObject *
111 _wrap_g_irepository_is_registered (PyGIRepository *self,
112                                    PyObject       *args,
113                                    PyObject       *kwargs)
114 {
115     static char *kwlist[] = { "namespace", "version", NULL };
116     const char *namespace_;
117     const char *version = NULL;
118
119     if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s|z:Repository.is_registered",
120                                       kwlist, &namespace_, &version)) {
121         return NULL;
122     }
123
124     return PyBool_FromLong (g_irepository_is_registered (self->repository,
125                                                          namespace_, version));
126 }
127
128 static PyObject *
129 _wrap_g_irepository_find_by_name (PyGIRepository *self,
130                                   PyObject       *args,
131                                   PyObject       *kwargs)
132 {
133     static char *kwlist[] = { "namespace", "name", NULL };
134
135     const char *namespace_;
136     const char *name;
137     GIBaseInfo *info;
138     PyObject *py_info;
139     size_t len;
140     char *trimmed_name = NULL;
141
142     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
143                                       "ss:Repository.find_by_name", kwlist, &namespace_, &name)) {
144         return NULL;
145     }
146
147     /* If the given name ends with an underscore, it might be due to usage
148      * as an accessible replacement for something in GI with the same name
149      * as a Python keyword. Test for this and trim it out if necessary.
150      */
151     len = strlen (name);
152     if (len > 0 && name[len-1] == '_') {
153         trimmed_name = g_strndup (name, len-1);
154         if (_pygi_is_python_keyword (trimmed_name)) {
155             name = trimmed_name;
156         }
157     }
158
159     info = g_irepository_find_by_name (self->repository, namespace_, name);
160     g_free (trimmed_name);
161
162     if (info == NULL) {
163         Py_RETURN_NONE;
164     }
165
166     py_info = _pygi_info_new (info);
167
168     g_base_info_unref (info);
169
170     return py_info;
171 }
172
173 static PyObject *
174 _wrap_g_irepository_get_infos (PyGIRepository *self,
175                                PyObject       *args,
176                                PyObject       *kwargs)
177 {
178     static char *kwlist[] = { "namespace", NULL };
179
180     const char *namespace_;
181     gssize n_infos;
182     PyObject *infos;
183     gssize i;
184
185     if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s:Repository.get_infos",
186                                       kwlist, &namespace_)) {
187         return NULL;
188     }
189
190     n_infos = g_irepository_get_n_infos (self->repository, namespace_);
191     if (n_infos < 0) {
192         PyErr_Format (PyExc_RuntimeError, "Namespace '%s' not loaded", namespace_);
193         return NULL;
194     }
195
196     infos = PyTuple_New (n_infos);
197
198     for (i = 0; i < n_infos; i++) {
199         GIBaseInfo *info;
200         PyObject *py_info;
201
202         info = g_irepository_get_info (self->repository, namespace_, i);
203         g_assert (info != NULL);
204
205         py_info = _pygi_info_new (info);
206
207         g_base_info_unref (info);
208
209         if (py_info == NULL) {
210             Py_CLEAR (infos);
211             break;
212         }
213
214         PyTuple_SET_ITEM (infos, i, py_info);
215     }
216
217     return infos;
218 }
219
220 static PyObject *
221 _wrap_g_irepository_get_typelib_path (PyGIRepository *self,
222                                       PyObject       *args,
223                                       PyObject       *kwargs)
224 {
225     static char *kwlist[] = { "namespace", NULL };
226     const char *namespace_;
227     const gchar *typelib_path;
228
229     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
230                                       "s:Repository.get_typelib_path", kwlist, &namespace_)) {
231         return NULL;
232     }
233
234     typelib_path = g_irepository_get_typelib_path (self->repository, namespace_);
235     if (typelib_path == NULL) {
236         PyErr_Format (PyExc_RuntimeError, "Namespace '%s' not loaded", namespace_);
237         return NULL;
238     }
239
240     return PYGLIB_PyBytes_FromString (typelib_path);
241 }
242
243 static PyObject *
244 _wrap_g_irepository_get_version (PyGIRepository *self,
245                                  PyObject       *args,
246                                  PyObject       *kwargs)
247 {
248     static char *kwlist[] = { "namespace", NULL };
249     const char *namespace_;
250     const gchar *version;
251
252     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
253                                       "s:Repository.get_version", kwlist, &namespace_)) {
254         return NULL;
255     }
256
257     version = g_irepository_get_version (self->repository, namespace_);
258     if (version == NULL) {
259         PyErr_Format (PyExc_RuntimeError, "Namespace '%s' not loaded", namespace_);
260         return NULL;
261     }
262
263     return PYGLIB_PyUnicode_FromString (version);
264 }
265
266 static PyObject *
267 _wrap_g_irepository_get_loaded_namespaces (PyGIRepository *self)
268 {
269     char **namespaces;
270     PyObject *py_namespaces;
271     gssize i;
272
273     namespaces = g_irepository_get_loaded_namespaces (self->repository);
274
275     py_namespaces = PyList_New (0);
276     for (i = 0; namespaces[i] != NULL; i++) {
277         PyObject *py_namespace = PYGLIB_PyUnicode_FromString (namespaces[i]);
278         PyList_Append (py_namespaces, py_namespace);
279         Py_DECREF(py_namespace);
280         g_free (namespaces[i]);
281     }
282
283     g_free (namespaces);
284
285     return py_namespaces;
286 }
287
288 static PyObject *
289 _wrap_g_irepository_get_dependencies (PyGIRepository *self,
290                                       PyObject       *args,
291                                       PyObject       *kwargs)
292 {
293     static char *kwlist[] = { "namespace", NULL };
294     const char *namespace_;
295     char **namespaces;
296     PyObject *py_namespaces;
297     gssize i;
298
299     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
300                                       "s:Repository.get_dependencies", kwlist, &namespace_)) {
301         return NULL;
302     }
303
304     py_namespaces = PyList_New (0);
305     /* Returns NULL in case of no dependencies */
306     namespaces = g_irepository_get_dependencies (self->repository, namespace_);
307     if (namespaces == NULL) {
308         return py_namespaces;
309     }
310
311     for (i = 0; namespaces[i] != NULL; i++) {
312         PyObject *py_namespace = PYGLIB_PyUnicode_FromString (namespaces[i]);
313         PyList_Append (py_namespaces, py_namespace);
314         Py_DECREF(py_namespace);
315     }
316
317     g_strfreev (namespaces);
318
319     return py_namespaces;
320 }
321
322
323 static PyObject *
324 _wrap_g_irepository_get_immediate_dependencies (PyGIRepository *self,
325                                                 PyObject       *args,
326                                                 PyObject       *kwargs)
327 {
328     static char *kwlist[] = { "namespace", NULL };
329     const char *namespace_;
330     char **namespaces;
331     PyObject *py_namespaces;
332     gssize i;
333
334     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
335                                       "s:Repository.get_immediate_dependencies",
336                                       kwlist, &namespace_)) {
337         return NULL;
338     }
339
340     py_namespaces = PyList_New (0);
341     namespaces = g_irepository_get_immediate_dependencies (self->repository,
342                                                            namespace_);
343
344     for (i = 0; namespaces[i] != NULL; i++) {
345         PyObject *py_namespace = PYGLIB_PyUnicode_FromString (namespaces[i]);
346         PyList_Append (py_namespaces, py_namespace);
347         Py_DECREF (py_namespace);
348     }
349
350     g_strfreev (namespaces);
351
352     return py_namespaces;
353 }
354
355
356 static PyMethodDef _PyGIRepository_methods[] = {
357     { "enumerate_versions", (PyCFunction) _wrap_g_irepository_enumerate_versions, METH_VARARGS | METH_KEYWORDS },
358     { "get_default", (PyCFunction) _wrap_g_irepository_get_default, METH_STATIC | METH_NOARGS },
359     { "require", (PyCFunction) _wrap_g_irepository_require, METH_VARARGS | METH_KEYWORDS },
360     { "get_infos", (PyCFunction) _wrap_g_irepository_get_infos, METH_VARARGS | METH_KEYWORDS },
361     { "find_by_name", (PyCFunction) _wrap_g_irepository_find_by_name, METH_VARARGS | METH_KEYWORDS },
362     { "get_typelib_path", (PyCFunction) _wrap_g_irepository_get_typelib_path, METH_VARARGS | METH_KEYWORDS },
363     { "get_version", (PyCFunction) _wrap_g_irepository_get_version, METH_VARARGS | METH_KEYWORDS },
364     { "get_loaded_namespaces", (PyCFunction) _wrap_g_irepository_get_loaded_namespaces, METH_NOARGS },
365     { "get_dependencies", (PyCFunction) _wrap_g_irepository_get_dependencies, METH_VARARGS | METH_KEYWORDS  },
366     { "get_immediate_dependencies", (PyCFunction) _wrap_g_irepository_get_immediate_dependencies, METH_VARARGS | METH_KEYWORDS  },
367     { "is_registered", (PyCFunction) _wrap_g_irepository_is_registered, METH_VARARGS | METH_KEYWORDS  },
368     { NULL, NULL, 0 }
369 };
370
371 void
372 _pygi_repository_register_types (PyObject *m)
373 {
374     Py_TYPE(&PyGIRepository_Type) = &PyType_Type;
375
376     PyGIRepository_Type.tp_flags = Py_TPFLAGS_DEFAULT;
377     PyGIRepository_Type.tp_methods = _PyGIRepository_methods;
378
379     if (PyType_Ready (&PyGIRepository_Type)) {
380         return;
381     }
382
383     if (PyModule_AddObject (m, "Repository", (PyObject *) &PyGIRepository_Type)) {
384         return;
385     }
386
387     PyGIRepositoryError = PyErr_NewException ("gi.RepositoryError", NULL, NULL);
388     if (PyModule_AddObject (m, "RepositoryError", PyGIRepositoryError)) {
389         return;
390     }
391 }
392