Merge upstream changes

This commit is contained in:
Marshall T. Vandegrift 2009-01-14 20:00:07 -05:00
commit b3cc53c8d0
10 changed files with 5395 additions and 25 deletions

View File

@ -123,7 +123,8 @@ class Device(object):
""" """
raise NotImplementedError() raise NotImplementedError()
def upload_books(self, files, names, on_card=False, end_session=True): def upload_books(self, files, names, on_card=False, end_session=True,
metadata=None):
''' '''
Upload a list of books to the device. If a file already Upload a list of books to the device. If a file already
exists on the device, it should be replaced. exists on the device, it should be replaced.
@ -135,6 +136,10 @@ class Device(object):
once uploaded to the device. len(names) == len(files) once uploaded to the device. len(names) == len(files)
@return: A list of 3-element tuples. The list is meant to be passed @return: A list of 3-element tuples. The list is meant to be passed
to L{add_books_to_metadata}. to L{add_books_to_metadata}.
@param metadata: If not None, it is a list of dictionaries. Each dictionary
will have at least the key tags to allow the driver to choose book location
based on tags. len(metadata) == len(files). If your device does not support
hierarchical ebook folders, you can safely ignore this parameter.
''' '''
raise NotImplementedError() raise NotImplementedError()

View File

@ -841,7 +841,8 @@ class PRS500(Device):
self.upload_book_list(booklists[1], end_session=False) self.upload_book_list(booklists[1], end_session=False)
@safe @safe
def upload_books(self, files, names, on_card=False, end_session=True): def upload_books(self, files, names, on_card=False, end_session=True,
metadata=None):
card = self.card(end_session=False) card = self.card(end_session=False)
prefix = card + '/' + self.CARD_PATH_PREFIX +'/' if on_card else '/Data/media/books/' prefix = card + '/' + self.CARD_PATH_PREFIX +'/' if on_card else '/Data/media/books/'
if on_card and not self._exists(prefix)[0]: if on_card and not self._exists(prefix)[0]:

View File

@ -407,7 +407,8 @@ class PRS505(Device):
if not os.path.isdir(path): if not os.path.isdir(path):
os.utime(path, None) os.utime(path, None)
def upload_books(self, files, names, on_card=False, end_session=True): def upload_books(self, files, names, on_card=False, end_session=True,
metadata=None):
if on_card and not self._card_prefix: if on_card and not self._card_prefix:
raise ValueError(_('The reader has no storage card connected.')) raise ValueError(_('The reader has no storage card connected.'))
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 \

View File

@ -48,7 +48,8 @@ class USBMS(Device):
bl.append(Book(os.path.join(path, filename), title, author, mime)) bl.append(Book(os.path.join(path, filename), title, author, mime))
return bl return bl
def upload_books(self, files, names, on_card=False, end_session=True): def upload_books(self, files, names, on_card=False, end_session=True,
metadata=None):
if on_card and not self._card_prefix: if on_card and not self._card_prefix:
raise ValueError(_('The reader has no storage card connected.')) raise ValueError(_('The reader has no storage card connected.'))

View File

@ -109,6 +109,10 @@ class HTMLConverter(object, LoggingInterface):
# Remove self closing script tags as they also mess up BeautifulSoup # Remove self closing script tags as they also mess up BeautifulSoup
(re.compile(r'(?i)<script[^<>]+?/>'), lambda match: ''), (re.compile(r'(?i)<script[^<>]+?/>'), lambda match: ''),
# BeautifulSoup treats self closing <div> tags as open <div> tags
(re.compile(r'(?i)<\s*div([^>]*)/\s*>'),
lambda match: '<div%s></div>'%match.group(1))
] ]
# Fix Baen markup # Fix Baen markup
BAEN = [ BAEN = [
@ -576,20 +580,20 @@ class HTMLConverter(object, LoggingInterface):
if (css.has_key('display') and css['display'].lower() == 'none') or \ if (css.has_key('display') and css['display'].lower() == 'none') or \
(css.has_key('visibility') and css['visibility'].lower() == 'hidden'): (css.has_key('visibility') and css['visibility'].lower() == 'hidden'):
return '' return ''
text = u'' text, alt_text = u'', u''
for c in tag.contents: for c in tag.contents:
if limit != None and len(text) > limit: if limit != None and len(text) > limit:
break break
if isinstance(c, HTMLConverter.IGNORED_TAGS): if isinstance(c, HTMLConverter.IGNORED_TAGS):
return u'' continue
if isinstance(c, NavigableString): if isinstance(c, NavigableString):
text += unicode(c) text += unicode(c)
elif isinstance(c, Tag): elif isinstance(c, Tag):
if c.name.lower() == 'img' and c.has_key('alt'): if c.name.lower() == 'img' and c.has_key('alt'):
text += c['alt'] alt_text += c['alt']
return text continue
text += self.get_text(c) text += self.get_text(c)
return text return text if text.strip() else alt_text
def process_links(self): def process_links(self):
def add_toc_entry(text, target): def add_toc_entry(text, target):

View File

@ -49,13 +49,17 @@ def main(args=sys.argv):
input_pdf = PdfFileReader(file(source, "rb")) input_pdf = PdfFileReader(file(source, "rb"))
except: except:
print "Unable to read input" print "Unable to read input"
return 2 return 2
info = input_pdf.getDocumentInfo() title = _('Unknown')
title = 'Unknown' author = _('Unknown')
author = 'Unknown' try:
if info.title: info = input_pdf.getDocumentInfo()
title = info.title if info.title:
author = info.author title = info.title
if info.author:
author = info.author
except:
pass
if opts.bounding != None: if opts.bounding != None:
try: try:
bounding = open( opts.bounding , 'r' ) bounding = open( opts.bounding , 'r' )

View File

@ -136,16 +136,18 @@ class DeviceManager(Thread):
return self.create_job(self._sync_booklists, done, args=[booklists], return self.create_job(self._sync_booklists, done, args=[booklists],
description=_('Send metadata to device')) description=_('Send metadata to device'))
def _upload_books(self, files, names, on_card=False): def _upload_books(self, files, names, on_card=False, metadata=None):
'''Upload books to device: ''' '''Upload books to device: '''
return self.device.upload_books(files, names, on_card, end_session=False) return self.device.upload_books(files, names, on_card,
metadata=metadata, end_session=False)
def upload_books(self, done, files, names, on_card=False, titles=None): def upload_books(self, done, files, names, on_card=False, titles=None,
metadata=None):
desc = _('Upload %d books to device')%len(names) desc = _('Upload %d books to device')%len(names)
if titles: if titles:
desc += u':' + u', '.join(titles) desc += u':' + u', '.join(titles)
return self.create_job(self._upload_books, done, args=[files, names], return self.create_job(self._upload_books, done, args=[files, names],
kwargs={'on_card':on_card}, description=desc) kwargs={'on_card':on_card,'metadata':metadata}, description=desc)
def add_books_to_metadata(self, locations, metadata, booklists): def add_books_to_metadata(self, locations, metadata, booklists):
self.device.add_books_to_metadata(locations, metadata, booklists) self.device.add_books_to_metadata(locations, metadata, booklists)

View File

@ -385,13 +385,35 @@ class BooksModel(QAbstractTableModel):
metadata.append(mi) metadata.append(mi)
return metadata return metadata
def get_preferred_formats_from_ids(self, ids, all_formats, mode='r+b'):
ans = []
for id in ids:
format = None
fmts = self.db.formats(id, index_is_id=True)
if not fmts:
fmts = ''
available_formats = set(fmts.lower().split(','))
for f in all_formats:
if f.lower() in available_formats:
format = f.lower()
break
if format is None:
ans.append(format)
else:
f = self.db.format(id, format, index_is_id=True, as_file=True,
mode=mode)
ans.append(f)
return ans
def get_preferred_formats(self, rows, formats, paths=False): 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
fmts = self.db.formats(row) fmts = self.db.formats(row)
if not fmts: if not fmts:
return [] fmts = ''
db_formats = set(fmts.lower().split(',')) db_formats = set(fmts.lower().split(','))
available_formats = set([f.lower() for f in formats]) available_formats = set([f.lower() for f in formats])
u = available_formats.intersection(db_formats) u = available_formats.intersection(db_formats)

View File

@ -745,8 +745,8 @@ class Main(MainWindow, Ui_MainWindow):
''' '''
titles = [i['title'] for i in metadata] titles = [i['title'] for i in metadata]
job = self.device_manager.upload_books(Dispatcher(self.books_uploaded), job = self.device_manager.upload_books(Dispatcher(self.books_uploaded),
files, names, on_card=on_card, files, names, on_card=on_card,
titles=titles metadata=metadata, titles=titles
) )
self.upload_memory[job] = (metadata, on_card, memory, files) self.upload_memory[job] = (metadata, on_card, memory, files)
@ -887,7 +887,8 @@ class Main(MainWindow, Ui_MainWindow):
if self.device_connected: if self.device_connected:
ids = list(dynamic.get('news_to_be_synced', set([]))) ids = list(dynamic.get('news_to_be_synced', set([])))
ids = [id for id in ids if self.library_view.model().db.has_id(id)] ids = [id for id in ids if self.library_view.model().db.has_id(id)]
files = [self.library_view.model().db.format(id, prefs['output_format'], index_is_id=True, as_file=True) for id in ids] files = self.library_view.model().get_preferred_formats_from_ids(
ids, self.device_manager.device_class.FORMATS)
files = [f for f in files if f is not None] files = [f for f in files if f is not None]
if not files: if not files:
dynamic.set('news_to_be_synced', set([])) dynamic.set('news_to_be_synced', set([]))
@ -922,7 +923,7 @@ 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, paths=True) self.device_manager.device_class.FORMATS, paths=True)
files = [getattr(f, 'name', None) for f in _files] files = [getattr(f, 'name', None) for f in _files]
bad, good, gf, names = [], [], [], [] bad, good, gf, names = [], [], [], []

File diff suppressed because it is too large Load Diff