mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Use bulk fetch for list_folder by name
This commit is contained in:
parent
f19ca06b86
commit
b8c92ac9ce
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
|
#include <dictobject.h>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
namespace wpd {
|
namespace wpd {
|
||||||
@ -169,12 +170,14 @@ private:
|
|||||||
if (PyDict_SetItem(this->items, object_id.ptr(), obj.ptr()) != 0) { PyErr_Clear(); return; }
|
if (PyDict_SetItem(this->items, object_id.ptr(), obj.ptr()) != 0) { PyErr_Clear(); return; }
|
||||||
} else Py_INCREF(obj.ptr());
|
} else Py_INCREF(obj.ptr());
|
||||||
set_properties(obj.ptr(), properties);
|
set_properties(obj.ptr(), properties);
|
||||||
pyobject_raii r(PyObject_CallFunction(callback, "OI", obj.ptr(), this->level));
|
if (callback) {
|
||||||
if (!r) PyErr_Clear();
|
pyobject_raii r(PyObject_CallFunction(callback, "OI", obj.ptr(), this->level));
|
||||||
else if (r && PyObject_IsTrue(r.ptr())) {
|
if (!r) PyErr_Clear();
|
||||||
PyObject *borrowed = PyDict_GetItemString(obj.ptr(), "id");
|
else if (r && PyObject_IsTrue(r.ptr())) {
|
||||||
if (borrowed) if (PyList_Append(this->subfolders, borrowed) != 0) PyErr_Clear();
|
PyObject *borrowed = PyDict_GetItemString(obj.ptr(), "id");
|
||||||
}
|
if (borrowed) if (PyList_Append(this->subfolders, borrowed) != 0) PyErr_Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_values(IPortableDeviceValuesCollection* values) {
|
void handle_values(IPortableDeviceValuesCollection* values) {
|
||||||
@ -422,9 +425,11 @@ single_get_filesystem(unsigned int level, CComPtr<IPortableDeviceContent> &conte
|
|||||||
if (SUCCEEDED(hr) && pv.pwszVal != NULL) {
|
if (SUCCEEDED(hr) && pv.pwszVal != NULL) {
|
||||||
pyobject_raii item(get_object_properties(devprops, properties, pv.pwszVal));
|
pyobject_raii item(get_object_properties(devprops, properties, pv.pwszVal));
|
||||||
if (!item) return false;
|
if (!item) return false;
|
||||||
pyobject_raii r(PyObject_CallFunction(callback, "OI", item.ptr(), level));
|
|
||||||
if (PyDict_SetItem(ans, PyDict_GetItemString(item.ptr(), "id"), item.ptr()) != 0) return false;
|
if (PyDict_SetItem(ans, PyDict_GetItemString(item.ptr(), "id"), item.ptr()) != 0) return false;
|
||||||
if (r && PyObject_IsTrue(r.ptr())) recurse.attach(item.detach());
|
if (callback) {
|
||||||
|
pyobject_raii r(PyObject_CallFunction(callback, "OI", item.ptr(), level));
|
||||||
|
if (r && PyObject_IsTrue(r.ptr())) recurse.attach(item.detach());
|
||||||
|
}
|
||||||
} else { hresult_set_exc("Failed to get item from IPortableDevicePropVariantCollection", hr); return false; }
|
} else { hresult_set_exc("Failed to get item from IPortableDevicePropVariantCollection", hr); return false; }
|
||||||
|
|
||||||
if (recurse) {
|
if (recurse) {
|
||||||
@ -468,42 +473,28 @@ create_object_properties(const wchar_t *parent_id, const wchar_t *name, const GU
|
|||||||
} // }}}
|
} // }}}
|
||||||
|
|
||||||
PyObject*
|
PyObject*
|
||||||
list_folder(CComPtr<IPortableDeviceContent> &content, IPortableDevicePropertiesBulk *bulk_properties, const wchar_t *folder_id) {
|
list_folder(IPortableDevice *device, CComPtr<IPortableDeviceContent> &content, IPortableDevicePropertiesBulk *bulk_properties, const wchar_t *folder_id) {
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
CComPtr<IPortableDevicePropVariantCollection> object_ids;
|
CComPtr<IPortableDevicePropVariantCollection> object_ids;
|
||||||
Py_BEGIN_ALLOW_THREADS;
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
hr = object_ids.CoCreateInstance(CLSID_PortableDevicePropVariantCollection, NULL, CLSCTX_INPROC_SERVER);
|
hr = object_ids.CoCreateInstance(CLSID_PortableDevicePropVariantCollection, NULL, CLSCTX_INPROC_SERVER);
|
||||||
Py_END_ALLOW_THREADS;
|
Py_END_ALLOW_THREADS;
|
||||||
if (FAILED(hr)) { hresult_set_exc("Failed to create propvariantcollection", hr); return NULL; }
|
if (FAILED(hr)) { hresult_set_exc("Failed to create propvariantcollection", hr); return NULL; }
|
||||||
|
pyobject_raii ans(PyDict_New()); if (!ans) return NULL;
|
||||||
|
|
||||||
bool enum_failed = false;
|
bool enum_failed = false;
|
||||||
if (!find_objects_in(content, object_ids, folder_id, &enum_failed)) return NULL;
|
if (!find_objects_in(content, object_ids, folder_id, &enum_failed)) return NULL;
|
||||||
DWORD num;
|
|
||||||
CComPtr<IPortableDeviceProperties> devprops;
|
|
||||||
|
|
||||||
hr = content->Properties(&devprops);
|
if (bulk_properties) {
|
||||||
if (FAILED(hr)) { hresult_set_exc("Failed to get IPortableDeviceProperties interface", hr); return NULL; }
|
if (!bulk_get_filesystem(0, device, bulk_properties, object_ids, NULL, ans.ptr(), NULL)) return NULL;
|
||||||
|
} else {
|
||||||
CComPtr<IPortableDeviceKeyCollection> properties(create_filesystem_properties_collection());
|
if (!single_get_filesystem(0, content, object_ids, NULL, ans.ptr(), NULL)) return NULL;
|
||||||
if (!properties) return NULL;
|
|
||||||
hr = object_ids->GetCount(&num);
|
|
||||||
if (FAILED(hr)) { hresult_set_exc("Failed to get object id count", hr); return NULL; }
|
|
||||||
pyobject_raii ans(PyList_New(0)); if (!ans) return NULL;
|
|
||||||
|
|
||||||
for (DWORD i = 0; i < num; i++) {
|
|
||||||
prop_variant pv;
|
|
||||||
hr = object_ids->GetAt(i, &pv);
|
|
||||||
if (SUCCEEDED(hr) && pv.pwszVal != NULL) {
|
|
||||||
pyobject_raii item(get_object_properties(devprops, properties, pv.pwszVal));
|
|
||||||
if (!item) return NULL;
|
|
||||||
if (PyList_Append(ans.ptr(), item.ptr()) != 0) return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ans.detach();
|
return ans.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject*
|
PyObject*
|
||||||
find_in_parent(CComPtr<IPortableDeviceContent> &content, IPortableDevicePropertiesBulk *bulk_properties, const wchar_t *parent_id, PyObject *name) {
|
find_in_parent(CComPtr<IPortableDeviceContent> &content, const wchar_t *parent_id, PyObject *name) {
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
CComPtr<IPortableDevicePropVariantCollection> object_ids;
|
CComPtr<IPortableDevicePropVariantCollection> object_ids;
|
||||||
Py_BEGIN_ALLOW_THREADS;
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
|
@ -97,7 +97,7 @@ list_folder_by_name(Device *self, PyObject *args) {
|
|||||||
PyObject *k = PyTuple_GET_ITEM(names, i);
|
PyObject *k = PyTuple_GET_ITEM(names, i);
|
||||||
if (!PyUnicode_Check(k)) { PyErr_SetString(PyExc_TypeError, "names must contain only unicode strings"); return NULL; }
|
if (!PyUnicode_Check(k)) { PyErr_SetString(PyExc_TypeError, "names must contain only unicode strings"); return NULL; }
|
||||||
pyobject_raii l(PyObject_CallMethod(k, "lower", NULL)); if (!l) return NULL;
|
pyobject_raii l(PyObject_CallMethod(k, "lower", NULL)); if (!l) return NULL;
|
||||||
pyobject_raii object_id(wpd::find_in_parent(content, self->bulk_properties, parent_id.ptr(), l.ptr()));
|
pyobject_raii object_id(wpd::find_in_parent(content, parent_id.ptr(), l.ptr()));
|
||||||
if (!object_id) {
|
if (!object_id) {
|
||||||
if (PyErr_Occurred()) return NULL;
|
if (PyErr_Occurred()) return NULL;
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
@ -106,7 +106,7 @@ list_folder_by_name(Device *self, PyObject *args) {
|
|||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
if (!found) Py_RETURN_NONE;
|
if (!found) Py_RETURN_NONE;
|
||||||
return wpd::list_folder(content, self->bulk_properties, parent_id.ptr());
|
return wpd::list_folder(self->device, content, self->bulk_properties, parent_id.ptr());
|
||||||
} // }}}
|
} // }}}
|
||||||
|
|
||||||
// create_folder() {{{
|
// create_folder() {{{
|
||||||
|
@ -398,7 +398,7 @@ class MTP_DEVICE(MTPDeviceBase):
|
|||||||
x = self.dev.list_folder_by_name(parent.object_id, names)
|
x = self.dev.list_folder_by_name(parent.object_id, names)
|
||||||
if x is None:
|
if x is None:
|
||||||
raise DeviceError(f'Could not find folder named: {"/".join(names)} in {parent.full_path}')
|
raise DeviceError(f'Could not find folder named: {"/".join(names)} in {parent.full_path}')
|
||||||
return x
|
return list(x.values())
|
||||||
|
|
||||||
@same_thread
|
@same_thread
|
||||||
def get_mtp_file(self, f, stream=None, callback=None):
|
def get_mtp_file(self, f, stream=None, callback=None):
|
||||||
|
@ -50,7 +50,8 @@ extern PyObject* create_folder(IPortableDevice *device, const wchar_t *parent_id
|
|||||||
extern PyObject* delete_object(IPortableDevice *device, const wchar_t *object_id);
|
extern PyObject* delete_object(IPortableDevice *device, const wchar_t *object_id);
|
||||||
extern PyObject* put_file(IPortableDevice *device, const wchar_t *parent_id, const wchar_t *name, PyObject *src, unsigned PY_LONG_LONG size, PyObject *callback);
|
extern PyObject* put_file(IPortableDevice *device, const wchar_t *parent_id, const wchar_t *name, PyObject *src, unsigned PY_LONG_LONG size, PyObject *callback);
|
||||||
extern PyObject* find_in_parent(
|
extern PyObject* find_in_parent(
|
||||||
CComPtr<IPortableDeviceContent> &content, IPortableDevicePropertiesBulk *bulk_properties, const wchar_t *parent_id, PyObject *name);
|
CComPtr<IPortableDeviceContent> &content, const wchar_t *parent_id, PyObject *name);
|
||||||
extern PyObject* list_folder(
|
extern PyObject* list_folder(
|
||||||
CComPtr<IPortableDeviceContent> &content, IPortableDevicePropertiesBulk *bulk_properties, const wchar_t *folder_id);
|
IPortableDevice *device, CComPtr<IPortableDeviceContent> &content, IPortableDevicePropertiesBulk *bulk_properties,
|
||||||
|
const wchar_t *folder_id);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user