Disambiguate ambiguous transaltable strings

This commit is contained in:
Kovid Goyal 2011-07-10 13:09:11 -06:00
parent ac6594b79e
commit e17adec5e7
41 changed files with 439 additions and 417 deletions

View File

@ -446,7 +446,8 @@ class ITUNES(DriverBase):
} }
if self.report_progress is not None: if self.report_progress is not None:
self.report_progress((i+1)/book_count, _('%d of %d') % (i+1, book_count)) self.report_progress((i+1)/book_count,
_('%(num)d of %(tot)d') % dict(num=i+1, tot=book_count))
self._purge_orphans(library_books, cached_books) self._purge_orphans(library_books, cached_books)
elif iswindows: elif iswindows:
@ -485,7 +486,8 @@ class ITUNES(DriverBase):
if self.report_progress is not None: if self.report_progress is not None:
self.report_progress((i+1)/book_count, self.report_progress((i+1)/book_count,
_('%d of %d') % (i+1, book_count)) _('%(num)d of %(tot)d') % dict(num=i+1,
tot=book_count))
self._purge_orphans(library_books, cached_books) self._purge_orphans(library_books, cached_books)
finally: finally:
@ -1075,7 +1077,8 @@ class ITUNES(DriverBase):
# Report progress # Report progress
if self.report_progress is not None: if self.report_progress is not None:
self.report_progress((i+1)/file_count, _('%d of %d') % (i+1, file_count)) self.report_progress((i+1)/file_count,
_('%(num)d of %(tot)d') % dict(num=i+1, tot=file_count))
elif iswindows: elif iswindows:
try: try:
@ -1118,7 +1121,8 @@ class ITUNES(DriverBase):
# Report progress # Report progress
if self.report_progress is not None: if self.report_progress is not None:
self.report_progress((i+1)/file_count, _('%d of %d') % (i+1, file_count)) self.report_progress((i+1)/file_count,
_('%(num)d of %(tot)d') % dict(num=i+1, tot=file_count))
finally: finally:
pythoncom.CoUninitialize() pythoncom.CoUninitialize()
@ -3107,7 +3111,8 @@ class ITUNES_ASYNC(ITUNES):
} }
if self.report_progress is not None: if self.report_progress is not None:
self.report_progress((i+1)/book_count, _('%d of %d') % (i+1, book_count)) self.report_progress((i+1)/book_count,
_('%(num)d of %(tot)d') % dict(num=i+1, tot=book_count))
elif iswindows: elif iswindows:
try: try:
@ -3147,7 +3152,8 @@ class ITUNES_ASYNC(ITUNES):
if self.report_progress is not None: if self.report_progress is not None:
self.report_progress((i+1)/book_count, self.report_progress((i+1)/book_count,
_('%d of %d') % (i+1, book_count)) _('%(num)d of %(tot)d') % dict(num=i+1,
tot=book_count))
finally: finally:
pythoncom.CoUninitialize() pythoncom.CoUninitialize()

View File

@ -67,10 +67,10 @@ class PRS505(USBMS):
_('Comma separated list of metadata fields ' _('Comma separated list of metadata fields '
'to turn into collections on the device. Possibilities include: ')+\ 'to turn into collections on the device. Possibilities include: ')+\
'series, tags, authors' +\ 'series, tags, authors' +\
_('. Two special collections are available: %s:%s and %s:%s. Add ' _('. Two special collections are available: %(abt)s:%(abtv)s and %(aba)s:%(abav)s. Add '
'these values to the list to enable them. The collections will be ' 'these values to the list to enable them. The collections will be '
'given the name provided after the ":" character.')%( 'given the name provided after the ":" character.')%dict(
'abt', ALL_BY_TITLE, 'aba', ALL_BY_AUTHOR), abt='abt', abtv=ALL_BY_TITLE, aba='aba', abav=ALL_BY_AUTHOR),
_('Upload separate cover thumbnails for books (newer readers)') + _('Upload separate cover thumbnails for books (newer readers)') +
':::'+_('Normally, the SONY readers get the cover image from the' ':::'+_('Normally, the SONY readers get the cover image from the'
' ebook file itself. With this option, calibre will send a ' ' ebook file itself. With this option, calibre will send a '

View File

@ -144,9 +144,9 @@ def add_pipeline_options(parser, plumber):
'HEURISTIC PROCESSING' : ( 'HEURISTIC PROCESSING' : (
_('Modify the document text and structure using common' _('Modify the document text and structure using common'
' patterns. Disabled by default. Use %s to enable. ' ' patterns. Disabled by default. Use %(en)s to enable. '
' Individual actions can be disabled with the %s options.') ' Individual actions can be disabled with the %(dis)s options.')
% ('--enable-heuristics', '--disable-*'), % dict(en='--enable-heuristics', dis='--disable-*'),
['enable_heuristics'] + HEURISTIC_OPTIONS ['enable_heuristics'] + HEURISTIC_OPTIONS
), ),

View File

@ -17,7 +17,8 @@ class ParseError(ValueError):
self.name = name self.name = name
self.desc = desc self.desc = desc
ValueError.__init__(self, ValueError.__init__(self,
_('Failed to parse: %s with error: %s')%(name, desc)) _('Failed to parse: %(name)s with error: %(err)s')%dict(
name=name, err=desc))
class ePubFixer(Plugin): class ePubFixer(Plugin):

View File

@ -561,7 +561,9 @@ class HTMLConverter(object):
para = children[i] para = children[i]
break break
if para is None: if para is None:
raise ConversionError(_('Failed to parse link %s %s')%(tag, children)) raise ConversionError(
_('Failed to parse link %(tag)s %(children)s')%dict(
tag=tag, children=children))
text = self.get_text(tag, 1000) text = self.get_text(tag, 1000)
if not text: if not text:
text = 'Link' text = 'Link'
@ -954,7 +956,9 @@ class HTMLConverter(object):
self.scaled_images[path] = pt self.scaled_images[path] = pt
return pt.name return pt.name
except (IOError, SystemError) as err: # PIL chokes on interlaced PNG images as well a some GIF images except (IOError, SystemError) as err: # PIL chokes on interlaced PNG images as well a some GIF images
self.log.warning(_('Unable to process image %s. Error: %s')%(path, err)) self.log.warning(
_('Unable to process image %(path)s. Error: %(err)s')%dict(
path=path, err=err))
if width == None or height == None: if width == None or height == None:
width, height = im.size width, height = im.size
@ -1014,7 +1018,7 @@ class HTMLConverter(object):
try: try:
self.images[path] = ImageStream(path, encoding=encoding) self.images[path] = ImageStream(path, encoding=encoding)
except LrsError as err: except LrsError as err:
self.log.warning(_('Could not process image: %s\n%s')%( self.log.warning(('Could not process image: %s\n%s')%(
original_path, err)) original_path, err))
return return

View File

@ -21,9 +21,9 @@ USAGE='%%prog ebook_file [' + _('options') + ']\n' + \
_(''' _('''
Read/Write metadata from/to ebook files. Read/Write metadata from/to ebook files.
Supported formats for reading metadata: %s Supported formats for reading metadata: %(read)s
Supported formats for writing metadata: %s Supported formats for writing metadata: %(write)s
Different file types support different kinds of metadata. If you try to set Different file types support different kinds of metadata. If you try to set
some metadata on a file type that does not support it, the metadata will be some metadata on a file type that does not support it, the metadata will be
@ -99,7 +99,7 @@ def option_parser():
for w in metadata_writers(): for w in metadata_writers():
writers = writers.union(set(w.file_types)) writers = writers.union(set(w.file_types))
ft, w = ', '.join(sorted(filetypes())), ', '.join(sorted(writers)) ft, w = ', '.join(sorted(filetypes())), ', '.join(sorted(writers))
return config().option_parser(USAGE%(ft, w)) return config().option_parser(USAGE%dict(read=ft, write=w))
def do_set_metadata(opts, mi, stream, stream_type): def do_set_metadata(opts, mi, stream, stream_type):
mi = MetaInformation(mi) mi = MetaInformation(mi)

View File

@ -95,9 +95,9 @@ class CoverManager(object):
authors = [unicode(x) for x in m.creator if x.role == 'aut'] authors = [unicode(x) for x in m.creator if x.role == 'aut']
series_string = None series_string = None
if m.series and m.series_index: if m.series and m.series_index:
series_string = _('Book %s of %s')%( series_string = _('Book %(sidx)s of %(series)s')%dict(
fmt_sidx(m.series_index[0], use_roman=True), sidx=fmt_sidx(m.series_index[0], use_roman=True),
unicode(m.series[0])) series=unicode(m.series[0]))
try: try:
from calibre.ebooks import calibre_cover from calibre.ebooks import calibre_cover

View File

@ -32,8 +32,8 @@ class SplitError(ValueError):
size = len(tostring(root))/1024. size = len(tostring(root))/1024.
ValueError.__init__(self, ValueError.__init__(self,
_('Could not find reasonable point at which to split: ' _('Could not find reasonable point at which to split: '
'%s Sub-tree size: %d KB')% '%(path)s Sub-tree size: %(size)d KB')%dict(
(path, size)) path=path, size=size))
class Split(object): class Split(object):

View File

@ -1,4 +1,4 @@
# coding:utf8 # coding:utf-8
__license__ = 'GPL 3' __license__ = 'GPL 3'
__copyright__ = '2010, Hiroshi Miura <miurahr@linux.com>' __copyright__ = '2010, Hiroshi Miura <miurahr@linux.com>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'

View File

@ -120,16 +120,16 @@ class FetchAnnotationsAction(InterfaceAction):
spanTag['style'] = 'font-weight:bold' spanTag['style'] = 'font-weight:bold'
if bookmark.book_format == 'pdf': if bookmark.book_format == 'pdf':
spanTag.insert(0,NavigableString( spanTag.insert(0,NavigableString(
_("%s<br />Last Page Read: %d (%d%%)") % \ _("%(time)s<br />Last Page Read: %(loc)d (%(pr)d%%)") % \
(strftime(u'%x', timestamp.timetuple()), dict(time=strftime(u'%x', timestamp.timetuple()),
last_read_location, loc=last_read_location,
percent_read))) pr=percent_read)))
else: else:
spanTag.insert(0,NavigableString( spanTag.insert(0,NavigableString(
_("%s<br />Last Page Read: Location %d (%d%%)") % \ _("%(time)s<br />Last Page Read: Location %(loc)d (%(pr)d%%)") % \
(strftime(u'%x', timestamp.timetuple()), dict(time=strftime(u'%x', timestamp.timetuple()),
last_read_location, loc=last_read_location,
percent_read))) pr=percent_read)))
divTag.insert(dtc, spanTag) divTag.insert(dtc, spanTag)
dtc += 1 dtc += 1
@ -145,23 +145,23 @@ class FetchAnnotationsAction(InterfaceAction):
for location in sorted(user_notes): for location in sorted(user_notes):
if user_notes[location]['text']: if user_notes[location]['text']:
annotations.append( annotations.append(
_('<b>Location %d &bull; %s</b><br />%s<br />') % \ _('<b>Location %(dl)d &bull; %(typ)s</b><br />%(text)s<br />') % \
(user_notes[location]['displayed_location'], dict(dl=user_notes[location]['displayed_location'],
user_notes[location]['type'], typ=user_notes[location]['type'],
user_notes[location]['text'] if \ text=(user_notes[location]['text'] if \
user_notes[location]['type'] == 'Note' else \ user_notes[location]['type'] == 'Note' else \
'<i>%s</i>' % user_notes[location]['text'])) '<i>%s</i>' % user_notes[location]['text'])))
else: else:
if bookmark.book_format == 'pdf': if bookmark.book_format == 'pdf':
annotations.append( annotations.append(
_('<b>Page %d &bull; %s</b><br />') % \ _('<b>Page %(dl)d &bull; %(typ)s</b><br />') % \
(user_notes[location]['displayed_location'], dict(dl=user_notes[location]['displayed_location'],
user_notes[location]['type'])) typ=user_notes[location]['type']))
else: else:
annotations.append( annotations.append(
_('<b>Location %d &bull; %s</b><br />') % \ _('<b>Location %(dl)d &bull; %(typ)s</b><br />') % \
(user_notes[location]['displayed_location'], dict(dl=user_notes[location]['displayed_location'],
user_notes[location]['type'])) typ=user_notes[location]['type']))
for annotation in annotations: for annotation in annotations:
divTag.insert(dtc, annotation) divTag.insert(dtc, annotation)

View File

@ -82,7 +82,8 @@ class GenerateCatalogAction(InterfaceAction):
self.gui.sync_catalogs() self.gui.sync_catalogs()
if job.fmt not in ['EPUB','MOBI']: if job.fmt not in ['EPUB','MOBI']:
export_dir = choose_dir(self.gui, _('Export Catalog Directory'), export_dir = choose_dir(self.gui, _('Export Catalog Directory'),
_('Select destination for %s.%s') % (job.catalog_title, job.fmt.lower())) _('Select destination for %(title)s.%(fmt)s') % dict(
title=job.catalog_title, fmt=job.fmt.lower()))
if export_dir: if export_dir:
destination = os.path.join(export_dir, '%s.%s' % (job.catalog_title, job.fmt.lower())) destination = os.path.join(export_dir, '%s.%s' % (job.catalog_title, job.fmt.lower()))
shutil.copyfile(job.catalog_file_path, destination) shutil.copyfile(job.catalog_file_path, destination)

View File

@ -160,8 +160,9 @@ class CopyToLibraryAction(InterfaceAction):
error_dialog(self.gui, _('Failed'), _('Could not copy books: ') + e, error_dialog(self.gui, _('Failed'), _('Could not copy books: ') + e,
det_msg=tb, show=True) det_msg=tb, show=True)
else: else:
self.gui.status_bar.show_message(_('Copied %d books to %s') % self.gui.status_bar.show_message(
(len(ids), loc), 2000) _('Copied %(num)d books to %(loc)s') %
dict(num=len(ids), loc=loc), 2000)
if delete_after and self.worker.processed: if delete_after and self.worker.processed:
v = self.gui.library_view v = self.gui.library_view
ci = v.currentIndex() ci = v.currentIndex()

View File

@ -159,9 +159,9 @@ def render_data(mi, use_roman_numbers=True, all_fields=False):
sidx = mi.get(field+'_index') sidx = mi.get(field+'_index')
if sidx is None: if sidx is None:
sidx = 1.0 sidx = 1.0
val = _('Book %s of <span class="series_name">%s</span>')%(fmt_sidx(sidx, val = _('Book %(sidx)s of <span class="series_name">%(series)s</span>')%dict(
use_roman=use_roman_numbers), sidx=fmt_sidx(sidx, use_roman=use_roman_numbers),
prepare_string_for_xml(getattr(mi, field))) series=prepare_string_for_xml(getattr(mi, field)))
ans.append((field, u'<td class="title">%s</td><td>%s</td>'%(name, val))) ans.append((field, u'<td class="title">%s</td><td>%s</td>'%(name, val)))
@ -541,7 +541,8 @@ class BookDetails(QWidget): # {{{
self.setToolTip( self.setToolTip(
'<p>'+_('Double-click to open Book Details window') + '<p>'+_('Double-click to open Book Details window') +
'<br><br>' + _('Path') + ': ' + self.current_path + '<br><br>' + _('Path') + ': ' + self.current_path +
'<br><br>' + _('Cover size: %dx%d')%(sz.width(), sz.height()) '<br><br>' + _('Cover size: %(width)d x %(height)d')%dict(
width=sz.width(), height=sz.height())
) )
def reset_info(self): def reset_info(self):

View File

@ -912,8 +912,9 @@ class DeviceMixin(object): # {{{
format_count[f] = 1 format_count[f] = 1
for f in self.device_manager.device.settings().format_map: for f in self.device_manager.device.settings().format_map:
if f in format_count.keys(): if f in format_count.keys():
formats.append((f, _('%i of %i Books') % (format_count[f], formats.append((f, _('%(num)i of %(total)i Books') % dict(
len(rows)), True if f in aval_out_formats else False)) num=format_count[f], total=len(rows)),
True if f in aval_out_formats else False))
elif f in aval_out_formats: elif f in aval_out_formats:
formats.append((f, _('0 of %i Books') % len(rows), True)) formats.append((f, _('0 of %i Books') % len(rows), True))
d = ChooseFormatDeviceDialog(self, _('Choose format to send to device'), formats) d = ChooseFormatDeviceDialog(self, _('Choose format to send to device'), formats)

View File

@ -106,7 +106,8 @@ class BookInfo(QDialog, Ui_BookInfo):
Qt.KeepAspectRatio, Qt.SmoothTransformation) Qt.KeepAspectRatio, Qt.SmoothTransformation)
self.cover.set_pixmap(pixmap) self.cover.set_pixmap(pixmap)
sz = pixmap.size() sz = pixmap.size()
self.cover.setToolTip(_('Cover size: %dx%d')%(sz.width(), sz.height())) self.cover.setToolTip(_('Cover size: %(width)d x %(height)d')%dict(
width=sz.width(), height=sz.height()))
def refresh(self, row): def refresh(self, row):
if isinstance(row, QModelIndex): if isinstance(row, QModelIndex):

View File

@ -173,10 +173,10 @@ class MyBlockingBusy(QDialog): # {{{
mi = self.db.get_metadata(id, index_is_id=True) mi = self.db.get_metadata(id, index_is_id=True)
series_string = None series_string = None
if mi.series: if mi.series:
series_string = _('Book %s of %s')%( series_string = _('Book %(sidx)s of %(series)s')%dict(
fmt_sidx(mi.series_index, sidx=fmt_sidx(mi.series_index,
use_roman=config['use_roman_numerals_for_series_number']), use_roman=config['use_roman_numerals_for_series_number']),
mi.series) series=mi.series)
cdata = calibre_cover(mi.title, mi.format_field('authors')[-1], cdata = calibre_cover(mi.title, mi.format_field('authors')[-1],
series_string=series_string) series_string=series_string)

View File

@ -701,7 +701,9 @@ class PluginUpdaterDialog(SizePersistedDialog):
if DEBUG: if DEBUG:
prints('Locating zip file for %s: %s'% (display_plugin.name, display_plugin.forum_link)) prints('Locating zip file for %s: %s'% (display_plugin.name, display_plugin.forum_link))
self.gui.status_bar.showMessage(_('Locating zip file for %s: %s') % (display_plugin.name, display_plugin.forum_link)) self.gui.status_bar.showMessage(
_('Locating zip file for %(name)s: %(link)s') % dict(
name=display_plugin.name, link=display_plugin.forum_link))
plugin_zip_url = self._read_zip_attachment_url(display_plugin.forum_link) plugin_zip_url = self._read_zip_attachment_url(display_plugin.forum_link)
if not plugin_zip_url: if not plugin_zip_url:
return error_dialog(self.gui, _('Install Plugin Failed'), return error_dialog(self.gui, _('Install Plugin Failed'),

View File

@ -381,7 +381,9 @@ class SchedulerDialog(QDialog, Ui_Dialog):
d = utcnow() - last_downloaded d = utcnow() - last_downloaded
def hm(x): return (x-x%3600)//3600, (x%3600 - (x%3600)%60)//60 def hm(x): return (x-x%3600)//3600, (x%3600 - (x%3600)%60)//60
hours, minutes = hm(d.seconds) hours, minutes = hm(d.seconds)
tm = _('%d days, %d hours and %d minutes ago')%(d.days, hours, minutes) tm = _('%(days)d days, %(hours)d hours'
' and %(mins)d minutes ago')%dict(
days=d.days, hours=hours, mins=minutes)
if d < timedelta(days=366): if d < timedelta(days=366):
ld_text = tm ld_text = tm
else: else:

View File

@ -18,7 +18,8 @@ class ListWidgetItem(QListWidgetItem):
def data(self, role): def data(self, role):
if role == Qt.DisplayRole: if role == Qt.DisplayRole:
if self.initial_value != self.current_value: if self.initial_value != self.current_value:
return _('%s (was %s)')%(self.current_value, self.initial_value) return _('%(curr)s (was %(initial)s)')%dict(
curr=self.current_value, initial=self.initial_value)
else: else:
return self.current_value return self.current_value
elif role == Qt.EditRole: elif role == Qt.EditRole:

View File

@ -143,7 +143,9 @@ class UserProfiles(ResizableDialog, Ui_Dialog):
pt = PersistentTemporaryFile(suffix='.recipe') pt = PersistentTemporaryFile(suffix='.recipe')
pt.write(src.encode('utf-8')) pt.write(src.encode('utf-8'))
pt.close() pt.close()
body = _('The attached file: %s is a recipe to download %s.')%(os.path.basename(pt.name), title) body = _('The attached file: %(fname)s is a '
'recipe to download %(title)s.')%dict(
fname=os.path.basename(pt.name), title=title)
subject = _('Recipe for ')+title subject = _('Recipe for ')+title
url = QUrl('mailto:') url = QUrl('mailto:')
url.addQueryItem('subject', subject) url.addQueryItem('subject', subject)

View File

@ -51,8 +51,8 @@ class DownloadDialog(QDialog): # {{{
self.setWindowTitle(_('Download %s')%fname) self.setWindowTitle(_('Download %s')%fname)
self.l = QVBoxLayout(self) self.l = QVBoxLayout(self)
self.purl = urlparse(url) self.purl = urlparse(url)
self.msg = QLabel(_('Downloading <b>%s</b> from %s')%(fname, self.msg = QLabel(_('Downloading <b>%(fname)s</b> from %(url)s')%dict(
self.purl.netloc)) fname=fname, url=self.purl.netloc))
self.msg.setWordWrap(True) self.msg.setWordWrap(True)
self.l.addWidget(self.msg) self.l.addWidget(self.msg)
self.pb = QProgressBar(self) self.pb = QProgressBar(self)
@ -82,8 +82,8 @@ class DownloadDialog(QDialog): # {{{
self.exec_() self.exec_()
if self.worker.err is not None: if self.worker.err is not None:
error_dialog(self.parent(), _('Download failed'), error_dialog(self.parent(), _('Download failed'),
_('Failed to download from %r with error: %s')%( _('Failed to download from %(url)r with error: %(err)s')%dict(
self.worker.url, self.worker.err), url=self.worker.url, err=self.worker.err),
det_msg=self.worker.tb, show=True) det_msg=self.worker.tb, show=True)
def update(self): def update(self):

View File

@ -120,7 +120,7 @@ def send_mails(jobnames, callback, attachments, to_s, subjects,
texts, attachment_names, job_manager): texts, attachment_names, job_manager):
for name, attachment, to, subject, text, aname in zip(jobnames, for name, attachment, to, subject, text, aname in zip(jobnames,
attachments, to_s, subjects, texts, attachment_names): attachments, to_s, subjects, texts, attachment_names):
description = _('Email %s to %s') % (name, to) description = _('Email %(name)s to %(to)s') % dict(name=name, to=to)
job = ThreadedJob('email', description, gui_sendmail, (attachment, aname, to, job = ThreadedJob('email', description, gui_sendmail, (attachment, aname, to,
subject, text), {}, callback) subject, text), {}, callback)
job_manager.run_threaded_job(job) job_manager.run_threaded_job(job)

View File

@ -878,9 +878,10 @@ class Cover(ImageView): # {{{
series = self.dialog.series.current_val series = self.dialog.series.current_val
series_string = None series_string = None
if series: if series:
series_string = _('Book %s of %s')%( series_string = _('Book %(sidx)s of %(series)s')%dict(
fmt_sidx(self.dialog.series_index.current_val, sidx=fmt_sidx(self.dialog.series_index.current_val,
use_roman=config['use_roman_numerals_for_series_number']), series) use_roman=config['use_roman_numerals_for_series_number']),
series=series)
self.current_val = calibre_cover(title, author, self.current_val = calibre_cover(title, author,
series_string=series_string) series_string=series_string)
@ -921,8 +922,8 @@ class Cover(ImageView): # {{{
self.setPixmap(pm) self.setPixmap(pm)
tt = _('This book has no cover') tt = _('This book has no cover')
if self._cdata: if self._cdata:
tt = _('Cover size: %dx%d pixels') % \ tt = _('Cover size: %(width)d x %(height)d pixels') % \
(pm.width(), pm.height()) dict(width=pm.width(), height=pm.height())
self.setToolTip(tt) self.setToolTip(tt)
return property(fget=fget, fset=fset) return property(fget=fget, fset=fset)

View File

@ -196,7 +196,7 @@ def download(ids, db, do_identify, covers,
ans[i] = mi ans[i] = mi
count += 1 count += 1
notifications.put((count/len(ids), notifications.put((count/len(ids),
_('Downloaded %d of %d')%(count, len(ids)))) _('Downloaded %(num)d of %(tot)d')%dict(num=count, tot=len(ids))))
log('Download complete, with %d failures'%len(failed_ids)) log('Download complete, with %d failures'%len(failed_ids))
return (ans, failed_ids, failed_covers, title_map, all_failed) return (ans, failed_ids, failed_covers, title_map, all_failed)

View File

@ -726,8 +726,8 @@ class CoversWidget(QWidget): # {{{
if num < 2: if num < 2:
txt = _('Could not find any covers for <b>%s</b>')%self.book.title txt = _('Could not find any covers for <b>%s</b>')%self.book.title
else: else:
txt = _('Found <b>%d</b> covers of %s. Pick the one you like' txt = _('Found <b>%(num)d</b> covers of %(title)s. Pick the one you like'
' best.')%(num-1, self.title) ' best.')%dict(num=num-1, title=self.title)
self.msg.setText(txt) self.msg.setText(txt)
self.finished.emit() self.finished.emit()

View File

@ -445,15 +445,15 @@ class RulesModel(QAbstractListModel): # {{{
def rule_to_html(self, col, rule): def rule_to_html(self, col, rule):
if not isinstance(rule, Rule): if not isinstance(rule, Rule):
return _(''' return _('''
<p>Advanced Rule for column <b>%s</b>: <p>Advanced Rule for column <b>%(col)s</b>:
<pre>%s</pre> <pre>%(rule)s</pre>
''')%(col, prepare_string_for_xml(rule)) ''')%dict(col=col, rule=prepare_string_for_xml(rule))
conditions = [self.condition_to_html(c) for c in rule.conditions] conditions = [self.condition_to_html(c) for c in rule.conditions]
return _('''\ return _('''\
<p>Set the color of <b>%s</b> to <b>%s</b> if the following <p>Set the color of <b>%(col)s</b> to <b>%(color)s</b> if the following
conditions are met:</p> conditions are met:</p>
<ul>%s</ul> <ul>%(rule)s</ul>
''') % (col, rule.color, ''.join(conditions)) ''') % dict(col=col, color=rule.color, rule=''.join(conditions))
def condition_to_html(self, condition): def condition_to_html(self, condition):
c, a, v = condition c, a, v = condition
@ -464,8 +464,8 @@ class RulesModel(QAbstractListModel): # {{{
action_name = trans action_name = trans
return ( return (
_('<li>If the <b>%s</b> column <b>%s</b> value: <b>%s</b>') % _('<li>If the <b>%(col)s</b> column <b>%(action)s</b> value: <b>%(val)s</b>') %
(c, action_name, prepare_string_for_xml(v))) dict(col=c, action=action_name, val=prepare_string_for_xml(v)))
# }}} # }}}

View File

@ -262,8 +262,8 @@ class PluginConfig(QWidget): # {{{
self.l = l = QVBoxLayout() self.l = l = QVBoxLayout()
self.setLayout(l) self.setLayout(l)
self.c = c = QLabel(_('<b>Configure %s</b><br>%s') % (plugin.name, self.c = c = QLabel(_('<b>Configure %(name)s</b><br>%(desc)s') % dict(
plugin.description)) name=plugin.name, desc=plugin.description))
c.setAlignment(Qt.AlignHCenter) c.setAlignment(Qt.AlignHCenter)
l.addWidget(c) l.addWidget(c)

View File

@ -67,7 +67,9 @@ class CacheUpdateThread(Thread, QObject):
self.total_changed.emit(len(raw_books)) self.total_changed.emit(len(raw_books))
for i, book_data in enumerate(raw_books): for i, book_data in enumerate(raw_books):
self.update_details.emit(_('%s of %s books processed.') % (i, len(raw_books))) self.update_details.emit(
_('%(num)s of %(tot)s books processed.') % dict(
num=i, tot=len(raw_books)))
book = SearchResult() book = SearchResult()
book.detail_item = ''.join(book_data.xpath('.//a/@href')) book.detail_item = ''.join(book_data.xpath('.//a/@href'))
book.formats = ''.join(book_data.xpath('.//i/text()')) book.formats = ''.join(book_data.xpath('.//i/text()'))

View File

@ -384,8 +384,8 @@ class TagsView(QTreeView): # {{{
action='delete_search', key=tag.name)) action='delete_search', key=tag.name))
if key.startswith('@') and not item.is_gst: if key.startswith('@') and not item.is_gst:
self.context_menu.addAction(self.user_category_icon, self.context_menu.addAction(self.user_category_icon,
_('Remove %s from category %s')% _('Remove %(item)s from category %(cat)s')%
(display_name(tag), item.py_name), dict(item=display_name(tag), cat=item.py_name),
partial(self.context_menu_handler, partial(self.context_menu_handler,
action='delete_item_from_user_category', action='delete_item_from_user_category',
key = key, index = tag_item)) key = key, index = tag_item))

View File

@ -94,8 +94,8 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, # {{{
msg = '%s' % '\n'.join(res) msg = '%s' % '\n'.join(res)
warning_dialog(parent, _('Could not convert some books'), warning_dialog(parent, _('Could not convert some books'),
_('Could not convert %d of %d books, because no suitable source' _('Could not convert %(num)d of %(tot)d books, because no suitable source'
' format was found.') % (len(res), total), ' format was found.') % dict(num=len(res), tot=total),
msg).exec_() msg).exec_()
return jobs, changed, bad return jobs, changed, bad
@ -187,7 +187,8 @@ class QueueBulk(QProgressDialog):
except: except:
dtitle = repr(mi.title) dtitle = repr(mi.title)
self.setLabelText(_('Queueing ')+dtitle) self.setLabelText(_('Queueing ')+dtitle)
desc = _('Convert book %d of %d (%s)') % (self.i, len(self.book_ids), dtitle) desc = _('Convert book %(num)d of %(tot)d (%(title)s)') % dict(
num=self.i, tot=len(self.book_ids), title=dtitle)
args = [in_file.name, out_file.name, lrecs] args = [in_file.name, out_file.name, lrecs]
temp_files.append(out_file) temp_files.append(out_file)
@ -209,8 +210,8 @@ class QueueBulk(QProgressDialog):
msg = '%s' % '\n'.join(res) msg = '%s' % '\n'.join(res)
warning_dialog(self.parent, _('Could not convert some books'), warning_dialog(self.parent, _('Could not convert some books'),
_('Could not convert %d of %d books, because no suitable ' _('Could not convert %(num)d of %(tot)d books, because no suitable '
'source format was found.') % (len(res), len(self.book_ids)), 'source format was found.') % dict(num=len(res), tot=len(self.book_ids)),
msg).exec_() msg).exec_()
self.parent = None self.parent = None
self.jobs.reverse() self.jobs.reverse()

View File

@ -70,10 +70,10 @@ class UpdateNotification(QDialog):
self.logo.setPixmap(QPixmap(I('lt.png')).scaled(100, 100, self.logo.setPixmap(QPixmap(I('lt.png')).scaled(100, 100,
Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) Qt.IgnoreAspectRatio, Qt.SmoothTransformation))
self.label = QLabel(('<p>'+ self.label = QLabel(('<p>'+
_('%s has been updated to version <b>%s</b>. ' _('%(app)s has been updated to version <b>%(ver)s</b>. '
'See the <a href="http://calibre-ebook.com/whats-new' 'See the <a href="http://calibre-ebook.com/whats-new'
'">new features</a>.'))%( '">new features</a>.'))%dict(
__appname__, calibre_version)) app=__appname__, ver=calibre_version))
self.label.setOpenExternalLinks(True) self.label.setOpenExternalLinks(True)
self.label.setWordWrap(True) self.label.setWordWrap(True)
self.setWindowTitle(_('Update available!')) self.setWindowTitle(_('Update available!'))

View File

@ -492,11 +492,11 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.set_page_number(frac) self.set_page_number(frac)
def magnification_changed(self, val): def magnification_changed(self, val):
tt = _('Make font size %s\nCurrent magnification: %.1f') tt = _('Make font size %(which)s\nCurrent magnification: %(mag).1f')
self.action_font_size_larger.setToolTip( self.action_font_size_larger.setToolTip(
tt %(_('larger'), val)) tt %dict(which=_('larger'), mag=val))
self.action_font_size_smaller.setToolTip( self.action_font_size_smaller.setToolTip(
tt %(_('smaller'), val)) tt %dict(which=_('smaller'), mag=val))
def find(self, text, repeat=False, backwards=False): def find(self, text, repeat=False, backwards=False):
if not text: if not text:

View File

@ -569,9 +569,9 @@ def move_library(oldloc, newloc, parent, callback_on_complete):
det = traceback.format_exc() det = traceback.format_exc()
error_dialog(parent, _('Invalid database'), error_dialog(parent, _('Invalid database'),
_('<p>An invalid library already exists at ' _('<p>An invalid library already exists at '
'%s, delete it before trying to move the ' '%(loc)s, delete it before trying to move the '
'existing library.<br>Error: %s')%(newloc, 'existing library.<br>Error: %(err)s')%dict(loc=newloc,
str(err)), det, show=True) err=str(err)), det, show=True)
callback(None) callback(None)
return return
else: else:

View File

@ -31,9 +31,9 @@ class TestEmail(QDialog, TE_Dialog):
if pa: if pa:
self.to.setText(pa) self.to.setText(pa)
if opts.relay_host: if opts.relay_host:
self.label.setText(_('Using: %s:%s@%s:%s and %s encryption')% self.label.setText(_('Using: %(un)s:%(pw)s@%(host)s:%(port)s and %(enc)s encryption')%
(opts.relay_username, unhexlify(opts.relay_password), dict(un=opts.relay_username, pw=unhexlify(opts.relay_password),
opts.relay_host, opts.relay_port, opts.encryption)) host=opts.relay_host, port=opts.relay_port, enc=opts.encryption))
def test(self, *args): def test(self, *args):
self.log.setPlainText(_('Sending...')) self.log.setPlainText(_('Sending...'))

View File

@ -54,12 +54,12 @@ class CSV_XML(CatalogPlugin): # {{{
action = None, action = None,
help = _('The fields to output when cataloging books in the ' help = _('The fields to output when cataloging books in the '
'database. Should be a comma-separated list of fields.\n' 'database. Should be a comma-separated list of fields.\n'
'Available fields: %s,\n' 'Available fields: %(fields)s,\n'
'plus user-created custom fields.\n' 'plus user-created custom fields.\n'
'Example: %s=title,authors,tags\n' 'Example: %(opt)s=title,authors,tags\n'
"Default: '%%default'\n" "Default: '%%default'\n"
"Applies to: CSV, XML output formats")%(', '.join(FIELDS), "Applies to: CSV, XML output formats")%dict(
'--fields')), fields=', '.join(FIELDS), opt='--fields')),
Option('--sort-by', Option('--sort-by',
default = 'id', default = 'id',
@ -250,12 +250,12 @@ class BIBTEX(CatalogPlugin): # {{{
action = None, action = None,
help = _('The fields to output when cataloging books in the ' help = _('The fields to output when cataloging books in the '
'database. Should be a comma-separated list of fields.\n' 'database. Should be a comma-separated list of fields.\n'
'Available fields: %s.\n' 'Available fields: %(fields)s.\n'
'plus user-created custom fields.\n' 'plus user-created custom fields.\n'
'Example: %s=title,authors,tags\n' 'Example: %(opt)s=title,authors,tags\n'
"Default: '%%default'\n" "Default: '%%default'\n"
"Applies to: BIBTEX output format")%(', '.join(FIELDS), "Applies to: BIBTEX output format")%dict(
'--fields')), fields=', '.join(FIELDS), opt='--fields')),
Option('--sort-by', Option('--sort-by',
default = 'id', default = 'id',

View File

@ -62,7 +62,8 @@ class Tag(object):
if self.avg_rating > 0: if self.avg_rating > 0:
if tooltip: if tooltip:
tooltip = tooltip + ': ' tooltip = tooltip + ': '
tooltip = _('%sAverage rating is %3.1f')%(tooltip, self.avg_rating) tooltip = _('%(tt)sAverage rating is %(rating)3.1f')%dict(
tt=tooltip, rating=self.avg_rating)
self.tooltip = tooltip self.tooltip = tooltip
self.icon = icon self.icon = icon
self.category = category self.category = category

View File

@ -92,16 +92,17 @@ def config(defaults=None):
' By default all available formats are saved.')) ' By default all available formats are saved.'))
x('template', default=DEFAULT_TEMPLATE, x('template', default=DEFAULT_TEMPLATE,
help=_('The template to control the filename and directory structure of the saved files. ' help=_('The template to control the filename and directory structure of the saved files. '
'Default is "%s" which will save books into a per-author ' 'Default is "%(templ)s" which will save books into a per-author '
'subdirectory with filenames containing title and author. ' 'subdirectory with filenames containing title and author. '
'Available controls are: {%s}')%(DEFAULT_TEMPLATE, ', '.join(FORMAT_ARGS))) 'Available controls are: {%(controls)s}')%dict(
templ=DEFAULT_TEMPLATE, controls=', '.join(FORMAT_ARGS)))
x('send_template', default=DEFAULT_SEND_TEMPLATE, x('send_template', default=DEFAULT_SEND_TEMPLATE,
help=_('The template to control the filename and directory structure of files ' help=_('The template to control the filename and directory structure of files '
'sent to the device. ' 'sent to the device. '
'Default is "%s" which will save books into a per-author ' 'Default is "%(templ)s" which will save books into a per-author '
'directory with filenames containing title and author. ' 'directory with filenames containing title and author. '
'Available controls are: {%s}')%(DEFAULT_SEND_TEMPLATE, ', '.join(FORMAT_ARGS))) 'Available controls are: {%(controls)s}')%dict(
templ=DEFAULT_SEND_TEMPLATE, controls=', '.join(FORMAT_ARGS)))
x('asciiize', default=True, x('asciiize', default=True,
help=_('Normally, calibre will convert all non English characters into English equivalents ' help=_('Normally, calibre will convert all non English characters into English equivalents '
'for the file names. ' 'for the file names. '

View File

@ -124,7 +124,8 @@ def render_rating(rating, url_prefix, container='span', prefix=None): # {{{
added = 0 added = 0
if prefix is None: if prefix is None:
prefix = _('Average rating') prefix = _('Average rating')
rstring = xml(_('%s: %.1f stars')% (prefix, rating if rating else 0.0), rstring = xml(_('%(prefix)s: %(rating).1f stars')%dict(
prefix=prefix, rating=rating if rating else 0.0),
True) True)
ans = ['<%s class="rating">' % (container)] ans = ['<%s class="rating">' % (container)]
for i in range(5): for i in range(5):

View File

@ -171,9 +171,9 @@ def ACQUISITION_ENTRY(item, version, db, updated, CFM, CKEYS, prefix):
no_tag_count=True))) no_tag_count=True)))
series = item[FM['series']] series = item[FM['series']]
if series: if series:
extra.append(_('SERIES: %s [%s]<br />')%\ extra.append(_('SERIES: %(series)s [%(sidx)s]<br />')%\
(xml(series), dict(series=xml(series),
fmt_sidx(float(item[FM['series_index']])))) sidx=fmt_sidx(float(item[FM['series_index']]))))
for key in CKEYS: for key in CKEYS:
mi = db.get_metadata(item[CFM['id']['rec_index']], index_is_id=True) mi = db.get_metadata(item[CFM['id']['rec_index']], index_is_id=True)
name, val = mi.format_field(key) name, val = mi.format_field(key)

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@ class CustomHelpFormatter(IndentedHelpFormatter):
def format_usage(self, usage): def format_usage(self, usage):
tc = terminal_controller() tc = terminal_controller()
return _("%sUsage%s: %s\n") % (tc.BLUE, tc.NORMAL, usage) return "%s%s%s: %s\n" % (tc.BLUE, _('Usage'), tc.NORMAL, usage)
def format_heading(self, heading): def format_heading(self, heading):
tc = terminal_controller() tc = terminal_controller()