3 #define NO_IMPORT_PYGOBJECT
5 #include <pygtk/pygtk.h>
7 #include "override_common.h"
11 #include "rhythmdb-property-model.h"
12 #include "rhythmdb-query-model.h"
13 #include "rhythmdb-query-results.h"
15 void pyrhythmdb_register_classes (PyObject *d);
16 void pyrhythmdb_add_constants (PyObject *module, const gchar *strip_prefix);
18 /* hacks to deal with the nonstandard class name RHYTHMDB */
19 #define RHYTHMDB_TYPE_RHYTHMDB RHYTHMDB_TYPE
20 #define RHYTHMDB_RHYTHMDB(o) RHYTHMDB(o)
24 _py_decref (PyObject *o)
30 /* query model sorting stuff */
34 } PyRhythmDBQueryModelSortData;
37 _rhythmdb_query_model_sort_data_free (PyRhythmDBQueryModelSortData *data)
39 Py_DECREF (data->func);
40 Py_DECREF (data->data);
45 _rhythmdb_query_model_sort_func (RhythmDBEntry *a, RhythmDBEntry *b, PyRhythmDBQueryModelSortData *data)
49 PyObject *py_a, *py_b;
52 py_a = pyg_boxed_new (RHYTHMDB_TYPE_ENTRY, a, TRUE, TRUE);
53 py_b = pyg_boxed_new (RHYTHMDB_TYPE_ENTRY, b, TRUE, TRUE);
55 args = Py_BuildValue ("(OOO)", py_a, py_b, data->data);
57 args = Py_BuildValue ("(OO)", py_a, py_b);
59 py_result = PyEval_CallObject (data->func, args);
60 result = PyInt_AsLong (py_result);
65 Py_DECREF (py_result);
68 /* end query model sorting stuff */
73 import gtk.Widget as PyGtkWidget_Type
74 import gobject.GObject as PyGObject_Type
75 import gtk.TreeView as PyGtkTreeView_Type
84 rhythmdb_entry_get_pointer
85 rhythmdb_entry_get_string
86 rhythmdb_entry_get_boolean
87 rhythmdb_entry_get_uint64
88 rhythmdb_entry_get_ulong
89 rhythmdb_entry_get_double
90 rhythmdb_query_model_tree_path_to_entry
91 rhythmdb_query_model_iter_to_entry
93 override rhythmdb_entry_get kwargs
95 _wrap_rhythmdb_entry_get(PyGObject *self, PyObject *args, PyObject *kwargs)
97 static char *kwlist[] = { "entry", "propid", NULL };
98 PyObject *py_propid = NULL;
99 PyObject *entry = NULL;
101 RhythmDBPropType propid;
105 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO:RhythmDB.entry_get", kwlist, &entry, &py_propid))
107 if (pyg_enum_get_value(RHYTHMDB_TYPE_PROP_TYPE, py_propid, (gint *)&propid))
110 db = RHYTHMDB (self->obj);
111 g_value_init (&value, rhythmdb_get_property_type (db, propid));
112 rhythmdb_entry_get(db, pyg_boxed_get (entry, RhythmDBEntry), propid, &value);
113 ret = pyg_value_as_pyobject (&value, TRUE);
114 g_value_unset (&value);
121 override rhythmdb_entry_set kwargs
123 _wrap_rhythmdb_entry_set(PyGObject *self, PyObject *args, PyObject *kwargs)
125 static char *kwlist[] = { "entry", "propid", "value", NULL };
126 PyObject *py_entry = NULL;
127 PyObject *py_propid = NULL;
128 PyObject *py_value = NULL;
129 RhythmDBEntry *entry;
130 RhythmDBPropType propid;
134 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOO:RhythmDBEntry.set", kwlist, &py_entry, &py_propid, &py_value))
136 if (pyg_boxed_check(py_entry, RHYTHMDB_TYPE_ENTRY))
137 entry = pyg_boxed_get(py_entry, RhythmDBEntry);
139 PyErr_SetString(PyExc_TypeError, "entry should be a RhythmDBEntry");
142 if (pyg_enum_get_value(RHYTHMDB_TYPE_PROP_TYPE, py_propid, (gint *)&propid))
145 prop_type = rhythmdb_get_property_type (RHYTHMDB(self->obj), propid);
146 g_value_init(&value, prop_type);
147 if (pyg_value_from_pyobject(&value, py_value) < 0) {
150 s = g_strdup_printf ("could not convert argument from type '%s' (%d) to correct type '%s'",
151 g_type_name (pyg_type_from_object (py_value)),
152 pyg_type_from_object (py_value),
153 g_type_name (prop_type));
154 PyErr_SetString(PyExc_TypeError, s);
158 rhythmdb_entry_set(RHYTHMDB(self->obj), entry, propid, &value);
159 g_value_unset (&value);
164 override rhythmdb_query_results_add_results kwargs
166 _wrap_rhythmdb_query_results_add_results (PyGObject *self, PyObject *args, PyObject *kwargs)
168 static char *kwlist[] = { "entries", NULL };
169 PyObject *py_entries = NULL;
173 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:RhythmDBQueryResults.add_results", kwlist, &py_entries))
176 array = g_ptr_array_new();
177 size = PyList_Size(py_entries);
178 for (i = 0; i < size; i++) {
180 RhythmDBEntry *entry;
182 py_entry = PyList_GetItem(py_entries, i);
183 if (!pyg_boxed_check(py_entry, RHYTHMDB_TYPE_ENTRY)) {
184 g_ptr_array_free(array, FALSE);
188 entry = pyg_boxed_get(py_entry, RhythmDBEntry);
189 g_ptr_array_add(array, entry);
192 rhythmdb_query_results_add_results (RHYTHMDB_QUERY_RESULTS(self->obj), array);
193 g_ptr_array_free(array, FALSE);
200 override rhythmdb_entry_foreach kwargs
205 } PyRhythmDBEntryForeachData;
208 _rhythmdb_entry_foreach_func (RhythmDBEntry *entry, PyRhythmDBEntryForeachData *data)
214 py_entry = pyg_boxed_new (RHYTHMDB_TYPE_ENTRY, entry, TRUE, TRUE);
216 args = Py_BuildValue ("(OO)", py_entry, data->data);
218 args = Py_BuildValue ("(O)", py_entry);
220 result = PyEval_CallObject (data->func, args);
221 Py_DECREF (py_entry);
228 _wrap_rhythmdb_entry_foreach (PyGObject *self, PyObject *args, PyObject *kwargs)
230 static char *kwlist[] = {"func", "data", NULL};
231 PyRhythmDBEntryForeachData data;
233 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:RhythmDB.entry_foreach",
234 kwlist, &data.func, &data.data))
237 /* verify arguments' integrity */
238 if (!PyCallable_Check (data.func)) {
239 PyErr_SetString (PyExc_TypeError, "func must be callable");
243 rhythmdb_entry_foreach (RHYTHMDB (self->obj), (GFunc)_rhythmdb_entry_foreach_func, &data);
249 override rhythmdb_query_model_new kwargs
252 _wrap_rhythmdb_query_model_new (PyGObject *self, PyObject *args, PyObject *kwargs)
254 static char *kwlist[] = {"query", "func", "reverse", NULL};
257 PyRhythmDBQueryModelSortData *data;
258 RhythmDBQueryModel *query_model;
260 data = g_new0 (PyRhythmDBQueryModelSortData, 1);
262 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OiO:RhythmDB.query_model_new", kwlist,
263 &py_query, &data->func, &reverse, &data->data)) {
268 /* verify arguments' integrity */
269 if (!PyCallable_Check (data->func)) {
270 PyErr_SetString (PyExc_TypeError, "func must be callable");
275 if (!pyg_boxed_check(py_query, RHYTHMDB_TYPE_QUERY)) {
276 PyErr_SetString(PyExc_TypeError, "query should be a RhythmDBQuery");
281 Py_INCREF (data->func);
282 Py_INCREF (data->data);
285 query_model = rhythmdb_query_model_new (RHYTHMDB (self->obj), pyg_boxed_get (py_query, RhythmDBQuery),
286 (GCompareDataFunc) _rhythmdb_query_model_sort_func,
287 data, (GDestroyNotify) _rhythmdb_query_model_sort_data_free,
290 query_model = rhythmdb_query_model_new (RHYTHMDB (self->obj), pyg_boxed_get (py_query, RhythmDBQuery),
291 NULL, NULL, NULL, FALSE);
294 return pygobject_new (G_OBJECT (query_model));
297 override rhythmdb_query_model_set_sort_order kwargs
300 _wrap_rhythmdb_query_model_set_sort_order (PyGObject *self, PyObject *args, PyObject *kwargs)
302 static char *kwlist[] = {"func", "reverse", NULL};
304 PyRhythmDBQueryModelSortData *data;
306 data = g_new0 (PyRhythmDBQueryModelSortData, 1);
308 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iO:RhythmDB.query_model_set_sort_order", kwlist,
309 &data->func, &reverse, &data->data)) {
314 /* verify arguments' integrity */
315 if (!PyCallable_Check (data->func)) {
316 PyErr_SetString (PyExc_TypeError, "func must be callable");
321 Py_INCREF (data->func);
322 Py_INCREF (data->data);
324 rhythmdb_query_model_set_sort_order (RHYTHMDB_QUERY_MODEL (self->obj),
325 (GCompareDataFunc) _rhythmdb_query_model_sort_func,
326 data, (GDestroyNotify) _rhythmdb_query_model_sort_data_free,
333 override-attr RhythmDBEntryType_.sync_metadata
336 _wrap_py_entry_type_sync_metadata (RhythmDB *db, RhythmDBEntry *entry,
337 GError **error, PyObject *py_call)
339 if (PyCallable_Check (py_call)) {
340 PyObject *ret, *args, *error;
341 PyObject *py_db, *py_entry;
343 py_db = pygobject_new (G_OBJECT (db));
344 py_entry = pyg_boxed_new (RHYTHMDB_TYPE_ENTRY, entry, TRUE, TRUE);
345 args = Py_BuildValue ("(OO)", py_db, py_entry);
346 ret = PyObject_Call (py_call, args, NULL);
349 Py_DECREF (py_entry);
352 error = PyErr_Occurred ();
354 /* TODO: catch any exceptions, and set errors*/
358 /* TODO: set error */
363 _wrap_rhythmdb_entry_type__get_sync_metadata (PyGBoxed *self, void *closure)
365 RhythmDBEntryType et;
367 if (pyg_boxed_check(self, RHYTHMDB_TYPE_ENTRY_TYPE))
368 et = pyg_boxed_get(self, RhythmDBEntryType_);
370 PyErr_SetString(PyExc_TypeError, "self should be a RhythmDBEntryType");
374 if (et->sync_metadata == (RhythmDBEntrySyncFunc)rb_null_function) {
378 } else if (et->sync_metadata == (RhythmDBEntrySyncFunc)_wrap_py_entry_type_sync_metadata) {
380 PyObject *value = (PyObject*)et->sync_metadata_data;
385 /* FIXME: it's a non-python function */
391 _wrap_rhythmdb_entry_type__set_sync_metadata (PyGBoxed *self, PyObject *value, void *closure)
393 RhythmDBEntryType et;
395 if (pyg_boxed_check(self, RHYTHMDB_TYPE_ENTRY_TYPE))
396 et = pyg_boxed_get(self, RhythmDBEntryType_);
398 PyErr_SetString(PyExc_TypeError, "self should be a RhythmDBEntryType");
402 if (et->sync_metadata_data && et->sync_metadata_destroy)
403 et->sync_metadata_destroy (et->sync_metadata);
405 if (value == Py_None) {
406 et->sync_metadata = (RhythmDBEntrySyncFunc)rb_null_function;
407 et->sync_metadata_data = NULL;
408 et->sync_metadata_destroy = NULL;
409 } else if (PyCallable_Check (value)) {
411 et->sync_metadata = (RhythmDBEntrySyncFunc)_wrap_py_entry_type_sync_metadata;
413 et->sync_metadata_data = value;
414 et->sync_metadata_destroy = (GDestroyNotify)_py_decref;
416 PyErr_SetString(PyExc_TypeError, "value must be callable");
423 override-attr RhythmDBEntryType_.can_sync_metadata
426 _wrap_py_entry_type_can_sync_metadata (RhythmDB *db, RhythmDBEntry *entry,
429 gboolean retval = FALSE;
431 if (PyCallable_Check (py_call)) {
432 PyObject *ret, *args;
433 PyObject *py_db, *py_entry;
436 py_db = pygobject_new (G_OBJECT (db));
437 py_entry = pyg_boxed_new (RHYTHMDB_TYPE_ENTRY, entry, TRUE, TRUE);
438 args = Py_BuildValue ("(OO)", py_db, py_entry);
439 ret = PyObject_Call (py_call, args, NULL);
442 Py_DECREF (py_entry);
444 i = PyObject_IsTrue (ret);
451 /*TODO: emit error */
454 /* TODO: emit error */
461 _wrap_rhythmdb_entry_type__get_can_sync_metadata (PyGBoxed *self, void *closure)
463 RhythmDBEntryType et;
465 if (pyg_boxed_check(self, RHYTHMDB_TYPE_ENTRY_TYPE))
466 et = pyg_boxed_get(self, RhythmDBEntryType_);
468 PyErr_SetString(PyExc_TypeError, "self should be a RhythmDBEntryType");
472 if (et->can_sync_metadata == (RhythmDBEntryCanSyncFunc)rb_false_function) {
474 Py_INCREF (Py_False);
476 } else if (et->can_sync_metadata == (RhythmDBEntryCanSyncFunc)rb_true_function) {
480 } else if (et->can_sync_metadata == (RhythmDBEntryCanSyncFunc)rb_null_function) {
483 } else if (et->can_sync_metadata == (RhythmDBEntryCanSyncFunc)_wrap_py_entry_type_can_sync_metadata) {
485 PyObject *value = (PyObject*)et->can_sync_metadata_data;
490 /* FIXME: it's a non-python function */
496 _wrap_rhythmdb_entry_type__set_can_sync_metadata (PyGBoxed *self, PyObject *value, void *closure)
498 RhythmDBEntryType et;
500 if (pyg_boxed_check(self, RHYTHMDB_TYPE_ENTRY_TYPE))
501 et = pyg_boxed_get(self, RhythmDBEntryType_);
503 PyErr_SetString(PyExc_TypeError, "self should be a RhythmDBEntryType");
507 if (et->can_sync_metadata_data && et->can_sync_metadata_destroy)
508 et->can_sync_metadata_destroy (et->can_sync_metadata);
510 if (value == Py_False) {
511 et->can_sync_metadata = (RhythmDBEntryCanSyncFunc)rb_false_function;
512 et->can_sync_metadata_data = NULL;
513 et->can_sync_metadata_destroy = NULL;
514 } else if (value == Py_True) {
515 et->can_sync_metadata = (RhythmDBEntryCanSyncFunc)rb_true_function;
516 et->can_sync_metadata_data = NULL;
517 et->can_sync_metadata_destroy = NULL;
518 } else if (value == Py_None) {
519 et->can_sync_metadata = (RhythmDBEntryCanSyncFunc)rb_null_function;
520 et->can_sync_metadata_data = NULL;
521 et->can_sync_metadata_destroy = NULL;
522 } else if (PyCallable_Check (value)) {
524 et->can_sync_metadata = (RhythmDBEntryCanSyncFunc)_wrap_py_entry_type_can_sync_metadata;
526 et->can_sync_metadata_data = value;
527 et->can_sync_metadata_destroy = (GDestroyNotify)_py_decref;
529 PyErr_SetString(PyExc_TypeError, "value must be callable");
536 override rhythmdb_entry_request_extra_metadata kwargs
539 _wrap_rhythmdb_entry_request_extra_metadata(PyGObject *self, PyObject *args, PyObject *kwargs)
541 static char *kwlist[] = { "entry", "property_name", NULL };
545 RhythmDBEntry *entry = NULL;
547 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"Os:RhythmDB.entry_request_extra_metadata", kwlist, &py_entry, &property_name))
549 if (pyg_boxed_check(py_entry, RHYTHMDB_TYPE_ENTRY))
550 entry = pyg_boxed_get(py_entry, RhythmDBEntry);
552 PyErr_SetString(PyExc_TypeError, "entry should be a RhythmDBEntry");
556 ret = rhythmdb_entry_request_extra_metadata(RHYTHMDB_RHYTHMDB(self->obj), entry, property_name);
559 PyObject *py_ret = pyg_value_as_pyobject (ret, TRUE);
568 override rhythmdb_entry_gather_metadata kwargs
571 _hashtable_to_dict (const char *name, GValue *value, PyObject *dict)
575 obj = pyg_value_as_pyobject (value, TRUE);
576 PyDict_SetItemString (dict, name, obj);
581 _wrap_rhythmdb_entry_gather_metadata(PyGObject *self, PyObject *args, PyObject *kwargs)
583 static char *kwlist[] = { "entry", NULL };
586 RhythmDBEntry *entry = NULL;
588 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O:RhythmDB.entry_gather_metadata", kwlist, &py_entry))
590 if (pyg_boxed_check(py_entry, RHYTHMDB_TYPE_ENTRY))
591 entry = pyg_boxed_get(py_entry, RhythmDBEntry);
593 PyErr_SetString(PyExc_TypeError, "entry should be a RhythmDBEntry");
597 ret = rhythmdb_entry_gather_metadata(RHYTHMDB_RHYTHMDB(self->obj), entry);
600 PyObject *py_ret = PyDict_New();
602 g_hash_table_foreach (ret, (GHFunc)_hashtable_to_dict, py_ret);
604 g_hash_table_destroy(ret);
611 override rhythmdb_emit_entry_extra_metadata_notify kwargs
614 _wrap_rhythmdb_emit_entry_extra_metadata_notify(PyGObject *self, PyObject *args, PyObject *kwargs)
616 static char *kwlist[] = { "entry", "property_name", "metadata", NULL };
619 PyObject *py_metadata;
620 RhythmDBEntry *entry = NULL;
623 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"OsO:RhythmDB.emit_entry_extra_metadata_notify", kwlist, &py_entry, &property_name, &py_metadata))
626 if (pyg_boxed_check(py_entry, RHYTHMDB_TYPE_ENTRY)) {
627 entry = pyg_boxed_get(py_entry, RhythmDBEntry);
629 PyErr_SetString(PyExc_TypeError, "entry should be a RhythmDBEntry");
633 pyg_value_from_pyobject (&val, py_metadata);
634 rhythmdb_emit_entry_extra_metadata_notify(RHYTHMDB_RHYTHMDB(self->obj), entry, property_name, &val);
635 g_value_unset (&val);