From 6f5dd55f98c30287f988bdea7b2900978e283790 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 28 Sep 2008 09:20:27 -0700 Subject: [PATCH] Fix handling of covers in epub output. Various fixes for minor regressions. --- src/calibre/__init__.py | 2 +- src/calibre/ebooks/epub/__init__.py | 4 +++- src/calibre/ebooks/epub/from_any.py | 2 ++ src/calibre/ebooks/epub/from_html.py | 9 ++++++++ src/calibre/ebooks/epub/split.py | 8 +++++-- src/calibre/ebooks/html.py | 2 ++ src/calibre/ebooks/metadata/opf2.py | 31 +++++++++++++++++++++++++++- src/calibre/gui2/__init__.py | 4 ++-- src/calibre/gui2/main.py | 6 +++--- 9 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index afc74fbdef..1f33e34483 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -162,7 +162,7 @@ def fit_image(width, height, pwidth, pheight): @param height: Height of image @param pwidth: Width of box @param pheight: Height of box - @return: scaled, new_width, new_height. scaled is True iff new_widdth and/or new_height is different from width or height. + @return: scaled, new_width, new_height. scaled is True iff new_width and/or new_height is different from width or height. ''' scaled = height > pheight or width > pwidth if height > pheight: diff --git a/src/calibre/ebooks/epub/__init__.py b/src/calibre/ebooks/epub/__init__.py index f003df5ec2..1a48cddef7 100644 --- a/src/calibre/ebooks/epub/__init__.py +++ b/src/calibre/ebooks/epub/__init__.py @@ -15,10 +15,12 @@ from calibre.ebooks.html import config as common_config, tostring class DefaultProfile(object): flow_size = sys.maxint + screen_size = None class PRS505(DefaultProfile): - flow_size = 300000 + flow_size = 300000 + screen_size = (600, 775) PROFILES = { diff --git a/src/calibre/ebooks/epub/from_any.py b/src/calibre/ebooks/epub/from_any.py index 08129d0fa8..950e73ba1a 100644 --- a/src/calibre/ebooks/epub/from_any.py +++ b/src/calibre/ebooks/epub/from_any.py @@ -33,6 +33,8 @@ def mobi2opf(path, tdir, opts): reader = MobiReader(path) reader.extract_content(tdir) files = list(walk(tdir)) + opts.dont_preserve_structure = True + opts.encoding = 'utf-8' for f in files: if f.lower().endswith('.opf'): return f diff --git a/src/calibre/ebooks/epub/from_html.py b/src/calibre/ebooks/epub/from_html.py index 99c8430c33..92bf18b32d 100644 --- a/src/calibre/ebooks/epub/from_html.py +++ b/src/calibre/ebooks/epub/from_html.py @@ -162,6 +162,15 @@ def convert(htmlfile, opts, notification=None): spine = [htmlfile_map[f.path] for f in filelist] if mi.cover: cpath = '/'.join(('resources', os.path.basename(mi.cover))) + if opts.profile.screen_size is not None: + im = PILImage.open(os.path.join(tdir, 'content', *cpath.split('/'))) + width, height = im.size + dw, dh = (opts.profile.screen_size[0]-width)/float(width), (opts.profile.screen_size[1]-height)/float(height) + delta = min(dw, dh) + if delta > 0: + nwidth = int(width + delta*(width)) + nheight = int(height + delta*(height)) + im.resize((int(nwidth), int(nheight)), PILImage.ANTIALIAS).convert('RGB').save(os.path.join(tdir, 'content', *cpath.split('/'))) cover = '''\ Cover Page diff --git a/src/calibre/ebooks/epub/split.py b/src/calibre/ebooks/epub/split.py index 38f51ae3be..491d90c4d8 100644 --- a/src/calibre/ebooks/epub/split.py +++ b/src/calibre/ebooks/epub/split.py @@ -348,12 +348,16 @@ def split(pathtoopf, opts): item.set('href', item.get('href').replace('&', '%26')) html_files.append(f) changes = [] + always_remove = getattr(opts, 'dont_preserve_structure', False) for f in html_files: if os.stat(content(f)).st_size > opts.profile.flow_size: try: - changes.append(Splitter(f, opts)) + changes.append(Splitter(f, opts, always_remove=always_remove)) except SplitError: - changes.append(Splitter(f, opts, always_remove=True)) + if not always_remove: + changes.append(Splitter(f, opts, always_remove=True)) + else: + raise changes[-1].fix_opf(opf) open(pathtoopf, 'wb').write(opf.render()) diff --git a/src/calibre/ebooks/html.py b/src/calibre/ebooks/html.py index d04f6ba844..61abf7acb4 100644 --- a/src/calibre/ebooks/html.py +++ b/src/calibre/ebooks/html.py @@ -356,6 +356,7 @@ class Parser(PreProcessor, LoggingInterface): ''' ans = tostring(self.root, pretty_print=self.opts.pretty_print) ans = re.compile(r'', re.IGNORECASE).sub('', ans[:1000]) + ans[1000:] + ans = re.compile(r'', re.IGNORECASE).sub('\n\t\n', ans[:1000])+ans[1000:] with open(self.save_path(), 'wb') as f: f.write(ans) @@ -747,6 +748,7 @@ def create_metadata(basepath, mi, filelist, resources): Create an OPF metadata object with correct spine and manifest. ''' mi = OPFCreator(basepath, mi) + mi.guide = None entries = [('content/'+f, 'application/xhtml+xml') for f in filelist] + [(f, None) for f in resources] for f in filelist: if os.path.exists(os.path.join(basepath, 'content', 'resources', f+'.css')): diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index bed50876fe..5e402847d4 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -162,7 +162,7 @@ class ManifestItem(Resource): def from_opf_manifest_item(item, basedir): href = item.get('href', None) if href: - res = ManifestItem(href, basedir=basedir, is_path=False) + res = ManifestItem(href, basedir=basedir, is_path=True) mt = item.get('media-type', '').strip() if mt: res.mime_type = mt @@ -607,6 +607,35 @@ class OPF(object): matches[0].text = unicode(val) return property(fget=fget, fset=fset) + @apply + def cover(): + + def fget(self): + if self.guide is not None: + for t in ('cover', 'other.ms-coverimage-standard', 'other.ms-coverimage'): + for item in self.guide: + if item.type.lower() == t: + return item.path + + def fset(self, path): + if self.guide is not None: + self.guide.set_cover(path) + else: + g = etree.SubElement(self.root, 'opf:guide', nsmap=self.NAMESPACES) + self.guide = Guide() + self.guide.set_cover(path) + etree.SubElement(g, 'opf:reference', nsmap=self.NAMESPACES, + attrib={'type':'cover', 'href':self.guide[-1].href()}) + id = self.manifest.id_for_path(self.cover) + if id is None: + for t in ('cover', 'other.ms-coverimage-standard', 'other.ms-coverimage'): + for item in self.guide: + if item.type.lower() == t: + self.create_manifest_item(item.href(), mimetypes.guess_type(path)[0]) + + return property(fget=fget, fset=fset) + + def get_metadata_element(self, name): matches = self.metadata_elem_path(self.metadata, name=name) if matches: diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index b77b270054..58b78cc00a 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -21,8 +21,8 @@ def _config(): c = Config('gui', 'preferences for the calibre GUI') c.add_opt('frequently_used_directories', default=[], help=_('Frequently used directories')) - c.add_opt('send_to_device_by_default', default=True, - help=_('Send downloaded periodical content to device automatically')) + c.add_opt('send_to_storage_card_by_default', default=False, + help=_('Send file to storage card instead of main memory by default')) c.add_opt('save_to_disk_single_format', default='lrf', help=_('The format to use when saving single files to disk')) c.add_opt('confirm_delete', default=False, diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index a01812c00f..262325f2fa 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -122,13 +122,13 @@ class Main(MainWindow, Ui_MainWindow): sm.addAction(_('Send to storage card by default')) sm.actions()[-1].setCheckable(True) def default_sync(checked): - config.set('send_to_device_by_default', bool(checked)) + config.set('send_to_storage_card_by_default', bool(checked)) QObject.disconnect(self.action_sync, SIGNAL("triggered(bool)"), self.sync_to_main_memory) QObject.disconnect(self.action_sync, SIGNAL("triggered(bool)"), self.sync_to_card) QObject.connect(self.action_sync, SIGNAL("triggered(bool)"), self.sync_to_card if checked else self.sync_to_main_memory) QObject.connect(sm.actions()[-1], SIGNAL('toggled(bool)'), default_sync) - sm.actions()[-1].setChecked(config.get('send_to_device_by_default')) + sm.actions()[-1].setChecked(config.get('send_to_storage_card_by_default')) default_sync(sm.actions()[-1].isChecked()) self.sync_menu = sm # Needed md = QMenu() @@ -514,7 +514,7 @@ class Main(MainWindow, Ui_MainWindow): 'cover':self.default_thumbnail, 'tags':[]}) if not to_device: - model = self.current_view().model() + model = self.library_view.model() html_pat = re.compile(r'\.x{0,1}htm(l{0,1})\s*$', re.IGNORECASE) paths = list(paths) for i, path in enumerate(paths):