Merge from trunk

This commit is contained in:
Charles Haley 2010-06-17 21:05:20 +01:00
commit 3e726341da
12 changed files with 651 additions and 377 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

After

Width:  |  Height:  |  Size: 396 KiB

BIN
resources/tracer.epub Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ import os, re
from mimetypes import guess_type as guess_mimetype from mimetypes import guess_type as guess_mimetype
from calibre.ebooks.BeautifulSoup import BeautifulSoup, NavigableString from calibre.ebooks.BeautifulSoup import BeautifulSoup, NavigableString
from calibre.constants import iswindows
from calibre.utils.chm.chm import CHMFile from calibre.utils.chm.chm import CHMFile
from calibre.utils.chm.chmlib import ( from calibre.utils.chm.chmlib import (
CHM_RESOLVE_SUCCESS, CHM_ENUMERATE_NORMAL, CHM_RESOLVE_SUCCESS, CHM_ENUMERATE_NORMAL,
@ -135,10 +135,16 @@ class CHMReader(CHMFile):
if lpath.find(';') != -1: if lpath.find(';') != -1:
# fix file names with ";<junk>" at the end, see _reformat() # fix file names with ";<junk>" at the end, see _reformat()
lpath = lpath.split(';')[0] lpath = lpath.split(';')[0]
with open(lpath, 'wb') as f: try:
if guess_mimetype(path)[0] == ('text/html'): with open(lpath, 'wb') as f:
data = self._reformat(data) if guess_mimetype(path)[0] == ('text/html'):
f.write(data) data = self._reformat(data)
f.write(data)
except:
if iswindows and len(lpath) > 250:
self.log.warn('%r filename too long, skipping'%path)
continue
raise
self._extracted = True self._extracted = True
files = os.listdir(output_dir) files = os.listdir(output_dir)
if self.hhc_path not in files: if self.hhc_path not in files:

View File

@ -260,7 +260,7 @@ class MetaInformation(object):
setattr(self, x, getattr(mi, x, None)) setattr(self, x, getattr(mi, x, None))
def print_all_attributes(self): def print_all_attributes(self):
for x in ('author', 'author_sort', 'title_sort', 'comments', 'category', 'publisher', for x in ('title','author', 'author_sort', 'title_sort', 'comments', 'category', 'publisher',
'series', 'series_index', 'tags', 'rating', 'isbn', 'language', 'series', 'series_index', 'tags', 'rating', 'isbn', 'language',
'application_id', 'manifest', 'toc', 'spine', 'guide', 'cover', 'application_id', 'manifest', 'toc', 'spine', 'guide', 'cover',
'book_producer', 'timestamp', 'lccn', 'lcc', 'ddc', 'pubdate', 'book_producer', 'timestamp', 'lccn', 'lcc', 'ddc', 'pubdate',

View File

@ -182,7 +182,7 @@ def get_metadata(stream, extract_cover=True):
def get_quick_metadata(stream): def get_quick_metadata(stream):
return get_metadata(stream, False) return get_metadata(stream, False)
def set_metadata(stream, mi, apply_null=False): def set_metadata(stream, mi, apply_null=False, update_timestamp=False):
stream.seek(0) stream.seek(0)
reader = OCFZipReader(stream, root=os.getcwdu()) reader = OCFZipReader(stream, root=os.getcwdu())
mi = MetaInformation(mi) mi = MetaInformation(mi)
@ -196,6 +196,8 @@ def set_metadata(stream, mi, apply_null=False):
reader.opf.tags = [] reader.opf.tags = []
if not getattr(mi, 'isbn', None): if not getattr(mi, 'isbn', None):
reader.opf.isbn = None reader.opf.isbn = None
if update_timestamp and mi.timestamp is not None:
reader.opf.timestamp = mi.timestamp
newopf = StringIO(reader.opf.render()) newopf = StringIO(reader.opf.render())
safe_replace(stream, reader.container[OPF.MIMETYPE], newopf) safe_replace(stream, reader.container[OPF.MIMETYPE], newopf)

View File

@ -689,14 +689,28 @@ class DeviceMixin(object): # {{{
self.device_error_dialog.show() self.device_error_dialog.show()
# Device connected {{{ # Device connected {{{
def device_detected(self, connected, is_folder_device):
''' def set_device_menu_items_state(self, connected, is_folder_device):
Called when a device is connected to the computer.
'''
if connected: if connected:
self._sync_menu.connect_to_folder_action.setEnabled(False) self._sync_menu.connect_to_folder_action.setEnabled(False)
if is_folder_device: if is_folder_device:
self._sync_menu.disconnect_from_folder_action.setEnabled(True) self._sync_menu.disconnect_from_folder_action.setEnabled(True)
self._sync_menu.enable_device_actions(True,
self.device_manager.device.card_prefix(),
self.device_manager.device)
self.eject_action.setEnabled(True)
else:
self._sync_menu.connect_to_folder_action.setEnabled(True)
self._sync_menu.disconnect_from_folder_action.setEnabled(False)
self._sync_menu.enable_device_actions(False)
self.eject_action.setEnabled(False)
def device_detected(self, connected, is_folder_device):
'''
Called when a device is connected to the computer.
'''
self.set_device_menu_items_state(connected, is_folder_device)
if connected:
self.device_manager.get_device_information(\ self.device_manager.get_device_information(\
Dispatcher(self.info_read)) Dispatcher(self.info_read))
self.set_default_thumbnail(\ self.set_default_thumbnail(\
@ -705,17 +719,10 @@ class DeviceMixin(object): # {{{
self.device_manager.device.__class__.get_gui_name()+\ self.device_manager.device.__class__.get_gui_name()+\
_(' detected.'), 3000) _(' detected.'), 3000)
self.device_connected = 'device' if not is_folder_device else 'folder' self.device_connected = 'device' if not is_folder_device else 'folder'
self._sync_menu.enable_device_actions(True,
self.device_manager.device.card_prefix(),
self.device_manager.device)
self.location_view.model().device_connected(self.device_manager.device) self.location_view.model().device_connected(self.device_manager.device)
self.eject_action.setEnabled(True)
self.refresh_ondevice_info (device_connected = True, reset_only = True) self.refresh_ondevice_info (device_connected = True, reset_only = True)
else: else:
self._sync_menu.connect_to_folder_action.setEnabled(True)
self._sync_menu.disconnect_from_folder_action.setEnabled(False)
self.device_connected = None self.device_connected = None
self._sync_menu.enable_device_actions(False)
self.location_view.model().update_devices() self.location_view.model().update_devices()
self.vanity.setText(self.vanity_template%\ self.vanity.setText(self.vanity_template%\
dict(version=self.latest_version, device=' ')) dict(version=self.latest_version, device=' '))
@ -723,7 +730,6 @@ class DeviceMixin(object): # {{{
if self.current_view() != self.library_view: if self.current_view() != self.library_view:
self.book_details.reset_info() self.book_details.reset_info()
self.location_view.setCurrentIndex(self.location_view.model().index(0)) self.location_view.setCurrentIndex(self.location_view.model().index(0))
self.eject_action.setEnabled(False)
self.refresh_ondevice_info (device_connected = False) self.refresh_ondevice_info (device_connected = False)
def info_read(self, job): def info_read(self, job):

View File

@ -84,12 +84,12 @@ class DownloadMetadata(Thread):
if mi.isbn: if mi.isbn:
args['isbn'] = mi.isbn args['isbn'] = mi.isbn
else: else:
if not mi.title: if not mi.title or mi.title == _('Unknown'):
self.failures[id] = \ self.failures[id] = \
(str(id), _('Book has neither title nor ISBN')) (str(id), _('Book has neither title nor ISBN'))
continue continue
args['title'] = mi.title args['title'] = mi.title
if mi.authors: if mi.authors and mi.authors[0] != _('Unknown'):
args['author'] = mi.authors[0] args['author'] = mi.authors[0]
if self.key: if self.key:
args['isbndb_key'] = self.key args['isbndb_key'] = self.key

View File

@ -410,6 +410,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceMixin, ToolbarMixin, # {{{
self.tags_view.set_new_model() # in case columns changed self.tags_view.set_new_model() # in case columns changed
self.tags_view.recount() self.tags_view.recount()
self.create_device_menu() self.create_device_menu()
self.set_device_menu_items_state(bool(self.device_connected),
self.device_connected == 'folder')
if not patheq(self.library_path, d.database_location): if not patheq(self.library_path, d.database_location):
newloc = d.database_location newloc = d.database_location

View File

@ -788,6 +788,7 @@ class BasicNewsRecipe(Recipe):
} }
.summary_byline { .summary_byline {
text-align:left;
font-family:monospace; font-family:monospace;
} }
@ -1139,12 +1140,6 @@ class BasicNewsRecipe(Recipe):
mi = MetaInformation(self.short_title() + strftime(self.timefmt), [__appname__]) mi = MetaInformation(self.short_title() + strftime(self.timefmt), [__appname__])
mi.publisher = __appname__ mi.publisher = __appname__
mi.author_sort = __appname__ mi.author_sort = __appname__
if self.output_profile.name == 'iPad':
date_as_author = '%s, %s %s, %s' % (strftime('%A'), strftime('%B'), strftime('%d').lstrip('0'), strftime('%Y'))
mi = MetaInformation(self.short_title(), [date_as_author])
mi.publisher = __appname__
sort_author = re.sub('^\s*A\s+|^\s*The\s+|^\s*An\s+', '', self.title).rstrip()
mi.author_sort = '%s %s' % (sort_author, strftime('%Y-%m-%d'))
mi.publication_type = 'periodical:'+self.publication_type mi.publication_type = 'periodical:'+self.publication_type
mi.timestamp = nowf() mi.timestamp = nowf()
mi.comments = self.description mi.comments = self.description