From ee45978cd01cf4cfdd7ea85db85645a3a64e3c1f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 13 Aug 2012 21:58:54 +0530 Subject: [PATCH 1/7] ... --- src/calibre/devices/prst1/driver.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/calibre/devices/prst1/driver.py b/src/calibre/devices/prst1/driver.py index d3c92b5eff..b51e55b829 100644 --- a/src/calibre/devices/prst1/driver.py +++ b/src/calibre/devices/prst1/driver.py @@ -193,7 +193,11 @@ class PRST1(USBMS): time_offsets = {} for i, row in enumerate(cursor): - comp_date = int(os.path.getmtime(self.normalize_path(prefix + row[0])) * 1000); + try: + comp_date = int(os.path.getmtime(self.normalize_path(prefix + row[0])) * 1000); + except (OSError, IOError): + # In case the db has incorrect path info + continue device_date = int(row[1]); offset = device_date - comp_date time_offsets.setdefault(offset, 0) From 205e79c30e03a07ec172a070c2dfab853e0f3ad3 Mon Sep 17 00:00:00 2001 From: GRiker Date: Mon, 13 Aug 2012 17:07:34 -0600 Subject: [PATCH 2/7] Fine tuning layout, added special case CSS for MOBI --- resources/catalog/stylesheet.css | 350 +++++++++++++----- .../library/catalogs/epub_mobi_builder.py | 24 +- 2 files changed, 272 insertions(+), 102 deletions(-) diff --git a/resources/catalog/stylesheet.css b/resources/catalog/stylesheet.css index 48edce76c8..41a5980ed2 100644 --- a/resources/catalog/stylesheet.css +++ b/resources/catalog/stylesheet.css @@ -1,35 +1,229 @@ body { background-color: white; } +/* +** The following rules apply principally to the line items shown in the +** Authors, Titles, Genres, Series, and Recently Added sections. Rules for the +** Descriptions section are grouped together later in the file. +** ------------------------------------------------------------------------ +*/ + + +/* +**
grouping an author's works together +** Used in Sections: +** Authors +** +** Minimize widows and orphans by logically grouping chunks +** Some reports of problems with Sony (ADE) ereaders +** ADE: page-break-inside:avoid; +** iBooks: display:inline-block; +** width:100%; +*/ +div.author_logical_group { + page-break-inside:avoid; + } + +/* +** Force page break when starting new initial letter +** Used in Sections: +** Authors +** Titles +*/ +div.initial_letter { + page-break-before:always; + } + +/* +** Author name +** Used in Sections: +** Authors +** Genres +** Recently Added +*/ +p.author_index { + clear:both; + font-size:large; + font-weight:bold; + text-align:left; + margin-top:0.25px; + margin-bottom:-2px; + text-indent: 0em; + } + +/* +** Index letter +** Used in Sections: +** Authors +** Titles +*/ +p.author_title_letter_index { + clear:both; + font-size:x-large; + text-align:center; + font-weight:bold; + margin-top:0px; + margin-bottom:0px; + } + +/* +** Index letter +** Used in Sections: +** Series +*/ +p.series_letter_index { + font-size:x-large; + text-align:center; + font-weight:bold; + margin-top:1em; + margin-bottom:0px; + } + + +/* +** Month-Year +** Used in Sections: +** Recently Added +*/ +p.date_index { + clear:both; + font-size:x-large; + text-align:center; + font-weight:bold; + margin-top:1em; + margin-bottom:0px; + } + +p.date_read { + clear:both; + text-align:left; + margin-top:0px; + margin-bottom:0px; + margin-left:6em; + text-indent:-6em; + } + +/* +** Series name +** Used in Sections: +** Authors +** Series +** Genres +** Recently Added +** Optimized for ePub +*/ +p.series { + clear:both; + font-style:italic; + margin-top:0.10em; + margin-bottom:0em; + margin-left:1.5em; + text-align:left; + text-indent:-1.25em; + } + +/* +** Series name +** Used in Sections: +** Authors +** Series +** Genres +** Recently Added +** Optimized for mobi +*/ +p.series_mobi { + clear:both; + font-style:italic; + margin-top:0em; + margin-bottom:0em; + margin-left:0em; + text-align:left; + text-indent:-30px; + } + +/* +** Section title +** Used in Sections: +** Authors +** Titles +** Series +** Genres +** Recently Added +** Descriptions +*/ +p.title { + margin-top:0em; + margin-bottom:0em; + text-align:center; + font-style:italic; + font-size:xx-large; + } + +/* +** Line item book listing +** Used in Sections: +** Authors +** Titles +** Series +** Genres +** Recently Added +*/ +p.line_item { + clear: both; + font-family:monospace; + margin-top:0px; + margin-bottom:0px; + margin-left:2em; + text-align:left; + text-indent:-2em; + } + +/* +** Prefix +** Used in Sections: +** Authors +** Titles +** Series +** Genres +** Recently Added +*/ +span.prefix { + float:left; + margin-left: 0.25em; + text-align: left; + vertical-align: middle; + width: 1.5em; + } + +/* +** Book details entry +** Used in Sections: +** Authors +** Titles +** Series +** Genres +** Recently Added +*/ +span.entry { + font-family: serif; + vertical-align:middle; + } + +/* +** The following rules apply to Descriptions +** ----------------------------------------- +*/ + +/* +** Link to Series +*/ a.series_id { font-style:normal; font-size:large; } /* -* Minimize widows and orphans by logically grouping chunks -* Some reports of problems with Sony (ADE) ereaders -* ADE: page-break-inside:avoid; -* iBooks: display:inline-block; -* width:100%; +** Various dividers */ -div.author_logical_group { - page-break-inside:avoid; - } - -div.description > p:first-child { - margin: 0 0 0 0; - text-indent: 0em; - } - -div.description { - margin: 0 0 0 0; - text-indent: 1em; - } - -div.initial_letter { - page-break-before:always; - } - hr.annotations_divider { width:50%; margin-left:1em; @@ -63,15 +257,11 @@ hr.merged_comments_divider { border-left: solid white 0px; } -p.date_read { - text-align:left; - margin-top:0px; - margin-bottom:0px; - margin-left:6em; - text-indent:-6em; - } - +/* +** Author name +*/ p.author { + clear:both; font-size:large; margin-top:0em; margin-bottom:0.1em; @@ -79,31 +269,9 @@ p.author { text-indent: 0em; } -p.author_index { - font-size:large; - font-weight:bold; - text-align:left; - margin-top:0.25px; - margin-bottom:-2px; - text-indent: 0em; - } - -p.author_title_letter_index { - font-size:x-large; - text-align:center; - font-weight:bold; - margin-top:0px; - margin-bottom:0px; - } - -p.date_index { - font-size:x-large; - text-align:center; - font-weight:bold; - margin-top:1em; - margin-bottom:0px; - } - +/* +** Formats +*/ p.formats { font-size:90%; margin-top:0em; @@ -112,6 +280,9 @@ p.formats { text-indent: 0.0in; } +/* +** Genres +*/ p.genres { font-style:normal; margin-top:0.5em; @@ -120,68 +291,55 @@ p.genres { text-indent: 0.0in; } -p.series { - font-style:italic; - margin-top:0.10em; - margin-bottom:0em; - margin-left:2em; - text-align:left; - text-indent:-2em; - } +/* +** Series name +*/ p.series_id { margin-top:0em; margin-bottom:0em; text-align:center; } -p.series_letter_index { - font-size:x-large; - text-align:center; - font-weight:bold; - margin-top:1em; - margin-bottom:0px; - } - -p.title { - margin-top:0em; - margin-bottom:0em; - text-align:center; - font-style:italic; - font-size:xx-large; - } - -p.wishlist_item, p.unread_book, p.read_book, p.line_item { - font-family:monospace; - margin-top:0px; - margin-bottom:0px; - margin-left:2em; - text-align:left; - text-indent:-2em; - } - -span.prefix {} -span.entry { - font-family: serif; - } - /* -* Book Descriptions +** Publisher, Publication Date */ td.publisher, td.date { font-weight:bold; text-align:center; } +/* +** Rating +*/ td.rating{ text-align:center; } +/* +** Additional notes +*/ td.notes { font-size: 100%; text-align:center; } +/* +** Thumbnail +*/ td.thumbnail img { -webkit-box-shadow: 4px 4px 12px #999; - } \ No newline at end of file + } + +/* +** Comments +*/ +div.description { + margin: 0 0 0 0; + text-indent: 1em; + } +div.description > p:first-child { + margin: 0 0 0 0; + text-indent: 0em; + } + diff --git a/src/calibre/library/catalogs/epub_mobi_builder.py b/src/calibre/library/catalogs/epub_mobi_builder.py index 1ebe710993..603ab487e9 100644 --- a/src/calibre/library/catalogs/epub_mobi_builder.py +++ b/src/calibre/library/catalogs/epub_mobi_builder.py @@ -1188,7 +1188,8 @@ Author '{0}': current_series = book['series'] pSeriesTag = Tag(soup,'p') pSeriesTag['class'] = "series" - + if self.opts.fmt == 'mobi': + pSeriesTag['class'] = "series_mobi" if self.opts.generate_series: aTag = Tag(soup,'a') aTag['href'] = "%s.html#%s" % ('BySeries',self.generateSeriesAnchor(book['series'])) @@ -1330,6 +1331,8 @@ Author '{0}': current_series = new_entry['series'] pSeriesTag = Tag(soup,'p') pSeriesTag['class'] = "series" + if self.opts.fmt == 'mobi': + pSeriesTag['class'] = "series_mobi" if self.opts.generate_series: aTag = Tag(soup,'a') @@ -1776,6 +1779,8 @@ Author '{0}': current_series = book['series'] pSeriesTag = Tag(soup,'p') pSeriesTag['class'] = "series" + if self.opts.fmt == 'mobi': + pSeriesTag['class'] = "series_mobi" aTag = Tag(soup, 'a') aTag['id'] = self.generateSeriesAnchor(book['series']) pSeriesTag.insert(0,aTag) @@ -3343,11 +3348,17 @@ Author '{0}': return codeTag else: spanTag = Tag(soup, "span") - #spanTag['class'] = "prefix" + spanTag['class'] = "prefix" + + # color:white was the original technique used to align columns. + # The new technique is to float the prefix left with CSS. if prefix_char is None: - spanTag['style'] = "color:white" - prefix_char = self.defaultPrefix - #prefix_char = " " + if True: + prefix_char = " " + else: + del spanTag['class'] + spanTag['style'] = "color:white" + prefix_char = self.defaultPrefix spanTag.insert(0,NavigableString(prefix_char)) return spanTag @@ -3428,6 +3439,8 @@ Author '{0}': current_series = book['series'] pSeriesTag = Tag(soup,'p') pSeriesTag['class'] = "series" + if self.opts.fmt == 'mobi': + pSeriesTag['class'] = "series_mobi" if self.opts.generate_series: aTag = Tag(soup,'a') aTag['href'] = "%s.html#%s" % ('BySeries', self.generateSeriesAnchor(book['series'])) @@ -3773,7 +3786,6 @@ Author '{0}': else: return "%s_series" % re.sub('\W','',ascii_text(series)).lower() - def generateShortDescription(self, description, dest=None): # Truncate the description, on word boundaries if necessary # Possible destinations: From 4f117c0fb7dac0553cc4a24c1d98208d4424d224 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 14 Aug 2012 09:57:52 +0530 Subject: [PATCH 3/7] Fix #1036358 (Validation bug in First Run Wizzard) --- src/calibre/gui2/wizard/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/calibre/gui2/wizard/__init__.py b/src/calibre/gui2/wizard/__init__.py index ef756a226a..576db914f0 100644 --- a/src/calibre/gui2/wizard/__init__.py +++ b/src/calibre/gui2/wizard/__init__.py @@ -440,8 +440,7 @@ class KindlePage(QWizardPage, KindleUI): x = unicode(self.to_address.text()).strip() parts = x.split('@') - if (self.send_email_widget.set_email_settings(True) and len(parts) >= 2 - and parts[0]): + if (len(parts) >= 2 and parts[0] and self.send_email_widget.set_email_settings(True)): conf = smtp_prefs() accounts = conf.parse().accounts if not accounts: accounts = {} From 9631fc0ca9dc9e6ea5bad89677accee8884839d0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 14 Aug 2012 10:16:15 +0530 Subject: [PATCH 4/7] Fix restore database not restoring entries for the original_* formats --- src/calibre/library/restore.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/library/restore.py b/src/calibre/library/restore.py index 0b352f365b..ac1fce5783 100644 --- a/src/calibre/library/restore.py +++ b/src/calibre/library/restore.py @@ -42,7 +42,7 @@ class Restore(Thread): self.src_library_path = os.path.abspath(library_path) self.progress_callback = progress_callback self.db_id_regexp = re.compile(r'^.* \((\d+)\)$') - self.bad_ext_pat = re.compile(r'[^a-z0-9]+') + self.bad_ext_pat = re.compile(r'[^a-z0-9_]+') if not callable(self.progress_callback): self.progress_callback = lambda x, y: x self.dirs = [] From 666335ecbce85e816656aaee4afac49897b26f84 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 14 Aug 2012 10:21:20 +0530 Subject: [PATCH 5/7] E-book viewer: Make paged mode the default. You can go back to the old flow mode by clicking the button witht e yellow scroll in the top right corner of the viewer. --- src/calibre/gui2/viewer/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index 49487518ef..6e4d129eaf 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -417,7 +417,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer): vprefs.set('viewer_splitter_state', bytearray(self.splitter.saveState())) vprefs['multiplier'] = self.view.multiplier - vprefs['in_paged_mode1'] = not self.action_toggle_paged_mode.isChecked() + vprefs['in_paged_mode'] = not self.action_toggle_paged_mode.isChecked() def restore_state(self): state = vprefs.get('viewer_toolbar_state', None) @@ -434,8 +434,8 @@ class EbookViewer(MainWindow, Ui_EbookViewer): # specific location, ensure they are visible. self.tool_bar.setVisible(True) self.tool_bar2.setVisible(True) - self.action_toggle_paged_mode.setChecked(not vprefs.get('in_paged_mode1', - False)) + self.action_toggle_paged_mode.setChecked(not vprefs.get('in_paged_mode', + True)) self.toggle_paged_mode(self.action_toggle_paged_mode.isChecked(), at_start=True) From 09495f18402d6e8cbd67b7b63ce823204ccf0cbf Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 14 Aug 2012 12:10:45 +0530 Subject: [PATCH 6/7] Nicer error message when attempting to set cover froma file open in another program on windows --- src/calibre/gui2/metadata/single.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index bb69197b58..6089b5422b 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -310,8 +310,18 @@ class MetadataSingleDialogBase(ResizableDialog): self.update_from_mi(mi) def cover_from_format(self, *args): - mi, ext = self.formats_manager.get_selected_format_metadata(self.db, - self.book_id) + try: + mi, ext = self.formats_manager.get_selected_format_metadata(self.db, + self.book_id) + except (IOError, OSError) as err: + if getattr(err, 'errno', None) == errno.EACCES: # Permission denied + import traceback + fname = err.filename if err.filename else 'file' + error_dialog(self, _('Permission denied'), + _('Could not open %s. Is it being used by another' + ' program?')%fname, det_msg=traceback.format_exc(), + show=True) + return False if mi is None: return cdata = None From e75958a1f1c0d0d493e08ff9ed6f3144a8fd616d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 14 Aug 2012 12:11:18 +0530 Subject: [PATCH 7/7] ... --- src/calibre/gui2/metadata/single.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 6089b5422b..54067f4c0f 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -321,7 +321,7 @@ class MetadataSingleDialogBase(ResizableDialog): _('Could not open %s. Is it being used by another' ' program?')%fname, det_msg=traceback.format_exc(), show=True) - return False + return if mi is None: return cdata = None