diff --git a/src/calibre/devices/mtp/unix/driver.py b/src/calibre/devices/mtp/unix/driver.py index b8e8938c93..2a22b175e9 100644 --- a/src/calibre/devices/mtp/unix/driver.py +++ b/src/calibre/devices/mtp/unix/driver.py @@ -212,8 +212,13 @@ class MTP_DEVICE(MTPDeviceBase): ans += pprint.pformat(storage) return ans - def _filesystem_callback(self, entry): - self.filesystem_callback(_('Found object: %s')%entry.get('name', '')) + def _filesystem_callback(self, entry, level): + name = entry.get('name', '') + self.filesystem_callback(_('Found object: %s')%name) + if (level == 0 and + self.is_folder_ignored(self._currently_getting_sid, name)): + return False + return True @property def filesystem_cache(self): @@ -234,6 +239,7 @@ class MTP_DEVICE(MTPDeviceBase): storage.append({'id':sid, 'size':capacity, 'is_folder':True, 'name':name, 'can_delete':False, 'is_system':True}) + self._currently_getting_sid = unicode(sid) items, errs = self.dev.get_filesystem(sid, self._filesystem_callback) all_items.extend(items), all_errs.extend(errs) diff --git a/src/calibre/devices/mtp/unix/libmtp.c b/src/calibre/devices/mtp/unix/libmtp.c index b62bd8a9c7..1716265ec7 100644 --- a/src/calibre/devices/mtp/unix/libmtp.c +++ b/src/calibre/devices/mtp/unix/libmtp.c @@ -122,7 +122,7 @@ static PyObject* build_file_metadata(LIBMTP_file_t *nf, uint32_t storage_id) { PyObject *ans = NULL; ans = Py_BuildValue("{s:s, s:k, s:k, s:k, s:K, s:L, s:O}", - "name", (unsigned long)nf->filename, + "name", nf->filename, "id", (unsigned long)nf->item_id, "parent_id", (unsigned long)nf->parent_id, "storage_id", (unsigned long)storage_id, @@ -357,10 +357,10 @@ Device_storage_info(Device *self, void *closure) { // Device.get_filesystem {{{ -static int recursive_get_files(LIBMTP_mtpdevice_t *dev, uint32_t storage_id, uint32_t parent_id, PyObject *ans, PyObject *errs, PyObject *callback) { +static int recursive_get_files(LIBMTP_mtpdevice_t *dev, uint32_t storage_id, uint32_t parent_id, PyObject *ans, PyObject *errs, PyObject *callback, unsigned int level) { LIBMTP_file_t *f, *files; - PyObject *entry; - int ok = 1; + PyObject *entry, *r; + int ok = 1, recurse; Py_BEGIN_ALLOW_THREADS; files = LIBMTP_Get_Files_And_Folders(dev, storage_id, parent_id); @@ -372,13 +372,15 @@ static int recursive_get_files(LIBMTP_mtpdevice_t *dev, uint32_t storage_id, uin entry = build_file_metadata(f, storage_id); if (entry == NULL) { ok = 0; } else { - Py_XDECREF(PyObject_CallFunctionObjArgs(callback, entry, NULL)); + r = PyObject_CallFunction(callback, "OI", entry, level); + recurse = (r != NULL && PyObject_IsTrue(r)) ? 1 : 0; + Py_XDECREF(r); if (PyList_Append(ans, entry) != 0) { ok = 0; } Py_DECREF(entry); } - if (ok && f->filetype == LIBMTP_FILETYPE_FOLDER) { - if (!recursive_get_files(dev, storage_id, f->item_id, ans, errs, callback)) { + if (ok && recurse && f->filetype == LIBMTP_FILETYPE_FOLDER) { + if (!recursive_get_files(dev, storage_id, f->item_id, ans, errs, callback, level+1)) { ok = 0; } } @@ -408,7 +410,7 @@ Device_get_filesystem(Device *self, PyObject *args) { if (errs == NULL || ans == NULL) { PyErr_NoMemory(); return NULL; } LIBMTP_Clear_Errorstack(self->device); - ok = recursive_get_files(self->device, (uint32_t)storage_id, 0, ans, errs, callback); + ok = recursive_get_files(self->device, (uint32_t)storage_id, 0xFFFFFFFF, ans, errs, callback, 0); dump_errorstack(self->device, errs); if (!ok) { Py_DECREF(ans); @@ -537,7 +539,7 @@ static PyMethodDef Device_methods[] = { }, {"get_filesystem", (PyCFunction)Device_get_filesystem, METH_VARARGS, - "get_filesystem(storage_id, callback) -> Get the list of files and folders on the device in storage_id. Returns files, errors. callback must be a callable that accepts a single argument. It is called with every found object." + "get_filesystem(storage_id, callback) -> Get the list of files and folders on the device in storage_id. Returns files, errors. callback must be a callable that is called as with (entry, level). It is called with every found object. If callback returns False and the object is a folder, it is not recursed into." }, {"get_file", (PyCFunction)Device_get_file, METH_VARARGS,