This commit is contained in:
Kovid Goyal 2012-08-24 17:55:32 +05:30
parent 9977d6d581
commit 2d6b0badd0
4 changed files with 56 additions and 8 deletions

View File

@ -51,6 +51,21 @@ class FileOrFolder(object):
self.fs_cache = weakref.ref(fs_cache) self.fs_cache = weakref.ref(fs_cache)
self.deleted = False self.deleted = False
def __repr__(self):
name = 'Folder' if self.is_folder else 'File'
try:
path = unicode(self.full_path)
except:
path = ''
datum = 'size=%s'%(self.size)
if self.is_folder:
datum = 'children=%s'%(len(self.files) + len(self.folders))
return '%s(id=%s, storage_id=%s, %s, path=%s)'%(name, self.object_id,
self.storage_id, datum, path)
__str__ = __repr__
__unicode__ = __repr__
@property @property
def id_map(self): def id_map(self):
return self.fs_cache().id_map return self.fs_cache().id_map

View File

@ -14,6 +14,7 @@ from collections import namedtuple
from calibre import prints from calibre import prints
from calibre.constants import plugins from calibre.constants import plugins
from calibre.ptempfile import SpooledTemporaryFile
from calibre.devices.errors import OpenFailed, DeviceError from calibre.devices.errors import OpenFailed, DeviceError
from calibre.devices.mtp.base import MTPDeviceBase, synchronous from calibre.devices.mtp.base import MTPDeviceBase, synchronous
from calibre.devices.mtp.filesystem_cache import FilesystemCache from calibre.devices.mtp.filesystem_cache import FilesystemCache
@ -264,13 +265,17 @@ class MTP_DEVICE(MTPDeviceBase):
return parent.add_child(ans) return parent.add_child(ans)
@synchronous @synchronous
def get_file(self, f, stream, callback=None): def get_file(self, f, stream=None, callback=None):
if f.is_folder: if f.is_folder:
raise ValueError('%s if a folder'%(f.full_path,)) raise ValueError('%s if a folder'%(f.full_path,))
if stream is None:
stream = SpooledTemporaryFile(5*1024*1024, '_wpd_receive_file.dat')
stream.name = f.name
ok, errs = self.dev.get_file(f.object_id, stream, callback) ok, errs = self.dev.get_file(f.object_id, stream, callback)
if not ok: if not ok:
raise DeviceError('Failed to get file: %s with errors: %s'%( raise DeviceError('Failed to get file: %s with errors: %s'%(
f.full_path, self.format_errorstack(errs))) f.full_path, self.format_errorstack(errs)))
return stream
@synchronous @synchronous
def delete_file_or_folder(self, obj): def delete_file_or_folder(self, obj):
@ -315,13 +320,17 @@ if __name__ == '__main__':
# fname = b'moose.txt' # fname = b'moose.txt'
# src = BytesIO(raw) # src = BytesIO(raw)
# print (d.put_file(dev._main_id, 0, fname, src, len(raw), PR())) # print (d.put_file(dev._main_id, 0, fname, src, len(raw), PR()))
dev.filesystem_cache.dump()
# with open('/tmp/flint.epub', 'wb') as f: # with open('/tmp/flint.epub', 'wb') as f:
# print(d.get_file(786, f, PR())) # print(d.get_file(786, f, PR()))
# print() # print()
# with open('/tmp/bleak.epub', 'wb') as f: # with open('/tmp/bleak.epub', 'wb') as f:
# print(d.get_file(601, f, PR())) # print(d.get_file(601, f, PR()))
# print() # print()
dev.filesystem_cache.dump()
# print (dev.filesystem_cache.entries[0].files[0])
# print (dev.filesystem_cache.entries[0].folders[0])
dev.set_debug_level(dev.LIBMTP_DEBUG_ALL) dev.set_debug_level(dev.LIBMTP_DEBUG_ALL)
del d del d
dev.shutdown() dev.shutdown()

View File

@ -245,18 +245,18 @@ class MTP_DEVICE(MTPDeviceBase):
return tuple(ans) return tuple(ans)
@same_thread @same_thread
def get_file(self, object_id, stream=None, callback=None): def get_file(self, f, stream=None, callback=None):
f = self.filesystem_cache.id_map[object_id]
if f.is_folder: if f.is_folder:
raise ValueError('%s is a folder on the device'%(f.full_path,)) raise ValueError('%s if a folder'%(f.full_path,))
if stream is None: if stream is None:
stream = SpooledTemporaryFile(5*1024*1024, '_wpd_receive_file.dat') stream = SpooledTemporaryFile(5*1024*1024, '_wpd_receive_file.dat')
stream.name = f.name
try: try:
try: try:
self.dev.get_file(object_id, stream, callback) self.dev.get_file(f.object_id, stream, callback)
except self.wpd.WPDFileBusy: except self.wpd.WPDFileBusy:
time.sleep(2) time.sleep(2)
self.dev.get_file(object_id, stream, callback) self.dev.get_file(f.object_id, stream, callback)
except Exception as e: except Exception as e:
raise DeviceError('Failed to fetch the file %s with error: %s'% raise DeviceError('Failed to fetch the file %s with error: %s'%
f.full_path, as_unicode(e)) f.full_path, as_unicode(e))
@ -290,3 +290,21 @@ class MTP_DEVICE(MTPDeviceBase):
self.dev.delete_object(obj.object_id) self.dev.delete_object(obj.object_id)
parent.remove_child(obj) parent.remove_child(obj)
@same_thread
def put_file(self, parent, name, stream, size, callback=None, replace=True):
e = parent.folder_named(name)
if e is not None:
raise ValueError('Cannot upload file, %s already has a folder named: %s'%(
parent.full_path, e.name))
e = parent.file_named(name)
if e is not None:
if not replace:
raise ValueError('Cannot upload file %s, it already exists'%(
e.full_path,))
self.delete_file_or_folder(e)
sid, pid = parent.storage_id, parent.object_id
ans = self.dev.put_file(sid, pid, name, stream, size, callback)
ans['storage_id'] = parent.storage_id
return parent.add_child(ans)

View File

@ -70,12 +70,18 @@ def main():
print ('Connected to:', dev.get_gui_name()) print ('Connected to:', dev.get_gui_name())
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()
# pprint.pprint(dev.dev.create_folder(dev.filesystem_cache.entries[0].object_id, # pprint.pprint(dev.dev.create_folder(dev.filesystem_cache.entries[0].object_id,
# 'zzz')) # '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())
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: finally:
dev.shutdown() dev.shutdown()