This commit is contained in:
Kovid Goyal 2008-06-20 13:02:54 -07:00
parent 15305e3bea
commit af4be77ae2
4 changed files with 38 additions and 18 deletions

View file

@ -353,9 +353,16 @@ def touch(self, path, end_session=True):
def upload_books(self, files, names, on_card=False, end_session=True):
path = os.path.join(self._card_prefix, self.CARD_PATH_PREFIX) if on_card \
else os.path.join(self._main_prefix, 'database', 'media', 'books')
infiles = [file if hasattr(file, 'read') else open(file, 'rb') for file in files]
for f in infiles: f.seek(0, 2)
sizes = [f.tell() for f in infiles]
def get_size(obj):
if hasattr(obj, 'seek'):
obj.seek(0, 2)
size = obj.tell()
obj.seek(0)
return size
return os.path.getsize(obj)
sizes = map(get_size, files)
size = sum(sizes)
space = self.free_space()
mspace = space[0]
@ -370,13 +377,18 @@ def upload_books(self, files, names, on_card=False, end_session=True):
paths, ctimes = [], []
names = iter(names)
for infile in infiles:
for infile in files:
close = False
if not hasattr(infile, 'read'):
infile, close = open(infile, 'rb'), True
infile.seek(0)
name = names.next()
paths.append(os.path.join(path, name))
if not os.path.exists(os.path.dirname(paths[-1])):
os.makedirs(os.path.dirname(paths[-1]))
self.put_file(infile, paths[-1], replace_file=True)
if close:
infile.close()
ctimes.append(os.path.getctime(paths[-1]))
return zip(paths, sizes, ctimes, cycle([on_card]))

View file

@ -312,7 +312,7 @@ def get_metadata(self, rows):
metadata.append(mi)
return metadata
def get_preferred_formats(self, rows, formats):
def get_preferred_formats(self, rows, formats, paths=False):
ans = []
for row in (row.row() for row in rows):
format = None
@ -323,7 +323,8 @@ def get_preferred_formats(self, rows, formats):
if format:
pt = PersistentTemporaryFile(suffix='.'+format)
pt.write(self.db.format(row, format))
pt.seek(0)
pt.flush()
pt.close() if paths else pt.seek(0)
ans.append(pt)
else:
ans.append(None)

View file

@ -466,7 +466,7 @@ def _add_books(self, paths, to_device):
else:
self.upload_books(paths, names, infos, on_card=on_card)
def upload_books(self, files, names, metadata, on_card=False):
def upload_books(self, files, names, metadata, on_card=False, memory=None):
'''
Upload books to device.
@param files: List of either paths to files or file like objects
@ -477,13 +477,13 @@ def upload_books(self, files, names, metadata, on_card=False):
files, names, on_card=on_card,
job_extra_description=titles
)
self.upload_memory[id] = (metadata, on_card)
self.upload_memory[id] = (metadata, on_card, memory)
def books_uploaded(self, id, description, result, exception, formatted_traceback):
'''
Called once books have been uploaded.
'''
metadata, on_card = self.upload_memory.pop(id)
metadata, on_card = self.upload_memory.pop(id)[:2]
if exception:
if isinstance(exception, FreeSpaceError):
where = 'in main memory.' if 'memory' in str(exception) else 'on the storage card.'
@ -611,8 +611,9 @@ def sync_to_device(self, on_card):
if cdata:
mi['cover'] = self.cover_to_thumbnail(cdata)
metadata = iter(metadata)
files = self.library_view.model().get_preferred_formats(rows,
self.device_manager.device_class.FORMATS)
_files = self.library_view.model().get_preferred_formats(rows,
self.device_manager.device_class.FORMATS, paths=True)
files = [f.name for f in _files]
bad, good, gf, names = [], [], [], []
for f in files:
mi = metadata.next()
@ -627,7 +628,9 @@ def sync_to_device(self, on_card):
try:
smi = MetaInformation(mi['title'], aus2)
smi.comments = mi.get('comments', None)
set_metadata(f, smi, f.name.rpartition('.')[2])
_f = open(f, 'r+b')
set_metadata(_f, smi, f.rpartition('.')[2])
_f.close()
except:
print 'Error setting metadata in book:', mi['title']
traceback.print_exc()
@ -644,8 +647,8 @@ def sync_to_device(self, on_card):
prefix = prefix.encode('ascii', 'ignore')
else:
prefix = prefix.decode('ascii', 'ignore').encode('ascii', 'ignore')
names.append('%s_%d%s'%(prefix, id, os.path.splitext(f.name)[1]))
self.upload_books(gf, names, good, on_card)
names.append('%s_%d%s'%(prefix, id, os.path.splitext(f)[1]))
self.upload_books(gf, names, good, on_card, memory=_files)
self.status_bar.showMessage(_('Sending books to device.'), 5000)
if bad:
bad = '\n'.join('<li>%s</li>'%(i,) for i in bad)

View file

@ -4,7 +4,8 @@
'''
Used to run jobs in parallel in separate processes.
'''
import sys, os, gc, cPickle, traceback, atexit, cStringIO, time, subprocess, socket, collections
import sys, os, gc, cPickle, traceback, atexit, cStringIO, time, \
subprocess, socket, collections, binascii
from select import select
from functools import partial
from threading import RLock, Thread, Event
@ -392,7 +393,7 @@ def run_free_job(self, func, args=[], kwdargs={}):
pt = PersistentTemporaryFile('.pickle', '_IPC_')
pt.write(cPickle.dumps((func, args, kwdargs)))
pt.close()
cmd = free_spirit_command%repr(pt.name)
cmd = free_spirit_command%repr(binascii.hexlify(pt.name))
popen(executable + [cmd])
##########################################################################################
@ -484,9 +485,12 @@ def worker(host, port):
return 0
elif not msg:
time.sleep(1)
else:
print >>sys.__stderr__, 'Invalid protocols message', msg
return 1
def free_spirit(path):
func, args, kwdargs = cPickle.load(open(path, 'rb'))
func, args, kwdargs = cPickle.load(open(binascii.unhexlify(path), 'rb'))
try:
os.unlink(path)
except:
@ -496,7 +500,7 @@ def free_spirit(path):
def main(args=sys.argv):
args = args[1].split(':')
if len(args) == 1:
free_spirit(args[0])
free_spirit(args[0].replace("'", ''))
else:
worker(args[0].replace("'", ''), int(args[1]))
return 0