mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Use RAII for delete and create_folder
This commit is contained in:
parent
481474aae2
commit
b69f48cc73
@ -577,13 +577,15 @@ def main():
|
|||||||
dev.filesystem_cache.dump()
|
dev.filesystem_cache.dump()
|
||||||
print('Prefix for main mem:', dev.prefix_for_location(None), flush=True)
|
print('Prefix for main mem:', dev.prefix_for_location(None), flush=True)
|
||||||
raw = os.urandom(32 * 1024)
|
raw = os.urandom(32 * 1024)
|
||||||
f = dev.put_file(dev.filesystem_cache.entries[0], 'developing-mtp-driver.bin', io.BytesIO(raw), len(raw))
|
folder = dev.create_folder(dev.filesystem_cache.entries[0], 'developing-mtp-driver')
|
||||||
|
f = dev.put_file(folder, 'developing-mtp-driver.bin', io.BytesIO(raw), len(raw))
|
||||||
print('Put file:', f, flush=True)
|
print('Put file:', f, flush=True)
|
||||||
buf = io.BytesIO()
|
buf = io.BytesIO()
|
||||||
dev.get_file(f.mtp_id_path, buf)
|
dev.get_file(f.mtp_id_path, buf)
|
||||||
if buf.getvalue() != raw:
|
if buf.getvalue() != raw:
|
||||||
raise ValueError('Getting previously put file did not return expected data')
|
raise ValueError('Getting previously put file did not return expected data')
|
||||||
print('Successfully got previously put file', flush=True)
|
print('Successfully got previously put file', flush=True)
|
||||||
|
dev.recursive_delete(f)
|
||||||
finally:
|
finally:
|
||||||
dev.shutdown()
|
dev.shutdown()
|
||||||
|
|
||||||
|
@ -591,82 +591,65 @@ wpd::get_file(IPortableDevice *device, const wchar_t *object_id, PyObject *dest,
|
|||||||
|
|
||||||
PyObject*
|
PyObject*
|
||||||
wpd::create_folder(IPortableDevice *device, const wchar_t *parent_id, const wchar_t *name) { // {{{
|
wpd::create_folder(IPortableDevice *device, const wchar_t *parent_id, const wchar_t *name) { // {{{
|
||||||
IPortableDeviceContent *content = NULL;
|
CComPtr<IPortableDeviceContent> content;
|
||||||
IPortableDeviceValues *values = NULL;
|
CComPtr<IPortableDeviceValues> values;
|
||||||
IPortableDeviceProperties *devprops = NULL;
|
CComPtr<IPortableDeviceProperties> devprops;
|
||||||
IPortableDeviceKeyCollection *properties = NULL;
|
CComPtr<IPortableDeviceKeyCollection> properties;
|
||||||
wchar_t *newid = NULL;
|
|
||||||
PyObject *ans = NULL;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
values = create_object_properties(parent_id, name, WPD_CONTENT_TYPE_FOLDER, 0);
|
values = create_object_properties(parent_id, name, WPD_CONTENT_TYPE_FOLDER, 0);
|
||||||
if (values == NULL) goto end;
|
if (!values) return NULL;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS;
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
hr = device->Content(&content);
|
hr = device->Content(&content);
|
||||||
Py_END_ALLOW_THREADS;
|
Py_END_ALLOW_THREADS;
|
||||||
if (FAILED(hr)) { hresult_set_exc("Failed to create content interface", hr); goto end; }
|
if (FAILED(hr)) { hresult_set_exc("Failed to create content interface", hr); return NULL; }
|
||||||
|
|
||||||
hr = content->Properties(&devprops);
|
hr = content->Properties(&devprops);
|
||||||
if (FAILED(hr)) { hresult_set_exc("Failed to get IPortableDeviceProperties interface", hr); goto end; }
|
if (FAILED(hr)) { hresult_set_exc("Failed to get IPortableDeviceProperties interface", hr); return NULL; }
|
||||||
|
|
||||||
properties = create_filesystem_properties_collection();
|
properties = create_filesystem_properties_collection();
|
||||||
if (properties == NULL) goto end;
|
if (!properties) return NULL;
|
||||||
|
|
||||||
|
wchar_raii newid;
|
||||||
Py_BEGIN_ALLOW_THREADS;
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
hr = content->CreateObjectWithPropertiesOnly(values, &newid);
|
hr = content->CreateObjectWithPropertiesOnly(values, newid.unsafe_address());
|
||||||
Py_END_ALLOW_THREADS;
|
Py_END_ALLOW_THREADS;
|
||||||
if (FAILED(hr) || newid == NULL) { hresult_set_exc("Failed to create folder", hr); goto end; }
|
if (FAILED(hr) || !newid) { hresult_set_exc("Failed to create folder", hr); return NULL; }
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
return get_object_properties(devprops, properties, newid.ptr());
|
||||||
} // }}}
|
} // }}}
|
||||||
|
|
||||||
PyObject*
|
PyObject*
|
||||||
wpd::delete_object(IPortableDevice *device, const wchar_t *object_id) { // {{{
|
wpd::delete_object(IPortableDevice *device, const wchar_t *object_id) { // {{{
|
||||||
IPortableDeviceContent *content = NULL;
|
CComPtr<IPortableDeviceContent> content;
|
||||||
|
CComPtr<IPortableDevicePropVariantCollection> object_ids;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
BOOL ok = FALSE;
|
|
||||||
PROPVARIANT pv;
|
|
||||||
IPortableDevicePropVariantCollection *object_ids = NULL;
|
|
||||||
|
|
||||||
PropVariantInit(&pv);
|
|
||||||
pv.vt = VT_LPWSTR;
|
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS;
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection, NULL,
|
hr = object_ids.CoCreateInstance(CLSID_PortableDevicePropVariantCollection, NULL, CLSCTX_INPROC_SERVER);
|
||||||
CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&object_ids));
|
|
||||||
Py_END_ALLOW_THREADS;
|
Py_END_ALLOW_THREADS;
|
||||||
if (FAILED(hr)) { hresult_set_exc("Failed to create propvariantcollection", hr); goto end; }
|
if (FAILED(hr)) { hresult_set_exc("Failed to create propvariantcollection", hr); return NULL; }
|
||||||
|
|
||||||
|
prop_variant pv(VT_LPWSTR);
|
||||||
pv.pwszVal = (wchar_t*)object_id;
|
pv.pwszVal = (wchar_t*)object_id;
|
||||||
hr = object_ids->Add(&pv);
|
hr = object_ids->Add(&pv);
|
||||||
pv.pwszVal = NULL;
|
pv.pwszVal = NULL;
|
||||||
if (FAILED(hr)) { hresult_set_exc("Failed to add device id to propvariantcollection", hr); goto end; }
|
if (FAILED(hr)) { hresult_set_exc("Failed to add device id to propvariantcollection", hr); return NULL; }
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS;
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
hr = device->Content(&content);
|
hr = device->Content(&content);
|
||||||
Py_END_ALLOW_THREADS;
|
Py_END_ALLOW_THREADS;
|
||||||
if (FAILED(hr)) { hresult_set_exc("Failed to create content interface", hr); goto end; }
|
if (FAILED(hr)) { hresult_set_exc("Failed to create content interface", hr); return NULL; }
|
||||||
|
|
||||||
hr = content->Delete(PORTABLE_DEVICE_DELETE_NO_RECURSION, object_ids, NULL);
|
hr = content->Delete(PORTABLE_DEVICE_DELETE_NO_RECURSION, object_ids, NULL);
|
||||||
if (hr == E_ACCESSDENIED) PyErr_SetString(WPDError, "Do not have permission to delete this object");
|
if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND) || SUCCEEDED(hr)) {Py_RETURN_NONE;}
|
||||||
else if (hr == HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) || hr == HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION)) PyErr_SetString(WPDError, "Cannot delete object as it has children");
|
|
||||||
else if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND) || SUCCEEDED(hr)) ok = TRUE;
|
|
||||||
else hresult_set_exc("Cannot delete object", hr);
|
|
||||||
|
|
||||||
end:
|
if (hr == E_ACCESSDENIED) { PyErr_SetExcFromWindowsErr(WPDError, ERROR_ACCESS_DENIED); }
|
||||||
PropVariantClear(&pv);
|
else if (hr == HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) || hr == HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION)) {
|
||||||
if (content != NULL) content->Release();
|
PyErr_SetString(WPDError, "Cannot delete object as it has children"); }
|
||||||
if (object_ids != NULL) object_ids->Release();
|
else hresult_set_exc("Cannot delete object", hr);
|
||||||
if (!ok) return NULL;
|
return NULL;
|
||||||
Py_RETURN_NONE;
|
|
||||||
|
|
||||||
} // }}}
|
} // }}}
|
||||||
|
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:fdm=marker:ai
|
|
||||||
|
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
|
||||||
__copyright__ = '2012, Kovid Goyal <kovid at kovidgoyal.net>'
|
|
||||||
__docformat__ = 'restructuredtext en'
|
|
||||||
|
|
||||||
import subprocess, os, pprint, signal, time, glob, io
|
|
||||||
pprint, io
|
|
||||||
from polyglot.builtins import environ_item
|
|
||||||
|
|
||||||
|
|
||||||
def build(mod='wpd'):
|
|
||||||
master = subprocess.Popen('ssh -MN getafix'.split())
|
|
||||||
master2 = subprocess.Popen('ssh -MN win64'.split())
|
|
||||||
try:
|
|
||||||
while not glob.glob(os.path.expanduser('~/.ssh/*kovid@win64*')):
|
|
||||||
time.sleep(0.05)
|
|
||||||
builder = subprocess.Popen('ssh win64 ~/build-wpd'.split())
|
|
||||||
if builder.wait() != 0:
|
|
||||||
raise Exception('Failed to build plugin')
|
|
||||||
while not glob.glob(os.path.expanduser('~/.ssh/*kovid@getafix*')):
|
|
||||||
time.sleep(0.05)
|
|
||||||
syncer = subprocess.Popen('ssh getafix ~/update-calibre'.split())
|
|
||||||
if syncer.wait() != 0:
|
|
||||||
raise Exception('Failed to rsync to getafix')
|
|
||||||
subprocess.check_call(
|
|
||||||
('scp win64:build/calibre/src/calibre/plugins/%s.pyd /tmp'%mod).split())
|
|
||||||
subprocess.check_call(
|
|
||||||
('scp /tmp/%s.pyd getafix:calibre-src/src/calibre/devices/mtp/windows'%mod).split())
|
|
||||||
p = subprocess.Popen(
|
|
||||||
'ssh getafix calibre-debug -e calibre-src/src/calibre/devices/mtp/windows/remote.py'.split())
|
|
||||||
p.wait()
|
|
||||||
print()
|
|
||||||
finally:
|
|
||||||
for m in (master2, master):
|
|
||||||
m.send_signal(signal.SIGHUP)
|
|
||||||
for m in (master2, master):
|
|
||||||
m.wait()
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
fp, d = os.path.abspath(__file__), os.path.dirname
|
|
||||||
if 'CALIBRE_DEVELOP_FROM' not in os.environ:
|
|
||||||
env = os.environ.copy()
|
|
||||||
env['CALIBRE_DEVELOP_FROM'] = environ_item(d(d(d(d(d(fp))))))
|
|
||||||
subprocess.call(['calibre-debug', '-e', fp], env=env)
|
|
||||||
return
|
|
||||||
|
|
||||||
# from calibre.devices.mtp.test import run
|
|
||||||
# run()
|
|
||||||
# return
|
|
||||||
|
|
||||||
from calibre.devices.winusb import scan_usb_devices
|
|
||||||
from calibre.devices.mtp.driver import MTP_DEVICE
|
|
||||||
dev = MTP_DEVICE(None)
|
|
||||||
dev.startup()
|
|
||||||
print(dev.wpd, dev.wpd_error)
|
|
||||||
|
|
||||||
try:
|
|
||||||
devices = scan_usb_devices()
|
|
||||||
pnp_id = dev.detect_managed_devices(devices)
|
|
||||||
if not pnp_id:
|
|
||||||
raise ValueError('Failed to detect device')
|
|
||||||
# pprint.pprint(dev.detected_devices)
|
|
||||||
print('Trying to connect to:', pnp_id)
|
|
||||||
dev.open(pnp_id, '')
|
|
||||||
pprint.pprint(dev.dev.data)
|
|
||||||
print('Connected to:', dev.get_gui_name())
|
|
||||||
print('Total space', dev.total_space())
|
|
||||||
print('Free space', dev.free_space())
|
|
||||||
# pprint.pprint(dev.dev.create_folder(dev.filesystem_cache.entries[0].object_id,
|
|
||||||
# 'zzz'))
|
|
||||||
# print ('Fetching file: oFF (198214 bytes)')
|
|
||||||
# stream = dev.get_file('oFF')
|
|
||||||
# print ("Fetched size: ", stream.tell())
|
|
||||||
# size = 4
|
|
||||||
# stream = io.BytesIO(b'a'*size)
|
|
||||||
# name = 'zzz-test-file.txt'
|
|
||||||
# stream.seek(0)
|
|
||||||
# f = dev.put_file(dev.filesystem_cache.entries[0], name, stream, size)
|
|
||||||
# print ('Put file:', f)
|
|
||||||
dev.filesystem_cache.dump()
|
|
||||||
finally:
|
|
||||||
dev.shutdown()
|
|
||||||
|
|
||||||
print('Device connection shutdown')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
Loading…
x
Reference in New Issue
Block a user