mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -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()
|
||||
print('Prefix for main mem:', dev.prefix_for_location(None), flush=True)
|
||||
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)
|
||||
buf = io.BytesIO()
|
||||
dev.get_file(f.mtp_id_path, buf)
|
||||
if buf.getvalue() != raw:
|
||||
raise ValueError('Getting previously put file did not return expected data')
|
||||
print('Successfully got previously put file', flush=True)
|
||||
dev.recursive_delete(f)
|
||||
finally:
|
||||
dev.shutdown()
|
||||
|
||||
|
@ -591,82 +591,65 @@ wpd::get_file(IPortableDevice *device, const wchar_t *object_id, PyObject *dest,
|
||||
|
||||
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;
|
||||
wchar_t *newid = NULL;
|
||||
PyObject *ans = NULL;
|
||||
CComPtr<IPortableDeviceContent> content;
|
||||
CComPtr<IPortableDeviceValues> values;
|
||||
CComPtr<IPortableDeviceProperties> devprops;
|
||||
CComPtr<IPortableDeviceKeyCollection> properties;
|
||||
HRESULT hr;
|
||||
|
||||
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;
|
||||
hr = device->Content(&content);
|
||||
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);
|
||||
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();
|
||||
if (properties == NULL) goto end;
|
||||
if (!properties) return NULL;
|
||||
|
||||
wchar_raii newid;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
hr = content->CreateObjectWithPropertiesOnly(values, &newid);
|
||||
hr = content->CreateObjectWithPropertiesOnly(values, newid.unsafe_address());
|
||||
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;
|
||||
if (FAILED(hr) || !newid) { hresult_set_exc("Failed to create folder", hr); return NULL; }
|
||||
|
||||
return get_object_properties(devprops, properties, newid.ptr());
|
||||
} // }}}
|
||||
|
||||
PyObject*
|
||||
wpd::delete_object(IPortableDevice *device, const wchar_t *object_id) { // {{{
|
||||
IPortableDeviceContent *content = NULL;
|
||||
CComPtr<IPortableDeviceContent> content;
|
||||
CComPtr<IPortableDevicePropVariantCollection> object_ids;
|
||||
HRESULT hr;
|
||||
BOOL ok = FALSE;
|
||||
PROPVARIANT pv;
|
||||
IPortableDevicePropVariantCollection *object_ids = NULL;
|
||||
|
||||
PropVariantInit(&pv);
|
||||
pv.vt = VT_LPWSTR;
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection, NULL,
|
||||
CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&object_ids));
|
||||
hr = object_ids.CoCreateInstance(CLSID_PortableDevicePropVariantCollection, NULL, CLSCTX_INPROC_SERVER);
|
||||
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;
|
||||
hr = object_ids->Add(&pv);
|
||||
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;
|
||||
hr = device->Content(&content);
|
||||
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);
|
||||
if (hr == E_ACCESSDENIED) PyErr_SetString(WPDError, "Do not have permission to delete this object");
|
||||
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);
|
||||
if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND) || SUCCEEDED(hr)) {Py_RETURN_NONE;}
|
||||
|
||||
end:
|
||||
PropVariantClear(&pv);
|
||||
if (content != NULL) content->Release();
|
||||
if (object_ids != NULL) object_ids->Release();
|
||||
if (!ok) return NULL;
|
||||
Py_RETURN_NONE;
|
||||
if (hr == E_ACCESSDENIED) { PyErr_SetExcFromWindowsErr(WPDError, ERROR_ACCESS_DENIED); }
|
||||
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 hresult_set_exc("Cannot delete object", hr);
|
||||
return NULL;
|
||||
|
||||
} // }}}
|
||||
|
||||
|
@ -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