mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
WPD: Create folders and use the actual file name instead of the nominal_name
This commit is contained in:
parent
922e02e0d7
commit
179d4781f0
@ -28,6 +28,7 @@ static IPortableDeviceKeyCollection* create_filesystem_properties_collection() {
|
|||||||
ADDPROP(WPD_OBJECT_PARENT_ID);
|
ADDPROP(WPD_OBJECT_PARENT_ID);
|
||||||
ADDPROP(WPD_OBJECT_PERSISTENT_UNIQUE_ID);
|
ADDPROP(WPD_OBJECT_PERSISTENT_UNIQUE_ID);
|
||||||
ADDPROP(WPD_OBJECT_NAME);
|
ADDPROP(WPD_OBJECT_NAME);
|
||||||
|
ADDPROP(WPD_OBJECT_ORIGINAL_FILE_NAME);
|
||||||
// ADDPROP(WPD_OBJECT_SYNC_ID);
|
// ADDPROP(WPD_OBJECT_SYNC_ID);
|
||||||
ADDPROP(WPD_OBJECT_ISSYSTEM);
|
ADDPROP(WPD_OBJECT_ISSYSTEM);
|
||||||
ADDPROP(WPD_OBJECT_ISHIDDEN);
|
ADDPROP(WPD_OBJECT_ISHIDDEN);
|
||||||
@ -92,8 +93,9 @@ static void set_properties(PyObject *obj, IPortableDeviceValues *values) {
|
|||||||
set_content_type_property(obj, values);
|
set_content_type_property(obj, values);
|
||||||
|
|
||||||
set_string_property(obj, WPD_OBJECT_PARENT_ID, "parent_id", values);
|
set_string_property(obj, WPD_OBJECT_PARENT_ID, "parent_id", values);
|
||||||
set_string_property(obj, WPD_OBJECT_NAME, "name", values);
|
set_string_property(obj, WPD_OBJECT_NAME, "nominal_name", values);
|
||||||
// set_string_property(obj, WPD_OBJECT_SYNC_ID, "sync_id", values);
|
// set_string_property(obj, WPD_OBJECT_SYNC_ID, "sync_id", values);
|
||||||
|
set_string_property(obj, WPD_OBJECT_ORIGINAL_FILE_NAME, "name", values);
|
||||||
set_string_property(obj, WPD_OBJECT_PERSISTENT_UNIQUE_ID, "persistent_id", values);
|
set_string_property(obj, WPD_OBJECT_PERSISTENT_UNIQUE_ID, "persistent_id", values);
|
||||||
|
|
||||||
set_bool_property(obj, WPD_OBJECT_ISHIDDEN, "is_hidden", values);
|
set_bool_property(obj, WPD_OBJECT_ISHIDDEN, "is_hidden", values);
|
||||||
@ -370,6 +372,37 @@ end:
|
|||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
|
static IPortableDeviceValues* create_object_properties(const wchar_t *parent_id, const wchar_t *name, const GUID content_type) { // {{{
|
||||||
|
IPortableDeviceValues *values = NULL;
|
||||||
|
HRESULT hr;
|
||||||
|
BOOL ok = FALSE;
|
||||||
|
|
||||||
|
hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL,
|
||||||
|
CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&values));
|
||||||
|
if (FAILED(hr)) { hresult_set_exc("Failed to create values interface", hr); goto end; }
|
||||||
|
|
||||||
|
hr = values->SetStringValue(WPD_OBJECT_PARENT_ID, parent_id);
|
||||||
|
if (FAILED(hr)) { hresult_set_exc("Failed to set parent_id value", hr); goto end; }
|
||||||
|
|
||||||
|
hr = values->SetStringValue(WPD_OBJECT_NAME, name);
|
||||||
|
if (FAILED(hr)) { hresult_set_exc("Failed to set name value", hr); goto end; }
|
||||||
|
|
||||||
|
hr = values->SetStringValue(WPD_OBJECT_ORIGINAL_FILE_NAME, name);
|
||||||
|
if (FAILED(hr)) { hresult_set_exc("Failed to set original_file_name value", hr); goto end; }
|
||||||
|
|
||||||
|
hr = values->SetGuidValue(WPD_OBJECT_FORMAT, WPD_OBJECT_FORMAT_UNSPECIFIED);
|
||||||
|
if (FAILED(hr)) { hresult_set_exc("Failed to set object_format value", hr); goto end; }
|
||||||
|
|
||||||
|
hr = values->SetGuidValue(WPD_OBJECT_CONTENT_TYPE, content_type);
|
||||||
|
if (FAILED(hr)) { hresult_set_exc("Failed to set content_type value", hr); goto end; }
|
||||||
|
|
||||||
|
ok = TRUE;
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (!ok && values != NULL) { values->Release(); values = NULL; }
|
||||||
|
return values;
|
||||||
|
} // }}}
|
||||||
|
|
||||||
PyObject* wpd::get_filesystem(IPortableDevice *device, const wchar_t *storage_id, IPortableDevicePropertiesBulk *bulk_properties) { // {{{
|
PyObject* wpd::get_filesystem(IPortableDevice *device, const wchar_t *storage_id, IPortableDevicePropertiesBulk *bulk_properties) { // {{{
|
||||||
PyObject *folders = NULL;
|
PyObject *folders = NULL;
|
||||||
IPortableDevicePropVariantCollection *object_ids = NULL;
|
IPortableDevicePropVariantCollection *object_ids = NULL;
|
||||||
@ -500,4 +533,43 @@ end:
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
} // }}}
|
} // }}}
|
||||||
|
|
||||||
|
PyObject* wpd::create_folder(IPortableDevice *device, const wchar_t *parent_id, const wchar_t *name) { // {{{
|
||||||
|
IPortableDeviceContent *content = NULL;
|
||||||
|
IPortableDeviceValues *values = NULL;
|
||||||
|
IPortableDeviceProperties *devprops = NULL;
|
||||||
|
IPortableDeviceKeyCollection *properties = NULL;
|
||||||
|
PyObject *ans = NULL;
|
||||||
|
HRESULT hr;
|
||||||
|
wchar_t *newid = NULL;
|
||||||
|
|
||||||
|
values = create_object_properties(parent_id, name, WPD_CONTENT_TYPE_FOLDER);
|
||||||
|
if (values == NULL) goto end;
|
||||||
|
|
||||||
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
|
hr = device->Content(&content);
|
||||||
|
Py_END_ALLOW_THREADS;
|
||||||
|
if (FAILED(hr)) { hresult_set_exc("Failed to create content interface", hr); goto end; }
|
||||||
|
|
||||||
|
hr = content->Properties(&devprops);
|
||||||
|
if (FAILED(hr)) { hresult_set_exc("Failed to get IPortableDeviceProperties interface", hr); goto end; }
|
||||||
|
|
||||||
|
properties = create_filesystem_properties_collection();
|
||||||
|
if (properties == NULL) goto end;
|
||||||
|
|
||||||
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
|
hr = content->CreateObjectWithPropertiesOnly(values, &newid);
|
||||||
|
Py_END_ALLOW_THREADS;
|
||||||
|
if (FAILED(hr) || newid == NULL) { hresult_set_exc("Failed to create folder", hr); goto end; }
|
||||||
|
|
||||||
|
ans = get_object_properties(devprops, properties, newid);
|
||||||
|
end:
|
||||||
|
if (content != NULL) content->Release();
|
||||||
|
if (values != NULL) values->Release();
|
||||||
|
if (devprops != NULL) devprops->Release();
|
||||||
|
if (properties != NULL) properties->Release();
|
||||||
|
if (newid != NULL) CoTaskMemFree(newid);
|
||||||
|
return ans;
|
||||||
|
|
||||||
|
} // }}}
|
||||||
|
|
||||||
} // namespace wpd
|
} // namespace wpd
|
||||||
|
@ -103,6 +103,20 @@ py_get_file(Device *self, PyObject *args, PyObject *kwargs) {
|
|||||||
return wpd::get_file(self->device, object, stream, callback);
|
return wpd::get_file(self->device, object, stream, callback);
|
||||||
} // }}}
|
} // }}}
|
||||||
|
|
||||||
|
// create_folder() {{{
|
||||||
|
static PyObject*
|
||||||
|
py_create_folder(Device *self, PyObject *args, PyObject *kwargs) {
|
||||||
|
PyObject *pparent_id, *pname;
|
||||||
|
wchar_t *parent_id, *name;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "OO", &pparent_id, &pname)) return NULL;
|
||||||
|
parent_id = unicode_to_wchar(pparent_id);
|
||||||
|
name = unicode_to_wchar(pname);
|
||||||
|
if (parent_id == NULL || name == NULL) return NULL;
|
||||||
|
|
||||||
|
return wpd::create_folder(self->device, parent_id, name);
|
||||||
|
} // }}}
|
||||||
|
|
||||||
static PyMethodDef Device_methods[] = {
|
static PyMethodDef Device_methods[] = {
|
||||||
{"update_data", (PyCFunction)update_data, METH_VARARGS,
|
{"update_data", (PyCFunction)update_data, METH_VARARGS,
|
||||||
"update_data() -> Reread the basic device data from the device (total, space, free space, storage locations, etc.)"
|
"update_data() -> Reread the basic device data from the device (total, space, free space, storage locations, etc.)"
|
||||||
@ -116,6 +130,10 @@ static PyMethodDef Device_methods[] = {
|
|||||||
"get_file(object_id, stream, callback=None) -> Get the file identified by object_id from the device. The file is written to the stream object, which must be a file like object. If callback is not None, it must be a callable that accepts two arguments: (bytes_read, total_size). It will be called after each chunk is read from the device. Note that it can be called multiple times with the same values."
|
"get_file(object_id, stream, callback=None) -> Get the file identified by object_id from the device. The file is written to the stream object, which must be a file like object. If callback is not None, it must be a callable that accepts two arguments: (bytes_read, total_size). It will be called after each chunk is read from the device. Note that it can be called multiple times with the same values."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{"create_folder", (PyCFunction)py_create_folder, METH_VARARGS,
|
||||||
|
"create_folder(parent_id, name) -> Create a folder. Returns the folder metadata."
|
||||||
|
},
|
||||||
|
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ extern IPortableDevice* open_device(const wchar_t *pnp_id, IPortableDeviceValues
|
|||||||
extern PyObject* get_device_information(IPortableDevice *device, IPortableDevicePropertiesBulk **bulk_properties);
|
extern PyObject* get_device_information(IPortableDevice *device, IPortableDevicePropertiesBulk **bulk_properties);
|
||||||
extern PyObject* get_filesystem(IPortableDevice *device, const wchar_t *storage_id, IPortableDevicePropertiesBulk *bulk_properties);
|
extern PyObject* get_filesystem(IPortableDevice *device, const wchar_t *storage_id, IPortableDevicePropertiesBulk *bulk_properties);
|
||||||
extern PyObject* get_file(IPortableDevice *device, const wchar_t *object_id, PyObject *dest, PyObject *callback);
|
extern PyObject* get_file(IPortableDevice *device, const wchar_t *object_id, PyObject *dest, PyObject *callback);
|
||||||
|
extern PyObject* create_folder(IPortableDevice *device, const wchar_t *parent_id, const wchar_t *name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,12 +71,16 @@ def main():
|
|||||||
print ('Total space', dev.total_space())
|
print ('Total space', dev.total_space())
|
||||||
print ('Free space', dev.free_space())
|
print ('Free space', dev.free_space())
|
||||||
dev.filesystem_cache.dump()
|
dev.filesystem_cache.dump()
|
||||||
|
# pprint.pprint(dev.dev.create_folder(dev.filesystem_cache.entries[0].object_id,
|
||||||
|
# 'zzz'))
|
||||||
# print ('Fetching file: oFF (198214 bytes)')
|
# print ('Fetching file: oFF (198214 bytes)')
|
||||||
# stream = dev.get_file('oFF')
|
# stream = dev.get_file('oFF')
|
||||||
# print ("Fetched size: ", stream.tell())
|
# print ("Fetched size: ", stream.tell())
|
||||||
finally:
|
finally:
|
||||||
dev.shutdown()
|
dev.shutdown()
|
||||||
|
|
||||||
|
print ('Device connection shutdown')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user