diff --git a/src/calibre/gui2/convert/gui_conversion.py b/src/calibre/gui2/convert/gui_conversion.py index 70321b049b..5f339bf91d 100644 --- a/src/calibre/gui2/convert/gui_conversion.py +++ b/src/calibre/gui2/convert/gui_conversion.py @@ -42,6 +42,7 @@ def gui_catalog(fmt, title, dbspec, ids, out_file_name, sync, fmt_options, opts, args = parser.parse_args() # Populate opts + # opts.gui_search_text = something opts.catalog_title = title opts.ids = ids opts.search_text = None diff --git a/src/calibre/gui2/convert/mobi_output.py b/src/calibre/gui2/convert/mobi_output.py index 611ef96e11..57cc3a2ac1 100644 --- a/src/calibre/gui2/convert/mobi_output.py +++ b/src/calibre/gui2/convert/mobi_output.py @@ -6,9 +6,14 @@ __license__ = 'GPL v3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' +from PyQt4.Qt import Qt from calibre.gui2.convert.mobi_output_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.gui2.widgets import FontFamilyModel +from calibre.utils.fonts import fontconfig + +font_family_model = None class PluginWidget(Widget, Ui_Form): @@ -19,8 +24,35 @@ class PluginWidget(Widget, Ui_Form): def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, 'mobi_output', ['prefer_author_sort', 'rescale_images', 'toc_title', - 'dont_compress', 'no_inline_toc'] + 'dont_compress', 'no_inline_toc', 'masthead_font'] ) self.db, self.book_id = db, book_id + + global font_family_model + if font_family_model is None: + font_family_model = FontFamilyModel() + try: + font_family_model.families = fontconfig.find_font_families(allowed_extensions=['ttf']) + except: + import traceback + font_family_model.families = [] + print 'WARNING: Could not load fonts' + traceback.print_exc() + font_family_model.families.sort() + font_family_model.families[:0] = [_('Default')] + + self.font_family_model = font_family_model + self.opt_masthead_font.setModel(self.font_family_model) + self.initialize_options(get_option, get_help, db, book_id) + def set_value_handler(self, g, val): + if unicode(g.objectName()) in 'opt_masthead_font': + idx = -1 + if val: + idx = g.findText(val, Qt.MatchFixedString) + if idx < 0: + idx = 0 + g.setCurrentIndex(idx) + return True + return False diff --git a/src/calibre/gui2/convert/mobi_output.ui b/src/calibre/gui2/convert/mobi_output.ui index a1bad48fb0..9c3ec9e68e 100644 --- a/src/calibre/gui2/convert/mobi_output.ui +++ b/src/calibre/gui2/convert/mobi_output.ui @@ -6,7 +6,7 @@ 0 0 - 400 + 421 300 @@ -41,19 +41,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -68,6 +55,51 @@ + + + + Kindle options + + + + + + Masthead font: + + + + + + + + + + Qt::Vertical + + + + 20 + 55 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + diff --git a/src/calibre/library/catalog.py b/src/calibre/library/catalog.py index 611f5a9606..751d6c3ffb 100644 --- a/src/calibre/library/catalog.py +++ b/src/calibre/library/catalog.py @@ -403,10 +403,15 @@ class EPUB_MOBI(CatalogPlugin): right = EPUB_MOBI.NumberToText(strings[1]).text self.text = '%s-%s' % (left, right) + # Test for $xx,xxx + elif re.search('[$,]', self.number): + self.number_as_float = re.sub('[$,]','',self.number) + self.text = EPUB_MOBI.NumberToText(self.number_as_float).text + # Test for comma elif re.search(',', self.number): self.number_as_float = re.sub(',','',self.number) - self.text = EPUB_MOBI.NumberToText(self.number.replace(',','')).text + self.text = EPUB_MOBI.NumberToText(self.number_as_float).text # Test for hybrid e.g., 'K2' elif re.search('[\D]+', self.number): @@ -482,11 +487,6 @@ class EPUB_MOBI(CatalogPlugin): catalog.createDirectoryStructure() catalog.copyResources() catalog.buildSources() - - - To do: - *** generateThumbnails() creates a default book image from book.svg, but the background - is black instead of white. This needs to be fixed (approx line #1418) - ''' # Number of discrete steps to catalog creation @@ -811,7 +811,7 @@ class EPUB_MOBI(CatalogPlugin): # If failure, default mastheadImage.gif should still be in place if self.generateForKindle: try: - self.generate_masthead_image(os.path.join(self.catalogPath, + self.generateMastheadImage(os.path.join(self.catalogPath, 'images/mastheadImage.gif')) except: pass @@ -831,11 +831,14 @@ class EPUB_MOBI(CatalogPlugin): # Merge opts.exclude_tag with opts.search_text # What if no exclude tags? - exclude_tags = self.opts.exclude_tags.split(',') - search_terms = [] - for tag in exclude_tags: - search_terms.append("tag:%s" % tag) - search_phrase = "not (%s)" % " or ".join(search_terms) + empty_exclude_tags = False if len(self.opts.exclude_tags) else True + search_phrase = '' + if not empty_exclude_tags: + exclude_tags = self.opts.exclude_tags.split(',') + search_terms = [] + for tag in exclude_tags: + search_terms.append("tag:%s" % tag) + search_phrase = "not (%s)" % " or ".join(search_terms) # If a list of ids are provided, don't use search_text if self.opts.ids: @@ -846,6 +849,7 @@ class EPUB_MOBI(CatalogPlugin): else: self.opts.search_text = search_phrase + #print "fetchBooksByTitle(): opts.search_text: %s" % self.opts.search_text # Fetch the database as a dictionary data = self.plugin.search_sort_db(self.db, self.opts) @@ -1455,7 +1459,6 @@ class EPUB_MOBI(CatalogPlugin): self.updateProgressFullStep("'Genres'") - # filtered_tags = {friendly:normalized, } self.genre_tags_dict = self.filterDbTags(self.db.all_tags()) # Extract books matching filtered_tags @@ -2202,11 +2205,11 @@ class EPUB_MOBI(CatalogPlugin): # GwR *** Can this be optimized? normalized_tag = None - for genre_tag in self.genre_tags_dict: - if self.genre_tags_dict[genre_tag] == genre['tag']: - normalized_tag = self.genre_tags_dict[genre_tag] + for friendly_tag in self.genre_tags_dict: + if self.genre_tags_dict[friendly_tag] == genre['tag']: + normalized_tag = self.genre_tags_dict[friendly_tag] break - textTag.insert(0, self.formatNCXText(NavigableString(genre_tag))) + textTag.insert(0, self.formatNCXText(NavigableString(friendly_tag))) navLabelTag.insert(0,textTag) navPointVolumeTag.insert(0,navLabelTag) contentTag = Tag(ncx_soup, "content") @@ -2312,14 +2315,6 @@ class EPUB_MOBI(CatalogPlugin): if not os.path.isdir(images_path): os.makedirs(images_path) - def getMarkerTags(self): - ''' Return a list of special marker tags to be excluded from genre list ''' - markerTags = [] - markerTags.extend(self.opts.exclude_tags.split(',')) - markerTags.extend(self.opts.note_tag.split(',')) - markerTags.extend(self.opts.read_tag.split(',')) - return markerTags - def filterDbTags(self, tags): # Remove the special marker tags from the database's tag list, # return sorted list of normalized genre tags @@ -2337,7 +2332,6 @@ class EPUB_MOBI(CatalogPlugin): normalized_tags.append(re.sub('\W','',tag).lower()) friendly_tags.append(tag) - genre_tags_dict = dict(zip(friendly_tags,normalized_tags)) # Test for multiple genres resolving to same normalized form @@ -2405,10 +2399,10 @@ class EPUB_MOBI(CatalogPlugin): btc += 1 # Find the first instance of friendly_tag matching genre - # GwR *** optimize for friendly_tag in self.genre_tags_dict: if self.genre_tags_dict[friendly_tag] == genre: break + titleTag = body.find(attrs={'class':'title'}) titleTag.insert(0,NavigableString('%s' % escape(friendly_tag))) @@ -2570,8 +2564,22 @@ class EPUB_MOBI(CatalogPlugin): titleTag.insert(0,escape(NavigableString(title))) return soup - def generate_masthead_image(self, out_path): - font_path = P('fonts/liberation/LiberationSerif-Bold.ttf') + def generateMastheadImage(self, out_path): + from calibre.ebooks.conversion.config import load_defaults + from calibre.utils.fonts import fontconfig + font_path = default_font = P('fonts/liberation/LiberationSerif-Bold.ttf') + recs = load_defaults('mobi_output') + masthead_font_family = recs.get('masthead_font', 'Default') + + if masthead_font_family != 'Default': + masthead_font = fontconfig.files_for_family(masthead_font_family) + # Assume 'normal' always in dict, else use default + # {'normal': (path_to_font, friendly name)} + if 'normal' in masthead_font: + font_path = masthead_font['normal'][0] + + if not font_path or not os.access(font_path, os.R_OK): + font_path = default_font MI_WIDTH = 600 MI_HEIGHT = 60 @@ -2584,7 +2592,11 @@ class EPUB_MOBI(CatalogPlugin): img = Image.new('RGB', (MI_WIDTH, MI_HEIGHT), 'white') draw = ImageDraw.Draw(img) - font = ImageFont.truetype(font_path, 48) + try: + font = ImageFont.truetype(font_path, 48) + except: + self.opts.log.error(" Failed to load user-specifed font '%s'" % font_path) + font = ImageFont.truetype(default_font, 48) text = self.title.encode('utf-8') width, height = draw.textsize(text, font=font) left = max(int((MI_WIDTH - width)/2.), 0) @@ -2682,6 +2694,14 @@ class EPUB_MOBI(CatalogPlugin): else: return char + def getMarkerTags(self): + ''' Return a list of special marker tags to be excluded from genre list ''' + markerTags = [] + markerTags.extend(self.opts.exclude_tags.split(',')) + markerTags.extend(self.opts.note_tag.split(',')) + markerTags.extend(self.opts.read_tag.split(',')) + return markerTags + def processSpecialTags(self, tags, this_title, opts): tag_list = [] for tag in tags: diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index d182d856d8..f4f5ece98d 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -989,6 +989,22 @@ class BasicNewsRecipe(Recipe): MI_HEIGHT = 60 def default_masthead_image(self, out_path): + from calibre.ebooks.conversion.config import load_defaults + from calibre.utils.fonts import fontconfig + font_path = default_font = P('fonts/liberation/LiberationSerif-Bold.ttf') + recs = load_defaults('mobi_output') + masthead_font_family = recs.get('masthead_font', 'Default') + + if masthead_font_family != 'Default': + masthead_font = fontconfig.files_for_family(masthead_font_family) + # Assume 'normal' always in dict, else use default + # {'normal': (path_to_font, friendly name)} + if 'normal' in masthead_font: + font_path = masthead_font['normal'][0] + + if not font_path or not os.access(font_path, os.R_OK): + font_path = default_font + try: from PIL import Image, ImageDraw, ImageFont Image, ImageDraw, ImageFont @@ -997,7 +1013,10 @@ class BasicNewsRecipe(Recipe): img = Image.new('RGB', (self.MI_WIDTH, self.MI_HEIGHT), 'white') draw = ImageDraw.Draw(img) - font = ImageFont.truetype(P('fonts/liberation/LiberationSerif-Bold.ttf'), 48) + try: + font = ImageFont.truetype(font_path, 48) + except: + font = ImageFont.truetype(default_font, 48) text = self.get_masthead_title().encode('utf-8') width, height = draw.textsize(text, font=font) left = max(int((self.MI_WIDTH - width)/2.), 0)