Fix #1047426 (Missing translation strings)

This commit is contained in:
Kovid Goyal 2012-09-08 17:09:31 +05:30
commit 4a419d2d1d
4 changed files with 332 additions and 406 deletions

View File

@ -87,7 +87,7 @@ class PluginWidget(QWidget,Ui_Form):
option_fields += zip(['exclusion_rules_tw'], option_fields += zip(['exclusion_rules_tw'],
[{'ordinal':0, [{'ordinal':0,
'enabled':True, 'enabled':True,
'name':'Catalogs', 'name':_('Catalogs'),
'field':'Tags', 'field':'Tags',
'pattern':'Catalog'},], 'pattern':'Catalog'},],
['table_widget']) ['table_widget'])
@ -96,13 +96,13 @@ class PluginWidget(QWidget,Ui_Form):
option_fields += zip(['prefix_rules_tw','prefix_rules_tw'], option_fields += zip(['prefix_rules_tw','prefix_rules_tw'],
[{'ordinal':0, [{'ordinal':0,
'enabled':True, 'enabled':True,
'name':'Read book', 'name':_('Read book'),
'field':'Tags', 'field':'Tags',
'pattern':'+', 'pattern':'+',
'prefix':u'\u2713'}, 'prefix':u'\u2713'},
{'ordinal':1, {'ordinal':1,
'enabled':True, 'enabled':True,
'name':'Wishlist item', 'name':_('Wishlist item'),
'field':'Tags', 'field':'Tags',
'pattern':'Wishlist', 'pattern':'Wishlist',
'prefix':u'\u00d7'},], 'prefix':u'\u00d7'},],
@ -612,7 +612,7 @@ class GenericRulesTable(QTableWidget):
first_rule_name = unicode(self.cellWidget(first-1,self.COLUMNS['NAME']['ordinal']).text()).strip() first_rule_name = unicode(self.cellWidget(first-1,self.COLUMNS['NAME']['ordinal']).text()).strip()
message = _("Are you sure you want to delete '%s'?") % (first_rule_name) message = _("Are you sure you want to delete '%s'?") % (first_rule_name)
if len(rows) > 1: if len(rows) > 1:
message = _('Are you sure you want to delete rules #%d-%d?') % (first, last) message = _('Are you sure you want to delete rules #%(first)d-%(last)d?') % dict(first=first, last=last)
if not question_dialog(self, _('Delete Rule'), message, show_copy_button=False): if not question_dialog(self, _('Delete Rule'), message, show_copy_button=False):
return return
first_sel_row = self.currentRow() first_sel_row = self.currentRow()

View File

@ -59,7 +59,7 @@ class EPUB_MOBI(CatalogPlugin):
"Applies to: AZW3, ePub, MOBI output formats")), "Applies to: AZW3, ePub, MOBI output formats")),
Option('--exclusion-rules', Option('--exclusion-rules',
default="(('Excluded tags','Tags','Catalog'),)", default="(('Catalogs','Tags','Catalog'),)",
dest='exclusion_rules', dest='exclusion_rules',
action=None, action=None,
help=_("Specifies the rules used to exclude books from the generated catalog.\n" help=_("Specifies the rules used to exclude books from the generated catalog.\n"
@ -139,7 +139,7 @@ class EPUB_MOBI(CatalogPlugin):
"Default: '%default'\n" "Default: '%default'\n"
"Applies to: AZW3, ePub, MOBI output formats")), "Applies to: AZW3, ePub, MOBI output formats")),
Option('--prefix-rules', Option('--prefix-rules',
default="(('Read books','tags','+','\u2713'),('Wishlist items','tags','Wishlist','\u00d7'))", default="(('Read books','tags','+','\u2713'),('Wishlist item','tags','Wishlist','\u00d7'))",
dest='prefix_rules', dest='prefix_rules',
action=None, action=None,
help=_("Specifies the rules used to include prefixes indicating read books, wishlist items and other user-specified prefixes.\n" help=_("Specifies the rules used to include prefixes indicating read books, wishlist items and other user-specified prefixes.\n"
@ -412,10 +412,15 @@ class EPUB_MOBI(CatalogPlugin):
pass pass
if GENERATE_DEBUG_EPUB: if GENERATE_DEBUG_EPUB:
from calibre.ebooks.epub import initialize_container
from calibre.ebooks.tweak import zip_rebuilder from calibre.ebooks.tweak import zip_rebuilder
from calibre.utils.zipfile import ZipFile
input_path = os.path.join(catalog_debug_path,'input') input_path = os.path.join(catalog_debug_path,'input')
shutil.copy(P('catalog/mimetype'),input_path) epub_shell = os.path.join(catalog_debug_path,'epub_shell.zip')
shutil.copytree(P('catalog/META-INF'),os.path.join(input_path,'META-INF')) initialize_container(epub_shell, opf_name='content.opf')
with ZipFile(epub_shell, 'r') as zf:
zf.extractall(path=input_path)
os.remove(epub_shell)
zip_rebuilder(input_path, os.path.join(catalog_debug_path,'input.epub')) zip_rebuilder(input_path, os.path.join(catalog_debug_path,'input.epub'))
# returns to gui2.actions.catalog:catalog_generated() # returns to gui2.actions.catalog:catalog_generated()

View File

@ -5,6 +5,7 @@ __copyright__ = '2010, Greg Riker'
import datetime, htmlentitydefs, os, re, shutil, unicodedata, zlib import datetime, htmlentitydefs, os, re, shutil, unicodedata, zlib
from copy import deepcopy from copy import deepcopy
from operator import itemgetter
from xml.sax.saxutils import escape from xml.sax.saxutils import escape
from calibre import (prepare_string_for_xml, strftime, force_unicode) from calibre import (prepare_string_for_xml, strftime, force_unicode)
@ -54,214 +55,95 @@ class CatalogBuilder(object):
# title dc:title in OPF metadata, NCX periodical # title dc:title in OPF metadata, NCX periodical
# verbosity level of diagnostic printout # verbosity level of diagnostic printout
""" property decorators for attributes """ ''' device-specific symbol (default empty star) '''
if True: @property
def SYMBOL_EMPTY_RATING(self):
return self.output_profile.empty_ratings_char
''' device-specific symbol (default filled star) '''
@property
def SYMBOL_FULL_RATING(self):
return self.output_profile.ratings_char
''' device-specific symbol for reading progress '''
@property
def SYMBOL_PROGRESS_READ(self):
psr = '+'
if self.generate_for_kindle:
psr = '▪'
return psr
''' device-specific symbol for reading progress '''
@property
def SYMBOL_PROGRESS_UNREAD(self):
psu = '-'
if self.generate_for_kindle:
psu = '▫'
return psu
''' device-specific symbol for reading progress '''
@property
def SYMBOL_READING(self):
if self.generate_for_kindle:
return self.format_prefix('▷')
else:
return self.format_prefix(' ')
''' directory to store cached thumbs '''
@property
def cache_dir(self):
return self.__cache_dir
''' temp dir to store generated catalog '''
@property
def catalog_path(self):
return self.__catalog_path
''' content dir in generated catalog '''
@property
def content_dir(self):
return self.__content_dir
''' active database '''
@property
def db(self):
return self.__db
''' tags to exclude as genres '''
@property
def excluded_tags(self):
return self.__excluded_tags
''' True if generating for Kindle in MOBI format '''
@property
def generate_for_kindle(self):
return self.__generate_for_kindle
''' True if connected Kindle and generating for Kindle '''
@property
def generate_recently_read(self):
return self.__generate_recently_read
''' additional field to include before/after comments '''
@property
def merge_comments_rule(self):
return self.__merge_comments_rule
''' opts passed from gui2.catalog.catalog_epub_mobi.py '''
@property
def opts(self):
return self.__opts
''' output_profile declares special symbols '''
@property
def output_profile(self):
return self.__output_profile
''' catalog??? device??? '''
@property
def plugin(self):
return self.__plugin
''' Progress Reporter for Jobs '''
@property
def reporter(self):
return self.__reporter
''' stylesheet to include with catalog '''
@property
def stylesheet(self):
return self.__stylesheet
''' device-specific symbol (default empty star) '''
@property
def SYMBOL_EMPTY_RATING(self):
return self.output_profile.empty_ratings_char
''' device-specific symbol (default filled star) '''
@property
def SYMBOL_FULL_RATING(self):
return self.output_profile.ratings_char
''' device-specific symbol for reading progress '''
@property
def SYMBOL_PROGRESS_READ(self):
psr = '+'
if self.generate_for_kindle:
psr = '▪'
return psr
''' device-specific symbol for reading progress '''
@property
def SYMBOL_PROGRESS_UNREAD(self):
psu = '-'
if self.generate_for_kindle:
psu = '▫'
return psu
''' device-specific symbol for reading progress '''
@property
def SYMBOL_READING(self):
if self.generate_for_kindle:
return self.format_prefix('▷')
else:
return self.format_prefix(' ')
''' full path to thumbs archive '''
@property
def thumbs_path(self):
return self.__thumbs_path
''' switch controlling format of series books in Titles section '''
@property
def use_series_prefix_in_titles_section(self):
return self.__use_series_prefix_in_titles_section
def __init__(self, db, _opts, plugin, def __init__(self, db, _opts, plugin,
report_progress=DummyReporter(), report_progress=DummyReporter(),
stylesheet="content/stylesheet.css", stylesheet="content/stylesheet.css",
init_resources=True): init_resources=True):
self.__db = db self.db = db
self.__opts = _opts self.opts = _opts
self.__plugin = plugin self.plugin = plugin
self.__reporter = report_progress self.reporter = report_progress
self.__stylesheet = stylesheet self.stylesheet = stylesheet
self.__cache_dir = os.path.join(config_dir, 'caches', 'catalog') self.cache_dir = os.path.join(config_dir, 'caches', 'catalog')
self.__catalog_path = PersistentTemporaryDirectory("_epub_mobi_catalog", prefix='') self.catalog_path = PersistentTemporaryDirectory("_epub_mobi_catalog", prefix='')
self.__generate_for_kindle = True if (_opts.fmt == 'mobi' and self.excluded_tags = self.get_excluded_tags()
self.generate_for_kindle = True if (_opts.fmt == 'mobi' and
_opts.output_profile and _opts.output_profile and
_opts.output_profile.startswith("kindle")) else False _opts.output_profile.startswith("kindle")) else False
''' list of unique authors '''
self.authors = None self.authors = None
''' dict of bookmarked books '''
self.bookmarked_books = None self.bookmarked_books = None
''' list of bookmarked books, sorted by date read '''
self.bookmarked_books_by_date_read = None self.bookmarked_books_by_date_read = None
''' list of books, sorted by author '''
self.books_by_author = None self.books_by_author = None
''' list of books, grouped by date range (30 days) '''
self.books_by_date_range = None self.books_by_date_range = None
''' list of books, by date added reverse (most recent first) '''
self.books_by_month = None self.books_by_month = None
''' list of books in series '''
self.books_by_series = None self.books_by_series = None
''' list of books, sorted by title '''
self.books_by_title = None self.books_by_title = None
''' list of books in series, without series prefix '''
self.books_by_title_no_series_prefix = None self.books_by_title_no_series_prefix = None
self.__content_dir = os.path.join(self.catalog_path, "content") self.books_to_catalog = None
''' track Job progress ''' self.content_dir = os.path.join(self.catalog_path, "content")
self.current_step = 0.0 self.current_step = 0.0
''' cumulative error messages to report at conclusion '''
self.error = [] self.error = []
self.__excluded_tags = self.get_excluded_tags() self.generate_recently_read = True if (_opts.generate_recently_added and
self.__generate_recently_read = True if (_opts.generate_recently_added and _opts.connected_kindle and
_opts.connected_kindle and self.generate_for_kindle) else False
self.generate_for_kindle) else False
''' list of dicts with books by genre '''
self.genres = [] self.genres = []
''' dict of enabled genre tags '''
self.genre_tags_dict = None self.genre_tags_dict = None
''' Author, Title, Series sections '''
self.html_filelist_1 = [] self.html_filelist_1 = []
''' Date Added, Date Read '''
self.html_filelist_2 = [] self.html_filelist_2 = []
self.__merge_comments_rule = dict(zip(['field','position','hr'],_opts.merge_comments_rule.split(':'))) self.merge_comments_rule = dict(zip(['field','position','hr'],
''' cumulative HTML for NCX file ''' _opts.merge_comments_rule.split(':')))
self.ncx_soup = None self.ncx_soup = None
self.__output_profile = None self.output_profile = None
self.__output_profile = self.get_output_profile(_opts) self.output_profile = self.get_output_profile(_opts)
''' playOrder value for building NCX '''
self.play_order = 1 self.play_order = 1
''' dict of prefix rules '''
self.prefix_rules = self.get_prefix_rules() self.prefix_rules = self.get_prefix_rules()
''' used with ProgressReporter() '''
self.progress_int = 0.0 self.progress_int = 0.0
''' used with ProgressReporter() '''
self.progress_string = '' self.progress_string = ''
self.thumb_height = 0
self.__thumb_height = 0 self.thumb_width = 0
self.__thumb_width = 0
''' list of generated thumbs '''
self.thumbs = None self.thumbs = None
self.__thumbs_path = os.path.join(self.cache_dir, "thumbs.zip") self.thumbs_path = os.path.join(self.cache_dir, "thumbs.zip")
''' used with ProgressReporter() '''
self.total_steps = 6.0 self.total_steps = 6.0
self.__use_series_prefix_in_titles_section = False self.use_series_prefix_in_titles_section = False
self.books_to_catalog = self.fetch_books_to_catalog()
self.compute_total_steps() self.compute_total_steps()
self.calculate_thumbnail_dimensions() self.calculate_thumbnail_dimensions()
self.confirm_thumbs_archive() self.confirm_thumbs_archive()
@ -343,6 +225,15 @@ class CatalogBuilder(object):
series_index) series_index)
return key return key
def _kf_books_by_series_sorter(self, book):
index = book['series_index']
integer = int(index)
fraction = index-integer
series_index = '%04d%s' % (integer, str('%0.4f' % fraction).lstrip('0'))
key = '%s %s' % (self.generate_sort_title(book['series']),
series_index)
return key
""" Methods """ """ Methods """
def build_sources(self): def build_sources(self):
@ -614,7 +505,7 @@ class CatalogBuilder(object):
annoyance for EPUB. annoyance for EPUB.
Inputs: Inputs:
self.books_by_title (list): list of books to catalog self.books_to_catalog (list): list of books to catalog
Output: Output:
self.books_by_author (list): sorted by author self.books_by_author (list): sorted by author
@ -623,7 +514,7 @@ class CatalogBuilder(object):
AuthorSortMismatchException: author_sort mismatch detected AuthorSortMismatchException: author_sort mismatch detected
""" """
self.books_by_author = sorted(list(self.books_by_title), key=self._kf_books_by_author_sorter_author) self.books_by_author = sorted(list(self.books_to_catalog), key=self._kf_books_by_author_sorter_author)
authors = [(record['author'], record['author_sort']) for record in self.books_by_author] authors = [(record['author'], record['author_sort']) for record in self.books_by_author]
current_author = authors[0] current_author = authors[0]
for (i,author) in enumerate(authors): for (i,author) in enumerate(authors):
@ -671,7 +562,7 @@ class CatalogBuilder(object):
None: no match None: no match
""" """
def _log_prefix_rule_match_info(rule, record): def _log_prefix_rule_match_info(rule, record):
self.opts.log.info(" %s '%s' by %s (Prefix rule '%s')" % self.opts.log.info(" %s '%s' by %s (Prefix rule '%s')" %
(rule['prefix'],record['title'], (rule['prefix'],record['title'],
record['authors'][0], rule['name'])) record['authors'][0], rule['name']))
@ -770,7 +661,7 @@ class CatalogBuilder(object):
to self.authors. to self.authors.
Inputs: Inputs:
self.books_by_title (list): database, sorted by title self.books_to_catalog (list): database, sorted by title
Outputs: Outputs:
books_by_author: database, sorted by author books_by_author: database, sorted by author
@ -790,7 +681,7 @@ class CatalogBuilder(object):
# Determine the longest author_sort length before sorting # Determine the longest author_sort length before sorting
asl = [i['author_sort'] for i in self.books_by_author] asl = [i['author_sort'] for i in self.books_by_author]
las = max(asl, key=len) las = max(asl, key=len)
self.books_by_author = sorted(self.books_by_author, self.books_by_author = sorted(self.books_to_catalog,
key=lambda x: sort_key(self._kf_books_by_author_sorter_author_sort(x, len(las)))) key=lambda x: sort_key(self._kf_books_by_author_sorter_author_sort(x, len(las))))
if self.DEBUG and self.opts.verbose: if self.DEBUG and self.opts.verbose:
@ -843,9 +734,42 @@ class CatalogBuilder(object):
return True return True
def fetch_books_by_title(self): def fetch_books_by_title(self):
""" Populate self.books_by_title from database """ Generate a list of books sorted by title.
Create self.books_by_title from filtered database. Sort the database by title.
Inputs:
self.books_to_catalog (list): database
Outputs:
books_by_title: database, sorted by title
Return:
True: no errors
False: author_sort mismatch detected while building MOBI
"""
self.update_progress_full_step(_("Sorting titles"))
# Re-sort based on title_sort
if len(self.books_to_catalog):
self.books_by_title = sorted(self.books_to_catalog, key=lambda x: sort_key(x['title_sort'].upper()))
if self.DEBUG and self.opts.verbose:
self.opts.log.info("fetch_books_by_title(): %d books" % len(self.books_by_title))
self.opts.log.info(" %-40s %-40s" % ('title', 'title_sort'))
for title in self.books_by_title:
self.opts.log.info((u" %-40s %-40s" % (title['title'][0:40],
title['title_sort'][0:40])).encode('utf-8'))
else:
error_msg = _("No books to catalog.\nCheck 'Excluded books' rules in E-book options.\n")
self.opts.log.error('*** ' + error_msg + ' ***')
self.error.append(_('No books available to include in catalog'))
self.error.append(error_msg)
raise EmptyCatalogException, error_msg
def fetch_books_to_catalog(self):
""" Populate self.books_to_catalog from database
Create self.books_to_catalog from filtered database.
Keys: Keys:
authors massaged authors massaged
author_sort record['author_sort'] or computed author_sort record['author_sort'] or computed
@ -871,7 +795,7 @@ class CatalogBuilder(object):
data (list): filtered list of book metadata dicts data (list): filtered list of book metadata dicts
Outputs: Outputs:
(list) books_by_title (list) books_to_catalog
Returns: Returns:
True: Successful True: Successful
@ -953,9 +877,11 @@ class CatalogBuilder(object):
this_title['prefix'] = self.discover_prefix(record) this_title['prefix'] = self.discover_prefix(record)
this_title['tags'] = []
if record['tags']: if record['tags']:
this_title['tags'] = self.filter_excluded_genres(record['tags'], this_title['tags'] = self.filter_excluded_genres(record['tags'],
self.opts.exclude_genre) self.opts.exclude_genre)
if record['formats']: if record['formats']:
formats = [] formats = []
for format in record['formats']: for format in record['formats']:
@ -980,7 +906,6 @@ class CatalogBuilder(object):
return this_title return this_title
# Entry point # Entry point
self.update_progress_full_step(_("Fetching database"))
self.opts.sort_by = 'title' self.opts.sort_by = 'title'
search_phrase = '' search_phrase = ''
@ -1003,28 +928,15 @@ class CatalogBuilder(object):
data = self.plugin.search_sort_db(self.db, self.opts) data = self.plugin.search_sort_db(self.db, self.opts)
data = self.process_exclusions(data) data = self.process_exclusions(data)
if self.opts.verbose and self.prefix_rules:
self.opts.log.info(" Added prefixes:")
# Populate this_title{} from data[{},{}] # Populate this_title{} from data[{},{}]
titles = [] titles = []
for record in data: for record in data:
this_title = _populate_title(record) this_title = _populate_title(record)
titles.append(this_title) titles.append(this_title)
return titles
# Re-sort based on title_sort
if len(titles):
self.books_by_title = sorted(titles, key=lambda x: sort_key(x['title_sort'].upper()))
if self.DEBUG and self.opts.verbose:
self.opts.log.info("fetch_books_by_title(): %d books" % len(self.books_by_title))
self.opts.log.info(" %-40s %-40s" % ('title', 'title_sort'))
for title in self.books_by_title:
self.opts.log.info((u" %-40s %-40s" % (title['title'][0:40],
title['title_sort'][0:40])).encode('utf-8'))
else:
error_msg = _("No books to catalog.\nCheck 'Excluded books' rules in E-book options.\n")
self.opts.log.error('*** ' + error_msg + ' ***')
self.error.append(_('No books available to include in catalog'))
self.error.append(error_msg)
raise EmptyCatalogException, error_msg
def fetch_bookmarks(self): def fetch_bookmarks(self):
""" Interrogate connected Kindle for bookmarks. """ Interrogate connected Kindle for bookmarks.
@ -1104,7 +1016,7 @@ class CatalogBuilder(object):
d.initialize(self.opts.connected_device['save_template']) d.initialize(self.opts.connected_device['save_template'])
bookmarks = {} bookmarks = {}
for book in self.books_by_title: for book in self.books_to_catalog:
if 'formats' in book: if 'formats' in book:
path_map = {} path_map = {}
id = book['id'] id = book['id']
@ -1148,7 +1060,7 @@ class CatalogBuilder(object):
genre_tags_dict (dict): dict of filtered, normalized tags in data set genre_tags_dict (dict): dict of filtered, normalized tags in data set
""" """
def _format_tag_list(tags, indent=5, line_break=70, header='Tag list'): def _format_tag_list(tags, indent=2, line_break=70, header='Tag list'):
def _next_tag(sorted_tags): def _next_tag(sorted_tags):
for (i, tag) in enumerate(sorted_tags): for (i, tag) in enumerate(sorted_tags):
if i < len(tags) - 1: if i < len(tags) - 1:
@ -1541,7 +1453,7 @@ class CatalogBuilder(object):
def generate_html_by_date_added(self): def generate_html_by_date_added(self):
""" Generate content/ByDateAdded.html. """ Generate content/ByDateAdded.html.
Loop through self.books_by_title sorted by reverse date, generate HTML. Loop through self.books_to_catalog sorted by reverse date, generate HTML.
Input: Input:
books_by_title (list): books, sorted by title books_by_title (list): books, sorted by title
@ -1735,10 +1647,10 @@ class CatalogBuilder(object):
# >>> Books by date range <<< # >>> Books by date range <<<
if self.use_series_prefix_in_titles_section: if self.use_series_prefix_in_titles_section:
self.books_by_date_range = sorted(self.books_by_title, self.books_by_date_range = sorted(self.books_to_catalog,
key=lambda x:(x['timestamp'], x['timestamp']),reverse=True) key=lambda x:(x['timestamp'], x['timestamp']),reverse=True)
else: else:
nspt = deepcopy(self.books_by_title) nspt = deepcopy(self.books_to_catalog)
self.books_by_date_range = sorted(nspt, key=lambda x:(x['timestamp'], x['timestamp']),reverse=True) self.books_by_date_range = sorted(nspt, key=lambda x:(x['timestamp'], x['timestamp']),reverse=True)
date_range_list = [] date_range_list = []
@ -1763,7 +1675,7 @@ class CatalogBuilder(object):
# >>>> Books by month <<<< # >>>> Books by month <<<<
# Sort titles case-insensitive for by month using series prefix # Sort titles case-insensitive for by month using series prefix
self.books_by_month = sorted(self.books_by_title, self.books_by_month = sorted(self.books_to_catalog,
key=lambda x:(x['timestamp'], x['timestamp']),reverse=True) key=lambda x:(x['timestamp'], x['timestamp']),reverse=True)
# Loop through books by date # Loop through books by date
@ -2026,12 +1938,12 @@ class CatalogBuilder(object):
if self.opts.verbose: if self.opts.verbose:
if len(genre_list): if len(genre_list):
self.opts.log.info(" Genre summary: %d active genre tags used in generating catalog with %d titles" % self.opts.log.info(" Genre summary: %d active genre tags used in generating catalog with %d titles" %
(len(genre_list), len(self.books_by_title))) (len(genre_list), len(self.books_to_catalog)))
for genre in genre_list: for genre in genre_list:
for key in genre: for key in genre:
self.opts.log.info(" %s: %d %s" % (self.get_friendly_genre_tag(key), self.opts.log.info(" %s: %d %s" % (self.get_friendly_genre_tag(key),
len(genre[key]), len(genre[key]),
'titles' if len(genre[key]) > 1 else 'title')) 'titles' if len(genre[key]) > 1 else 'title'))
@ -2226,48 +2138,28 @@ class CatalogBuilder(object):
Output: Output:
content/BySeries.html (file) content/BySeries.html (file)
To do:
self.books_by_series = [i for i in self.books_by_title if i['series']]
""" """
friendly_name = _("Series") friendly_name = _("Series")
self.update_progress_full_step("%s HTML" % friendly_name) self.update_progress_full_step("%s HTML" % friendly_name)
self.opts.sort_by = 'series' self.opts.sort_by = 'series'
# Merge self.excluded_tags with opts.search_text # *** Convert the existing database, resort by series/index ***
# Updated to use exact match syntax self.books_by_series = [i for i in self.books_to_catalog if i['series']]
self.books_by_series = sorted(self.books_by_series, key=lambda x: sort_key(self._kf_books_by_series_sorter(x)))
search_phrase = 'series:true '
if self.excluded_tags:
search_terms = []
for tag in self.excluded_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:
self.opts.search_text = search_phrase
else:
if self.opts.search_text:
self.opts.search_text += " " + search_phrase
else:
self.opts.search_text = search_phrase
# Fetch the database as a dictionary
data = self.plugin.search_sort_db(self.db, self.opts)
# Remove exclusions
self.books_by_series = self.process_exclusions(data, log_exclusion=False)
if not self.books_by_series: if not self.books_by_series:
self.opts.generate_series = False self.opts.generate_series = False
self.opts.log(" no series found in selected books, cancelling series generation") self.opts.log(" no series found in selected books, skipping Series section")
return return
# Generate series_sort # Generate series_sort
for book in self.books_by_series: for book in self.books_by_series:
book['series_sort'] = self.generate_sort_title(book['series']) book['series_sort'] = self.generate_sort_title(book['series'])
# Establish initial letter equivalencies
sort_equivalents = self.establish_equivalencies(self.books_by_series, key='series_sort')
soup = self.generate_html_empty_header(friendly_name) soup = self.generate_html_empty_header(friendly_name)
body = soup.find('body') body = soup.find('body')
@ -2277,9 +2169,6 @@ class CatalogBuilder(object):
current_letter = "" current_letter = ""
current_series = None current_series = None
# Establish initial letter equivalencies
sort_equivalents = self.establish_equivalencies(self.books_by_series, key='series_sort')
# Loop through books_by_series # Loop through books_by_series
series_count = 0 series_count = 0
for idx, book in enumerate(self.books_by_series): for idx, book in enumerate(self.books_by_series):
@ -2335,11 +2224,6 @@ class CatalogBuilder(object):
# Use series, series index if avail else just title # Use series, series index if avail else just title
#aTag.insert(0,'%d. %s &middot; %s' % (book['series_index'],escape(book['title']), ' & '.join(book['authors']))) #aTag.insert(0,'%d. %s &middot; %s' % (book['series_index'],escape(book['title']), ' & '.join(book['authors'])))
if is_date_undefined(book['pubdate']):
book['date'] = None
else:
book['date'] = strftime(u'%B %Y', book['pubdate'].timetuple())
args = self.generate_format_args(book) args = self.generate_format_args(book)
formatted_title = self.by_series_title_template.format(**args).rstrip() formatted_title = self.by_series_title_template.format(**args).rstrip()
aTag.insert(0,NavigableString(escape(formatted_title))) aTag.insert(0,NavigableString(escape(formatted_title)))
@ -2438,7 +2322,7 @@ class CatalogBuilder(object):
# Re-sort title list without leading series/series_index # Re-sort title list without leading series/series_index
# Incoming title <series> <series_index>: <title> # Incoming title <series> <series_index>: <title>
if not self.use_series_prefix_in_titles_section: if not self.use_series_prefix_in_titles_section:
nspt = deepcopy(self.books_by_title) nspt = deepcopy(self.books_to_catalog)
nspt = sorted(nspt, key=lambda x: sort_key(x['title_sort'].upper())) nspt = sorted(nspt, key=lambda x: sort_key(x['title_sort'].upper()))
self.books_by_title_no_series_prefix = nspt self.books_by_title_no_series_prefix = nspt
@ -3153,8 +3037,12 @@ class CatalogBuilder(object):
self.play_order += 1 self.play_order += 1
navLabelTag = Tag(soup, 'navLabel') navLabelTag = Tag(soup, 'navLabel')
textTag = Tag(soup, 'text') textTag = Tag(soup, 'text')
textTag.insert(0, NavigableString(_(u"Series beginning with %s") % \ if len(title_letters[i])>1:
(title_letters[i] if len(title_letters[i])>1 else "'" + title_letters[i] + "'"))) fmt_string = _(u"Series beginning with %s")
else:
fmt_string = _(u"Series beginning with '%s'")
textTag.insert(0, NavigableString(fmt_string %
(title_letters[i] if len(title_letters[i])>1 else title_letters[i])))
navLabelTag.insert(0, textTag) navLabelTag.insert(0, textTag)
navPointByLetterTag.insert(0,navLabelTag) navPointByLetterTag.insert(0,navLabelTag)
contentTag = Tag(soup, 'content') contentTag = Tag(soup, 'content')
@ -3274,8 +3162,12 @@ class CatalogBuilder(object):
self.play_order += 1 self.play_order += 1
navLabelTag = Tag(soup, 'navLabel') navLabelTag = Tag(soup, 'navLabel')
textTag = Tag(soup, 'text') textTag = Tag(soup, 'text')
textTag.insert(0, NavigableString(_(u"Titles beginning with %s") % \ if len(title_letters[i])>1:
(title_letters[i] if len(title_letters[i])>1 else "'" + title_letters[i] + "'"))) fmt_string = _(u"Titles beginning with %s")
else:
fmt_string = _(u"Titles beginning with '%s'")
textTag.insert(0, NavigableString(fmt_string %
(title_letters[i] if len(title_letters[i])>1 else title_letters[i])))
navLabelTag.insert(0, textTag) navLabelTag.insert(0, textTag)
navPointByLetterTag.insert(0,navLabelTag) navPointByLetterTag.insert(0,navLabelTag)
contentTag = Tag(soup, 'content') contentTag = Tag(soup, 'content')
@ -3385,7 +3277,11 @@ class CatalogBuilder(object):
self.play_order += 1 self.play_order += 1
navLabelTag = Tag(soup, 'navLabel') navLabelTag = Tag(soup, 'navLabel')
textTag = Tag(soup, 'text') textTag = Tag(soup, 'text')
textTag.insert(0, NavigableString(_("Authors beginning with '%s'") % (authors_by_letter[1]))) if len(authors_by_letter[1])>1:
fmt_string = _(u"Authors beginning with %s")
else:
fmt_string = _(u"Authors beginning with '%s'")
textTag.insert(0, NavigableString(fmt_string % (authors_by_letter[1])))
navLabelTag.insert(0, textTag) navLabelTag.insert(0, textTag)
navPointByLetterTag.insert(0,navLabelTag) navPointByLetterTag.insert(0,navLabelTag)
contentTag = Tag(soup, 'content') contentTag = Tag(soup, 'content')
@ -4339,7 +4235,7 @@ class CatalogBuilder(object):
# Report excluded books # Report excluded books
if self.opts.verbose and excluded_tags: if self.opts.verbose and excluded_tags:
self.opts.log.info(" Excluded books by Tags:") self.opts.log.info(" Excluded books:")
data = self.db.get_data_as_dict(ids=self.opts.ids) data = self.db.get_data_as_dict(ids=self.opts.ids)
for record in data: for record in data:
matched = list(set(record['tags']) & set(excluded_tags)) matched = list(set(record['tags']) & set(excluded_tags))
@ -4632,7 +4528,7 @@ class CatalogBuilder(object):
normalized += c normalized += c
return normalized return normalized
def process_exclusions(self, data_set, log_exclusion=True): def process_exclusions(self, data_set):
""" Filter data_set based on exclusion_rules. """ Filter data_set based on exclusion_rules.
Compare each book in data_set to each exclusion_rule. Remove Compare each book in data_set to each exclusion_rule. Remove
@ -4666,16 +4562,18 @@ class CatalogBuilder(object):
matched = re.search(pat, unicode(field_contents), matched = re.search(pat, unicode(field_contents),
re.IGNORECASE) re.IGNORECASE)
if matched is not None: if matched is not None:
if self.opts.verbose and log_exclusion: if self.opts.verbose:
field_md = self.db.metadata_for_field(field) field_md = self.db.metadata_for_field(field)
for rule in self.opts.exclusion_rules: for rule in self.opts.exclusion_rules:
if rule[1] == '#%s' % field_md['label']: if rule[1] == '#%s' % field_md['label']:
self.opts.log.info(" - '%s' by %s (Exclusion rule '%s')" % self.opts.log.info(" - '%s' by %s (Exclusion rule '%s')" %
(record['title'], record['authors'][0], rule[0])) (record['title'], record['authors'][0], rule[0]))
exclusion_set.append(record) exclusion_set.append(record)
if record in filtered_data_set: if record in filtered_data_set:
filtered_data_set.remove(record) filtered_data_set.remove(record)
break break
else:
filtered_data_set.append(record)
else: else:
if (record not in filtered_data_set and if (record not in filtered_data_set and
record not in exclusion_set): record not in exclusion_set):

View File

@ -5,8 +5,8 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: calibre 0.8.68\n" "Project-Id-Version: calibre 0.8.68\n"
"POT-Creation-Date: 2012-09-07 08:49+IST\n" "POT-Creation-Date: 2012-09-08 17:09+IST\n"
"PO-Revision-Date: 2012-09-07 08:49+IST\n" "PO-Revision-Date: 2012-09-08 17:09+IST\n"
"Last-Translator: Automatically generated\n" "Last-Translator: Automatically generated\n"
"Language-Team: LANGUAGE\n" "Language-Team: LANGUAGE\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -131,8 +131,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/pdb/ztxt/writer.py:27 #: /home/kovid/work/calibre/src/calibre/ebooks/pdb/ztxt/writer.py:27
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:108 #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:108
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:109 #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:109
#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:426 #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:439
#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:434 #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:447
#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:166 #: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:166
#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:397 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:397
#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:400 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:400
@ -143,8 +143,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:124 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:124
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:143 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:143
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:145 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:145
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1366 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1367
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1369 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1370
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_empty_book.py:55 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_empty_book.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_empty_book.py:60 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_empty_book.py:60
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:128
@ -173,12 +173,12 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/database2.py:585 #: /home/kovid/work/calibre/src/calibre/library/database2.py:585
#: /home/kovid/work/calibre/src/calibre/library/database2.py:593 #: /home/kovid/work/calibre/src/calibre/library/database2.py:593
#: /home/kovid/work/calibre/src/calibre/library/database2.py:604 #: /home/kovid/work/calibre/src/calibre/library/database2.py:604
#: /home/kovid/work/calibre/src/calibre/library/database2.py:2189 #: /home/kovid/work/calibre/src/calibre/library/database2.py:2192
#: /home/kovid/work/calibre/src/calibre/library/database2.py:2343 #: /home/kovid/work/calibre/src/calibre/library/database2.py:2346
#: /home/kovid/work/calibre/src/calibre/library/database2.py:2768 #: /home/kovid/work/calibre/src/calibre/library/database2.py:2771
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3415 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3418
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3417 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3420
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3554 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3557
#: /home/kovid/work/calibre/src/calibre/library/server/content.py:250 #: /home/kovid/work/calibre/src/calibre/library/server/content.py:250
#: /home/kovid/work/calibre/src/calibre/library/server/content.py:251 #: /home/kovid/work/calibre/src/calibre/library/server/content.py:251
#: /home/kovid/work/calibre/src/calibre/library/server/mobile.py:247 #: /home/kovid/work/calibre/src/calibre/library/server/mobile.py:247
@ -1034,14 +1034,14 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1199 #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1199
#: /home/kovid/work/calibre/src/calibre/library/database2.py:370 #: /home/kovid/work/calibre/src/calibre/library/database2.py:370
#: /home/kovid/work/calibre/src/calibre/library/database2.py:383 #: /home/kovid/work/calibre/src/calibre/library/database2.py:383
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3272 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3275
#: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:187 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:187
msgid "News" msgid "News"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2770 #: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2770
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3228 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3231
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3246 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3249
msgid "Catalog" msgid "Catalog"
msgstr "" msgstr ""
@ -3352,8 +3352,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:67 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:67
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:70 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:163 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:163
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:401 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:292
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2232 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2142
#: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:140 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:140
msgid "Series" msgid "Series"
msgid_plural "Series" msgid_plural "Series"
@ -3880,7 +3880,17 @@ msgstr ""
msgid "Show this confirmation again" msgid "Show this confirmation again"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:546 #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:332
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:134
msgid "Restart needed"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:334
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:741
msgid "Restart calibre now"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:559
msgid "Choose Files" msgid "Choose Files"
msgstr "" msgstr ""
@ -4112,7 +4122,7 @@ msgid "Merging user annotations into database"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:63 #: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:744 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:745
msgid "Fetch annotations (experimental)" msgid "Fetch annotations (experimental)"
msgstr "" msgstr ""
@ -4357,7 +4367,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:403 #: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:403
#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:197 #: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:197
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:933 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:934
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:1004 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:1004
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:114 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:114
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:128
@ -4590,14 +4600,14 @@ msgid "Main memory"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:239 #: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:239
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:669 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:670
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:678 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:679
msgid "Storage Card A" msgid "Storage Card A"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:240 #: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:240
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:671 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:672
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:680 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:681
msgid "Storage Card B" msgid "Storage Card B"
msgstr "" msgstr ""
@ -5373,7 +5383,7 @@ msgid "The specified directory could not be processed."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:274 #: /home/kovid/work/calibre/src/calibre/gui2/add.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1087 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1088
msgid "No books" msgid "No books"
msgstr "" msgstr ""
@ -5794,6 +5804,18 @@ msgstr ""
msgid "E-book options" msgid "E-book options"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:90
msgid "Catalogs"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:99
msgid "Read book"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:105
msgid "Wishlist item"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:133 #: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:133
#: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:769 #: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:769
msgid "any date" msgid "any date"
@ -5831,7 +5853,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:615 #: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:615
#, python-format #, python-format
msgid "Are you sure you want to delete rules #%d-%d?" msgid "Are you sure you want to delete rules #%(first)d-%(last)d?"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:616 #: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:616
@ -7685,226 +7707,222 @@ msgstr ""
msgid "tags to remove" msgid "tags to remove"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:50 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:51
#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:148 #: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:148
msgid "No details available." msgid "No details available."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:202 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:203
msgid "Device no longer connected." msgid "Device no longer connected."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:413 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:414
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/device_debug.py:27 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/device_debug.py:27
msgid "Debug device detection" msgid "Debug device detection"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:429 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:430
msgid "Get device information" msgid "Get device information"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:444 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:445
msgid "Get list of books on device" msgid "Get list of books on device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:451 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:452
msgid "Prepare files for transfer from device" msgid "Prepare files for transfer from device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:462 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:463
msgid "Get annotations from device" msgid "Get annotations from device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:474 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:475
msgid "Send metadata to device" msgid "Send metadata to device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:479 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:480
msgid "Send collections to device" msgid "Send collections to device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:529 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:530
#, python-format #, python-format
msgid "Upload %d books to device" msgid "Upload %d books to device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:545 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:546
msgid "Delete books from device" msgid "Delete books from device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:563 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:564
msgid "Download books from device" msgid "Download books from device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:573 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:574
msgid "View book on device" msgid "View book on device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:652 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:653
msgid "Set default send to device action" msgid "Set default send to device action"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:658 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:659
msgid "Send to main memory" msgid "Send to main memory"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:660 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:661
msgid "Send to storage card A" msgid "Send to storage card A"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:662 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:663
msgid "Send to storage card B" msgid "Send to storage card B"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:667 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:668
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:676 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:677
msgid "Main Memory" msgid "Main Memory"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:688 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:689
msgid "Send specific format to" msgid "Send specific format to"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:689 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:690
msgid "Send and delete from library" msgid "Send and delete from library"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:732 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:733
msgid "Eject device" msgid "Eject device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:813 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:814
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:71 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:71
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:332 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:332
#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:58 #: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:58
msgid "Error" msgid "Error"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:814 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:815
msgid "Error communicating with device" msgid "Error communicating with device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:843 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:844
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1416 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1417
#: /home/kovid/work/calibre/src/calibre/gui2/email.py:260 #: /home/kovid/work/calibre/src/calibre/gui2/email.py:260
msgid "No suitable formats" msgid "No suitable formats"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:859 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:860
msgid "Select folder to open as device" msgid "Select folder to open as device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:877 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:878
msgid "Running jobs" msgid "Running jobs"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:878 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:879
msgid "Cannot configure the device while there are running device jobs." msgid "Cannot configure the device while there are running device jobs."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:883 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:884
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:168 #: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:168
#, python-format #, python-format
msgid "Configure %s" msgid "Configure %s"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:898
msgid "Disconnect device"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:899 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:899
#, python-format #, python-format
msgid "Disconnect and re-connect the %s for your changes to be applied." msgid "Restart calibre for the changes to %s to be applied."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:939
msgid "Error talking to device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:940 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:940
msgid "Error talking to device"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:941
msgid "There was a temporary error talking to the device. Please unplug and reconnect the device or reboot." msgid "There was a temporary error talking to the device. Please unplug and reconnect the device or reboot."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:984 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:985
msgid "Device: " msgid "Device: "
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:986 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:987
msgid " detected." msgid " detected."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1088 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1089
msgid "selected to send" msgid "selected to send"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1095 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1096
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1125 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1126
msgid "No device" msgid "No device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1096 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1097
msgid "No device connected" msgid "No device connected"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1112 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1113
#, python-format #, python-format
msgid "%(num)i of %(total)i Books" msgid "%(num)i of %(total)i Books"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1116 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1117
#, python-format #, python-format
msgid "0 of %i Books" msgid "0 of %i Books"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1117 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1118
msgid "Choose format to send to device" msgid "Choose format to send to device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1126 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1127
msgid "Cannot send: No device is connected" msgid "Cannot send: No device is connected"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1129
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1133
msgid "No card"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1130 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1130
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1134 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1134
msgid "No card"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1131
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1135
msgid "Cannot send: Device has no storage card" msgid "Cannot send: Device has no storage card"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1195 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1196
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1278 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1279
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1410 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1411
msgid "Auto convert the following books before uploading to the device?" msgid "Auto convert the following books before uploading to the device?"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1224 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1225
msgid "Sending catalogs to device." msgid "Sending catalogs to device."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1323 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1324
msgid "Sending news to device." msgid "Sending news to device."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1377 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1378
msgid "Sending books to device." msgid "Sending books to device."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1417 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1418
msgid "Could not upload the following books to the device, as no suitable formats were found. Convert the book(s) to a format supported by your device first." msgid "Could not upload the following books to the device, as no suitable formats were found. Convert the book(s) to a format supported by your device first."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1490 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1491
msgid "No space on device" msgid "No space on device"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1491 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1492
msgid "<p>Cannot upload books to device there is no more free space available " msgid "<p>Cannot upload books to device there is no more free space available "
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1496 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1497
msgid "Incorrect destination" msgid "Incorrect destination"
msgstr "" msgstr ""
@ -9471,11 +9489,6 @@ msgstr ""
msgid "Plugin <b>{0}</b> successfully installed under <b> {1} plugins</b>. You may have to restart calibre for the plugin to take effect." msgid "Plugin <b>{0}</b> successfully installed under <b> {1} plugins</b>. You may have to restart calibre for the plugin to take effect."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:741
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:352
msgid "Restart calibre now"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:760 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:760
msgid "A problem occurred while installing this plugin. This plugin will now be uninstalled. Please post the error message in details below into the forum thread for this plugin and restart Calibre." msgid "A problem occurred while installing this plugin. This plugin will now be uninstalled. Please post the error message in details below into the forum thread for this plugin and restart Calibre."
msgstr "" msgstr ""
@ -9529,8 +9542,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/quickview.py:87 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/quickview.py:87
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories.py:60 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories.py:60
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:156 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:156
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:397 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:288
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:1342 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:1254
#: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:113 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:113
msgid "Authors" msgid "Authors"
msgstr "" msgstr ""
@ -13072,11 +13085,6 @@ msgstr ""
msgid "The changes you have made require calibre be restarted immediately. You will not be allowed to set any more preferences, until you restart." msgid "The changes you have made require calibre be restarted immediately. You will not be allowed to set any more preferences, until you restart."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:350
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:134
msgid "Restart needed"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:48 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:48
msgid "Source" msgid "Source"
msgstr "" msgstr ""
@ -14986,7 +14994,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/update.py:78 #: /home/kovid/work/calibre/src/calibre/gui2/update.py:78
#, python-format #, python-format
msgid "%(app)s has been updated to version <b>%(ver)s</b>. See the <a href=\"http://calibre-ebook.com/whats-new\">new features</a>." msgid "New version <b>%(ver)s</b> of %(app)s is available for download. See the <a href=\"http://calibre-ebook.com/whats-new\">new features</a>."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/update.py:84 #: /home/kovid/work/calibre/src/calibre/gui2/update.py:84
@ -16370,153 +16378,168 @@ msgid ""
"*** Adding 'By Authors' Section required for MOBI output ***" "*** Adding 'By Authors' Section required for MOBI output ***"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:46 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:47
msgid "Symbols" msgid "Symbols"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:382 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:273
msgid "No genres to catalog.\n" msgid "No genres to catalog.\n"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:384 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:275
msgid "Check 'Excluded genres' regex in E-book options.\n" msgid "Check 'Excluded genres' regex in E-book options.\n"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:386 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:277
msgid "No books available to catalog" msgid "No books available to catalog"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:399 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:290
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2429 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2313
msgid "Titles" msgid "Titles"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:403 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:294
msgid "Genres" msgid "Genres"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:405 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:296
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:1703 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:1615
msgid "Recently Added" msgid "Recently Added"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:407 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:298
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:1902 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:1814
msgid "Recently Read" msgid "Recently Read"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:409 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:300
msgid "Descriptions" msgid "Descriptions"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:634 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:525
msgid "<p>Inconsistent Author Sort values for Author<br/>" msgid "<p>Inconsistent Author Sort values for Author<br/>"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:651 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:542
msgid "Warning: Inconsistent Author Sort values for Author '{!s}':\n" msgid "Warning: Inconsistent Author Sort values for Author '{!s}':\n"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:785 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:676
msgid "Sorting database" msgid "Sorting database"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:983 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:751
msgid "Fetching database" msgid "Sorting titles"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:1023 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:763
msgid "" msgid ""
"No books to catalog.\n" "No books to catalog.\n"
"Check 'Excluded books' rules in E-book options.\n" "Check 'Excluded books' rules in E-book options.\n"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:1025 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:765
msgid "No books available to include in catalog" msgid "No books available to include in catalog"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:1983 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:1895
msgid "Genres HTML" msgid "Genres HTML"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2409 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2293
msgid "Titles HTML" msgid "Titles HTML"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2604 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2488
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2606 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2490
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2608 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2492
msgid "by " msgid "by "
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2745 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2629
msgid "Descriptions HTML" msgid "Descriptions HTML"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2749 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2633
msgid "Description HTML" msgid "Description HTML"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2884 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2768
msgid "NCX header" msgid "NCX header"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2959 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2843
msgid "NCX for Descriptions" msgid "NCX for Descriptions"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3080 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:2964
msgid "NCX for Series" msgid "NCX for Series"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3156 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3041
#, python-format #, python-format
msgid "Series beginning with %s" msgid "Series beginning with %s"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3199 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3043
#, python-format
msgid "Series beginning with '%s'"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3087
msgid "NCX for Titles" msgid "NCX for Titles"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3277 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3166
#, python-format #, python-format
msgid "Titles beginning with %s" msgid "Titles beginning with %s"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3318 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3168
#, python-format
msgid "Titles beginning with '%s'"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3210
msgid "NCX for Authors" msgid "NCX for Authors"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3388 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3281
#, python-format
msgid "Authors beginning with %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3283
#, python-format #, python-format
msgid "Authors beginning with '%s'" msgid "Authors beginning with '%s'"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3428 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3324
msgid "NCX for Recently Added" msgid "NCX for Recently Added"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3615 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3511
msgid "NCX for Recently Read" msgid "NCX for Recently Read"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3752 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3648
msgid "NCX for Genres" msgid "NCX for Genres"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3870 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:3766
msgid "Generating OPF" msgid "Generating OPF"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:4242 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:4138
msgid "Thumbnails" msgid "Thumbnails"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:4248 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:4144
msgid "Thumbnail" msgid "Thumbnail"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:4743 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:4641
msgid "Saving NCX" msgid "Saving NCX"
msgstr "" msgstr ""
@ -17107,17 +17130,17 @@ msgstr ""
msgid "creating custom column " msgid "creating custom column "
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3580 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3583
#, python-format #, python-format
msgid "<p>Migrating old database to ebook library in %s<br><center>" msgid "<p>Migrating old database to ebook library in %s<br><center>"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3609 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3612
#, python-format #, python-format
msgid "Copying <b>%s</b>" msgid "Copying <b>%s</b>"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3626 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3629
msgid "Compacting database" msgid "Compacting database"
msgstr "" msgstr ""