root/trunk/midgard/apis/python/py_midgard_object.c

Revision 19072, 21.1 kB (checked in by piotras, 6 days ago)

Try to convert string to utf8 when setting underlying gobject property

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2  * Copyright (C) 2007 Piotr Pokora <piotrek.pokora@gmail.com>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published
6  * by 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 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #define NO_IMPORT_PYGOBJECT
24 #include "py_midgard.h"
25
26 #define MGDOBJECT_DEBUG(__name) \
27         CHECK_MGD; \
28         const gchar *cname = NULL; \
29         if(self) { \
30                 CLASS_METHOD_DEBUG(G_OBJECT_TYPE_NAME(G_OBJECT(self->obj)), __name); \
31         } else { \
32         if(cname == NULL) \
33                 CLASS_METHOD_DEBUG("midgard_dbobject", __name); \
34         }
35
36 PyTypeObject G_GNUC_INTERNAL Pymidgard_schema_object_Type;
37
38 PyTypeObject G_GNUC_INTERNAL Pymidgard_object_Type = {
39     PyObject_HEAD_INIT(NULL)
40     0,                                 /* ob_size */
41     "midgard_object",                   /* tp_name */
42     sizeof(PyGObject),          /* tp_basicsize */
43     0,                                 /* tp_itemsize */
44     /* methods */
45     (destructor)0,        /* tp_dealloc */
46     (printfunc)0,                      /* tp_print */
47     (getattrfunc)0,       /* tp_getattr */
48     (setattrfunc)0,       /* tp_setattr */
49     (cmpfunc)0,           /* tp_compare */
50     (reprfunc)0,             /* tp_repr */
51     (PyNumberMethods*)0,     /* tp_as_number */
52     (PySequenceMethods*)0, /* tp_as_sequence */
53     (PyMappingMethods*)0,   /* tp_as_mapping */
54     (hashfunc)0,             /* tp_hash */
55     (ternaryfunc)0,          /* tp_call */
56     (reprfunc)0,              /* tp_str */
57     (getattrofunc)0,     /* tp_getattro */
58     (setattrofunc)0,     /* tp_setattro */
59     (PyBufferProcs*)0,  /* tp_as_buffer */
60     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,                      /* tp_flags */
61     NULL,                        /* Documentation string */
62     (traverseproc)0,     /* tp_traverse */
63     (inquiry)0,             /* tp_clear */
64     (richcmpfunc)0,   /* tp_richcompare */
65     offsetof(PyGObject, weakreflist),             /* tp_weaklistoffset */
66     (getiterfunc)0,          /* tp_iter */
67     (iternextfunc)0,     /* tp_iternext */
68     (struct PyMethodDef*)NULL, /* tp_methods */
69     (struct PyMemberDef*)0,              /* tp_members */
70     (struct PyGetSetDef*)0,  /* tp_getset */
71     NULL,                              /* tp_base */
72     NULL,                              /* tp_dict */
73     (descrgetfunc)0,    /* tp_descr_get */
74     (descrsetfunc)0,    /* tp_descr_set */
75     offsetof(PyGObject, inst_dict),                 /* tp_dictoffset */
76     (initproc)0,             /* tp_init */
77     (allocfunc)0,           /* tp_alloc */
78     (newfunc)0,               /* tp_new */
79     (freefunc)0,             /* tp_free */
80     (inquiry)0              /* tp_is_gc */
81 };
82
83 void py_midgard_base_object_register_class(
84                 PyObject *d, gpointer pygobject_type)
85 {
86         pygobject_register_class(d,
87                         "midgard_object",
88                         MIDGARD_TYPE_OBJECT,
89                         &Pymidgard_object_Type,
90                         Py_BuildValue("(O)", pygobject_type));
91
92         pyg_set_object_has_new_constructor(MIDGARD_TYPE_OBJECT);
93 }
94
95 PyTypeObject G_GNUC_INTERNAL Pymidgard_metadata_Type = {
96     PyObject_HEAD_INIT(NULL)
97     0,                                 /* ob_size */
98     "metadata",                   /* tp_name */
99     sizeof(PyGObject),          /* tp_basicsize */
100     0,                                 /* tp_itemsize */
101     /* methods */
102     (destructor)0,        /* tp_dealloc */
103     (printfunc)0,                      /* tp_print */
104     (getattrfunc)0,       /* tp_getattr */
105     (setattrfunc)0,       /* tp_setattr */
106     (cmpfunc)0,           /* tp_compare */
107     (reprfunc)0,             /* tp_repr */
108     (PyNumberMethods*)0,     /* tp_as_number */
109     (PySequenceMethods*)0, /* tp_as_sequence */
110     (PyMappingMethods*)0,   /* tp_as_mapping */
111     (hashfunc)0,             /* tp_hash */
112     (ternaryfunc)0,          /* tp_call */
113     (reprfunc)0,              /* tp_str */
114     _py_midgard_get_object_attribute, /* tp_getattro */
115     _py_midgard_set_object_attribute, /* tp_setattro */
116     (PyBufferProcs*)0,  /* tp_as_buffer */
117     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,                      /* tp_flags */
118     NULL,                        /* Documentation string */
119     (traverseproc)0,     /* tp_traverse */
120     (inquiry)0,             /* tp_clear */
121     (richcmpfunc)0,   /* tp_richcompare */
122     offsetof(PyGObject, weakreflist),             /* tp_weaklistoffset */
123     (getiterfunc)0,          /* tp_iter */
124     (iternextfunc)0,     /* tp_iternext */
125     (struct PyMethodDef*)NULL, /* tp_methods */
126     (struct PyMemberDef*)0,              /* tp_members */
127     (struct PyGetSetDef*)0,  /* tp_getset */
128     NULL,                              /* tp_base */
129     NULL,                              /* tp_dict */
130     (descrgetfunc)0,    /* tp_descr_get */
131     (descrsetfunc)0,    /* tp_descr_set */
132     offsetof(PyGObject, inst_dict),                 /* tp_dictoffset */
133     (initproc)0,             /* tp_init */
134     (allocfunc)0,           /* tp_alloc */
135     (newfunc)0,               /* tp_new */
136     (freefunc)0,             /* tp_free */
137     (inquiry)0              /* tp_is_gc */
138 };
139
140 void py_midgard_metadata_register_class(
141                 PyObject *d, gpointer pygobject_type)
142 {
143         pygobject_register_class(d,
144                         "metadata",
145                         MIDGARD_TYPE_METADATA,
146                         &Pymidgard_metadata_Type,
147                         Py_BuildValue("(O)", pygobject_type));
148
149         pyg_set_object_has_new_constructor(MIDGARD_TYPE_OBJECT);
150 }
151
152
153 /* MgdSchema classes */
154 static int __schema_object_construct(PyGObject *self, PyObject *args, PyObject *kwargs)
155 {
156         PyObject *pyval = NULL;
157         int id;
158         long lid;
159         const gchar *guid;
160         if(!PyArg_ParseTuple(args, "|O", &pyval))
161                 return -1;
162        
163         if(pygobject_constructv(self, 0, NULL))
164                 PyErr_SetString(PyExc_RuntimeError, "could not create object");
165
166         MidgardConnection *mgd =
167                 _py_midgard_connection_singleton_get();
168         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
169
170         if(!mgd)
171                 PyErr_SetString(PyExc_RuntimeError, "Failed to get midgard connection");
172
173         if(!mobj)
174                 PyErr_SetString(PyExc_RuntimeError, "Failed to get underlying object");
175        
176         midgard_object_set_connection(mobj, mgd);
177
178         MGDOBJECT_DEBUG("__init__");
179
180         /* FIXME
181          * I parse arguments again , but I really do not have idea how to
182          * get PyObject type from pyval in this case.
183          * GType returned from pyval PyObject is always 0. */
184         if(pyval) {
185
186                 if(PyString_Check(pyval)) {
187                        
188                         PyArg_ParseTuple(args, "s", &guid);
189                         if(!midgard_object_get_by_guid(mobj, guid)) {
190                                 PyErr_SetString(PyExc_TypeError, "Could not create new instance");
191                                 return -1;
192                         }
193                 }
194
195                 if(PyInt_Check(pyval)) {
196                        
197                         PyArg_ParseTuple(args, "i", &id);
198                         if(!midgard_object_get_by_id(mobj, id)) {
199                                 PyErr_SetString(PyExc_TypeError, "Could not create new instance");
200                                 return -1;
201                         }
202                 }
203
204                 if(PyLong_Check(pyval)) {
205                        
206                         PyArg_ParseTuple(args, "l", &id);
207                         if(!midgard_object_get_by_id(mobj, id)) {
208                                 PyErr_SetString(PyExc_TypeError, "Could not create new instance");
209                                 return -1;
210                         }
211                 }
212         }       
213
214         return (self->obj) ? 0 : -1;
215 }
216
217 static PyObject *
218 pymidgard_object_create(PyGObject *self, PyObject *args)
219 {
220         MGDOBJECT_DEBUG("create");
221
222         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
223
224         if(midgard_object_create(mobj))
225                 Py_RETURN_TRUE;
226
227         Py_RETURN_FALSE;
228 }
229
230 static PyObject *
231 pymidgard_object_get_by_id(PyGObject *self, PyObject *args)
232 {
233         MGDOBJECT_DEBUG("get_by_id");
234         guint id;
235         if(!PyArg_ParseTuple(args, "i", &id))
236                 return NULL;
237
238         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
239
240         if(midgard_object_get_by_id(mobj, id))
241                 Py_RETURN_TRUE;
242
243         Py_RETURN_FALSE;
244 }
245
246 static PyObject *
247 pymidgard_object_get_by_guid(PyGObject *self, PyObject *args)
248 {
249         MGDOBJECT_DEBUG("get_by_guid");
250         const gchar *guid;
251         if(!PyArg_ParseTuple(args, "s", &guid))
252                 return NULL;
253
254         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
255
256         if(midgard_object_get_by_guid(mobj, guid))
257                 Py_RETURN_TRUE;
258
259         Py_RETURN_FALSE;
260 }
261
262 static PyObject *
263 pymidgard_object_update(PyGObject *self, PyObject *args)
264 {
265         MGDOBJECT_DEBUG("update");     
266         if(!PyArg_ParseTuple(args, ""))
267                 return NULL;
268
269         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
270
271         if(midgard_object_update(mobj))
272                 Py_RETURN_TRUE;
273
274         Py_RETURN_FALSE;
275 }
276
277 static PyObject *
278 pymidgard_object_delete(PyGObject *self, PyObject *args)
279 {
280         MGDOBJECT_DEBUG("delete");
281         if(!PyArg_ParseTuple(args, ""))
282                 return NULL;
283
284         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
285
286         if(midgard_object_delete(mobj))
287                 Py_RETURN_TRUE;
288
289         Py_RETURN_FALSE;
290 }
291
292 static PyObject *
293 pymidgard_object_purge(PyGObject *self, PyObject *args)
294 {
295         MGDOBJECT_DEBUG("purge");
296         if(!PyArg_ParseTuple(args, ""))
297                 return NULL;
298
299         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
300
301         if(midgard_object_purge(mobj))
302                 Py_RETURN_TRUE;
303
304         Py_RETURN_FALSE;
305 }
306
307 static PyObject *
308 pymidgard_object_is_in_parent_tree(PyGObject *self, PyObject *args)
309 {
310         MGDOBJECT_DEBUG("is_in_parent_tree");
311         guint root_id, id;
312         if(!PyArg_ParseTuple(args, "ii", root_id, id))
313                 return NULL;
314
315         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
316
317         if(midgard_object_is_in_parent_tree(mobj, root_id, id))
318                 Py_RETURN_TRUE;
319
320         Py_RETURN_FALSE;
321 }
322
323 static PyObject *
324 pymidgard_object_is_in_tree(PyGObject *self, PyObject *args)
325 {
326         MGDOBJECT_DEBUG("is_in_tree");
327         guint root_id, id;
328         if(!PyArg_ParseTuple(args, "ii", root_id, id))
329                 return NULL;
330
331         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
332
333         if(midgard_object_is_in_tree(mobj, root_id, id))
334                 Py_RETURN_TRUE;
335
336         Py_RETURN_FALSE;
337 }
338
339 static PyObject *
340 pymidgard_object_get_parent(PyGObject *self, PyObject *args)
341 {
342         MGDOBJECT_DEBUG("get_parent");
343         if(!PyArg_ParseTuple(args, ""))
344                 return NULL;
345        
346         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
347         MgdObject *parent =
348                 midgard_object_get_parent(mobj);
349        
350         if(parent)
351                 return Py_BuildValue("O", pygobject_new(G_OBJECT(parent)));
352        
353         Py_INCREF(Py_None);
354         return Py_None;
355 }
356
357 static PyObject *
358 pymidgard_object_parent(PyGObject *self, PyObject *args)
359 {
360         MGDOBJECT_DEBUG("parent");
361         if(!PyArg_ParseTuple(args, ""))
362                 return NULL;
363        
364         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
365         const gchar *parent =
366                 midgard_object_parent(mobj);
367
368         return Py_BuildValue("s", parent);     
369 }
370
371 static PyObject *
372 pymidgard_object_list(PyGObject *self, PyObject *args)
373 {
374         MGDOBJECT_DEBUG("list");
375         if(!PyArg_ParseTuple(args, ""))
376                 return NULL;
377
378         guint i = 0;
379         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
380         GObject **objects = midgard_object_list(mobj, NULL);
381        
382         if(objects == NULL) {
383                
384                 PyObject *list = PyTuple_New(i);
385                 return list;
386         }
387
388         /* Count how many objects we have in array, so we can
389          * initialize correct list */
390         while(objects[i] != NULL)
391                 i++;
392
393         PyObject *list = PyTuple_New(i);
394
395         if(!objects)
396                 return list;
397
398         OBJECTS2LIST(objects, list);
399
400         g_free(objects);
401
402         return list;
403 }
404
405 static PyObject *
406 pymidgard_object_list_children(PyGObject *self, PyObject *args)
407 {
408         MGDOBJECT_DEBUG("list_children");
409         const gchar *childcname;
410         if(!PyArg_ParseTuple(args, "s", &childcname))
411                 return NULL;
412
413         guint i = 0;
414         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
415         GObject **objects = midgard_object_list_children(mobj, childcname, NULL);
416
417         if(objects == NULL) {
418                
419                 PyObject *list = PyTuple_New(i);
420                 return list;
421         }
422
423         /* Count how many objects we have in array, so we can
424          * initialize correct list */
425         while(objects[i] != NULL)
426                 i++;
427
428         PyObject *list = PyTuple_New(i);
429
430         if(!objects)
431                 return list;
432
433         OBJECTS2LIST(objects, list);
434
435         g_free(objects);
436
437         return list;
438 }
439
440 static PyObject *
441 pymidgard_object_get_languages(PyGObject *self, PyObject *args)
442 {
443         MGDOBJECT_DEBUG("get_languages");
444         if(!PyArg_ParseTuple(args, ""))
445                 return NULL;
446
447         guint i = 0;
448         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
449         GObject **objects = midgard_object_get_languages(mobj, NULL);
450
451         if(objects == NULL) {
452                
453                 PyObject *list = PyTuple_New(i);
454                 return list;
455         }
456
457         while(objects[i] != NULL)
458                 i++;
459
460         PyObject *list = PyTuple_New(i);
461
462         if(!objects)
463                 return list;
464
465         OBJECTS2LIST(objects, list);
466
467         g_free(objects);
468
469         return list;
470 }
471
472 static PyObject *
473 pymidgard_object_get_by_path(PyGObject *self, PyObject *args)
474 {
475         MGDOBJECT_DEBUG("get_by_path");
476         const gchar *path;
477         if(!PyArg_ParseTuple(args, "s", &path))
478                 return NULL;
479        
480         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
481
482         if(midgard_object_get_by_path(mobj, path))
483                 Py_RETURN_TRUE;
484        
485         Py_RETURN_FALSE;
486 }
487
488 static PyObject *
489 pymidgard_object_approve(PyGObject *self, PyObject *args)
490 {
491         MGDOBJECT_DEBUG("approve");
492
493         if(!PyArg_ParseTuple(args, ""))
494                 return NULL;
495        
496         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
497
498         if(midgard_object_approve(mobj))
499                 Py_RETURN_TRUE;
500        
501         Py_RETURN_FALSE;
502 }
503
504 static PyObject *
505 pymidgard_object_is_approved(PyGObject *self, PyObject *args)
506 {
507         MGDOBJECT_DEBUG("is_approved");
508
509         if(!PyArg_ParseTuple(args, ""))
510                 return NULL;
511        
512         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
513
514         if(midgard_object_is_approved(mobj))
515                 Py_RETURN_TRUE;
516        
517         Py_RETURN_FALSE;
518 }
519
520 static PyObject *
521 pymidgard_object_unapprove(PyGObject *self, PyObject *args)
522 {
523         MGDOBJECT_DEBUG("unapprove");
524
525         if(!PyArg_ParseTuple(args, ""))
526                 return NULL;
527        
528         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
529
530         if(midgard_object_unapprove(mobj))
531                 Py_RETURN_TRUE;
532        
533         Py_RETURN_FALSE;
534 }
535
536 static PyObject *
537 pymidgard_object_lock(PyGObject *self, PyObject *args)
538 {
539         MGDOBJECT_DEBUG("lock");
540
541         if(!PyArg_ParseTuple(args, ""))
542                 return NULL;
543        
544         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
545
546         if(midgard_object_lock(mobj))
547                 Py_RETURN_TRUE;
548        
549         Py_RETURN_FALSE;
550 }
551
552 static PyObject *
553 pymidgard_object_is_locked(PyGObject *self, PyObject *args)
554 {
555         MGDOBJECT_DEBUG("is_locked");
556
557         if(!PyArg_ParseTuple(args, ""))
558                 return NULL;
559        
560         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
561
562         if(midgard_object_is_locked(mobj))
563                 Py_RETURN_TRUE;
564        
565         Py_RETURN_FALSE;
566 }
567
568 static PyObject *
569 pymidgard_object_unlock(PyGObject *self, PyObject *args)
570 {
571         MGDOBJECT_DEBUG("unlock");
572
573         if(!PyArg_ParseTuple(args, ""))
574                 return NULL;
575        
576         MgdObject *mobj = MIDGARD_OBJECT(self->obj);
577
578         if(midgard_object_unlock(mobj))
579                 Py_RETURN_TRUE;
580        
581         Py_RETURN_FALSE;
582 }
583
584 static PyMethodDef pymidgard_object_methods[] = {
585         { "get_by_id", (PyCFunction)pymidgard_object_get_by_id, METH_VARARGS, NULL },
586         { "get_by_guid", (PyCFunction)pymidgard_object_get_by_guid, METH_VARARGS, NULL },
587         { "create", (PyCFunction)pymidgard_object_create, METH_NOARGS, NULL },
588         { "update", (PyCFunction)pymidgard_object_update, METH_VARARGS, NULL },
589         { "delete", (PyCFunction)pymidgard_object_delete, METH_VARARGS, NULL },
590         { "purge", (PyCFunction)pymidgard_object_purge, METH_VARARGS, NULL },
591         { "is_in_parent_tree", (PyCFunction)pymidgard_object_is_in_parent_tree, METH_VARARGS },
592         { "is_in_tree", (PyCFunction)pymidgard_object_is_in_tree, METH_VARARGS },
593         { "get_parent", (PyCFunction)pymidgard_object_get_parent, METH_VARARGS },
594         { "parent", (PyCFunction)pymidgard_object_parent, METH_VARARGS },
595         { "list", (PyCFunction)pymidgard_object_list, METH_VARARGS },
596         { "list_children", (PyCFunction)pymidgard_object_list_children, METH_VARARGS },
597         { "get_languages", (PyCFunction)pymidgard_object_get_languages, METH_VARARGS },
598         { "get_by_path", (PyCFunction)pymidgard_object_get_by_path, METH_VARARGS },
599         { "get_parameter", (PyCFunction)pymidgard_object_get_parameter, METH_VARARGS },
600         { "set_parameter", (PyCFunction)pymidgard_object_set_parameter, METH_VARARGS },
601         { "delete_parameters", (PyCFunction)pymidgard_object_delete_parameters, METH_VARARGS },
602         { "purge_parameters", (PyCFunction)pymidgard_object_purge_parameters, METH_VARARGS },
603         { "list_parameters", (PyCFunction)pymidgard_object_list_parameters, METH_VARARGS },
604         { "find_parameters", (PyCFunction)pymidgard_object_find_parameters, METH_VARARGS },
605         { "delete_attachments", (PyCFunction)pymidgard_object_delete_attachments, METH_VARARGS },
606         { "purge_attachments", (PyCFunction)pymidgard_object_purge_attachments, METH_VARARGS },
607         { "list_attachments", (PyCFunction)pymidgard_object_list_attachments, METH_VARARGS },
608         { "find_attachments", (PyCFunction)pymidgard_object_find_attachments, METH_VARARGS },
609         { "create_attachment", (PyCFunction)pymidgard_object_create_attachment, METH_VARARGS },
610         { "approve", (PyCFunction)pymidgard_object_approve, METH_NOARGS },
611         { "is_approved", (PyCFunction)pymidgard_object_is_approved, METH_NOARGS },
612         { "unapprove", (PyCFunction)pymidgard_object_unapprove, METH_NOARGS },
613         { "lock", (PyCFunction)pymidgard_object_lock, METH_NOARGS },
614         { "is_locked", (PyCFunction)pymidgard_object_is_locked, METH_NOARGS },
615         { "unlock", (PyCFunction)pymidgard_object_unlock, METH_NOARGS },
616         { NULL, NULL, 0 }
617 };
618
619 PyObject *
620 _py_midgard_get_object_attribute(PyObject *self, PyObject *attr)
621 {
622         GObject *object = G_OBJECT(((PyGObject*)self)->obj);
623
624         /* Now we do fallback to generic GetAttr */
625         if(!object)
626                 return PyObject_GenericGetAttr(self, attr);
627
628         /* There's underlying GObject so we can run custom routines and get property*/
629         GObjectClass *klass = G_OBJECT_GET_CLASS(object);
630         GParamSpec *pspec;
631         const gchar *attr_name = PyString_AsString(attr);
632         PyTypeObject *tp = self->ob_type;
633
634         pspec = g_object_class_find_property(klass, attr_name);
635
636         if(!pspec) {
637
638                 /* Try Generic Fallback once again */
639                 return PyObject_GenericGetAttr(self, attr);             
640         }
641
642         GValue pval = {0, };
643         g_value_init(&pval, pspec->value_type);
644         g_object_get_property(object, attr_name, &pval);
645
646         PyObject *pvalue = pyg_value_as_pyobject((const GValue *)&pval, FALSE);
647
648         g_value_unset(&pval);
649
650         return pvalue;
651 }
652
653 int
654 _py_midgard_set_object_attribute(PyObject *self, PyObject *attr, PyObject *value)
655 {
656         GObject *object = G_OBJECT(((PyGObject*)self)->obj);   
657
658         /* Now we do fallback to generic SetAttr */
659         if(!object)
660                 return PyObject_GenericSetAttr(self, attr, value);
661
662         /* There's underlying GObject so we can run custom routines and set property*/
663         GObjectClass *klass = G_OBJECT_GET_CLASS(object);
664         GParamSpec *pspec;
665         const gchar *attr_name = PyString_AsString(attr);
666         PyTypeObject *tp = self->ob_type;
667
668         pspec = g_object_class_find_property(klass, attr_name);
669
670         if(!pspec) {
671                
672                 PyErr_Format(PyExc_AttributeError,
673                                 "'%.50s' object has no attribute '%.400s'",
674                                 tp->tp_name, attr_name);
675                 return -1;
676         }
677
678         GValue pval = {0, };
679         g_value_init(&pval, pspec->value_type);
680
681
682         if(pspec->value_type == G_TYPE_STRING) {
683                
684                 const gchar *strv = PyString_AsString(value);
685                 gchar *utf8_string;
686                 gboolean is_utf8 = TRUE;
687                
688                 if(strv != NULL)
689                         is_utf8 = g_utf8_validate(strv, -1, NULL);
690                
691                 if(!is_utf8) {
692                        
693                         utf8_string = g_locale_to_utf8(strv, -1, NULL, NULL, NULL);
694                        
695                         if(utf8_string == NULL) {
696                                 g_warning("UTF-8 converion failed");
697                                 return -1;
698                         }
699                        
700                         g_value_set_string(&pval, utf8_string);
701                         g_object_set_property(object, attr_name, &pval);
702                         g_value_unset(&pval);
703
704                         return 0;
705                 }
706         }
707
708         pyg_value_from_pyobject(&pval, value);
709         g_object_set_property(object, attr_name, &pval);
710         g_value_unset(&pval);
711
712         return 0;
713 }
714
715 PyTypeObject *__new_object_struct(const gchar *typename)
716 {
717         /* initialize object type */
718         PyTypeObject *ot = g_new0(PyTypeObject, 1);
719         ot->ob_refcnt = 1;
720         ot->ob_type = NULL;
721         ot->tp_name = g_strdup(typename);
722         ot->ob_size = 0;
723         ot->tp_basicsize = sizeof(PyGObject);
724         ot->tp_itemsize = 0;
725         ot->tp_dealloc = 0;
726         ot->tp_print = 0;
727         ot->tp_getattr = 0;
728         ot->tp_setattr = 0;
729         ot->tp_compare = 0;
730         ot->tp_repr = 0;
731         ot->tp_as_number = 0;
732         ot->tp_as_sequence = 0;
733         ot->tp_as_mapping = 0;
734         ot->tp_hash = 0;
735         ot->tp_call = 0;
736         ot->tp_str = 0;
737         ot->tp_getattro = _py_midgard_get_object_attribute;
738         ot->tp_setattro = _py_midgard_set_object_attribute;
739         ot->tp_as_buffer = 0;
740         ot->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
741         ot->tp_doc = "User defined MgdSchema class";
742         ot->tp_traverse = 0;
743         ot->tp_clear = 0;
744         ot->tp_richcompare = 0;
745         ot->tp_weaklistoffset = offsetof(PyGObject, weakreflist);
746         ot->tp_iter = 0;
747         ot->tp_iternext = 0;   
748         ot->tp_methods = pymidgard_object_methods;
749         //ot->tp_methods = NULL;
750         ot->tp_members = 0;
751         ot->tp_getset = 0;
752         ot->tp_base = NULL;
753         ot->tp_dict = NULL;
754         ot->tp_descr_get = 0;
755         ot->tp_descr_set = 0;
756         ot->tp_dictoffset = offsetof(PyGObject, inst_dict);
757         ot->tp_init = (initproc)__schema_object_construct;             
758         ot->tp_alloc = 0;
759         ot->tp_new = 0;
760         ot->tp_free = 0;
761         ot->tp_is_gc = 0;
762
763         ot->tp_bases = 0;
764         ot->tp_mro = 0; /* method resolution order */
765         ot->tp_cache = 0;
766         ot->tp_subclasses = 0;
767         ot->tp_weaklist = 0;
768         ot->tp_del = 0;
769        
770         return ot;
771 }
772
773 GHashTable *_pytype_hash;
774
775 void py_midgard_object_register_class(
776                 PyObject *d, gpointer pygobject_type)
777 {
778         py_midgard_base_object_register_class(d, pygobject_type);
779
780         _pytype_hash = g_hash_table_new(g_str_hash, g_str_equal);
781
782         guint n_types, i;
783         const gchar *typename;
784         GType *all_types = g_type_children(MIDGARD_TYPE_OBJECT, &n_types);
785
786         for (i = 0; i < n_types; i++) {
787
788                 typename = g_type_name(all_types[i]);
789
790                 PyTypeObject *ot = __new_object_struct(typename);
791                 pygobject_register_class(d,
792                                 typename, all_types[i], ot, 
793                                 /* FIXME, What is a static bases in this case? */
794                                 Py_BuildValue("(O)", pygobject_type));
795
796                 pyg_set_object_has_new_constructor(all_types[i]);
797
798                 g_hash_table_insert(_pytype_hash,
799                                 (gpointer*)typename, (gpointer *)ot);
800         }
801
802         g_free(all_types);
803 }
804
805 PyTypeObject *py_midgard_lookup_schema_type(const gchar *name)
806 {
807         g_assert(name != NULL);
808         g_assert(_pytype_hash != NULL);
809
810         return (PyTypeObject *)g_hash_table_lookup(_pytype_hash, name);
811 }
812
Note: See TracBrowser for help on using the browser.