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 @@ class PRS505(Device):
def upload_books(self, files, names, on_card=False, 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 \ path = os.path.join(self._card_prefix, self.CARD_PATH_PREFIX) if on_card \
else os.path.join(self._main_prefix, 'database', 'media', 'books') 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) def get_size(obj):
sizes = [f.tell() for f in infiles] 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) size = sum(sizes)
space = self.free_space() space = self.free_space()
mspace = space[0] mspace = space[0]
@ -370,13 +377,18 @@ class PRS505(Device):
paths, ctimes = [], [] paths, ctimes = [], []
names = iter(names) 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) infile.seek(0)
name = names.next() name = names.next()
paths.append(os.path.join(path, name)) paths.append(os.path.join(path, name))
if not os.path.exists(os.path.dirname(paths[-1])): if not os.path.exists(os.path.dirname(paths[-1])):
os.makedirs(os.path.dirname(paths[-1])) os.makedirs(os.path.dirname(paths[-1]))
self.put_file(infile, paths[-1], replace_file=True) self.put_file(infile, paths[-1], replace_file=True)
if close:
infile.close()
ctimes.append(os.path.getctime(paths[-1])) ctimes.append(os.path.getctime(paths[-1]))
return zip(paths, sizes, ctimes, cycle([on_card])) return zip(paths, sizes, ctimes, cycle([on_card]))

View File

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

View File

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

View File

@ -4,7 +4,8 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
''' '''
Used to run jobs in parallel in separate processes. 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 select import select
from functools import partial from functools import partial
from threading import RLock, Thread, Event from threading import RLock, Thread, Event
@ -392,7 +393,7 @@ class Server(Thread):
pt = PersistentTemporaryFile('.pickle', '_IPC_') pt = PersistentTemporaryFile('.pickle', '_IPC_')
pt.write(cPickle.dumps((func, args, kwdargs))) pt.write(cPickle.dumps((func, args, kwdargs)))
pt.close() pt.close()
cmd = free_spirit_command%repr(pt.name) cmd = free_spirit_command%repr(binascii.hexlify(pt.name))
popen(executable + [cmd]) popen(executable + [cmd])
########################################################################################## ##########################################################################################
@ -484,9 +485,12 @@ def worker(host, port):
return 0 return 0
elif not msg: elif not msg:
time.sleep(1) time.sleep(1)
else:
print >>sys.__stderr__, 'Invalid protocols message', msg
return 1
def free_spirit(path): def free_spirit(path):
func, args, kwdargs = cPickle.load(open(path, 'rb')) func, args, kwdargs = cPickle.load(open(binascii.unhexlify(path), 'rb'))
try: try:
os.unlink(path) os.unlink(path)
except: except:
@ -496,7 +500,7 @@ def free_spirit(path):
def main(args=sys.argv): def main(args=sys.argv):
args = args[1].split(':') args = args[1].split(':')
if len(args) == 1: if len(args) == 1:
free_spirit(args[0]) free_spirit(args[0].replace("'", ''))
else: else:
worker(args[0].replace("'", ''), int(args[1])) worker(args[0].replace("'", ''), int(args[1]))
return 0 return 0