diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index 0050e091d3..4f2e98b4f7 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -353,9 +353,16 @@ class PRS505(Device): 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 @@ class PRS505(Device): 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])) diff --git a/src/calibre/gui2/library.py b/src/calibre/gui2/library.py index 5ede2b49a0..ce9db76eed 100644 --- a/src/calibre/gui2/library.py +++ b/src/calibre/gui2/library.py @@ -312,7 +312,7 @@ class BooksModel(QAbstractTableModel): 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 @@ class BooksModel(QAbstractTableModel): 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) diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index a567bc567d..e856d748f0 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -466,7 +466,7 @@ class Main(MainWindow, Ui_MainWindow): 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 @@ class Main(MainWindow, Ui_MainWindow): 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 @@ class Main(MainWindow, Ui_MainWindow): 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 @@ class Main(MainWindow, Ui_MainWindow): 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 @@ class Main(MainWindow, Ui_MainWindow): 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('
  • %s
  • '%(i,) for i in bad) diff --git a/src/calibre/parallel.py b/src/calibre/parallel.py index 5ba20d28aa..7c0c997def 100644 --- a/src/calibre/parallel.py +++ b/src/calibre/parallel.py @@ -4,7 +4,8 @@ __copyright__ = '2008, Kovid Goyal ' ''' 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 @@ class Server(Thread): 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