All pastes #1678049 Raw Edit

Diff

public text v1 · immutable
#1678049 ·published 2009-11-19 18:01 UTC
rendered paste body
diff --git a/examples/source_browsing.py b/examples/source_browsing.pyindex f45f73d..7199baa 100644--- a/examples/source_browsing.py+++ b/examples/source_browsing.py@@ -108,13 +108,14 @@ class SourceBrowsing(object):          keys = [mafw.METADATA_KEY_TITLE, mafw.METADATA_KEY_ARTIST,                 mafw.METADATA_KEY_ALBUM, mafw.METADATA_KEY_GENRE]+        filt = '(artist=*)'          self.browse_id = self.app_source.browse(-            self.obj_id, recursive=False, keys=keys, count=30,-                        callback=browse_request_cb)+            self.obj_id, filt, self.browse_request_cb, keys=keys, count=30) -        if self.browse_id == mafw.SOURCE_INVALID_BROWSE_ID:+        if self.browse_id == mafw.SOURCE_ERROR_INVALID_BROWSE_ID:             logging.warning('Incorrect browse request.')+            self.mainloop.quit()          return False @@ -123,7 +124,7 @@ class SourceBrowsing(object):          name = source.get_name()         logging.info('Source %s available.' % name)-        +         if name == WANTED_SOURCE:             logging.info('Wanted source found!')             self.app_source = source@@ -135,7 +136,7 @@ class SourceBrowsing(object):         """Checks if the referenced source is removed, and if so, exits."""          logging.info('Source %s removed' % source.get_name())-        +         if source == sef.app_source:             logging.error('Wanted source removed! Exiting...')             self.mainloop.quit()diff --git a/mafw.override b/mafw.overrideindex 22d9bce..3fb7497 100644--- a/mafw.override+++ b/mafw.override@@ -226,39 +226,210 @@ _wrap_mafw_registry_list_plugins(PyGObject *self) }  %%-override mafw_source_browse varargs+override mafw_source_browse kwargs++static+PyObject *+ghashtable_to_pydict(const GHashTable *table)+{+    PyObject *pytable = PyDict_New();+    GList *keys = NULL;+    GList *current_key = NULL;++    keys = g_hash_table_get_keys(table);+    current_key = keys;++    while (current_key) {+        PyObject *pyvalue;++        GValue *value = g_hash_table_lookup(table, current_key->data);+        const gchar *key = (const gchar *)current_key->data;++        if (G_VALUE_HOLDS_STRING(value)) {+            pyvalue = PyString_FromString(g_value_get_string(value));+        } else if (G_VALUE_HOLDS_INT(value)) {+            pyvalue = PyInt_FromLong(g_value_get_int(value));+        } else { // TODO Support other stuff+            pyvalue = Py_None;+            Py_XINCREF(pyvalue);+        }++        PyDict_SetItemString(pytable, key, pyvalue);++        current_key = g_list_next(current_key);+    }++    if (keys)+        g_list_free(keys);++    return pytable;+}++/**+ * Callback for mafw.Source.browse+ */+void+pymafw_browse_cb(MafwSource *self, guint browse_id, gint remaining_count,+                 guint index, const char *object_id, GHashTable *metadata,+                 gpointer user_data, const GError *error)+{+    PyObject *pymetadata = NULL;+    PyObject *pycallback = (PyObject *)user_data;+    PyObject *pyargs = NULL;+    PyGILState_STATE gil_lock;+++    if (error) {+        PyErr_SetString(PyExc_RuntimeError, error->message);+        PyErr_Print();+        return;+    }++    gil_lock = PyGILState_Ensure();++    if (object_id == NULL) {+        g_debug("Object_id null, returning");+        Py_XDECREF((PyObject *)user_data); // Finished, callback not needed anymore+        goto cleanup;+    }++    pymetadata = ghashtable_to_pydict(metadata);++    pyargs = PyTuple_New(6); // TODO Support user_data?++    PyTuple_SetItem(pyargs, 0, pygobject_new(self));+    PyTuple_SetItem(pyargs, 1, PyInt_FromLong(browse_id));+    PyTuple_SetItem(pyargs, 2, PyInt_FromLong(remaining_count));+    PyTuple_SetItem(pyargs, 3, PyInt_FromLong(index));+    PyTuple_SetItem(pyargs, 4, PyString_FromString(object_id));+    PyTuple_SetItem(pyargs, 5, pymetadata);+++    PyObject_Call(pycallback, pyargs, PyDict_New());++    if (PyErr_Occurred())+        PyErr_Print();++cleanup:++    if (pyargs)+        Py_XDECREF(pyargs);++    if (pymetadata)+        Py_XDECREF(pymetadata);++    PyGILState_Release(gil_lock);++    return;+}++/**+ * mafw.Source.browse+ *+ * Arguments:+ *+ * Requided+ * object_id+ * filter // mafw.Filter or string+ * callback+ *+ * Optional+ * recursive=False/0+ * sort_criteria="+name"+ * metadata_keys = NULL+ * skip_count = 0+ * item_count = 0+ * data=None - Not supported yet+ */ static PyObject *-_wrap_mafw_source_browse(PyObject *self, PyObject *args, PyObject *kwds)+_wrap_mafw_source_browse(PyGObject *self, PyObject *args, PyObject *kwargs) {-    char *object_id;-    int recursive;-    char *filter;-    char *sort_criteria;-    char *metadata_keys;-    int skip_count;-    int item_count;-    PyObject *browse_cb;-    gpointer user_data = NULL;--    int browse_id = 0;--    if (!PyArg_ParseTuple(args, "ssO", &object_id, &metadata_keys, &browse_cb))+    static char *kwlist[] = { "object_id", "filter", "callback", "recursive",+                              "sort", "keys", "count",+                              "count", "data", NULL };++    char *object_id = NULL;+    PyObject *pyfilter = NULL;+    PyObject *pycallback = NULL;+    int recursive = 0;+    char *sort_criteria = "+name"; /* Should we require this? */+    PyObject *pymetadata_keys = NULL;+    int skip_count = 0;+    int item_count = MAFW_SOURCE_BROWSE_ALL;+    PyObject *pydata = NULL;++    MafwFilter *filter = NULL;++    char **metadata_keys = NULL;+    int i = 0;+    int size;++    int browse_id = MAFW_SOURCE_ERROR_INVALID_BROWSE_ID;++    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sOO|isOiiO:mafw.Source.browse",+                                     kwlist, &object_id, &pyfilter, &pycallback,+                                     &recursive, &sort_criteria, &pymetadata_keys,+                                     &skip_count, &item_count, &pydata))         return NULL; -    g_print("DEBUG::object_id: %s \n", object_id);-    g_print("DEBUG::metadata_keys: %s \n", metadata_keys);+    /* Check filter */+    if (PyString_Check(pyfilter)) {+        filter = mafw_filter_parse(PyString_AsString(pyfilter));+    } else { // TODO Support mafw.Filter+        PyErr_SetString(PyExc_TypeError, "filter must be a string");+        goto cleanup;+    } -    browse_id = mafw_source_browse(self,            /* Source */-                                   object_id,       /* Object identifier */-                                   FALSE,           /* Recursive */-                                   NULL,            /* Filter */-                                   NULL,            /* Sorting */-                                   metadata_keys,   /* Requested keys */-                                   0, 30,            /* Offset, Count*/-                                   browse_cb,        /* Callback */-                                   NULL);            /* User data */+    /* Check callback */+    if (!PyCallable_Check(pycallback)) {+        PyErr_SetString(PyExc_TypeError, "Callback must be a callable");+        goto cleanup;+    }+    /* Convert metadata keys */+    if (pymetadata_keys == Py_None || pymetadata_keys == NULL) {+        // Empty on purpose+    } else if (PySequence_Check(pymetadata_keys) && !PyString_Check(pymetadata_keys)) {+        size = PySequence_Size(pymetadata_keys);+        metadata_keys = g_new(char **, size+1);+        for (i = 0; i < size; i++) {+            PyObject *key = PySequence_GetItem(pymetadata_keys, i);+            if (!PyString_Check(key)) {+                PyErr_SetString(PyExc_TypeError, "Metadata keys must be a sequence of strings");+                goto cleanup;+            }+            metadata_keys[i] = PyString_AsString(key);+        }+        metadata_keys[size] = NULL;+    } else {+        PyErr_SetString(PyExc_TypeError, "Metadata keys must be a sequence of strings or None");+        goto cleanup;+    } -    return Py_BuildValue("i", browse_id);+    Py_XINCREF(pycallback);++    /* TODO Currently we do not allow the user sending user data */+    browse_id = mafw_source_browse(MAFW_SOURCE(self->obj),+                                   object_id,+                                   recursive,+                                   filter,+                                   sort_criteria,+                                   metadata_keys,+                                   skip_count,+                                   item_count,+                                   pymafw_browse_cb,+                                   pycallback);++cleanup:+    if (filter)+        mafw_filter_free(filter);++    if (metadata_keys)+        g_free(metadata_keys);++    if (PyErr_Occurred())+        return NULL;+    else+        return Py_BuildValue("i", browse_id); }  %%