diff --git a/app.yaml b/app.yaml index 9d2dd49f..9c7eeed3 100644 --- a/app.yaml +++ b/app.yaml @@ -1,6 +1,6 @@ # ffd-retief-hrd fanfictiondownloader application: fanfictiondownloader -version: 4-4-82 +version: 4-4-83 runtime: python27 api_version: 1 threadsafe: true diff --git a/calibre-plugin/__init__.py b/calibre-plugin/__init__.py index 2c635778..d02c32ca 100644 --- a/calibre-plugin/__init__.py +++ b/calibre-plugin/__init__.py @@ -17,6 +17,12 @@ if sys.version_info >= (2, 7): loghandler.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG) +# pulls in translation files for _() strings +try: + load_translations() +except NameError: + pass # load_translations() added in calibre 1.9 + # The class that all Interface Action plugin wrappers must inherit from from calibre.customize import InterfaceActionBase @@ -33,7 +39,7 @@ class FanFictionDownLoaderBase(InterfaceActionBase): calibre utilities to run without needing to load the GUI libraries. ''' name = 'FanFictionDownLoader' - description = 'UI plugin to download FanFiction stories from various sites.' + description = _('UI plugin to download FanFiction stories from various sites.') supported_platforms = ['windows', 'osx', 'linux'] author = 'Jim Miller' version = (1, 7, 54) diff --git a/calibre-plugin/config.py b/calibre-plugin/config.py index 8cc27cfc..63871ddf 100644 --- a/calibre-plugin/config.py +++ b/calibre-plugin/config.py @@ -22,9 +22,36 @@ from calibre.gui2.ui import get_gui from calibre.gui2 import dynamic, info_dialog from calibre.constants import numeric_version as calibre_version +# pulls in translation files for _() strings +try: + load_translations() +except NameError: + pass # load_translations() added in calibre 1.9 + +# There are a number of things used several times that shouldn't be +# translated. This is just a way to make that easier by keeping them +# out of the _() strings. +# I'm tempted to override _() to include them... +no_trans = { 'pini':'personal.ini', + 'imgset':'\n\n[epub]\ninclude_images:true\nkeep_summary_html:true\nmake_firstimage_cover:true\n\n', + 'gcset':'generate_cover_settings', + 'ccset':'custom_columns_settings', + 'gc':'Generate Cover', + 'rl':'Reading List', + 'cp':'Count Pages', + 'cmplt':'Completed', + 'inprog':'In-Progress', + 'lul':'Last Updated', + 'lus':'lastupdate', + 'is':'include_subject', + 'isa':'is_adult', + 'u':'username', + 'p':'password', + } + from calibre_plugins.fanfictiondownloader_plugin.prefs import prefs, PREFS_NAMESPACE from calibre_plugins.fanfictiondownloader_plugin.dialogs \ - import (UPDATE, UPDATEALWAYS, OVERWRITE, collision_order, RejectListDialog, + import (UPDATE, UPDATEALWAYS, collision_order, save_collisions, RejectListDialog, EditTextDialog, RejectUrlEntry) from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader.adapters \ @@ -125,7 +152,7 @@ class ConfigWidget(QWidget): self.l = QVBoxLayout() self.setLayout(self.l) - label = QLabel('List of Supported Sites -- FAQs') + label = QLabel(''+_('List of Supported Sites')+' -- '+_('FAQs')+'') label.setOpenExternalLinks(True) self.l.addWidget(label) @@ -139,7 +166,7 @@ class ConfigWidget(QWidget): self.scroll_area.setWidget(tab_widget) self.basic_tab = BasicTab(self, plugin_action) - tab_widget.addTab(self.basic_tab, 'Basic') + tab_widget.addTab(self.basic_tab, _('Basic')) self.personalini_tab = PersonalIniTab(self, plugin_action) tab_widget.addTab(self.personalini_tab, 'personal.ini') @@ -160,20 +187,20 @@ class ConfigWidget(QWidget): self.countpages_tab.setEnabled(False) self.std_columns_tab = StandardColumnsTab(self, plugin_action) - tab_widget.addTab(self.std_columns_tab, 'Standard Columns') + tab_widget.addTab(self.std_columns_tab, _('Standard Columns')) self.cust_columns_tab = CustomColumnsTab(self, plugin_action) - tab_widget.addTab(self.cust_columns_tab, 'Custom Columns') + tab_widget.addTab(self.cust_columns_tab, _('Custom Columns')) self.other_tab = OtherTab(self, plugin_action) - tab_widget.addTab(self.other_tab, 'Other') + tab_widget.addTab(self.other_tab, _('Other')) def save_settings(self): # basic prefs['fileform'] = unicode(self.basic_tab.fileform.currentText()) - prefs['collision'] = unicode(self.basic_tab.collision.currentText()) + prefs['collision'] = save_collisions[unicode(self.basic_tab.collision.currentText())] prefs['updatemeta'] = self.basic_tab.updatemeta.isChecked() prefs['updatecover'] = self.basic_tab.updatecover.isChecked() prefs['updateepubcover'] = self.basic_tab.updateepubcover.isChecked() @@ -284,17 +311,17 @@ class BasicTab(QWidget): topl = QVBoxLayout() self.setLayout(topl) - label = QLabel('These settings control the basic features of the plugin--downloading FanFiction.') + label = QLabel(_('These settings control the basic features of the plugin--downloading FanFiction.')) label.setWordWrap(True) topl.addWidget(label) - defs_gb = groupbox = QGroupBox("Defaults Options on Download") + defs_gb = groupbox = QGroupBox(_("Defaults Options on Download")) self.l = QVBoxLayout() groupbox.setLayout(self.l) - tooltip = "On each download, FFDL offers an option to select the output format.
This sets what that option will default to." + tooltip = _("On each download, FFDL offers an option to select the output format.
This sets what that option will default to.") horz = QHBoxLayout() - label = QLabel('Default Output &Format:') + label = QLabel(_('Default Output &Format:')) label.setToolTip(tooltip) horz.addWidget(label) self.fileform = QComboBox(self) @@ -309,15 +336,15 @@ class BasicTab(QWidget): horz.addWidget(self.fileform) self.l.addLayout(horz) - tooltip = "On each download, FFDL offers an option of what happens if that story already exists.
This sets what that option will default to." + tooltip = _("On each download, FFDL offers an option of what happens if that story already exists.
This sets what that option will default to.") horz = QHBoxLayout() - label = QLabel('Default If Story Already Exists?') + label = QLabel(_('Default If Story Already Exists?')) label.setToolTip(tooltip) horz.addWidget(label) self.collision = QComboBox(self) # add collision options self.set_collisions() - i = self.collision.findText(prefs['collision']) + i = self.collision.findText(save_collisions[prefs['collision']]) if i > -1: self.collision.setCurrentIndex(i) self.collision.setToolTip(tooltip) @@ -325,127 +352,126 @@ class BasicTab(QWidget): horz.addWidget(self.collision) self.l.addLayout(horz) - self.updatemeta = QCheckBox('Default Update Calibre &Metadata?',self) - self.updatemeta.setToolTip("On each download, FFDL offers an option to update Calibre's metadata (title, author, URL, tags, custom columns, etc) from the web site.
This sets whether that will default to on or off.
Columns set to 'New Only' in the column tabs will only be set for new books.") + self.updatemeta = QCheckBox(_('Default Update Calibre &Metadata?'),self) + self.updatemeta.setToolTip(_("On each download, FFDL offers an option to update Calibre's metadata (title, author, URL, tags, custom columns, etc) from the web site.
This sets whether that will default to on or off.
Columns set to 'New Only' in the column tabs will only be set for new books.")) self.updatemeta.setChecked(prefs['updatemeta']) self.l.addWidget(self.updatemeta) - self.updateepubcover = QCheckBox('Default Update EPUB Cover when Updating EPUB?',self) - self.updateepubcover.setToolTip("On each download, FFDL offers an option to update the book cover image inside the EPUB from the web site when the EPUB is updated.
This sets whether that will default to on or off.") + self.updateepubcover = QCheckBox(_('Default Update EPUB Cover when Updating EPUB?'),self) + self.updateepubcover.setToolTip(_("On each download, FFDL offers an option to update the book cover image inside the EPUB from the web site when the EPUB is updated.
This sets whether that will default to on or off.")) self.updateepubcover.setChecked(prefs['updateepubcover']) self.l.addWidget(self.updateepubcover) - self.smarten_punctuation = QCheckBox('Smarten Punctuation (EPUB only)',self) - self.smarten_punctuation.setToolTip("Run Smarten Punctuation from Calibre's Polish Book feature on each EPUB download and update.") + self.smarten_punctuation = QCheckBox(_('Smarten Punctuation (EPUB only)'),self) + self.smarten_punctuation.setToolTip(_("Run Smarten Punctuation from Calibre's Polish Book feature on each EPUB download and update.")) self.smarten_punctuation.setChecked(prefs['smarten_punctuation']) if calibre_version >= (0, 9, 39): self.l.addWidget(self.smarten_punctuation) - cali_gb = groupbox = QGroupBox("Updating Calibre Options") + cali_gb = groupbox = QGroupBox(_("Updating Calibre Options")) self.l = QVBoxLayout() groupbox.setLayout(self.l) - self.deleteotherforms = QCheckBox('Delete other existing formats?',self) - self.deleteotherforms.setToolTip('Check this to automatically delete all other ebook formats when updating an existing book.\nHandy if you have both a Nook(epub) and Kindle(mobi), for example.') + self.deleteotherforms = QCheckBox(_('Delete other existing formats?'),self) + self.deleteotherforms.setToolTip(_('Check this to automatically delete all other ebook formats when updating an existing book.\nHandy if you have both a Nook(epub) and Kindle(mobi), for example.')) self.deleteotherforms.setChecked(prefs['deleteotherforms']) self.l.addWidget(self.deleteotherforms) - self.updatecover = QCheckBox('Update Calibre Cover when Updating Metadata?',self) - self.updatecover.setToolTip("Update calibre book cover image from EPUB when metadata is updated. (EPUB only.)\nDoesn't go looking for new images on 'Update Calibre Metadata Only'.") + self.updatecover = QCheckBox(_('Update Calibre Cover when Updating Metadata?'),self) + self.updatecover.setToolTip(_("Update calibre book cover image from EPUB when metadata is updated. (EPUB only.)\nDoesn't go looking for new images on 'Update Calibre Metadata Only'.")) self.updatecover.setChecked(prefs['updatecover']) self.l.addWidget(self.updatecover) - self.keeptags = QCheckBox('Keep Existing Tags when Updating Metadata?',self) - self.keeptags.setToolTip("Existing tags will be kept and any new tags added.\nCompleted and In-Progress tags will be still be updated, if known.\nLast Updated tags will be updated if lastupdate in include_subject_tags.\n(If Tags is set to 'New Only' in the Standard Columns tab, this has no effect.)") + self.keeptags = QCheckBox(_('Keep Existing Tags when Updating Metadata?'),self) + self.keeptags.setToolTip(_("Existing tags will be kept and any new tags added.\n%(cmplt)s and %(inprog)s tags will be still be updated, if known.\n%(lul)s tags will be updated if %(lus)s in %(is)s.\n(If Tags is set to 'New Only' in the Standard Columns tab, this has no effect.)")%no_trans) self.keeptags.setChecked(prefs['keeptags']) self.l.addWidget(self.keeptags) - self.suppressauthorsort = QCheckBox('Force Author into Author Sort?',self) - self.suppressauthorsort.setToolTip("If checked, the author(s) as given will be used for the Author Sort, too.\nIf not checked, calibre will apply it's built in algorithm which makes 'Bob Smith' sort as 'Smith, Bob', etc.") + self.suppressauthorsort = QCheckBox(_('Force Author into Author Sort?'),self) + self.suppressauthorsort.setToolTip(_("If checked, the author(s) as given will be used for the Author Sort, too.\nIf not checked, calibre will apply it's built in algorithm which makes 'Bob Smith' sort as 'Smith, Bob', etc.")) self.suppressauthorsort.setChecked(prefs['suppressauthorsort']) self.l.addWidget(self.suppressauthorsort) - self.suppresstitlesort = QCheckBox('Force Title into Title Sort?',self) - self.suppresstitlesort.setToolTip("If checked, the title as given will be used for the Title Sort, too.\nIf not checked, calibre will apply it's built in algorithm which makes 'The Title' sort as 'Title, The', etc.") + self.suppresstitlesort = QCheckBox(_('Force Title into Title Sort?'),self) + self.suppresstitlesort.setToolTip(_("If checked, the title as given will be used for the Title Sort, too.\nIf not checked, calibre will apply it's built in algorithm which makes 'The Title' sort as 'Title, The', etc.")) self.suppresstitlesort.setChecked(prefs['suppresstitlesort']) self.l.addWidget(self.suppresstitlesort) - self.checkforseriesurlid = QCheckBox("Check for existing Series Anthology books?",self) - self.checkforseriesurlid.setToolTip("Check for existings Series Anthology books using each new story's series URL before downloading.\nOffer to skip downloading if a Series Anthology is found.") + self.checkforseriesurlid = QCheckBox(_("Check for existing Series Anthology books?"),self) + self.checkforseriesurlid.setToolTip(_("Check for existings Series Anthology books using each new story's series URL before downloading.\nOffer to skip downloading if a Series Anthology is found.")) self.checkforseriesurlid.setChecked(prefs['checkforseriesurlid']) self.l.addWidget(self.checkforseriesurlid) - self.checkforurlchange = QCheckBox("Check for changed Story URL?",self) - self.checkforurlchange.setToolTip("Warn you if an update will change the URL of an existing book.") + self.checkforurlchange = QCheckBox(_("Check for changed Story URL?"),self) + self.checkforurlchange.setToolTip(_("Warn you if an update will change the URL of an existing book.")) self.checkforurlchange.setChecked(prefs['checkforurlchange']) self.l.addWidget(self.checkforurlchange) - self.lookforurlinhtml = QCheckBox("Search EPUB text for Story URL?",self) - self.lookforurlinhtml.setToolTip("Look for first valid story URL inside EPUB text if not found in metadata.\nSomewhat risky, could find wrong URL depending on EPUB content.\nAlso finds and corrects bad ffnet URLs from ficsaver.com files.") + self.lookforurlinhtml = QCheckBox(_("Search EPUB text for Story URL?"),self) + self.lookforurlinhtml.setToolTip(_("Look for first valid story URL inside EPUB text if not found in metadata.\nSomewhat risky, could find wrong URL depending on EPUB content.\nAlso finds and corrects bad ffnet URLs from ficsaver.com files.")) self.lookforurlinhtml.setChecked(prefs['lookforurlinhtml']) self.l.addWidget(self.lookforurlinhtml) - self.mark = QCheckBox("Mark added/updated books when finished?",self) - self.mark.setToolTip("Mark added/updated books when finished. Use with option below.\nYou can also manually search for 'marked:ffdl_success'.\n'marked:ffdl_failed' is also available, or search 'marked:ffdl' for both.") + self.mark = QCheckBox(_("Mark added/updated books when finished?"),self) + self.mark.setToolTip(_("Mark added/updated books when finished. Use with option below.\nYou can also manually search for 'marked:ffdl_success'.\n'marked:ffdl_failed' is also available, or search 'marked:ffdl' for both.")) self.mark.setChecked(prefs['mark']) self.l.addWidget(self.mark) - self.showmarked = QCheckBox("Show Marked books when finished?",self) - self.showmarked.setToolTip("Show Marked added/updated books only when finished.\nYou can also manually search for 'marked:ffdl_success'.\n'marked:ffdl_failed' is also available, or search 'marked:ffdl' for both.") + self.showmarked = QCheckBox(_("Show Marked books when finished?"),self) + self.showmarked.setToolTip(_("Show Marked added/updated books only when finished.\nYou can also manually search for 'marked:ffdl_success'.\n'marked:ffdl_failed' is also available, or search 'marked:ffdl' for both.")) self.showmarked.setChecked(prefs['showmarked']) self.l.addWidget(self.showmarked) - gui_gb = groupbox = QGroupBox("GUI Options") + gui_gb = groupbox = QGroupBox(_("GUI Options")) self.l = QVBoxLayout() groupbox.setLayout(self.l) - self.urlsfromclip = QCheckBox('Take URLs from Clipboard?',self) - self.urlsfromclip.setToolTip('Prefill URLs from valid URLs in Clipboard when Adding New.') + self.urlsfromclip = QCheckBox(_('Take URLs from Clipboard?'),self) + self.urlsfromclip.setToolTip(_('Prefill URLs from valid URLs in Clipboard when Adding New.')) self.urlsfromclip.setChecked(prefs['urlsfromclip']) self.l.addWidget(self.urlsfromclip) - self.updatedefault = QCheckBox('Default to Update when books selected?',self) - self.updatedefault.setToolTip('The top FanFictionDownLoader plugin button will start Update if\n'+ - 'books are selected. If unchecked, it will always bring up \'Add New\'.') + self.updatedefault = QCheckBox(_('Default to Update when books selected?'),self) + self.updatedefault.setToolTip(_('The top FanFictionDownLoader plugin button will start Update if\nbooks are selected. If unchecked, it will always bring up \'Add New\'.')) self.updatedefault.setChecked(prefs['updatedefault']) self.l.addWidget(self.updatedefault) - self.adddialogstaysontop = QCheckBox("Keep 'Add New from URL(s)' dialog on top?",self) - self.adddialogstaysontop.setToolTip("Instructs the OS and Window Manager to keep the 'Add New from URL(s)'\ndialog on top of all other windows. Useful for dragging URLs onto it.") + self.adddialogstaysontop = QCheckBox(_("Keep 'Add New from URL(s)' dialog on top?"),self) + self.adddialogstaysontop.setToolTip(_("Instructs the OS and Window Manager to keep the 'Add New from URL(s)'\ndialog on top of all other windows. Useful for dragging URLs onto it.")) self.adddialogstaysontop.setChecked(prefs['adddialogstaysontop']) self.l.addWidget(self.adddialogstaysontop) - misc_gb = groupbox = QGroupBox("Misc Options") + misc_gb = groupbox = QGroupBox(_("Misc Options")) self.l = QVBoxLayout() groupbox.setLayout(self.l) # this is a cheat to make it easier for users to realize there's a new include_images features. - self.includeimages = QCheckBox("Include images in EPUBs?",self) - self.includeimages.setToolTip("Download and include images in EPUB stories. This is equivalent to adding:\n\n[epub]\ninclude_images:true\nkeep_summary_html:true\nmake_firstimage_cover:true\n\n ...to the top of personal.ini. Your settings in personal.ini will override this.") + self.includeimages = QCheckBox(_("Include images in EPUBs?"),self) + self.includeimages.setToolTip(_("Download and include images in EPUB stories. This is equivalent to adding:%(imgset)s ...to the top of %(pini)s. Your settings in %(pini)s will override this.")%no_trans) self.includeimages.setChecked(prefs['includeimages']) self.l.addWidget(self.includeimages) - self.injectseries = QCheckBox("Inject calibre Series when none found?",self) - self.injectseries.setToolTip("If no series is found, inject the calibre series (if there is one) so it appears on the FFDL title page(not cover).") + self.injectseries = QCheckBox(_("Inject calibre Series when none found?"),self) + self.injectseries.setToolTip(_("If no series is found, inject the calibre series (if there is one) so it appears on the FFDL title page(not cover).")) self.injectseries.setChecked(prefs['injectseries']) self.l.addWidget(self.injectseries) - rej_gb = groupbox = QGroupBox("Reject List") + rej_gb = groupbox = QGroupBox(_("Reject List")) self.l = QVBoxLayout() groupbox.setLayout(self.l) - self.rejectlist = QPushButton('Edit Reject URL List', self) - self.rejectlist.setToolTip("Edit list of URLs FFDL will automatically Reject.") + self.rejectlist = QPushButton(_('Edit Reject URL List'), self) + self.rejectlist.setToolTip(_("Edit list of URLs FFDL will automatically Reject.")) self.rejectlist.clicked.connect(self.show_rejectlist) self.l.addWidget(self.rejectlist) - self.reject_urls = QPushButton('Add Reject URLs', self) - self.reject_urls.setToolTip("Add additional URLs to Reject as text.") + self.reject_urls = QPushButton(_('Add Reject URLs'), self) + self.reject_urls.setToolTip(_("Add additional URLs to Reject as text.")) self.reject_urls.clicked.connect(self.add_reject_urls) self.l.addWidget(self.reject_urls) - self.reject_reasons = QPushButton('Edit Reject Reasons List', self) - self.reject_reasons.setToolTip("Customize the Reasons presented when Rejecting URLs") + self.reject_reasons = QPushButton(_('Edit Reject Reasons List'), self) + self.reject_reasons.setToolTip(_("Customize the Reasons presented when Rejecting URLs")) self.reject_reasons.clicked.connect(self.show_reject_reasons) self.l.addWidget(self.reject_reasons) @@ -483,7 +509,7 @@ class BasicTab(QWidget): d = RejectListDialog(self, rejecturllist.get_list(), rejectreasons=rejecturllist.get_reject_reasons(), - header="Edit Reject URLs List", + header=_("Edit Reject URLs List"), show_delete=False, show_all_reasons=False) d.exec_() @@ -497,22 +523,22 @@ class BasicTab(QWidget): d = EditTextDialog(self, prefs['rejectreasons'], icon=self.windowIcon(), - title="Reject Reasons", - label="Customize Reject List Reasons", - tooltip="Customize the Reasons presented when Rejecting URLs") + title=_("Reject Reasons"), + label=_("Customize Reject List Reasons"), + tooltip=_("Customize the Reasons presented when Rejecting URLs")) d.exec_() if d.result() == d.Accepted: prefs['rejectreasons'] = d.get_plain_text() def add_reject_urls(self): d = EditTextDialog(self, - "http://example.com/story.php?sid=5,Reason why I rejected it\nhttp://example.com/story.php?sid=6,Title by Author - Reason why I rejected it", + "http://example.com/story.php?sid=5,"+_("Reason why I rejected it")+"\nhttp://example.com/story.php?sid=6,"+_("Title by Author")+" - "+_("Reason why I rejected it"), icon=self.windowIcon(), - title="Add Reject URLs", - label="Add Reject URLs. Use: http://...,note or http://...,title by author - note
Invalid story URLs will be ignored.", - tooltip="One URL per line:\nhttp://...,note\nhttp://...,title by author - note", + title=_("Add Reject URLs"), + label=_("Add Reject URLs. Use: http://...,note or http://...,title by author - note
Invalid story URLs will be ignored."), + tooltip=_("One URL per line:\nhttp://...,note\nhttp://...,title by author - note"), rejectreasons=rejecturllist.get_reject_reasons(), - reasonslabel='Add this reason to all URLs added:') + reasonslabel=_('Add this reason to all URLs added:')) d.exec_() if d.result() == d.Accepted: rejecturllist.add_text(d.get_plain_text(),d.get_reason_text()) @@ -527,7 +553,7 @@ class PersonalIniTab(QWidget): self.l = QVBoxLayout() self.setLayout(self.l) - label = QLabel('These settings provide more detailed control over what metadata will be displayed inside the ebook as well as let you set is_adult and user/password for different sites.') + label = QLabel(_('These settings provide more detailed control over what metadata will be displayed inside the ebook as well as let you set %(isa)s and %(u)s/%(p)s for different sites.')%no_trans) label.setWordWrap(True) self.l.addWidget(label) self.l.addSpacing(5) @@ -545,8 +571,8 @@ class PersonalIniTab(QWidget): self.ini.setText(prefs['personal.ini']) self.l.addWidget(self.ini) - self.defaults = QPushButton('View Defaults (plugin-defaults.ini)', self) - self.defaults.setToolTip("View all of the plugin's configurable settings\nand their default settings.") + self.defaults = QPushButton(_('View Defaults')+' (plugin-defaults.ini)', self) + self.defaults.setToolTip(_("View all of the plugin's configurable settings\nand their default settings.")) self.defaults.clicked.connect(self.show_defaults) self.l.addWidget(self.defaults) @@ -564,14 +590,14 @@ class ShowDefaultsIniDialog(QDialog): self.resize(600, 500) self.l = QVBoxLayout() self.setLayout(self.l) - self.label = QLabel("Plugin Defaults (plugin-defaults.ini) (Read-Only)") - self.label.setToolTip("These are all of the plugin's configurable options\nand their default settings.") + self.label = QLabel(_("Plugin Defaults (%s) (Read-Only)")%'plugin-defaults.ini') + self.label.setToolTip(_("These are all of the plugin's configurable options\nand their default settings.")) self.setWindowTitle(_('Plugin Defaults')) self.setWindowIcon(icon) self.l.addWidget(self.label) self.ini = QTextEdit(self) - self.ini.setToolTip("These are all of the plugin's configurable options\nand their default settings.") + self.ini.setToolTip(_("These are all of the plugin's configurable options\nand their default settings.")) try: self.ini.setFont(QFont("Courier", get_gui().font().pointSize()+1)) @@ -582,7 +608,7 @@ class ShowDefaultsIniDialog(QDialog): self.ini.setReadOnly(True) self.l.addWidget(self.ini) - self.ok_button = QPushButton('OK', self) + self.ok_button = QPushButton(_('OK'), self) self.ok_button.clicked.connect(self.hide) self.l.addWidget(self.ok_button) @@ -602,45 +628,45 @@ class ReadingListTab(QWidget): except KeyError: reading_lists= [] - label = QLabel('These settings provide integration with the Reading List Plugin. Reading List can automatically send to devices and change custom columns. You have to create and configure the lists in Reading List to be useful.') + label = QLabel(_('These settings provide integration with the %(rl)s Plugin. %(rl)s can automatically send to devices and change custom columns. You have to create and configure the lists in %(rl)s to be useful.')%no_trans) label.setWordWrap(True) self.l.addWidget(label) self.l.addSpacing(5) - self.addtolists = QCheckBox('Add new/updated stories to "Send to Device" Reading List(s).',self) - self.addtolists.setToolTip('Automatically add new/updated stories to these lists in the Reading List plugin.') + self.addtolists = QCheckBox(_('Add new/updated stories to "Send to Device" Reading List(s).'),self) + self.addtolists.setToolTip(_('Automatically add new/updated stories to these lists in the %(rl)s plugin.')%no_trans) self.addtolists.setChecked(prefs['addtolists']) self.l.addWidget(self.addtolists) horz = QHBoxLayout() - label = QLabel('"Send to Device" Reading Lists') - label.setToolTip("When enabled, new/updated stories will be automatically added to these lists.") + label = QLabel(_('"Send to Device" Reading Lists')) + label.setToolTip(_("When enabled, new/updated stories will be automatically added to these lists.")) horz.addWidget(label) self.send_lists_box = MultiCompleteLineEdit(self) - self.send_lists_box.setToolTip("When enabled, new/updated stories will be automatically added to these lists.") + self.send_lists_box.setToolTip(_("When enabled, new/updated stories will be automatically added to these lists.")) self.send_lists_box.update_items_cache(reading_lists) self.send_lists_box.setText(prefs['send_lists']) horz.addWidget(self.send_lists_box) self.l.addLayout(horz) - self.addtoreadlists = QCheckBox('Add new/updated stories to "To Read" Reading List(s).',self) - self.addtoreadlists.setToolTip('Automatically add new/updated stories to these lists in the Reading List plugin.\nAlso offers menu option to remove stories from the "To Read" lists.') + self.addtoreadlists = QCheckBox(_('Add new/updated stories to "To Read" Reading List(s).'),self) + self.addtoreadlists.setToolTip(_('Automatically add new/updated stories to these lists in the %(rl)s plugin.\nAlso offers menu option to remove stories from the "To Read" lists.')%no_trans) self.addtoreadlists.setChecked(prefs['addtoreadlists']) self.l.addWidget(self.addtoreadlists) horz = QHBoxLayout() - label = QLabel('"To Read" Reading Lists') - label.setToolTip("When enabled, new/updated stories will be automatically added to these lists.") + label = QLabel(_('"To Read" Reading Lists')) + label.setToolTip(_("When enabled, new/updated stories will be automatically added to these lists.")) horz.addWidget(label) self.read_lists_box = MultiCompleteLineEdit(self) - self.read_lists_box.setToolTip("When enabled, new/updated stories will be automatically added to these lists.") + self.read_lists_box.setToolTip(_("When enabled, new/updated stories will be automatically added to these lists.")) self.read_lists_box.update_items_cache(reading_lists) self.read_lists_box.setText(prefs['read_lists']) horz.addWidget(self.read_lists_box) self.l.addLayout(horz) - self.addtolistsonread = QCheckBox('Add stories back to "Send to Device" Reading List(s) when marked "Read".',self) - self.addtolistsonread.setToolTip('Menu option to remove from "To Read" lists will also add stories back to "Send to Device" Reading List(s)') + self.addtolistsonread = QCheckBox(_('Add stories back to "Send to Device" Reading List(s) when marked "Read".'),self) + self.addtolistsonread.setToolTip(_('Menu option to remove from "To Read" lists will also add stories back to "Send to Device" Reading List(s)')) self.addtolistsonread.setChecked(prefs['addtolistsonread']) self.l.addWidget(self.addtolistsonread) @@ -662,7 +688,7 @@ class GenerateCoverTab(QWidget): except KeyError: gc_settings= [] - label = QLabel('The Generate Cover plugin can create cover images for books using various metadata and configurations. If you have GC installed, FFDL can run GC on new downloads and metadata updates. Pick a GC setting by site or Default.') + label = QLabel(_('The %(gc)s plugin can create cover images for books using various metadata and configurations. If you have GC installed, FFDL can run GC on new downloads and metadata updates. Pick a GC setting by site or Default.')%no_trans) label.setWordWrap(True) self.l.addWidget(label) self.l.addSpacing(5) @@ -680,14 +706,15 @@ class GenerateCoverTab(QWidget): sitelist = getConfigSections() sitelist.sort() - sitelist.insert(0,u"Default") + sitelist.insert(0,_("Default")) for site in sitelist: horz = QHBoxLayout() label = QLabel(site) - if site == u"Default": - s = "On Metadata update, run Generate Cover with this setting, if not selected for specific site." + if site == _("Default"): + s = _("On Metadata update, run %(gc)s with this setting, if not selected for specific site.")%no_trans else: - s = "On Metadata update, run Generate Cover with this setting for %s stories."%site + no_trans['site']=site # not ideal, but, meh. + s = _("On Metadata update, run %(gc)s with this setting for %(site)s stories.")%no_trans label.setToolTip(s) horz.addWidget(label) @@ -705,13 +732,13 @@ class GenerateCoverTab(QWidget): self.sl.insertStretch(-1) - self.gcnewonly = QCheckBox("Run Generate Cover Only on New Books",self) - self.gcnewonly.setToolTip("Default is to run GC any time the calibre metadata is updated.") + self.gcnewonly = QCheckBox(_("Run %(gc)s Only on New Books")%no_trans,self) + self.gcnewonly.setToolTip(_("Default is to run GC any time the calibre metadata is updated.")) self.gcnewonly.setChecked(prefs['gcnewonly']) self.l.addWidget(self.gcnewonly) - self.allow_gc_from_ini = QCheckBox('Allow generate_cover_settings from personal.ini to override',self) - self.allow_gc_from_ini.setToolTip("The personal.ini parameter generate_cover_settings allows you to choose a GC setting based on metadata rather than site, but it's much more complex.
generate_cover_settings is ignored when this is off.") + self.allow_gc_from_ini = QCheckBox(_('Allow %(gcset)s from %(pini)s to override')%no_trans,self) + self.allow_gc_from_ini.setToolTip(_("The %(pini)s parameter %(gcset)s allows you to choose a GC setting based on metadata rather than site, but it's much more complex.
%(gcset)s is ignored when this is off.")%no_trans) self.allow_gc_from_ini.setChecked(prefs['allow_gc_from_ini']) self.l.addWidget(self.allow_gc_from_ini) @@ -725,39 +752,41 @@ class CountPagesTab(QWidget): self.l = QVBoxLayout() self.setLayout(self.l) - label = QLabel('These settings provide integration with the Count Pages Plugin. Count Pages can automatically update custom columns with page, word and reading level statistics. You have to create and configure the columns in Count Pages first.') + label = QLabel(_('These settings provide integration with the %(cp)s Plugin. %(cp)s can automatically update custom columns with page, word and reading level statistics. You have to create and configure the columns in %(cp)s first.')%no_trans) label.setWordWrap(True) self.l.addWidget(label) self.l.addSpacing(5) - label = QLabel('If any of the settings below are checked, when stories are added or updated, the Count Pages Plugin will be called to update the checked statistics.') + label = QLabel(_('If any of the settings below are checked, when stories are added or updated, the %(cp)s Plugin will be called to update the checked statistics.')%no_trans) label.setWordWrap(True) self.l.addWidget(label) self.l.addSpacing(5) - + + # the same for all settings. Mostly. + tooltip = _('Which column and algorithm to use are configured in %(cp)s.')%no_trans # 'PageCount', 'WordCount', 'FleschReading', 'FleschGrade', 'GunningFog' self.pagecount = QCheckBox('Page Count',self) - self.pagecount.setToolTip('Which column and algorithm to use are configured in Count Pages.') + self.pagecount.setToolTip(tooltip) self.pagecount.setChecked('PageCount' in prefs['countpagesstats']) self.l.addWidget(self.pagecount) self.wordcount = QCheckBox('Word Count',self) - self.wordcount.setToolTip('Which column and algorithm to use are configured in Count Words.\nWill overwrite word count from FFDL metadata if set to update the same custom column.') + self.wordcount.setToolTip(tooltip+"\n"+_('Will overwrite word count from FFDL metadata if set to update the same custom column.')) self.wordcount.setChecked('WordCount' in prefs['countpagesstats']) self.l.addWidget(self.wordcount) self.fleschreading = QCheckBox('Flesch Reading Ease',self) - self.fleschreading.setToolTip('Which column and algorithm to use are configured in Count Pages.') + self.fleschreading.setToolTip(tooltip) self.fleschreading.setChecked('FleschReading' in prefs['countpagesstats']) self.l.addWidget(self.fleschreading) self.fleschgrade = QCheckBox('Flesch-Kincaid Grade Level',self) - self.fleschgrade.setToolTip('Which column and algorithm to use are configured in Count Pages.') + self.fleschgrade.setToolTip(tooltip) self.fleschgrade.setChecked('FleschGrade' in prefs['countpagesstats']) self.l.addWidget(self.fleschgrade) self.gunningfog = QCheckBox('Gunning Fog Index',self) - self.gunningfog.setToolTip('Which column and algorithm to use are configured in Count Pages.') + self.gunningfog.setToolTip(tooltip) self.gunningfog.setChecked('GunningFog' in prefs['countpagesstats']) self.l.addWidget(self.gunningfog) @@ -773,26 +802,23 @@ class OtherTab(QWidget): self.l = QVBoxLayout() self.setLayout(self.l) - label = QLabel("These controls aren't plugin settings as such, but convenience buttons for setting Keyboard shortcuts and getting all the FanFictionDownLoader confirmation dialogs back again.") + label = QLabel(_("These controls aren't plugin settings as such, but convenience buttons for setting Keyboard shortcuts and getting all the FanFictionDownLoader confirmation dialogs back again.")) label.setWordWrap(True) self.l.addWidget(label) self.l.addSpacing(5) - keyboard_shortcuts_button = QPushButton('Keyboard shortcuts...', self) - keyboard_shortcuts_button.setToolTip(_( - 'Edit the keyboard shortcuts associated with this plugin')) + keyboard_shortcuts_button = QPushButton(_('Keyboard shortcuts...'), self) + keyboard_shortcuts_button.setToolTip(_('Edit the keyboard shortcuts associated with this plugin')) keyboard_shortcuts_button.clicked.connect(parent_dialog.edit_shortcuts) self.l.addWidget(keyboard_shortcuts_button) reset_confirmation_button = QPushButton(_('Reset disabled &confirmation dialogs'), self) - reset_confirmation_button.setToolTip(_( - 'Reset all show me again dialogs for the FanFictionDownLoader plugin')) + reset_confirmation_button.setToolTip(_('Reset all show me again dialogs for the FanFictionDownLoader plugin')) reset_confirmation_button.clicked.connect(self.reset_dialogs) self.l.addWidget(reset_confirmation_button) - view_prefs_button = QPushButton('&View library preferences...', self) - view_prefs_button.setToolTip(_( - 'View data stored in the library database for this plugin')) + view_prefs_button = QPushButton(_('&View library preferences...'), self) + view_prefs_button.setToolTip(_('View data stored in the library database for this plugin')) view_prefs_button.clicked.connect(self.view_prefs) self.l.addWidget(view_prefs_button) @@ -852,35 +878,35 @@ permitted_values['text'] = permitted_values['enumeration'] permitted_values['comments'] = permitted_values['enumeration'] titleLabels = { - 'category':'Category', - 'genre':'Genre', - 'language':'Language', - 'status':'Status', - 'status-C':'Status:Completed', - 'status-I':'Status:In-Progress', - 'series':'Series', - 'characters':'Characters', - 'ships':'Relationships', - 'datePublished':'Published', - 'dateUpdated':'Updated', - 'dateCreated':'Created', - 'rating':'Rating', - 'warnings':'Warnings', - 'numChapters':'Chapters', - 'numWords':'Words', - 'site':'Site', - 'storyId':'Story ID', - 'authorId':'Author ID', - 'extratags':'Extra Tags', - 'title':'Title', - 'storyUrl':'Story URL', - 'description':'Description', - 'author':'Author', - 'authorUrl':'Author URL', - 'formatname':'File Format', - 'formatext':'File Extension', - 'siteabbrev':'Site Abbrev', - 'version':'FFDL Version' + 'category':_('Category'), + 'genre':_('Genre'), + 'language':_('Language'), + 'status':_('Status'), + 'status-C':_('Status:%(cmplt)s')%no_trans, + 'status-I':_('Status:%(inprog)s')%no_trans, + 'series':_('Series'), + 'characters':_('Characters'), + 'ships':_('Relationships'), + 'datePublished':_('Published'), + 'dateUpdated':_('Updated'), + 'dateCreated':_('Created'), + 'rating':_('Rating'), + 'warnings':_('Warnings'), + 'numChapters':_('Chapters'), + 'numWords':_('Words'), + 'site':_('Site'), + 'storyId':_('Story ID'), + 'authorId':_('Author ID'), + 'extratags':_('Extra Tags'), + 'title':_('Title'), + 'storyUrl':_('Story URL'), + 'description':_('Description'), + 'author':_('Author'), + 'authorUrl':_('Author URL'), + 'formatname':_('File Format'), + 'formatext':_('File Extension'), + 'siteabbrev':_('Site Abbrev'), + 'version':_('FFDL Version') } class CustomColumnsTab(QWidget): @@ -895,7 +921,7 @@ class CustomColumnsTab(QWidget): self.l = QVBoxLayout() self.setLayout(self.l) - label = QLabel("If you have custom columns defined, they will be listed below. Choose a metadata value type to fill your columns automatically.") + label = QLabel(_("If you have custom columns defined, they will be listed below. Choose a metadata value type to fill your columns automatically.")) label.setWordWrap(True) self.l.addWidget(label) self.l.addSpacing(5) @@ -920,7 +946,7 @@ class CustomColumnsTab(QWidget): # print("column['%s'] => %s"%(k,v)) horz = QHBoxLayout() label = QLabel(column['name']) - label.setToolTip("Update this %s column(%s) with..."%(key,column['datatype'])) + label.setToolTip(_("Update this %s column(%s) with...")%(key,column['datatype'])) horz.addWidget(label) dropdown = QComboBox(self) dropdown.addItem('',QVariant('none')) @@ -930,13 +956,13 @@ class CustomColumnsTab(QWidget): if key in prefs['custom_cols']: dropdown.setCurrentIndex(dropdown.findData(QVariant(prefs['custom_cols'][key]))) if column['datatype'] == 'enumeration': - dropdown.setToolTip("Metadata values valid for this type of column.\nValues that aren't valid for this enumeration column will be ignored.") + dropdown.setToolTip(_("Metadata values valid for this type of column.")+"\n"+_("Values that aren't valid for this enumeration column will be ignored.")) else: - dropdown.setToolTip("Metadata values valid for this type of column.") + dropdown.setToolTip(_("Metadata values valid for this type of column.")) horz.addWidget(dropdown) - newonlycheck = QCheckBox("New Only",self) - newonlycheck.setToolTip("Write to %s(%s) only for new\nbooks, not updates to existing books."%(column['name'],key)) + newonlycheck = QCheckBox(_("New Only"),self) + newonlycheck.setToolTip(_("Write to %s(%s) only for new\nbooks, not updates to existing books.")%(column['name'],key)) self.custcol_newonlycheck[key] = newonlycheck if key in prefs['custom_cols_newonly']: newonlycheck.setChecked(prefs['custom_cols_newonly'][key]) @@ -947,19 +973,19 @@ class CustomColumnsTab(QWidget): self.sl.insertStretch(-1) self.l.addSpacing(5) - self.allow_custcol_from_ini = QCheckBox('Allow custom_columns_settings from personal.ini to override',self) - self.allow_custcol_from_ini.setToolTip("The personal.ini parameter custom_columns_settings allows you to set custom columns to site specific values that aren't common to all sites.
custom_columns_settings is ignored when this is off.") + self.allow_custcol_from_ini = QCheckBox(_('Allow %(ccset)s from %(pini)s to override')%no_trans,self) + self.allow_custcol_from_ini.setToolTip(_("The %(pini)s parameter %(ccset)s allows you to set custom columns to site specific values that aren't common to all sites.
%(ccset)s is ignored when this is off.")%no_trans) self.allow_custcol_from_ini.setChecked(prefs['allow_custcol_from_ini']) self.l.addWidget(self.allow_custcol_from_ini) self.l.addSpacing(5) - label = QLabel("Special column:") + label = QLabel(_("Special column:")) label.setWordWrap(True) self.l.addWidget(label) horz = QHBoxLayout() - label = QLabel("Update/Overwrite Error Column:") - tooltip="When an update or overwrite of an existing story fails, record the reason in this column.\n(Text and Long Text columns only.)" + label = QLabel(_("Update/Overwrite Error Column:")) + tooltip=_("When an update or overwrite of an existing story fails, record the reason in this column.\n(Text and Long Text columns only.)") label.setToolTip(tooltip) horz.addWidget(label) self.errorcol = QComboBox(self) @@ -984,21 +1010,21 @@ class StandardColumnsTab(QWidget): columns=OrderedDict() - columns["title"]="Title" - columns["authors"]="Author(s)" - columns["publisher"]="Publisher" - columns["tags"]="Tags" - columns["languages"]="Languages" - columns["pubdate"]="Published Date" - columns["timestamp"]="Date" - columns["comments"]="Comments" - columns["series"]="Series" - columns["identifiers"]="Ids(url id only)" + columns["title"]=_("Title") + columns["authors"]=_("Author(s)") + columns["publisher"]=_("Publisher") + columns["tags"]=_("Tags") + columns["languages"]=_("Languages") + columns["pubdate"]=_("Published Date") + columns["timestamp"]=_("Date") + columns["comments"]=_("Comments") + columns["series"]=_("Series") + columns["identifiers"]=_("Ids(url id only)") self.l = QVBoxLayout() self.setLayout(self.l) - label = QLabel("The standard calibre metadata columns are listed below. You may choose whether FFDL will fill each column automatically on updates or only for new books.") + label = QLabel(_("The standard calibre metadata columns are listed below. You may choose whether FFDL will fill each column automatically on updates or only for new books.")) label.setWordWrap(True) self.l.addWidget(label) self.l.addSpacing(5) @@ -1011,8 +1037,8 @@ class StandardColumnsTab(QWidget): #label.setToolTip("Update this %s column(%s) with..."%(key,column['datatype'])) horz.addWidget(label) - newonlycheck = QCheckBox("New Only",self) - newonlycheck.setToolTip("Write to %s only for new\nbooks, not updates to existing books."%column) + newonlycheck = QCheckBox(_("New Only"),self) + newonlycheck.setToolTip(_("Write to %s only for new\nbooks, not updates to existing books.")%column) self.stdcol_newonlycheck[key] = newonlycheck if key in prefs['std_cols_newonly']: newonlycheck.setChecked(prefs['std_cols_newonly'][key]) diff --git a/calibre-plugin/dialogs.py b/calibre-plugin/dialogs.py index bd05698f..1bfd3135 100644 --- a/calibre-plugin/dialogs.py +++ b/calibre-plugin/dialogs.py @@ -29,6 +29,12 @@ from PyQt4.Qt import (QDialog, QTableWidget, QVBoxLayout, QHBoxLayout, QGridLayo from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.complete2 import EditWithComplete +# pulls in translation files for _() strings +try: + load_translations() +except NameError: + pass # load_translations() added in calibre 1.9 + from calibre_plugins.fanfictiondownloader_plugin.common_utils \ import (ReadOnlyTableWidgetItem, ReadOnlyTextIconWidgetItem, SizePersistedDialog, ImageTitleLayout, get_icon) @@ -36,13 +42,13 @@ from calibre_plugins.fanfictiondownloader_plugin.common_utils \ from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader.geturls import get_urls_from_html, get_urls_from_text from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader.adapters import getNormalStoryURL -SKIP=u'Skip' -ADDNEW=u'Add New Book' -UPDATE=u'Update EPUB if New Chapters' -UPDATEALWAYS=u'Update EPUB Always' -OVERWRITE=u'Overwrite if Newer' -OVERWRITEALWAYS=u'Overwrite Always' -CALIBREONLY=u'Update Calibre Metadata Only' +SKIP=_('Skip') +ADDNEW=_('Add New Book') +UPDATE=_('Update EPUB if New Chapters') +UPDATEALWAYS=_('Update EPUB Always') +OVERWRITE=_('Overwrite if Newer') +OVERWRITEALWAYS=_('Overwrite Always') +CALIBREONLY=_('Update Calibre Metadata Only') collision_order=[SKIP, ADDNEW, UPDATE, @@ -51,6 +57,32 @@ collision_order=[SKIP, OVERWRITEALWAYS, CALIBREONLY,] +# best idea I've had for how to deal with config/pref saving the +# collision name in english. +SAVE_SKIP='Skip' +SAVE_ADDNEW='Add New Book' +SAVE_UPDATE='Update EPUB if New Chapters' +SAVE_UPDATEALWAYS='Update EPUB Always' +SAVE_OVERWRITE='Overwrite if Newer' +SAVE_OVERWRITEALWAYS='Overwrite Always' +SAVE_CALIBREONLY='Update Calibre Metadata Only' +save_collisions={ + SKIP:SAVE_SKIP, + ADDNEW:SAVE_ADDNEW, + UPDATE:SAVE_UPDATE, + UPDATEALWAYS:SAVE_UPDATEALWAYS, + OVERWRITE:SAVE_OVERWRITE, + OVERWRITEALWAYS:SAVE_OVERWRITEALWAYS, + CALIBREONLY:SAVE_CALIBREONLY, + SAVE_SKIP:SKIP, + SAVE_ADDNEW:ADDNEW, + SAVE_UPDATE:UPDATE, + SAVE_UPDATEALWAYS:UPDATEALWAYS, + SAVE_OVERWRITE:OVERWRITE, + SAVE_OVERWRITEALWAYS:OVERWRITEALWAYS, + SAVE_CALIBREONLY:CALIBREONLY, + } + anthology_collision_order=[UPDATE, UPDATEALWAYS, OVERWRITEALWAYS] @@ -104,7 +136,7 @@ class RejectUrlEntry: def fullnote(self): retval = "" if self.title and self.auth: - retval = retval + "%s by %s"%(self.title,self.auth) + retval = retval + _("%s by %s")%(self.title,self.auth) if self.note: retval = retval + " - " @@ -192,7 +224,7 @@ class AddNewDialog(SizePersistedDialog): self.l = QVBoxLayout() self.setLayout(self.l) - self.setWindowTitle('FanFictionDownLoader') + self.setWindowTitle(_('FanFictionDownLoader')) self.setWindowIcon(icon) self.toplabel=QLabel("Toplabel") @@ -209,7 +241,7 @@ class AddNewDialog(SizePersistedDialog): # elements to show again when doing *update* merge self.mergeupdateshow = [] - self.groupbox = QGroupBox("Show Download Options") + self.groupbox = QGroupBox(_("Show Download Options")) self.groupbox.setCheckable(True) self.groupbox.setChecked(False) self.groupbox.setFlat(True) @@ -228,7 +260,7 @@ class AddNewDialog(SizePersistedDialog): self.groupbox.toggled.connect(self.gbf.setVisible) horz = QHBoxLayout() - label = QLabel('Output &Format:') + label = QLabel(_('Output &Format:')) self.mergehide.append(label) self.fileform = QComboBox(self) @@ -236,7 +268,7 @@ class AddNewDialog(SizePersistedDialog): self.fileform.addItem('mobi') self.fileform.addItem('html') self.fileform.addItem('txt') - self.fileform.setToolTip('Choose output format to create. May set default from plugin configuration.') + self.fileform.setToolTip(_('Choose output format to create. May set default from plugin configuration.')) self.fileform.activated.connect(self.set_collisions) horz.addWidget(label) @@ -252,7 +284,7 @@ class AddNewDialog(SizePersistedDialog): self.collision.setToolTip("CollisionToolTip") # add collision options self.set_collisions() - i = self.collision.findText(prefs['collision']) + i = self.collision.findText(save_collisions[prefs['collision']]) if i > -1: self.collision.setCurrentIndex(i) self.collisionlabel.setBuddy(self.collision) @@ -264,15 +296,15 @@ class AddNewDialog(SizePersistedDialog): self.mergeupdateshow.append(self.collision) horz = QHBoxLayout() - self.updatemeta = QCheckBox('Update Calibre &Metadata?',self) - self.updatemeta.setToolTip("Update metadata for existing stories in Calibre from web site?\n(Columns set to 'New Only' in the column tabs will only be set for new books.)") + self.updatemeta = QCheckBox(_('Update Calibre &Metadata?'),self) + self.updatemeta.setToolTip(_("Update metadata for existing stories in Calibre from web site?\n(Columns set to 'New Only' in the column tabs will only be set for new books.)")) self.updatemeta.setChecked(prefs['updatemeta']) horz.addWidget(self.updatemeta) self.mergehide.append(self.updatemeta) self.mergeupdateshow.append(self.updatemeta) - self.updateepubcover = QCheckBox('Update EPUB Cover?',self) - self.updateepubcover.setToolTip('Update book cover image from site or defaults (if found) inside the EPUB when EPUB is updated.') + self.updateepubcover = QCheckBox(_('Update EPUB Cover?'),self) + self.updateepubcover.setToolTip(_('Update book cover image from site or defaults (if found) inside the EPUB when EPUB is updated.')) self.updateepubcover.setChecked(prefs['updateepubcover']) horz.addWidget(self.updateepubcover) self.mergehide.append(self.updateepubcover) @@ -319,10 +351,10 @@ class AddNewDialog(SizePersistedDialog): self.groupbox.setVisible(not(self.merge and self.newmerge)) if self.merge: - self.toplabel.setText('Story URL(s) for anthology, one per line:') - self.url.setToolTip('URLs for stories to include in the anthology, one per line.\nWill take URLs from clipboard, but only valid URLs.') - self.collisionlabel.setText('If Story Already Exists in Anthology?') - self.collision.setToolTip("What to do if there's already an existing story with the same URL in the anthology.") + self.toplabel.setText(_('Story URL(s) for anthology, one per line:')) + self.url.setToolTip(_('URLs for stories to include in the anthology, one per line.\nWill take URLs from clipboard, but only valid URLs.')) + self.collisionlabel.setText(_('If Story Already Exists in Anthology?')) + self.collision.setToolTip(_("What to do if there's already an existing story with the same URL in the anthology.")) for widget in self.mergehide: widget.setVisible(False) if not self.newmerge: @@ -331,10 +363,10 @@ class AddNewDialog(SizePersistedDialog): else: for widget in self.mergehide: widget.setVisible(True) - self.toplabel.setText('Story URL(s), one per line:') - self.url.setToolTip('URLs for stories, one per line.\nWill take URLs from clipboard, but only valid URLs.\nAdd [1,5] after the URL to limit the download to chapters 1-5.') - self.collisionlabel.setText('If Story Already Exists?') - self.collision.setToolTip("What to do if there's already an existing story with the same URL or title and author.") + self.toplabel.setText(_('Story URL(s), one per line:')) + self.url.setToolTip(_('URLs for stories, one per line.\nWill take URLs from clipboard, but only valid URLs.\nAdd [1,5] after the URL to limit the download to chapters 1-5.')) + self.collisionlabel.setText(_('If Story Already Exists?')) + self.collision.setToolTip(_("What to do if there's already an existing story with the same URL or title and author.")) # Need to re-able after hiding/showing self.setAcceptDrops(True) @@ -350,10 +382,10 @@ class AddNewDialog(SizePersistedDialog): # add collision options self.set_collisions() - - i = self.collision.findText(self.prefs['collision']) + i = self.collision.findText(save_collisions[self.prefs['collision']]) if i > -1: self.collision.setCurrentIndex(i) + self.updatemeta.setChecked(self.prefs['updatemeta']) if not self.merge: @@ -434,18 +466,18 @@ class CollectURLDialog(SizePersistedDialog): self.url.setText(url_text) self.l.addWidget(self.url,1,1,1,2) - self.indiv_button = QPushButton('For Individual Books', self) - self.indiv_button.setToolTip('Get URLs and go to dialog for individual story downloads.') + self.indiv_button = QPushButton(_('For Individual Books'), self) + self.indiv_button.setToolTip(_('Get URLs and go to dialog for individual story downloads.')) self.indiv_button.clicked.connect(self.indiv) self.l.addWidget(self.indiv_button,2,0) - self.merge_button = QPushButton('For Anthology Epub', self) - self.merge_button.setToolTip('Get URLs and go to dialog for Anthology download.\nRequires EpubMerge 1.3.1+ plugin.') + self.merge_button = QPushButton(_('For Anthology Epub'), self) + self.merge_button.setToolTip(_('Get URLs and go to dialog for Anthology download.\nRequires %s plugin.')%'EpubMerge 1.3.1+') self.merge_button.clicked.connect(self.merge) self.l.addWidget(self.merge_button,2,1) self.merge_button.setEnabled(epubmerge_plugin!=None) - self.cancel_button = QPushButton('Cancel', self) + self.cancel_button = QPushButton(_('Cancel'), self) self.cancel_button.clicked.connect(self.cancel) self.l.addWidget(self.cancel_button,2,2) @@ -477,29 +509,29 @@ class UserPassDialog(QDialog): self.setLayout(self.l) if exception.passwdonly: - self.setWindowTitle('Password') - self.l.addWidget(QLabel("Author requires a password for this story(%s)."%exception.url),0,0,1,2) + self.setWindowTitle(_('Password')) + self.l.addWidget(QLabel(_("Author requires a password for this story(%s).")%exception.url),0,0,1,2) # user isn't used, but it's easier to still have it for # post processing. self.user = FakeLineEdit() else: - self.setWindowTitle('User/Password') - self.l.addWidget(QLabel("%s requires you to login to download this story."%site),0,0,1,2) + self.setWindowTitle(_('User/Password')) + self.l.addWidget(QLabel(_("%s requires you to login to download this story.")%site),0,0,1,2) - self.l.addWidget(QLabel("User:"),1,0) + self.l.addWidget(QLabel(_("User:")),1,0) self.user = QLineEdit(self) self.l.addWidget(self.user,1,1) - self.l.addWidget(QLabel("Password:"),2,0) + self.l.addWidget(QLabel(_("Password:")),2,0) self.passwd = QLineEdit(self) self.passwd.setEchoMode(QLineEdit.Password) self.l.addWidget(self.passwd,2,1) - self.ok_button = QPushButton('OK', self) + self.ok_button = QPushButton(_('OK'), self) self.ok_button.clicked.connect(self.ok) self.l.addWidget(self.ok_button,3,0) - self.cancel_button = QPushButton('Cancel', self) + self.cancel_button = QPushButton(_('Cancel'), self) self.cancel_button.clicked.connect(self.cancel) self.l.addWidget(self.cancel_button,3,1) @@ -521,9 +553,9 @@ class LoopProgressDialog(QProgressDialog): book_list, foreach_function, finish_function, - init_label="Fetching metadata for stories...", - win_title="Downloading metadata for stories", - status_prefix="Fetched metadata for"): + init_label=_("Fetching metadata for stories..."), + win_title=_("Downloading metadata for stories"), + status_prefix=_("Fetched metadata for")): QProgressDialog.__init__(self, init_label, QString(), 0, len(book_list), gui) @@ -541,7 +573,7 @@ class LoopProgressDialog(QProgressDialog): self.exec_() def updateStatus(self): - self.setLabelText("%s %d of %d"%(self.status_prefix,self.i+1,len(self.book_list))) + self.setLabelText("%s %d / %d"%(self.status_prefix,self.i+1,len(self.book_list))) self.setValue(self.i+1) #print(self.labelText()) @@ -647,7 +679,7 @@ class UpdateExistingDialog(SizePersistedDialog): spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) button_layout.addItem(spacerItem) self.remove_button = QtGui.QToolButton(self) - self.remove_button.setToolTip('Remove selected books from the list') + self.remove_button.setToolTip(_('Remove selected books from the list')) self.remove_button.setIcon(get_icon('list_remove.png')) self.remove_button.clicked.connect(self.remove_from_list) button_layout.addWidget(self.remove_button) @@ -656,7 +688,7 @@ class UpdateExistingDialog(SizePersistedDialog): options_layout = QHBoxLayout() - groupbox = QGroupBox("Show Download Options") + groupbox = QGroupBox(_("Show Download Options")) groupbox.setCheckable(True) groupbox.setChecked(False) groupbox.setFlat(True) @@ -673,7 +705,7 @@ class UpdateExistingDialog(SizePersistedDialog): gbf.setVisible(False) groupbox.toggled.connect(gbf.setVisible) - label = QLabel('Output &Format:') + label = QLabel(_('Output &Format:')) gbl.addWidget(label) self.fileform = QComboBox(self) self.fileform.addItem('epub') @@ -681,30 +713,30 @@ class UpdateExistingDialog(SizePersistedDialog): self.fileform.addItem('html') self.fileform.addItem('txt') self.fileform.setCurrentIndex(self.fileform.findText(prefs['fileform'])) - self.fileform.setToolTip('Choose output format to create. May set default from plugin configuration.') + self.fileform.setToolTip(_('Choose output format to create. May set default from plugin configuration.')) self.fileform.activated.connect(self.set_collisions) label.setBuddy(self.fileform) gbl.addWidget(self.fileform) - label = QLabel('Update Mode:') + label = QLabel(_('Update Mode:')) gbl.addWidget(label) self.collision = QComboBox(self) - self.collision.setToolTip("What sort of update to perform. May set default from plugin configuration.") + self.collision.setToolTip(_("What sort of update to perform. May set default from plugin configuration.")) # add collision options self.set_collisions() - i = self.collision.findText(prefs['collision']) + i = self.collision.findText(save_collisions[prefs['collision']]) if i > -1: self.collision.setCurrentIndex(i) label.setBuddy(self.collision) gbl.addWidget(self.collision) - self.updatemeta = QCheckBox('Update Calibre &Metadata?',self) - self.updatemeta.setToolTip("Update metadata for existing stories in Calibre from web site?\n(Columns set to 'New Only' in the column tabs will only be set for new books.)") + self.updatemeta = QCheckBox(_('Update Calibre &Metadata?'),self) + self.updatemeta.setToolTip(_("Update metadata for existing stories in Calibre from web site?\n(Columns set to 'New Only' in the column tabs will only be set for new books.)")) self.updatemeta.setChecked(prefs['updatemeta']) gbl.addWidget(self.updatemeta) - self.updateepubcover = QCheckBox('Update EPUB Cover?',self) - self.updateepubcover.setToolTip('Update book cover image from site or defaults (if found) inside the EPUB when EPUB is updated.') + self.updateepubcover = QCheckBox(_('Update EPUB Cover?'),self) + self.updateepubcover.setToolTip(_('Update book cover image from site or defaults (if found) inside the EPUB when EPUB is updated.')) self.updateepubcover.setChecked(prefs['updateepubcover']) gbl.addWidget(self.updateepubcover) @@ -757,7 +789,7 @@ class StoryListTableWidget(QTableWidget): self.clear() self.setAlternatingRowColors(True) self.setRowCount(len(books)) - header_labels = ['','Title', 'Author', 'URL', 'Comment'] + header_labels = ['',_('Title'), _('Author'), 'URL', _('Comment')] self.setColumnCount(len(header_labels)) self.setHorizontalHeaderLabels(header_labels) self.horizontalHeader().setStretchLastSection(True) @@ -825,9 +857,9 @@ class StoryListTableWidget(QTableWidget): rows = self.selectionModel().selectedRows() if len(rows) == 0: return - message = '

Are you sure you want to remove this book from the list?' + message = '

'+_('Are you sure you want to remove this book from the list?') if len(rows) > 1: - message = '

Are you sure you want to remove the selected %d books from the list?'%len(rows) + message = '

'+_('Are you sure you want to remove the selected %d books from the list?')%len(rows) if not confirm(message,'fanfictiondownloader_delete_item', self): return first_sel_row = self.currentRow() @@ -853,7 +885,7 @@ class RejectListTableWidget(QTableWidget): self.clear() self.setAlternatingRowColors(True) self.setRowCount(len(reject_list)) - header_labels = ['URL', 'Title', 'Author', 'Note'] + header_labels = ['URL', _('Title'), _('Author'), _('Note')] self.setColumnCount(len(header_labels)) self.setHorizontalHeaderLabels(header_labels) self.horizontalHeader().setStretchLastSection(True) @@ -895,7 +927,7 @@ class RejectListTableWidget(QTableWidget): note_cell.update_items_cache(items) note_cell.show_initial_value(rej.note) note_cell.set_separator(None) - note_cell.setToolTip('Select or Edit Reject Note.') + note_cell.setToolTip(_('Select or Edit Reject Note.')) self.setCellWidget(row, 3, note_cell) def remove_selected_rows(self): @@ -903,9 +935,9 @@ class RejectListTableWidget(QTableWidget): rows = self.selectionModel().selectedRows() if len(rows) == 0: return - message = '

Are you sure you want to remove this URL from the list?' + message = '

'+_('Are you sure you want to remove this URL from the list?') if len(rows) > 1: - message = '

Are you sure you want to remove the %d selected URLs from the list?'%len(rows) + message = '

'+_('Are you sure you want to remove the %d selected URLs from the list?')%len(rows) if not confirm(message,'ffdl_rejectlist_delete_item_again', self): return first_sel_row = self.currentRow() @@ -923,7 +955,7 @@ class RejectListTableWidget(QTableWidget): class RejectListDialog(SizePersistedDialog): def __init__(self, gui, reject_list, rejectreasons=[], - header="List of Books to Reject", + header=_("List of Books to Reject"), icon='rotate-right.png', show_delete=True, show_all_reasons=True, @@ -936,7 +968,7 @@ class RejectListDialog(SizePersistedDialog): layout = QVBoxLayout(self) self.setLayout(layout) title_layout = ImageTitleLayout(self, icon, header, - 'FFDL will remember these URLs and display the note and offer to reject them if you try to download them again later.') + ''+_('FFDL will remember these URLs and display the note and offer to reject them if you try to download them again later.')) layout.addLayout(title_layout) rejects_layout = QHBoxLayout() layout.addLayout(rejects_layout) @@ -950,7 +982,7 @@ class RejectListDialog(SizePersistedDialog): button_layout.addItem(spacerItem) self.remove_button = QtGui.QToolButton(self) - self.remove_button.setToolTip('Remove selected URL(s) from the list') + self.remove_button.setToolTip(_('Remove selected URL(s) from the list')) self.remove_button.setIcon(get_icon('list_remove.png')) self.remove_button.clicked.connect(self.remove_from_list) button_layout.addWidget(self.remove_button) @@ -968,11 +1000,11 @@ class RejectListDialog(SizePersistedDialog): self.reason_edit.update_items_cache(items) self.reason_edit.show_initial_value('') self.reason_edit.set_separator(None) - self.reason_edit.setToolTip("This will be added to whatever note you've set for each URL above.") + self.reason_edit.setToolTip(_("This will be added to whatever note you've set for each URL above.")) horz = QHBoxLayout() - label = QLabel("Add this reason to all URLs added:") - label.setToolTip("This will be added to whatever note you've set for each URL above.") + label = QLabel(_("Add this reason to all URLs added:")) + label.setToolTip(_("This will be added to whatever note you've set for each URL above.")) horz.addWidget(label) horz.addWidget(self.reason_edit) horz.insertStretch(-1) @@ -981,8 +1013,8 @@ class RejectListDialog(SizePersistedDialog): options_layout = QHBoxLayout() if show_delete: - self.deletebooks = QCheckBox('Delete Books (including books without FanFiction URLs)?',self) - self.deletebooks.setToolTip("Delete the selected books after adding them to the Rejected URLs list.") + self.deletebooks = QCheckBox(_('Delete Books (including books without FanFiction URLs)?'),self) + self.deletebooks.setToolTip(_("Delete the selected books after adding them to the Rejected URLs list.")) self.deletebooks.setChecked(True) options_layout.addWidget(self.deletebooks) diff --git a/calibre-plugin/ffdl_plugin.py b/calibre-plugin/ffdl_plugin.py index 568691a6..1683fd0f 100644 --- a/calibre-plugin/ffdl_plugin.py +++ b/calibre-plugin/ffdl_plugin.py @@ -39,6 +39,12 @@ from calibre.constants import config_dir as calibre_config_dir # The class that all interface action plugins must inherit from from calibre.gui2.actions import InterfaceAction +# pulls in translation files for _() strings +try: + load_translations() +except NameError: + pass # load_translations() added in calibre 1.9 + from calibre_plugins.fanfictiondownloader_plugin.common_utils import (set_plugin_icon_resources, get_icon, create_menu_action_unique, get_library_uuid) @@ -77,7 +83,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): # keyboard shortcuts, so try to use an unusual/unused shortcut. # (text, icon_path, tooltip, keyboard shortcut) # icon_path isn't in the zip--icon loaded below. - action_spec = (name, None, + action_spec = (_('FanFictionDownLoader'), None, _('Download FanFiction stories from various web sites'), ()) # None for keyboard shortcut doesn't allow shortcut. () does, there just isn't one yet @@ -231,78 +237,89 @@ class FanFictionDownLoaderPlugin(InterfaceAction): self.menu.clear() self.actions_unique_map = {} self.menu_actions = [] - self.add_action = self.create_menu_item_ex(self.menu, '&Add New from URL(s)', image='plus.png', + self.add_action = self.create_menu_item_ex(self.menu, _('&Add New from URL(s)'), image='plus.png', unique_name='Add New FanFiction Book(s) from URL(s)', - shortcut_name='Add New FanFiction Book(s) from URL(s)', + shortcut_name=_('Add New FanFiction Book(s) from URL(s)'), triggered=self.add_dialog ) - self.update_action = self.create_menu_item_ex(self.menu, '&Update Existing FanFiction Book(s)', image='plusplus.png', + self.update_action = self.create_menu_item_ex(self.menu, _('&Update Existing FanFiction Book(s)'), image='plusplus.png', + unique_name='&Update Existing FanFiction Book(s)', triggered=self.update_dialog) if self.get_epubmerge_plugin(): self.menu.addSeparator() - self.get_list_url_action = self.create_menu_item_ex(self.menu, 'Get Story URLs to Download from Web Page', image='view.png', + self.get_list_url_action = self.create_menu_item_ex(self.menu, _('Get Story URLs to Download from Web Page'), image='view.png', unique_name='Get Story URLs from Web Page', triggered=self.get_urls_from_page_menu) - self.makeanth_action = self.create_menu_item_ex(self.menu, '&Make Anthology Epub Manually from URL(s)', image='plusplus.png', + self.makeanth_action = self.create_menu_item_ex(self.menu, _('&Make Anthology Epub Manually from URL(s)'), image='plusplus.png', unique_name='Make FanFiction Anthology Epub Manually from URL(s)', - shortcut_name='Make FanFiction Anthology Epub Manually from URL(s)', + shortcut_name=_('Make FanFiction Anthology Epub Manually from URL(s)'), triggered=partial(self.add_dialog,merge=True) ) - self.updateanth_action = self.create_menu_item_ex(self.menu, '&Update Anthology Epub', image='plusplus.png', + self.updateanth_action = self.create_menu_item_ex(self.menu, _('&Update Anthology Epub'), image='plusplus.png', unique_name='Update FanFiction Anthology Epub', - shortcut_name='Update FanFiction Anthology Epub', + shortcut_name=_('Update FanFiction Anthology Epub'), triggered=self.update_anthology) if 'Reading List' in self.gui.iactions and (prefs['addtolists'] or prefs['addtoreadlists']) : + self.menu.addSeparator() addmenutxt, rmmenutxt = None, None if prefs['addtolists'] and prefs['addtoreadlists'] : - addmenutxt = 'Add to "To Read" and "Send to Device" Lists' + addmenutxt = _('Add to "To Read" and "Send to Device" Lists') if prefs['addtolistsonread']: - rmmenutxt = 'Remove from "To Read" and add to "Send to Device" Lists' + rmmenutxt = _('Remove from "To Read" and add to "Send to Device" Lists') else: - rmmenutxt = 'Remove from "To Read" Lists' + rmmenutxt = _('Remove from "To Read" Lists') elif prefs['addtolists'] : - addmenutxt = 'Add Selected to "Send to Device" Lists' + addmenutxt = _('Add Selected to "Send to Device" Lists') elif prefs['addtoreadlists']: - addmenutxt = 'Add to "To Read" Lists' - rmmenutxt = 'Remove from "To Read" Lists' + addmenutxt = _('Add to "To Read" Lists') + rmmenutxt = _('Remove from "To Read" Lists') if addmenutxt: - self.add_send_action = self.create_menu_item_ex(self.menu, addmenutxt, image='plusplus.png', + self.add_send_action = self.create_menu_item_ex(self.menu, addmenutxt, + unique_name='Add to "To Read" and "Send to Device" Lists', + image='plusplus.png', triggered=partial(self.update_lists,add=True)) if rmmenutxt: - self.add_remove_action = self.create_menu_item_ex(self.menu, rmmenutxt, image='minusminus.png', + self.add_remove_action = self.create_menu_item_ex(self.menu, rmmenutxt, + unique_name='Remove from "To Read" and add to "Send to Device" Lists', + image='minusminus.png', triggered=partial(self.update_lists,add=False)) self.menu.addSeparator() - self.get_list_action = self.create_menu_item_ex(self.menu, 'Get URLs from Selected Books', image='bookmarks.png', + self.get_list_action = self.create_menu_item_ex(self.menu, _('Get URLs from Selected Books'), + unique_name='Get URLs from Selected Books', + image='bookmarks.png', triggered=self.list_story_urls) if not self.get_epubmerge_plugin(): - self.get_list_url_action = self.create_menu_item_ex(self.menu, 'Get Story URLs from Web Page', image='view.png', + self.get_list_url_action = self.create_menu_item_ex(self.menu, _('Get Story URLs from Web Page'), + unique_name='Get Story URLs from Web Page', + image='view.png', triggered=self.get_urls_from_page_menu) - self.reject_list_action = self.create_menu_item_ex(self.menu, 'Reject Selected Books', image='rotate-right.png', + self.reject_list_action = self.create_menu_item_ex(self.menu, _('Reject Selected Books'), + unique_name='Reject Selected Books', image='rotate-right.png', triggered=self.reject_list_urls) # print("platform.system():%s"%platform.system()) # print("platform.mac_ver()[0]:%s"%platform.mac_ver()[0]) if not self.check_macmenuhack(): # not platform.mac_ver()[0]: # Some macs crash on these menu items for unknown reasons. self.menu.addSeparator() - self.config_action = self.create_menu_item_ex(self.menu, '&Configure Plugin', + self.config_action = self.create_menu_item_ex(self.menu, _('&Configure Plugin'), image= 'config.png', unique_name='Configure FanFictionDownLoader', - shortcut_name='Configure FanFictionDownLoader', + shortcut_name=_('Configure FanFictionDownLoader'), triggered=partial(do_user_config,parent=self.gui)) - self.about_action = self.create_menu_item_ex(self.menu, 'About Plugin', + self.about_action = self.create_menu_item_ex(self.menu, _('About Plugin'), image= 'images/icon.png', unique_name='About FanFictionDownLoader', - shortcut_name='About FanFictionDownLoader', + shortcut_name=_('About FanFictionDownLoader'), triggered=self.about) # Before we finalize, make sure we delete any actions for menus that are no longer displayed @@ -373,7 +390,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): except: urltxt = "" - d = CollectURLDialog(self.gui,"Get Story URLs from Web Page",urltxt,self.get_epubmerge_plugin()) + d = CollectURLDialog(self.gui,_("Get Story URLs from Web Page"),urltxt,self.get_epubmerge_plugin()) d.exec_() if not d.status: return @@ -418,9 +435,9 @@ class FanFictionDownLoaderPlugin(InterfaceAction): book_list, partial(self.get_list_story_urls_loop, db=self.gui.current_db), self.get_list_story_urls_finish, - init_label="Collecting URLs for stories...", - win_title="Get URLs for stories", - status_prefix="URL retrieved") + init_label=_("Collecting URLs for stories..."), + win_title=_("Get URLs for stories"), + status_prefix=_("URL retrieved")) def get_list_story_urls_loop(self,book,db=None): if book['calibre_id']: @@ -465,9 +482,9 @@ class FanFictionDownLoaderPlugin(InterfaceAction): book_list, partial(self.reject_list_urls_loop, db=self.gui.current_db), self.reject_list_urls_finish, - init_label="Collecting URLs for Reject List...", - win_title="Get URLs for Reject List", - status_prefix="URL retrieved") + init_label=_("Collecting URLs for Reject List..."), + win_title=_("Get URLs for Reject List"), + status_prefix=_("URL retrieved")) def reject_list_urls_loop(self,book,db=None): self.get_list_story_urls_loop(book,db) # common with get_list_story_urls_loop @@ -501,7 +518,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): self.gui.iactions['Remove Books'].do_library_delete(d.get_reject_list_ids()) else: - message="

Rejecting FFDL URLs: None of the books selected have FanFiction URLs.

Proceed to Remove?

" + message="

"+_("Rejecting FFDL URLs: None of the books selected have FanFiction URLs.")+"

"+_("Proceed to Remove?")+"

" if confirm(message,'fanfictiondownloader_reject_non_fanfiction', self.gui): self.gui.iactions['Remove Books'].delete_books() @@ -523,7 +540,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): def update_anthology(self): if not self.get_epubmerge_plugin(): - self.gui.status_bar.show_message(_('Cannot Make Anthologys without EpubMerge 1.3.0+'), 3000) + self.gui.status_bar.show_message(_('Cannot Make Anthologys without %s')%'EpubMerge 1.3.1+', 3000) return if not self.is_library_view(): @@ -559,7 +576,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): if not filenames or len(filenames) != len (url_list): info_dialog(self.gui, _("Cannot Update Anthology"), - _("

Cannot Update Anthology

Book isn't an FFDL Anthology or contains book(s) without valid FFDL URLs."), + "

"+_("Cannot Update Anthology")+"

"+_("Book isn't an FFDL Anthology or contains book(s) without valid FFDL URLs."), show=True, show_copy_button=False) remove_dir(tdir) @@ -611,14 +628,17 @@ class FanFictionDownLoaderPlugin(InterfaceAction): if urlmapfile: text = ''' -

There are %d stories in the current anthology that are not going kept if you go ahead.

-

Story URLs that will be removed:

- -

Update anyway?

- '''%(len(urlmapfile),"
  • ".join(urlmapfile.keys())) - if not question_dialog(self.gui, 'Stories Removed', +

    %s

    +

    %s

    + +

    %s

    '''%( + _('There are %d stories in the current anthology that are not going to be kept if you go ahead.')%len(urlmapfile), + _('Story URLs that will be removed:'), + "
  • ".join(urlmapfile.keys()), + _('Update anyway?')) + if not question_dialog(self.gui, _('Stories Removed'), text, show_copy_button=False): logger.debug("Canceling anthology update due to removed stories.") return @@ -649,9 +669,9 @@ class FanFictionDownLoaderPlugin(InterfaceAction): book_list, partial(self.populate_book_from_calibre_id, db=self.gui.current_db), self.update_dialog_finish, - init_label="Collecting stories for update...", - win_title="Get stories for updates", - status_prefix="URL retrieved") + init_label=_("Collecting stories for update..."), + win_title=_("Get stories for updates"), + status_prefix=_("URL retrieved")) #books = self.convert_calibre_ids_to_books(db, book_ids) #print("update books:%s"%books) @@ -660,7 +680,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): '''Present list to update and head to prep when done.''' d = UpdateExistingDialog(self.gui, - 'Update Existing List', + _('Update Existing List'), prefs, self.qaction.icon(), book_list, @@ -740,23 +760,35 @@ class FanFictionDownLoaderPlugin(InterfaceAction): if not merge: # skip reject list when merging. if rejecturllist.check(url): rejnote = rejecturllist.get_full_note(url) - if question_dialog(self.gui, 'Reject URL?', - '

    Reject URL?

    '+ - '

    %s is on your Reject URL list:

    "%s"

    '%(url,rejnote)+ - "

    Click 'Yes' to Reject.

    "+ - "

    Click 'No' to download anyway.

    ", + if question_dialog(self.gui, _('Reject URL?'),''' +

    %s

    +

    %s

    +

    "%s"

    +

    %s

    +

    %s

    '''%( + _('Reject URL?'), + _('%s is on your Reject URL list:')%url, + rejnote, + _("Click 'Yes' to Reject."), + _("Click 'No' to download anyway.")), show_copy_button=False): - book['comment'] = "Story on Reject URLs list (%s)."%rejnote + book['comment'] = _("Story on Reject URLs list (%s).")%rejnote book['good']=False book['icon']='rotate-right.png' - book['status'] = 'Rejected' + book['status'] = _('Rejected') return else: - if question_dialog(self.gui, 'Remove Reject URL?', - "

    Remove URL from Reject List?

    "+ - '

    %s is on your Reject URL list:

    "%s"

    '%(url,rejnote)+ - "

    Click 'Yes' to remove it from the list,

    "+ - "

    Click 'No' to leave it on the list.

    ", + if question_dialog(self.gui, _('Remove Reject URL?'),''' +

    %s

    +

    %s

    +

    "%s"

    +

    %s

    +

    %s

    '''%( + _("Remove URL from Reject List?"), + _('%s is on your Reject URL list:')%url, + rejnote, + _("Click 'Yes' to remove it from the list,"), + _("Click 'No' to leave it on the list.")), show_copy_button=False): rejecturllist.remove(url) @@ -773,7 +805,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): # Dialogs should prevent this case now. if collision in (UPDATE,UPDATEALWAYS) and fileform != 'epub': - raise NotGoingToDownload("Cannot update non-epub format.") + raise NotGoingToDownload(_("Cannot update non-epub format.")) if not book['good']: # book has already been flagged bad for whatever reason. @@ -798,8 +830,8 @@ class FanFictionDownLoaderPlugin(InterfaceAction): adapter.password = userpass.passwd.text() except exceptions.AdultCheckRequired: - if question_dialog(self.gui, 'Are You Adult?', '

    '+ - "%s requires that you be an adult. Please confirm you are an adult in your locale:"%url, + if question_dialog(self.gui, _('Are You an Adult?'), '

    '+ + _("%s requires that you be an adult. Please confirm you are an adult in your locale:")%url, show_copy_button=False): adapter.is_adult=True @@ -813,19 +845,23 @@ class FanFictionDownLoaderPlugin(InterfaceAction): identicalbooks = db.search_getting_ids(searchstr, None) # print("searchstr:%s"%searchstr) # print("identicalbooks:%s"%identicalbooks) - if len(identicalbooks) > 0 and question_dialog(self.gui, 'Skip Story?', - '

    Skip Anthology Story?

    '+ - '

    "%s" is in series "%s" that you have an anthology book for.

    '% - (story.getMetadata('title'),story.getMetadata('seriesUrl'),series[:series.index(' [')])+ - "

    Click 'Yes' to Skip.

    "+ - "

    Click 'No' to download anyway.

    ", + if len(identicalbooks) > 0 and question_dialog(self.gui, _('Skip Story?'),''' +

    %s

    +

    %s

    +

    %s

    +

    %s

    + '''%( + _('Skip Anthology Story?'), + _('"%s" is in series "%s" that you have an anthology book for.')%(story.getMetadata('title'),story.getMetadata('seriesUrl'),series[:series.index(' [')]), + _("Click 'Yes' to Skip."), + _("Click 'No' to download anyway.")), show_copy_button=False): - book['comment'] = "Story in Series Anthology(%s)."%series + book['comment'] = _("Story in Series Anthology(%s).")%series book['title'] = story.getMetadata('title') book['author'] = [story.getMetadata('author')] book['good']=False book['icon']='rotate-right.png' - book['status'] = 'Skipped' + book['status'] = _('Skipped') return @@ -853,7 +889,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): book['password'] = adapter.password book['icon'] = 'plus.png' - book['status'] = 'Add' + book['status'] = _('Add') if story.getMetadataRaw('datePublished'): book['pubdate'] = story.getMetadataRaw('datePublished').replace(tzinfo=local_tz) if story.getMetadataRaw('dateUpdated'): @@ -866,7 +902,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): if not merge:# skip all the collision code when d/ling for merging. if collision in (CALIBREONLY): book['icon'] = 'metadata.png' - book['status'] = 'Meta' + book['status'] = _('Meta') book_id = None @@ -904,7 +940,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): logger.debug("existing found by identifier URL") if collision == SKIP and identicalbooks: - raise NotGoingToDownload("Skipping duplicate story.","list_remove.png") + raise NotGoingToDownload(_("Skipping duplicate story."),"list_remove.png") if len(identicalbooks) > 1: raise NotGoingToDownload("More than one identical book by Identifer URL or title/author(s)--can't tell which book to update/overwrite.","minusminus.png") @@ -918,47 +954,52 @@ class FanFictionDownLoaderPlugin(InterfaceAction): book_id = identicalbooks.pop() book['calibre_id'] = book_id book['icon'] = 'edit-redo.png' - book['status'] = 'Update' + book['status'] = _('Update') if book_id and mi: # book_id and mi only set if matched by title/author. liburl = self.get_story_url(db,book_id) if book['url'] != liburl and prefs['checkforurlchange']: - if collision in (OVERWRITE,OVERWRITEALWAYS): - updat="overwrit" - else: - updat="updat" - if not question_dialog(self.gui, 'Change Story URL?', - '

    Change Story URL?

    '+ - '

    %s by %s is already in your library with a different source URL:

    '% - (mi.title,', '.join(mi.author))+ - '

    In library: %(liburl)s

    New URL: %(newurl)s

    '% - {'liburl':liburl,'newurl':book['url']}+ - "

    Click 'Yes' to %se book with new URL.

    "%updat+ - "

    Click 'No' to skip %sing this book.

    "%updat, + if not question_dialog(self.gui, _('Change Story URL?'),''' +

    %s

    +

    %s

    +

    %s

    +

    %s

    +

    %s

    +

    %s

    '''%( + _('Change Story URL?'), + _('%s by %s is already in your library with a different source URL:')%(mi.title,', '.join(mi.author)), + _('In library: %(liburl)s')%{'liburl':liburl}, + _('New URL: %(newurl)s')%{'newurl':book['url']}, + _("Click 'Yes' to update/overwrite book with new URL."), + _("Click 'No' to skip updating/overwriting this book.")), show_copy_button=False): - if question_dialog(self.gui, 'Download as New Book?', - '

    Download as New Book?

    '+ - '

    %s by %s is already in your library with a different source URL.

    '% - (mi.title,', '.join(mi.author))+ - '

    You chose not to update the existing book. Do you want to add a new book for this URL?

    '+ - '

    New URL: %(newurl)s

    '% - {'newurl':book['url']}+ - "

    Click 'Yes' to a new book with new URL.

    "+ - "

    Click 'No' to skip URL.

    ", + if question_dialog(self.gui, _('Download as New Book?'),''' +

    %s

    +

    %s

    +

    %s

    +

    %s

    +

    %s

    +

    %s

    '''%( + _('Download as New Book?'), + _('%s by %s is already in your library with a different source URL.')%(mi.title,', '.join(mi.author)), + _('You chose not to update the existing book. Do you want to add a new book for this URL?'), + _('New URL: %(newurl)s')%{'newurl':book['url']}, + _("Click 'Yes' to a new book with new URL."), + _("Click 'No' to skip URL.")), show_copy_button=False): book_id = None mi = None book['calibre_id'] = None else: - book['comment'] = "Update declined by user due to differing story URL(%s)"%liburl + book['comment'] = _("Update declined by user due to differing story URL(%s)")%liburl book['good']=False book['icon']='rotate-right.png' - book['status'] = 'Different URL' + book['status'] = _('Different URL') return if book_id != None and collision != ADDNEW: if collision in (CALIBREONLY): - book['comment'] = 'Metadata collected.' + book['comment'] = _('Metadata collected.') # don't need temp file created below. return @@ -974,14 +1015,14 @@ class FanFictionDownLoaderPlugin(InterfaceAction): urlchaptercount = int(story.getMetadata('numChapters')) if chaptercount == urlchaptercount: if collision == UPDATE: - raise NotGoingToDownload("Already contains %d chapters."%chaptercount,'edit-undo.png') + raise NotGoingToDownload(_("Already contains %d chapters.")%chaptercount,'edit-undo.png') else: # UPDATEALWAYS skip_date_update = True elif chaptercount > urlchaptercount: - raise NotGoingToDownload("Existing epub contains %d chapters, web site only has %d. Use Overwrite to force update." % (chaptercount,urlchaptercount),'dialog_error.png') + raise NotGoingToDownload(_("Existing epub contains %d chapters, web site only has %d. Use Overwrite to force update.") % (chaptercount,urlchaptercount),'dialog_error.png') elif chaptercount == 0: - raise NotGoingToDownload("FFDL doesn't recognize chapters in existing epub, epub is probably from a different source. Use Overwrite to force update.",'dialog_error.png') + raise NotGoingToDownload(_("FFDL doesn't recognize chapters in existing epub, epub is probably from a different source. Use Overwrite to force update."),'dialog_error.png') if collision == OVERWRITE and \ db.has_format(book_id,formmapping[fileform],index_is_id=True): @@ -989,7 +1030,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): lastupdated=story.getMetadataRaw('dateUpdated').date() fileupdated=datetime.fromtimestamp(os.stat(db.format_abspath(book_id, formmapping[fileform], index_is_id=True))[8]).date() if fileupdated > lastupdated: - raise NotGoingToDownload("Not Overwriting, web site is not newer.",'edit-undo.png') + raise NotGoingToDownload(_("Not Overwriting, web site is not newer."),'edit-undo.png') # For update, provide a tmp file copy of the existing epub so # it can't change underneath us. Now also overwrite for logpage preserve. @@ -1053,17 +1094,19 @@ class FanFictionDownLoaderPlugin(InterfaceAction): ## No good stories to try to download, go straight to ## updating error col. msg = ''' -

    None of the %d URLs/stories given can be/need to be downloaded.

    -

    See log for details.

    -

    Proceed with updating your library(Error Column, if configured)?

    -'''%len(book_list) +

    %s

    +

    %s

    +

    %s

    '''%( + _('None of the %d URLs/stories given can be/need to be downloaded.')%len(book_list), + _('See log for details.'), + _('Proceed with updating your library(Error Column, if configured)?')) - htmllog='' + htmllog='
    StatusTitleAuthorCommentURL
    ' for book in book_list: if 'status' in book: status = book['status'] else: - status = 'Bad' + status = _('Bad') htmllog = htmllog + '' htmllog = htmllog + '
    '+_('Status')+''+_('Title')+''+_('Author')+''+_('Comment')+'URL
    ' + ''.join([escapehtml(status),escapehtml(book['title']),escapehtml(", ".join(book['author'])),escapehtml(book['comment']),book['url']]) + '
    ' @@ -1071,7 +1114,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): payload = ([], book_list, options) self.gui.proceed_question(self.update_error_column, payload, htmllog, - 'FFDL log', 'FFDL download ended', msg, + _('FFDL log'), _('FFDL download ended'), msg, show_copy_button=False) return @@ -1079,13 +1122,13 @@ class FanFictionDownLoaderPlugin(InterfaceAction): cpus = self.gui.job_manager.server.pool_size args = ['calibre_plugins.fanfictiondownloader_plugin.jobs', 'do_download_worker', (book_list, options, cpus)] - desc = 'Download FanFiction Book' + desc = _('Download FanFiction Book') job = self.gui.job_manager.run_job( self.Dispatcher(partial(self.download_list_completed,options=options,merge=merge)), func, args=args, description=desc) - self.gui.status_bar.show_message('Starting %d FanFictionDownLoads'%len(book_list),3000) + self.gui.status_bar.show_message(_('Starting %d FanFictionDownLoads')%len(book_list),3000) def update_books_loop(self,book,db=None, options={'fileform':'epub', @@ -1115,12 +1158,12 @@ class FanFictionDownLoaderPlugin(InterfaceAction): try: self.update_metadata(db, book['calibre_id'], book, mi, options) except: - det_msg = "".join(traceback.format_exception(*sys.exc_info()))+"\nStory Details:\n%s"%pretty_book(book) + det_msg = "".join(traceback.format_exception(*sys.exc_info()))+"\n"+_("Story Details:")+pretty_book(book) logger.error("Error Updating Metadata:\n%s"%det_msg) error_dialog(self.gui, - "Error Updating Metadata", - "

    An error has occurred while FFDL was updating calibre's metadata for %s.

    "%(book['url'],book['title'])+ - "The ebook has been updated, but the metadata has not.", + _("Error Updating Metadata"), + "

    "+_("An error has occurred while FFDL was updating calibre's metadata for %s.")%(book['url'],book['title'])+"

    "+ + _("The ebook has been updated, but the metadata has not."), det_msg=det_msg, show=True) @@ -1203,24 +1246,29 @@ class FanFictionDownLoaderPlugin(InterfaceAction): show_copy_button=False) return - msg = '

    FFDL found %s good and %s bad updates.

    '%(len(good_list),len(bad_list)) + msg = '

    '+_('FFDL found %s good and %s bad updates.')%(len(good_list),len(bad_list))+'

    ' if len(bad_list) > 0: - msg = msg + '''

    Are you sure you want to continue with creating/updating this Anthology?

    -

    Any updates that failed will not be included in the Anthology.

    -

    However, if there's an older version, it will still be included.

    -

    See log for details.

    -''' - msg = msg + '

    Proceed with updating this anthology and your library?

    ' + msg = msg + ''' +

    %s

    +

    %s

    +

    %s

    +

    %s

    '''%( + _('Are you sure you want to continue with creating/updating this Anthology?'), + _('Any updates that failed will not be included in the Anthology.'), + _("However, if there's an older version, it will still be included."), + _('See log for details.')) + + msg = msg + '

    '+_('Proceed with updating this anthology and your library?')+ '

    ' - htmllog='' + htmllog='
    StatusTitleAuthorCommentURL
    ' for book in sorted(good_list+bad_list,key=lambda x : x['listorder']): if 'status' in book: status = book['status'] else: if book in good_list: - status = 'Good' + status = _('Good') else: - status = 'Bad' + status = _('Bad') htmllog = htmllog + '' htmllog = htmllog + '
    '+_('Status')+''+_('Title')+''+_('Author')+''+_('Comment')+'URL
    ' + ''.join([escapehtml(status),escapehtml(book['title']),escapehtml(", ".join(book['author'])),escapehtml(book['comment']),book['url']]) + '
    ' @@ -1234,12 +1282,15 @@ class FanFictionDownLoaderPlugin(InterfaceAction): do_update_func = self.do_download_merge_update else: msg = ''' -

    FFDL found %s good and %s bad updates.

    -

    See log for details.

    -

    Proceed with updating your library?

    -'''%(len(good_list),len(bad_list)) +

    %s

    +

    %s

    +

    %s

    '''%( + _('FFDL found %s good and %s bad updates.')%(len(good_list),len(bad_list)), + _('See log for details.'), + _('Proceed with updating your library?') + ) - htmllog='' + htmllog='
    StatusTitleAuthorCommentURL
    ' for book in good_list: if 'status' in book: status = book['status'] @@ -1260,7 +1311,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): self.gui.proceed_question(do_update_func, payload, htmllog, - 'FFDL log', 'FFDL download complete', msg, + _('FFDL log'), _('FFDL download complete'), msg, show_copy_button=False) def do_download_merge_update(self, payload): @@ -1321,9 +1372,9 @@ class FanFictionDownLoaderPlugin(InterfaceAction): good_list+bad_list, partial(self.update_books_loop, options=options, db=self.gui.current_db), partial(self.update_books_finish, options=options), - init_label="Updating calibre for FanFiction stories...", - win_title="Update calibre for FanFiction stories", - status_prefix="Updated") + init_label=_("Updating calibre for FanFiction stories..."), + win_title=_("Update calibre for FanFiction stories"), + status_prefix=_("Updated")) def update_error_column(self,payload): '''Update custom error column if configured.''' @@ -1337,9 +1388,9 @@ class FanFictionDownLoaderPlugin(InterfaceAction): book_list, partial(self.update_error_column_loop, db=self.gui.current_db, label=label), partial(self.update_books_finish, options=options), - init_label="Updating calibre for BAD FanFiction stories...", - win_title="Update calibre for BAD FanFiction stories", - status_prefix="Updated") + init_label=_("Updating calibre for BAD FanFiction stories..."), + win_title=_("Update calibre for BAD FanFiction stories"), + status_prefix=_("Updated")) def update_error_column_loop(self,book,db=None,label='errorcol'): if book['calibre_id']: @@ -1366,10 +1417,10 @@ class FanFictionDownLoaderPlugin(InterfaceAction): if not db.add_format_with_hooks(book_id, options['fileform'], book['outfile'], index_is_id=True): - book['comment'] = "Adding format to book failed for some reason..." + book['comment'] = _("Adding format to book failed for some reason...") book['good']=False book['icon']='dialog_error.png' - book['status'] = 'Error' + book['status'] = _('Error') if prefs['deleteotherforms']: fmts = db.formats(book['calibre_id'], index_is_id=True).split(',') @@ -1599,7 +1650,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): rl_plugin = self.gui.iactions['Reading List'] except: if prefs['addtolists'] or prefs['addtoreadlists']: - message="

    You configured FanFictionDownLoader to automatically update Reading Lists, but you don't have the Reading List plugin installed anymore?

    " + message="

    "+_("You configured FanFictionDownLoader to automatically update Reading Lists, but you don't have the %s plugin installed anymore?")%'Reading List'+"

    " confirm(message,'fanfictiondownloader_no_reading_list_plugin', self.gui) return @@ -1611,7 +1662,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): lists = self.get_clean_reading_lists(prefs['read_lists']) if len(lists) < 1 : - message="

    You configured FanFictionDownLoader to automatically update \"To Read\" Reading Lists, but you don't have any lists set?

    " + message="

    "+_("You configured FanFictionDownLoader to automatically update \"To Read\" Reading Lists, but you don't have any lists set?")+"

    " confirm(message,'fanfictiondownloader_no_read_lists', self.gui) for l in lists: if l in rl_plugin.get_list_names(): @@ -1621,13 +1672,13 @@ class FanFictionDownLoaderPlugin(InterfaceAction): display_warnings=False) else: if l != '': - message="

    You configured FanFictionDownLoader to automatically update Reading List '%s', but you don't have a list of that name?

    "%l + message="

    "+_("You configured FanFictionDownLoader to automatically update Reading List '%s', but you don't have a list of that name?")%l+"

    " confirm(message,'fanfictiondownloader_no_reading_list_%s'%l, self.gui) if prefs['addtolists'] and (add or (prefs['addtolistsonread'] and prefs['addtoreadlists']) ): lists = self.get_clean_reading_lists(prefs['send_lists']) if len(lists) < 1 : - message="

    You configured FanFictionDownLoader to automatically update \"Send to Device\" Reading Lists, but you don't have any lists set?

    " + message="

    "+_("You configured FanFictionDownLoader to automatically update \"Send to Device\" Reading Lists, but you don't have any lists set?")+"

    " confirm(message,'fanfictiondownloader_no_send_lists', self.gui) for l in lists: @@ -1639,7 +1690,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): display_warnings=False) else: if l != '': - message="

    You configured FanFictionDownLoader to automatically update Reading List '%s', but you don't have a list of that name?

    "%l + message="

    "+_("You configured FanFictionDownLoader to automatically update Reading List '%s', but you don't have a list of that name?")%l+"

    " confirm(message,'fanfictiondownloader_no_reading_list_%s'%l, self.gui) def make_mi_from_book(self,book): @@ -1746,19 +1797,19 @@ class FanFictionDownLoaderPlugin(InterfaceAction): def set_book_url_and_comment(self,book,url): if not url: - book['comment'] = "No story URL found." + book['comment'] = _("No story URL found.") book['good'] = False book['icon'] = 'search_delete_saved.png' - book['status'] = 'Not Found' + book['status'] = _('Not Found') else: # get normalized url or None. book['url'] = self.is_good_downloader_url(url) if book['url'] == None: book['url'] = url - book['comment'] = "URL is not a valid story URL." + book['comment'] = _("URL is not a valid story URL.") book['good'] = False book['icon']='dialog_error.png' - book['status'] = 'Bad URL' + book['status'] = _('Bad URL') def get_story_url(self, db, book_id=None, path=None): if book_id == None: @@ -1888,8 +1939,8 @@ class FanFictionDownLoaderPlugin(InterfaceAction): book['comments'] = existingbook['comments'] else: book['title'] = deftitle = book_list[0]['title'] - book['comments'] = "Anthology containing:\n" + \ - "\n".join([ "%s by %s"%(b['title'],', '.join(b['author'])) for b in book_list ]) + book['comments'] = _("Anthology containing:")+"\n" + \ + "\n".join([ _("%s by %s")%(b['title'],', '.join(b['author'])) for b in book_list ]) # book['all_metadata']['description'] # if all same series, use series for name. But only if all and not previous named @@ -1909,7 +1960,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): else: # No setting, do fall back default. Shouldn't happen, # should always have a version in defaults. - book['title'] = book['title']+" Anthology" + book['title'] = book['title']+_(" Anthology") book['all_metadata']['title'] = book['title'] # because custom columns are set from all_metadata book['all_metadata']['author'] = ", ".join(book['author']) @@ -1946,7 +1997,7 @@ def pretty_book(d, indent=0, spacer=' '): if isinstance(d, dict): for k in ('password','username'): if k in d and d[k]: - d[k]='' + d[k]=_('(was set, removed for security)') return '\n'.join(['%s%s:\n%s' % (kindent, k, pretty_book(v, indent + 1, spacer)) for k, v in d.items()]) return "%s%s"%(kindent, d) diff --git a/calibre-plugin/translations/default.po b/calibre-plugin/translations/default.po new file mode 100644 index 00000000..ce5d903d --- /dev/null +++ b/calibre-plugin/translations/default.po @@ -0,0 +1,1575 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: FanFictionDownLoader 1.8\n" +"POT-Creation-Date: 2013-11-15 14:15+Central Standard Time\n" +"PO-Revision-Date: 2013-11-15 14:15-0600\n" +"Last-Translator: Jim Miller \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: pygettext.py 1.5\n" +"X-Generator: Poedit 1.5.7\n" + +#: __init__.py:42 +msgid "UI plugin to download FanFiction stories from various sites." +msgstr "" + +#: __init__.py:109 +msgid "" +"Path to the calibre library. Default is to use the path stored in the " +"settings." +msgstr "" + +#: config.py:155 +msgid "FAQs" +msgstr "" + +#: config.py:155 +msgid "List of Supported Sites" +msgstr "" + +#: config.py:169 +msgid "Basic" +msgstr "" + +#: config.py:190 +msgid "Standard Columns" +msgstr "" + +#: config.py:193 +msgid "Custom Columns" +msgstr "" + +#: config.py:196 +msgid "Other" +msgstr "" + +#: config.py:314 +msgid "" +"These settings control the basic features of the plugin--downloading " +"FanFiction." +msgstr "" + +#: config.py:318 +msgid "Defaults Options on Download" +msgstr "" + +#: config.py:322 +msgid "" +"On each download, FFDL offers an option to select the output format.
    This sets what that option will default to." +msgstr "" + +#: config.py:324 +msgid "Default Output &Format:" +msgstr "" + +#: config.py:339 +msgid "" +"On each download, FFDL offers an option of what happens if that story " +"already exists.
    This sets what that option will default to." +msgstr "" + +#: config.py:341 +msgid "Default If Story Already Exists?" +msgstr "" + +#: config.py:355 +msgid "Default Update Calibre &Metadata?" +msgstr "" + +#: config.py:356 +msgid "" +"On each download, FFDL offers an option to update Calibre's metadata (title, " +"author, URL, tags, custom columns, etc) from the web site.
    This sets " +"whether that will default to on or off.
    Columns set to 'New Only' in " +"the column tabs will only be set for new books." +msgstr "" + +#: config.py:360 +msgid "Default Update EPUB Cover when Updating EPUB?" +msgstr "" + +#: config.py:361 +msgid "" +"On each download, FFDL offers an option to update the book cover image " +"inside the EPUB from the web site when the EPUB is updated.
    This " +"sets whether that will default to on or off." +msgstr "" + +#: config.py:365 +msgid "Smarten Punctuation (EPUB only)" +msgstr "" + +#: config.py:366 +msgid "" +"Run Smarten Punctuation from Calibre's Polish Book feature on each EPUB " +"download and update." +msgstr "" + +#: config.py:371 +msgid "Updating Calibre Options" +msgstr "" + +#: config.py:375 +msgid "Delete other existing formats?" +msgstr "" + +#: config.py:376 +msgid "" +"Check this to automatically delete all other ebook formats when updating an " +"existing book.\n" +"Handy if you have both a Nook(epub) and Kindle(mobi), for example." +msgstr "" + +#: config.py:380 +msgid "Update Calibre Cover when Updating Metadata?" +msgstr "" + +#: config.py:381 +msgid "" +"Update calibre book cover image from EPUB when metadata is updated. (EPUB " +"only.)\n" +"Doesn't go looking for new images on 'Update Calibre Metadata Only'." +msgstr "" + +#: config.py:385 +msgid "Keep Existing Tags when Updating Metadata?" +msgstr "" + +#: config.py:386 +msgid "" +"Existing tags will be kept and any new tags added.\n" +"%(cmplt)s and %(inprog)s tags will be still be updated, if known.\n" +"%(lul)s tags will be updated if %(lus)s in %(is)s.\n" +"(If Tags is set to 'New Only' in the Standard Columns tab, this has no " +"effect.)" +msgstr "" + +#: config.py:390 +msgid "Force Author into Author Sort?" +msgstr "" + +#: config.py:391 +msgid "" +"If checked, the author(s) as given will be used for the Author Sort, too.\n" +"If not checked, calibre will apply it's built in algorithm which makes 'Bob " +"Smith' sort as 'Smith, Bob', etc." +msgstr "" + +#: config.py:395 +msgid "Force Title into Title Sort?" +msgstr "" + +#: config.py:396 +msgid "" +"If checked, the title as given will be used for the Title Sort, too.\n" +"If not checked, calibre will apply it's built in algorithm which makes 'The " +"Title' sort as 'Title, The', etc." +msgstr "" + +#: config.py:400 +msgid "Check for existing Series Anthology books?" +msgstr "" + +#: config.py:401 +msgid "" +"Check for existings Series Anthology books using each new story's series URL " +"before downloading.\n" +"Offer to skip downloading if a Series Anthology is found." +msgstr "" + +#: config.py:405 +msgid "Check for changed Story URL?" +msgstr "" + +#: config.py:406 +msgid "Warn you if an update will change the URL of an existing book." +msgstr "" + +#: config.py:410 +msgid "Search EPUB text for Story URL?" +msgstr "" + +#: config.py:411 +msgid "" +"Look for first valid story URL inside EPUB text if not found in metadata.\n" +"Somewhat risky, could find wrong URL depending on EPUB content.\n" +"Also finds and corrects bad ffnet URLs from ficsaver.com files." +msgstr "" + +#: config.py:415 +msgid "Mark added/updated books when finished?" +msgstr "" + +#: config.py:416 +msgid "" +"Mark added/updated books when finished. Use with option below.\n" +"You can also manually search for 'marked:ffdl_success'.\n" +"'marked:ffdl_failed' is also available, or search 'marked:ffdl' for both." +msgstr "" + +#: config.py:420 +msgid "Show Marked books when finished?" +msgstr "" + +#: config.py:421 +msgid "" +"Show Marked added/updated books only when finished.\n" +"You can also manually search for 'marked:ffdl_success'.\n" +"'marked:ffdl_failed' is also available, or search 'marked:ffdl' for both." +msgstr "" + +#: config.py:425 +msgid "GUI Options" +msgstr "" + +#: config.py:429 +msgid "Take URLs from Clipboard?" +msgstr "" + +#: config.py:430 +msgid "Prefill URLs from valid URLs in Clipboard when Adding New." +msgstr "" + +#: config.py:434 +msgid "Default to Update when books selected?" +msgstr "" + +#: config.py:435 +msgid "" +"The top FanFictionDownLoader plugin button will start Update if\n" +"books are selected. If unchecked, it will always bring up 'Add New'." +msgstr "" + +#: config.py:439 +msgid "Keep 'Add New from URL(s)' dialog on top?" +msgstr "" + +#: config.py:440 +msgid "" +"Instructs the OS and Window Manager to keep the 'Add New from URL(s)'\n" +"dialog on top of all other windows. Useful for dragging URLs onto it." +msgstr "" + +#: config.py:444 +msgid "Misc Options" +msgstr "" + +#: config.py:449 +msgid "Include images in EPUBs?" +msgstr "" + +#: config.py:450 +msgid "" +"Download and include images in EPUB stories. This is equivalent to adding:" +"%(imgset)s ...to the top of %(pini)s. Your settings in %(pini)s will " +"override this." +msgstr "" + +#: config.py:454 +msgid "Inject calibre Series when none found?" +msgstr "" + +#: config.py:455 +msgid "" +"If no series is found, inject the calibre series (if there is one) so it " +"appears on the FFDL title page(not cover)." +msgstr "" + +#: config.py:459 +msgid "Reject List" +msgstr "" + +#: config.py:463 +msgid "Edit Reject URL List" +msgstr "" + +#: config.py:464 +msgid "Edit list of URLs FFDL will automatically Reject." +msgstr "" + +#: config.py:468 config.py:537 +msgid "Add Reject URLs" +msgstr "" + +#: config.py:469 +msgid "Add additional URLs to Reject as text." +msgstr "" + +#: config.py:473 +msgid "Edit Reject Reasons List" +msgstr "" + +#: config.py:474 config.py:528 +msgid "Customize the Reasons presented when Rejecting URLs" +msgstr "" + +#: config.py:512 +msgid "Edit Reject URLs List" +msgstr "" + +#: config.py:526 +msgid "Reject Reasons" +msgstr "" + +#: config.py:527 +msgid "Customize Reject List Reasons" +msgstr "" + +#: config.py:535 +msgid "Reason why I rejected it" +msgstr "" + +#: config.py:535 +msgid "Title by Author" +msgstr "" + +#: config.py:538 +msgid "" +"Add Reject URLs. Use: http://...,note or http://...,title by " +"author - note
    Invalid story URLs will be ignored." +msgstr "" + +#: config.py:539 +msgid "" +"One URL per line:\n" +"http://...,note\n" +"http://...,title by author - note" +msgstr "" + +#: config.py:541 dialogs.py:1006 +msgid "Add this reason to all URLs added:" +msgstr "" + +#: config.py:556 +msgid "" +"These settings provide more detailed control over what metadata will be " +"displayed inside the ebook as well as let you set %(isa)s and %(u)s/%(p)s " +"for different sites." +msgstr "" + +#: config.py:574 +msgid "View Defaults" +msgstr "" + +#: config.py:575 +msgid "" +"View all of the plugin's configurable settings\n" +"and their default settings." +msgstr "" + +#: config.py:593 +msgid "Plugin Defaults (%s) (Read-Only)" +msgstr "" + +#: config.py:594 config.py:600 +msgid "" +"These are all of the plugin's configurable options\n" +"and their default settings." +msgstr "" + +#: config.py:595 +msgid "Plugin Defaults" +msgstr "" + +#: config.py:611 dialogs.py:530 dialogs.py:633 +msgid "OK" +msgstr "" + +# %(rl)s = Reading List. Keep as is. +#: config.py:631 +msgid "" +"These settings provide integration with the %(rl)s Plugin. %(rl)s can " +"automatically send to devices and change custom columns. You have to create " +"and configure the lists in %(rl)s to be useful." +msgstr "" + +#: config.py:636 +msgid "Add new/updated stories to \"Send to Device\" Reading List(s)." +msgstr "" + +# %(rl)s = Reading List. Keep as is. +#: config.py:637 +msgid "" +"Automatically add new/updated stories to these lists in the %(rl)s plugin." +msgstr "" + +#: config.py:642 +msgid "\"Send to Device\" Reading Lists" +msgstr "" + +#: config.py:643 config.py:646 config.py:659 config.py:662 +msgid "" +"When enabled, new/updated stories will be automatically added to these lists." +msgstr "" + +#: config.py:652 +msgid "Add new/updated stories to \"To Read\" Reading List(s)." +msgstr "" + +# %(rl)s = Reading List. Keep as is. +#: config.py:653 +msgid "" +"Automatically add new/updated stories to these lists in the %(rl)s plugin.\n" +"Also offers menu option to remove stories from the \"To Read\" lists." +msgstr "" + +#: config.py:658 +msgid "\"To Read\" Reading Lists" +msgstr "" + +#: config.py:668 +msgid "" +"Add stories back to \"Send to Device\" Reading List(s) when marked \"Read\"." +msgstr "" + +#: config.py:669 +msgid "" +"Menu option to remove from \"To Read\" lists will also add stories back to " +"\"Send to Device\" Reading List(s)" +msgstr "" + +# %(gc)s = Generate Cover. Keep as is. +#: config.py:691 +msgid "" +"The %(gc)s plugin can create cover images for books using various metadata " +"and configurations. If you have GC installed, FFDL can run GC on new " +"downloads and metadata updates. Pick a GC setting by site or Default." +msgstr "" + +#: config.py:709 config.py:713 +msgid "Default" +msgstr "" + +# %(gc)s = Generate Cover. Keep as is. +#: config.py:714 +msgid "" +"On Metadata update, run %(gc)s with this setting, if not selected for " +"specific site." +msgstr "" + +# %(gc)s = Generate Cover. Keep as is. +#: config.py:717 +msgid "On Metadata update, run %(gc)s with this setting for %(site)s stories." +msgstr "" + +# %(gc)s = Generate Cover. Keep as is. +#: config.py:735 +msgid "Run %(gc)s Only on New Books" +msgstr "" + +#: config.py:736 +msgid "Default is to run GC any time the calibre metadata is updated." +msgstr "" + +#: config.py:740 +msgid "Allow %(gcset)s from %(pini)s to override" +msgstr "" + +#: config.py:741 +msgid "" +"The %(pini)s parameter %(gcset)s allows you to choose a GC setting based on " +"metadata rather than site, but it's much more complex.
    %(gcset)s is " +"ignored when this is off." +msgstr "" + +#: config.py:755 +msgid "" +"These settings provide integration with the %(cp)s Plugin. %(cp)s can " +"automatically update custom columns with page, word and reading level " +"statistics. You have to create and configure the columns in %(cp)s first." +msgstr "" + +#: config.py:760 +msgid "" +"If any of the settings below are checked, when stories are added or updated, " +"the %(cp)s Plugin will be called to update the checked statistics." +msgstr "" + +#: config.py:766 +msgid "Which column and algorithm to use are configured in %(cp)s." +msgstr "" + +#: config.py:774 +msgid "" +"Will overwrite word count from FFDL metadata if set to update the same " +"custom column." +msgstr "" + +#: config.py:805 +msgid "" +"These controls aren't plugin settings as such, but convenience buttons for " +"setting Keyboard shortcuts and getting all the FanFictionDownLoader " +"confirmation dialogs back again." +msgstr "" + +#: config.py:810 +msgid "Keyboard shortcuts..." +msgstr "" + +#: config.py:811 +msgid "Edit the keyboard shortcuts associated with this plugin" +msgstr "" + +#: config.py:815 +msgid "Reset disabled &confirmation dialogs" +msgstr "" + +#: config.py:816 +msgid "Reset all show me again dialogs for the FanFictionDownLoader plugin" +msgstr "" + +#: config.py:820 +msgid "&View library preferences..." +msgstr "" + +#: config.py:821 +msgid "View data stored in the library database for this plugin" +msgstr "" + +#: config.py:832 +msgid "Done" +msgstr "" + +#: config.py:833 +msgid "Confirmation dialogs have all been reset" +msgstr "" + +#: config.py:881 +msgid "Category" +msgstr "" + +#: config.py:882 +msgid "Genre" +msgstr "" + +#: config.py:883 +msgid "Language" +msgstr "" + +#: config.py:884 ffdl_plugin.py:1104 ffdl_plugin.py:1263 ffdl_plugin.py:1293 +msgid "Status" +msgstr "" + +#: config.py:885 +msgid "Status:%(cmplt)s" +msgstr "" + +#: config.py:886 +msgid "Status:%(inprog)s" +msgstr "" + +#: config.py:887 config.py:1021 +msgid "Series" +msgstr "" + +#: config.py:888 +msgid "Characters" +msgstr "" + +#: config.py:889 +msgid "Relationships" +msgstr "" + +#: config.py:890 +msgid "Published" +msgstr "" + +#: config.py:891 ffdl_plugin.py:1377 ffdl_plugin.py:1393 +msgid "Updated" +msgstr "" + +#: config.py:892 +msgid "Created" +msgstr "" + +#: config.py:893 +msgid "Rating" +msgstr "" + +#: config.py:894 +msgid "Warnings" +msgstr "" + +#: config.py:895 +msgid "Chapters" +msgstr "" + +#: config.py:896 +msgid "Words" +msgstr "" + +#: config.py:897 +msgid "Site" +msgstr "" + +#: config.py:898 +msgid "Story ID" +msgstr "" + +#: config.py:899 +msgid "Author ID" +msgstr "" + +#: config.py:900 +msgid "Extra Tags" +msgstr "" + +#: config.py:901 config.py:1013 dialogs.py:792 dialogs.py:888 +#: ffdl_plugin.py:1104 ffdl_plugin.py:1263 ffdl_plugin.py:1293 +msgid "Title" +msgstr "" + +#: config.py:902 +msgid "Story URL" +msgstr "" + +#: config.py:903 +msgid "Description" +msgstr "" + +#: config.py:904 dialogs.py:792 dialogs.py:888 ffdl_plugin.py:1104 +#: ffdl_plugin.py:1263 ffdl_plugin.py:1293 +msgid "Author" +msgstr "" + +#: config.py:905 +msgid "Author URL" +msgstr "" + +#: config.py:906 +msgid "File Format" +msgstr "" + +#: config.py:907 +msgid "File Extension" +msgstr "" + +#: config.py:908 +msgid "Site Abbrev" +msgstr "" + +#: config.py:909 +msgid "FFDL Version" +msgstr "" + +#: config.py:924 +msgid "" +"If you have custom columns defined, they will be listed below. Choose a " +"metadata value type to fill your columns automatically." +msgstr "" + +#: config.py:949 +msgid "Update this %s column(%s) with..." +msgstr "" + +#: config.py:959 +msgid "Values that aren't valid for this enumeration column will be ignored." +msgstr "" + +#: config.py:959 config.py:961 +msgid "Metadata values valid for this type of column." +msgstr "" + +#: config.py:964 config.py:1040 +msgid "New Only" +msgstr "" + +#: config.py:965 +msgid "" +"Write to %s(%s) only for new\n" +"books, not updates to existing books." +msgstr "" + +#: config.py:976 +msgid "Allow %(ccset)s from %(pini)s to override" +msgstr "" + +#: config.py:977 +msgid "" +"The %(pini)s parameter %(ccset)s allows you to set custom columns to site " +"specific values that aren't common to all sites.
    %(ccset)s is ignored " +"when this is off." +msgstr "" + +#: config.py:982 +msgid "Special column:" +msgstr "" + +#: config.py:987 +msgid "Update/Overwrite Error Column:" +msgstr "" + +#: config.py:988 +msgid "" +"When an update or overwrite of an existing story fails, record the reason in " +"this column.\n" +"(Text and Long Text columns only.)" +msgstr "" + +#: config.py:1014 +msgid "Author(s)" +msgstr "" + +#: config.py:1015 +msgid "Publisher" +msgstr "" + +#: config.py:1016 +msgid "Tags" +msgstr "" + +#: config.py:1017 +msgid "Languages" +msgstr "" + +#: config.py:1018 +msgid "Published Date" +msgstr "" + +#: config.py:1019 +msgid "Date" +msgstr "" + +#: config.py:1020 +msgid "Comments" +msgstr "" + +#: config.py:1022 +msgid "Ids(url id only)" +msgstr "" + +#: config.py:1027 +msgid "" +"The standard calibre metadata columns are listed below. You may choose " +"whether FFDL will fill each column automatically on updates or only for new " +"books." +msgstr "" + +#: config.py:1041 +msgid "" +"Write to %s only for new\n" +"books, not updates to existing books." +msgstr "" + +#: dialogs.py:45 +msgid "Skip" +msgstr "" + +#: dialogs.py:46 +msgid "Add New Book" +msgstr "" + +#: dialogs.py:47 +msgid "Update EPUB if New Chapters" +msgstr "" + +#: dialogs.py:48 +msgid "Update EPUB Always" +msgstr "" + +#: dialogs.py:49 +msgid "Overwrite if Newer" +msgstr "" + +#: dialogs.py:50 +msgid "Overwrite Always" +msgstr "" + +#: dialogs.py:51 +msgid "Update Calibre Metadata Only" +msgstr "" + +# title by author +#: dialogs.py:139 ffdl_plugin.py:1943 +msgid "%s by %s" +msgstr "" + +#: dialogs.py:227 ffdl_plugin.py:86 +msgid "FanFictionDownLoader" +msgstr "" + +#: dialogs.py:244 dialogs.py:691 +msgid "Show Download Options" +msgstr "" + +#: dialogs.py:263 dialogs.py:708 +msgid "Output &Format:" +msgstr "" + +#: dialogs.py:271 dialogs.py:716 +msgid "" +"Choose output format to create. May set default from plugin configuration." +msgstr "" + +#: dialogs.py:299 dialogs.py:733 +msgid "Update Calibre &Metadata?" +msgstr "" + +#: dialogs.py:300 dialogs.py:734 +msgid "" +"Update metadata for existing stories in Calibre from web site?\n" +"(Columns set to 'New Only' in the column tabs will only be set for new " +"books.)" +msgstr "" + +#: dialogs.py:306 dialogs.py:738 +msgid "Update EPUB Cover?" +msgstr "" + +#: dialogs.py:307 dialogs.py:739 +msgid "" +"Update book cover image from site or defaults (if found) inside the " +"EPUB when EPUB is updated." +msgstr "" + +#: dialogs.py:354 +msgid "Story URL(s) for anthology, one per line:" +msgstr "" + +#: dialogs.py:355 +msgid "" +"URLs for stories to include in the anthology, one per line.\n" +"Will take URLs from clipboard, but only valid URLs." +msgstr "" + +#: dialogs.py:356 +msgid "If Story Already Exists in Anthology?" +msgstr "" + +#: dialogs.py:357 +msgid "" +"What to do if there's already an existing story with the same URL in the " +"anthology." +msgstr "" + +#: dialogs.py:366 +msgid "Story URL(s), one per line:" +msgstr "" + +#: dialogs.py:367 +msgid "" +"URLs for stories, one per line.\n" +"Will take URLs from clipboard, but only valid URLs.\n" +"Add [1,5] after the URL to limit the download to chapters 1-5." +msgstr "" + +#: dialogs.py:368 +msgid "If Story Already Exists?" +msgstr "" + +#: dialogs.py:369 +msgid "" +"What to do if there's already an existing story with the same URL or title " +"and author." +msgstr "" + +#: dialogs.py:469 +msgid "For Individual Books" +msgstr "" + +#: dialogs.py:470 +msgid "Get URLs and go to dialog for individual story downloads." +msgstr "" + +#: dialogs.py:474 +msgid "For Anthology Epub" +msgstr "" + +#: dialogs.py:475 +msgid "" +"Get URLs and go to dialog for Anthology download.\n" +"Requires %s plugin." +msgstr "" + +#: dialogs.py:480 dialogs.py:534 +msgid "Cancel" +msgstr "" + +#: dialogs.py:512 +msgid "Password" +msgstr "" + +#: dialogs.py:513 +msgid "Author requires a password for this story(%s)." +msgstr "" + +#: dialogs.py:518 +msgid "User/Password" +msgstr "" + +#: dialogs.py:519 +msgid "%s requires you to login to download this story." +msgstr "" + +#: dialogs.py:521 +msgid "User:" +msgstr "" + +#: dialogs.py:525 +msgid "Password:" +msgstr "" + +#: dialogs.py:556 +msgid "Fetching metadata for stories..." +msgstr "" + +#: dialogs.py:557 +msgid "Downloading metadata for stories" +msgstr "" + +#: dialogs.py:558 +msgid "Fetched metadata for" +msgstr "" + +#: dialogs.py:628 ffdl_plugin.py:322 +msgid "About FanFictionDownLoader" +msgstr "" + +#: dialogs.py:682 +msgid "Remove selected books from the list" +msgstr "" + +#: dialogs.py:721 +msgid "Update Mode:" +msgstr "" + +#: dialogs.py:724 +msgid "" +"What sort of update to perform. May set default from plugin configuration." +msgstr "" + +#: dialogs.py:792 ffdl_plugin.py:1104 ffdl_plugin.py:1263 ffdl_plugin.py:1293 +msgid "Comment" +msgstr "" + +#: dialogs.py:860 +msgid "Are you sure you want to remove this book from the list?" +msgstr "" + +#: dialogs.py:862 +msgid "Are you sure you want to remove the selected %d books from the list?" +msgstr "" + +#: dialogs.py:888 +msgid "Note" +msgstr "" + +#: dialogs.py:930 +msgid "Select or Edit Reject Note." +msgstr "" + +#: dialogs.py:938 +msgid "Are you sure you want to remove this URL from the list?" +msgstr "" + +#: dialogs.py:940 +msgid "Are you sure you want to remove the %d selected URLs from the list?" +msgstr "" + +#: dialogs.py:958 +msgid "List of Books to Reject" +msgstr "" + +#: dialogs.py:971 +msgid "" +"FFDL will remember these URLs and display the note and offer to reject them " +"if you try to download them again later." +msgstr "" + +#: dialogs.py:985 +msgid "Remove selected URL(s) from the list" +msgstr "" + +#: dialogs.py:1003 dialogs.py:1007 +msgid "This will be added to whatever note you've set for each URL above." +msgstr "" + +#: dialogs.py:1016 +msgid "Delete Books (including books without FanFiction URLs)?" +msgstr "" + +#: dialogs.py:1017 +msgid "Delete the selected books after adding them to the Rejected URLs list." +msgstr "" + +#: ffdl_plugin.py:87 +msgid "Download FanFiction stories from various web sites" +msgstr "" + +# This is what appears on the plugin button/menu when added to calibre's main toolbar or menu. +#: ffdl_plugin.py:117 +msgid "FanFictionDL" +msgstr "" + +#: ffdl_plugin.py:240 +msgid "&Add New from URL(s)" +msgstr "" + +#: ffdl_plugin.py:242 +msgid "Add New FanFiction Book(s) from URL(s)" +msgstr "" + +#: ffdl_plugin.py:245 +msgid "&Update Existing FanFiction Book(s)" +msgstr "" + +#: ffdl_plugin.py:251 +msgid "Get Story URLs to Download from Web Page" +msgstr "" + +#: ffdl_plugin.py:255 +msgid "&Make Anthology Epub Manually from URL(s)" +msgstr "" + +#: ffdl_plugin.py:257 +msgid "Make FanFiction Anthology Epub Manually from URL(s)" +msgstr "" + +#: ffdl_plugin.py:260 +msgid "&Update Anthology Epub" +msgstr "" + +#: ffdl_plugin.py:262 +msgid "Update FanFiction Anthology Epub" +msgstr "" + +#: ffdl_plugin.py:270 +msgid "Add to \"To Read\" and \"Send to Device\" Lists" +msgstr "" + +#: ffdl_plugin.py:272 +msgid "Remove from \"To Read\" and add to \"Send to Device\" Lists" +msgstr "" + +#: ffdl_plugin.py:274 ffdl_plugin.py:279 +msgid "Remove from \"To Read\" Lists" +msgstr "" + +#: ffdl_plugin.py:276 +msgid "Add Selected to \"Send to Device\" Lists" +msgstr "" + +#: ffdl_plugin.py:278 +msgid "Add to \"To Read\" Lists" +msgstr "" + +#: ffdl_plugin.py:294 +msgid "Get URLs from Selected Books" +msgstr "" + +#: ffdl_plugin.py:300 ffdl_plugin.py:393 +msgid "Get Story URLs from Web Page" +msgstr "" + +#: ffdl_plugin.py:305 +msgid "Reject Selected Books" +msgstr "" + +#: ffdl_plugin.py:313 +msgid "&Configure Plugin" +msgstr "" + +#: ffdl_plugin.py:316 +msgid "Configure FanFictionDownLoader" +msgstr "" + +#: ffdl_plugin.py:319 +msgid "About Plugin" +msgstr "" + +#: ffdl_plugin.py:376 +msgid "Cannot Update Reading Lists from Device View" +msgstr "" + +#: ffdl_plugin.py:380 +msgid "No Selected Books to Update Reading Lists" +msgstr "" + +#: ffdl_plugin.py:404 ffdl_plugin.py:456 +msgid "List of Story URLs" +msgstr "" + +#: ffdl_plugin.py:405 +msgid "No Valid Story URLs found on given page." +msgstr "" + +#: ffdl_plugin.py:420 +msgid "No Selected Books to Get URLs From" +msgstr "" + +#: ffdl_plugin.py:438 +msgid "Collecting URLs for stories..." +msgstr "" + +#: ffdl_plugin.py:439 +msgid "Get URLs for stories" +msgstr "" + +#: ffdl_plugin.py:440 ffdl_plugin.py:487 ffdl_plugin.py:674 +msgid "URL retrieved" +msgstr "" + +#: ffdl_plugin.py:460 +msgid "List of URLs" +msgstr "" + +#: ffdl_plugin.py:461 +msgid "No Story URLs found in selected books." +msgstr "" + +#: ffdl_plugin.py:477 +msgid "No Selected Books have URLs to Reject" +msgstr "" + +#: ffdl_plugin.py:485 +msgid "Collecting URLs for Reject List..." +msgstr "" + +#: ffdl_plugin.py:486 +msgid "Get URLs for Reject List" +msgstr "" + +#: ffdl_plugin.py:521 +msgid "Proceed to Remove?" +msgstr "" + +#: ffdl_plugin.py:521 +msgid "Rejecting FFDL URLs: None of the books selected have FanFiction URLs." +msgstr "" + +# %s = EpubMerge +#: ffdl_plugin.py:543 +msgid "Cannot Make Anthologys without %s" +msgstr "" + +#: ffdl_plugin.py:547 ffdl_plugin.py:651 +msgid "Cannot Update Books from Device View" +msgstr "" + +#: ffdl_plugin.py:551 +msgid "Can only update 1 anthology at a time" +msgstr "" + +#: ffdl_plugin.py:560 +msgid "Can only Update Epub Anthologies" +msgstr "" + +#: ffdl_plugin.py:578 ffdl_plugin.py:579 +msgid "Cannot Update Anthology" +msgstr "" + +#: ffdl_plugin.py:579 +msgid "" +"Book isn't an FFDL Anthology or contains book(s) without valid FFDL URLs." +msgstr "" + +#: ffdl_plugin.py:637 +msgid "" +"There are %d stories in the current anthology that are not going to " +"be kept if you go ahead." +msgstr "" + +#: ffdl_plugin.py:638 +msgid "Story URLs that will be removed:" +msgstr "" + +#: ffdl_plugin.py:640 +msgid "Update anyway?" +msgstr "" + +#: ffdl_plugin.py:641 +msgid "Stories Removed" +msgstr "" + +#: ffdl_plugin.py:658 +msgid "No Selected Books to Update" +msgstr "" + +#: ffdl_plugin.py:672 +msgid "Collecting stories for update..." +msgstr "" + +#: ffdl_plugin.py:673 +msgid "Get stories for updates" +msgstr "" + +#: ffdl_plugin.py:683 +msgid "Update Existing List" +msgstr "" + +#: ffdl_plugin.py:732 +msgid "Started fetching metadata for %s stories." +msgstr "" + +#: ffdl_plugin.py:738 +msgid "No valid story URLs entered." +msgstr "" + +#: ffdl_plugin.py:763 ffdl_plugin.py:769 +msgid "Reject URL?" +msgstr "" + +#: ffdl_plugin.py:770 ffdl_plugin.py:788 +msgid "%s is on your Reject URL list:" +msgstr "" + +#: ffdl_plugin.py:772 +msgid "Click 'Yes' to Reject." +msgstr "" + +#: ffdl_plugin.py:773 ffdl_plugin.py:857 +msgid "Click 'No' to download anyway." +msgstr "" + +#: ffdl_plugin.py:775 +msgid "Story on Reject URLs list (%s)." +msgstr "" + +#: ffdl_plugin.py:778 +msgid "Rejected" +msgstr "" + +#: ffdl_plugin.py:781 +msgid "Remove Reject URL?" +msgstr "" + +#: ffdl_plugin.py:787 +msgid "Remove URL from Reject List?" +msgstr "" + +#: ffdl_plugin.py:790 +msgid "Click 'Yes' to remove it from the list," +msgstr "" + +#: ffdl_plugin.py:791 +msgid "Click 'No' to leave it on the list." +msgstr "" + +#: ffdl_plugin.py:808 +msgid "Cannot update non-epub format." +msgstr "" + +#: ffdl_plugin.py:833 +msgid "Are You an Adult?" +msgstr "" + +#: ffdl_plugin.py:834 +msgid "" +"%s requires that you be an adult. Please confirm you are an adult in your " +"locale:" +msgstr "" + +#: ffdl_plugin.py:848 +msgid "Skip Story?" +msgstr "" + +#: ffdl_plugin.py:854 +msgid "Skip Anthology Story?" +msgstr "" + +#: ffdl_plugin.py:855 +msgid "" +"\"%s\" is in series \"%s\" that you have an " +"anthology book for." +msgstr "" + +#: ffdl_plugin.py:856 +msgid "Click 'Yes' to Skip." +msgstr "" + +#: ffdl_plugin.py:859 +msgid "Story in Series Anthology(%s)." +msgstr "" + +#: ffdl_plugin.py:864 +msgid "Skipped" +msgstr "" + +#: ffdl_plugin.py:892 +msgid "Add" +msgstr "" + +#: ffdl_plugin.py:905 +msgid "Meta" +msgstr "" + +#: ffdl_plugin.py:943 +msgid "Skipping duplicate story." +msgstr "" + +#: ffdl_plugin.py:957 +msgid "Update" +msgstr "" + +#: ffdl_plugin.py:962 ffdl_plugin.py:969 +msgid "Change Story URL?" +msgstr "" + +#: ffdl_plugin.py:970 +msgid "" +"%s by %s is already in your library with a different source " +"URL:" +msgstr "" + +#: ffdl_plugin.py:971 +msgid "In library: %(liburl)s" +msgstr "" + +#: ffdl_plugin.py:972 ffdl_plugin.py:986 +msgid "New URL: %(newurl)s" +msgstr "" + +#: ffdl_plugin.py:973 +msgid "Click 'Yes' to update/overwrite book with new URL." +msgstr "" + +#: ffdl_plugin.py:974 +msgid "Click 'No' to skip updating/overwriting this book." +msgstr "" + +#: ffdl_plugin.py:976 ffdl_plugin.py:983 +msgid "Download as New Book?" +msgstr "" + +#: ffdl_plugin.py:984 +msgid "" +"%s by %s is already in your library with a different source " +"URL." +msgstr "" + +#: ffdl_plugin.py:985 +msgid "" +"You chose not to update the existing book. Do you want to add a new book " +"for this URL?" +msgstr "" + +#: ffdl_plugin.py:987 +msgid "Click 'Yes' to a new book with new URL." +msgstr "" + +#: ffdl_plugin.py:988 +msgid "Click 'No' to skip URL." +msgstr "" + +#: ffdl_plugin.py:994 +msgid "Update declined by user due to differing story URL(%s)" +msgstr "" + +#: ffdl_plugin.py:997 +msgid "Different URL" +msgstr "" + +#: ffdl_plugin.py:1002 +msgid "Metadata collected." +msgstr "" + +#: ffdl_plugin.py:1018 +msgid "Already contains %d chapters." +msgstr "" + +#: ffdl_plugin.py:1023 +msgid "" +"Existing epub contains %d chapters, web site only has %d. Use Overwrite to " +"force update." +msgstr "" + +#: ffdl_plugin.py:1025 +msgid "" +"FFDL doesn't recognize chapters in existing epub, epub is probably from a " +"different source. Use Overwrite to force update." +msgstr "" + +#: ffdl_plugin.py:1033 +msgid "Not Overwriting, web site is not newer." +msgstr "" + +#: ffdl_plugin.py:1100 +msgid "None of the %d URLs/stories given can be/need to be downloaded." +msgstr "" + +#: ffdl_plugin.py:1101 ffdl_plugin.py:1259 ffdl_plugin.py:1289 +msgid "See log for details." +msgstr "" + +#: ffdl_plugin.py:1102 +msgid "Proceed with updating your library(Error Column, if configured)?" +msgstr "" + +#: ffdl_plugin.py:1109 ffdl_plugin.py:1271 +msgid "Bad" +msgstr "" + +#: ffdl_plugin.py:1117 +msgid "FFDL download ended" +msgstr "" + +#: ffdl_plugin.py:1117 ffdl_plugin.py:1314 +msgid "FFDL log" +msgstr "" + +#: ffdl_plugin.py:1125 +msgid "Download FanFiction Book" +msgstr "" + +#: ffdl_plugin.py:1131 +msgid "Starting %d FanFictionDownLoads" +msgstr "" + +#: ffdl_plugin.py:1161 +msgid "Story Details:" +msgstr "" + +#: ffdl_plugin.py:1164 +msgid "Error Updating Metadata" +msgstr "" + +#: ffdl_plugin.py:1165 +msgid "" +"An error has occurred while FFDL was updating calibre's metadata for %s." +msgstr "" + +#: ffdl_plugin.py:1166 +msgid "The ebook has been updated, but the metadata has not." +msgstr "" + +#: ffdl_plugin.py:1218 +msgid "Finished Adding/Updating %d books." +msgstr "" + +#: ffdl_plugin.py:1243 +msgid "No Good Stories for Anthology" +msgstr "" + +#: ffdl_plugin.py:1244 +msgid "" +"No good stories/updates where downloaded, Anthology creation/update aborted." +msgstr "" + +#: ffdl_plugin.py:1249 ffdl_plugin.py:1288 +msgid "FFDL found %s good and %s bad updates." +msgstr "" + +#: ffdl_plugin.py:1256 +msgid "" +"Are you sure you want to continue with creating/updating this Anthology?" +msgstr "" + +#: ffdl_plugin.py:1257 +msgid "Any updates that failed will not be included in the Anthology." +msgstr "" + +#: ffdl_plugin.py:1258 +msgid "However, if there's an older version, it will still be included." +msgstr "" + +#: ffdl_plugin.py:1261 +msgid "Proceed with updating this anthology and your library?" +msgstr "" + +#: ffdl_plugin.py:1269 +msgid "Good" +msgstr "" + +#: ffdl_plugin.py:1290 +msgid "Proceed with updating your library?" +msgstr "" + +#: ffdl_plugin.py:1314 +msgid "FFDL download complete" +msgstr "" + +#: ffdl_plugin.py:1327 +msgid "Merging %s books." +msgstr "" + +#: ffdl_plugin.py:1368 +msgid "FFDL Adding/Updating books." +msgstr "" + +#: ffdl_plugin.py:1375 +msgid "Updating calibre for FanFiction stories..." +msgstr "" + +#: ffdl_plugin.py:1376 +msgid "Update calibre for FanFiction stories" +msgstr "" + +#: ffdl_plugin.py:1385 +msgid "Adding/Updating %s BAD books." +msgstr "" + +#: ffdl_plugin.py:1391 +msgid "Updating calibre for BAD FanFiction stories..." +msgstr "" + +#: ffdl_plugin.py:1392 +msgid "Update calibre for BAD FanFiction stories" +msgstr "" + +#: ffdl_plugin.py:1420 +msgid "Adding format to book failed for some reason..." +msgstr "" + +#: ffdl_plugin.py:1423 +msgid "Error" +msgstr "" + +#: ffdl_plugin.py:1653 +msgid "" +"You configured FanFictionDownLoader to automatically update Reading Lists, " +"but you don't have the %s plugin installed anymore?" +msgstr "" + +#: ffdl_plugin.py:1665 +msgid "" +"You configured FanFictionDownLoader to automatically update \"To Read\" " +"Reading Lists, but you don't have any lists set?" +msgstr "" + +#: ffdl_plugin.py:1675 ffdl_plugin.py:1693 +msgid "" +"You configured FanFictionDownLoader to automatically update Reading List " +"'%s', but you don't have a list of that name?" +msgstr "" + +#: ffdl_plugin.py:1681 +msgid "" +"You configured FanFictionDownLoader to automatically update \"Send to Device" +"\" Reading Lists, but you don't have any lists set?" +msgstr "" + +#: ffdl_plugin.py:1800 +msgid "No story URL found." +msgstr "" + +#: ffdl_plugin.py:1803 +msgid "Not Found" +msgstr "" + +#: ffdl_plugin.py:1809 +msgid "URL is not a valid story URL." +msgstr "" + +#: ffdl_plugin.py:1812 +msgid "Bad URL" +msgstr "" + +#: ffdl_plugin.py:1942 +msgid "Anthology containing:" +msgstr "" + +#: ffdl_plugin.py:1963 +msgid " Anthology" +msgstr "" + +#: ffdl_plugin.py:2000 +msgid "(was set, removed for security)" +msgstr "" diff --git a/calibre-plugin/translations/messages.pot b/calibre-plugin/translations/messages.pot new file mode 100644 index 00000000..969ec1c9 --- /dev/null +++ b/calibre-plugin/translations/messages.pot @@ -0,0 +1,1458 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2013-11-15 14:15+Central Standard Time\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: ENCODING\n" +"Generated-By: pygettext.py 1.5\n" + + +#: __init__.py:42 +msgid "UI plugin to download FanFiction stories from various sites." +msgstr "" + +#: __init__.py:109 +msgid "Path to the calibre library. Default is to use the path stored in the settings." +msgstr "" + +#: config.py:155 +msgid "FAQs" +msgstr "" + +#: config.py:155 +msgid "List of Supported Sites" +msgstr "" + +#: config.py:169 +msgid "Basic" +msgstr "" + +#: config.py:190 +msgid "Standard Columns" +msgstr "" + +#: config.py:193 +msgid "Custom Columns" +msgstr "" + +#: config.py:196 +msgid "Other" +msgstr "" + +#: config.py:314 +msgid "These settings control the basic features of the plugin--downloading FanFiction." +msgstr "" + +#: config.py:318 +msgid "Defaults Options on Download" +msgstr "" + +#: config.py:322 +msgid "On each download, FFDL offers an option to select the output format.
    This sets what that option will default to." +msgstr "" + +#: config.py:324 +msgid "Default Output &Format:" +msgstr "" + +#: config.py:339 +msgid "On each download, FFDL offers an option of what happens if that story already exists.
    This sets what that option will default to." +msgstr "" + +#: config.py:341 +msgid "Default If Story Already Exists?" +msgstr "" + +#: config.py:355 +msgid "Default Update Calibre &Metadata?" +msgstr "" + +#: config.py:356 +msgid "On each download, FFDL offers an option to update Calibre's metadata (title, author, URL, tags, custom columns, etc) from the web site.
    This sets whether that will default to on or off.
    Columns set to 'New Only' in the column tabs will only be set for new books." +msgstr "" + +#: config.py:360 +msgid "Default Update EPUB Cover when Updating EPUB?" +msgstr "" + +#: config.py:361 +msgid "On each download, FFDL offers an option to update the book cover image inside the EPUB from the web site when the EPUB is updated.
    This sets whether that will default to on or off." +msgstr "" + +#: config.py:365 +msgid "Smarten Punctuation (EPUB only)" +msgstr "" + +#: config.py:366 +msgid "Run Smarten Punctuation from Calibre's Polish Book feature on each EPUB download and update." +msgstr "" + +#: config.py:371 +msgid "Updating Calibre Options" +msgstr "" + +#: config.py:375 +msgid "Delete other existing formats?" +msgstr "" + +#: config.py:376 +msgid "" +"Check this to automatically delete all other ebook formats when updating an existing book.\n" +"Handy if you have both a Nook(epub) and Kindle(mobi), for example." +msgstr "" + +#: config.py:380 +msgid "Update Calibre Cover when Updating Metadata?" +msgstr "" + +#: config.py:381 +msgid "" +"Update calibre book cover image from EPUB when metadata is updated. (EPUB only.)\n" +"Doesn't go looking for new images on 'Update Calibre Metadata Only'." +msgstr "" + +#: config.py:385 +msgid "Keep Existing Tags when Updating Metadata?" +msgstr "" + +#: config.py:386 +msgid "" +"Existing tags will be kept and any new tags added.\n" +"%(cmplt)s and %(inprog)s tags will be still be updated, if known.\n" +"%(lul)s tags will be updated if %(lus)s in %(is)s.\n" +"(If Tags is set to 'New Only' in the Standard Columns tab, this has no effect.)" +msgstr "" + +#: config.py:390 +msgid "Force Author into Author Sort?" +msgstr "" + +#: config.py:391 +msgid "" +"If checked, the author(s) as given will be used for the Author Sort, too.\n" +"If not checked, calibre will apply it's built in algorithm which makes 'Bob Smith' sort as 'Smith, Bob', etc." +msgstr "" + +#: config.py:395 +msgid "Force Title into Title Sort?" +msgstr "" + +#: config.py:396 +msgid "" +"If checked, the title as given will be used for the Title Sort, too.\n" +"If not checked, calibre will apply it's built in algorithm which makes 'The Title' sort as 'Title, The', etc." +msgstr "" + +#: config.py:400 +msgid "Check for existing Series Anthology books?" +msgstr "" + +#: config.py:401 +msgid "" +"Check for existings Series Anthology books using each new story's series URL before downloading.\n" +"Offer to skip downloading if a Series Anthology is found." +msgstr "" + +#: config.py:405 +msgid "Check for changed Story URL?" +msgstr "" + +#: config.py:406 +msgid "Warn you if an update will change the URL of an existing book." +msgstr "" + +#: config.py:410 +msgid "Search EPUB text for Story URL?" +msgstr "" + +#: config.py:411 +msgid "" +"Look for first valid story URL inside EPUB text if not found in metadata.\n" +"Somewhat risky, could find wrong URL depending on EPUB content.\n" +"Also finds and corrects bad ffnet URLs from ficsaver.com files." +msgstr "" + +#: config.py:415 +msgid "Mark added/updated books when finished?" +msgstr "" + +#: config.py:416 +msgid "" +"Mark added/updated books when finished. Use with option below.\n" +"You can also manually search for 'marked:ffdl_success'.\n" +"'marked:ffdl_failed' is also available, or search 'marked:ffdl' for both." +msgstr "" + +#: config.py:420 +msgid "Show Marked books when finished?" +msgstr "" + +#: config.py:421 +msgid "" +"Show Marked added/updated books only when finished.\n" +"You can also manually search for 'marked:ffdl_success'.\n" +"'marked:ffdl_failed' is also available, or search 'marked:ffdl' for both." +msgstr "" + +#: config.py:425 +msgid "GUI Options" +msgstr "" + +#: config.py:429 +msgid "Take URLs from Clipboard?" +msgstr "" + +#: config.py:430 +msgid "Prefill URLs from valid URLs in Clipboard when Adding New." +msgstr "" + +#: config.py:434 +msgid "Default to Update when books selected?" +msgstr "" + +#: config.py:435 +msgid "" +"The top FanFictionDownLoader plugin button will start Update if\n" +"books are selected. If unchecked, it will always bring up 'Add New'." +msgstr "" + +#: config.py:439 +msgid "Keep 'Add New from URL(s)' dialog on top?" +msgstr "" + +#: config.py:440 +msgid "" +"Instructs the OS and Window Manager to keep the 'Add New from URL(s)'\n" +"dialog on top of all other windows. Useful for dragging URLs onto it." +msgstr "" + +#: config.py:444 +msgid "Misc Options" +msgstr "" + +#: config.py:449 +msgid "Include images in EPUBs?" +msgstr "" + +#: config.py:450 +msgid "Download and include images in EPUB stories. This is equivalent to adding:%(imgset)s ...to the top of %(pini)s. Your settings in %(pini)s will override this." +msgstr "" + +#: config.py:454 +msgid "Inject calibre Series when none found?" +msgstr "" + +#: config.py:455 +msgid "If no series is found, inject the calibre series (if there is one) so it appears on the FFDL title page(not cover)." +msgstr "" + +#: config.py:459 +msgid "Reject List" +msgstr "" + +#: config.py:463 +msgid "Edit Reject URL List" +msgstr "" + +#: config.py:464 +msgid "Edit list of URLs FFDL will automatically Reject." +msgstr "" + +#: config.py:468 config.py:537 +msgid "Add Reject URLs" +msgstr "" + +#: config.py:469 +msgid "Add additional URLs to Reject as text." +msgstr "" + +#: config.py:473 +msgid "Edit Reject Reasons List" +msgstr "" + +#: config.py:474 config.py:528 +msgid "Customize the Reasons presented when Rejecting URLs" +msgstr "" + +#: config.py:512 +msgid "Edit Reject URLs List" +msgstr "" + +#: config.py:526 +msgid "Reject Reasons" +msgstr "" + +#: config.py:527 +msgid "Customize Reject List Reasons" +msgstr "" + +#: config.py:535 +msgid "Reason why I rejected it" +msgstr "" + +#: config.py:535 +msgid "Title by Author" +msgstr "" + +#: config.py:538 +msgid "Add Reject URLs. Use: http://...,note or http://...,title by author - note
    Invalid story URLs will be ignored." +msgstr "" + +#: config.py:539 +msgid "" +"One URL per line:\n" +"http://...,note\n" +"http://...,title by author - note" +msgstr "" + +#: config.py:541 dialogs.py:1006 +msgid "Add this reason to all URLs added:" +msgstr "" + +#: config.py:556 +msgid "These settings provide more detailed control over what metadata will be displayed inside the ebook as well as let you set %(isa)s and %(u)s/%(p)s for different sites." +msgstr "" + +#: config.py:574 +msgid "View Defaults" +msgstr "" + +#: config.py:575 +msgid "" +"View all of the plugin's configurable settings\n" +"and their default settings." +msgstr "" + +#: config.py:593 +msgid "Plugin Defaults (%s) (Read-Only)" +msgstr "" + +#: config.py:594 config.py:600 +msgid "" +"These are all of the plugin's configurable options\n" +"and their default settings." +msgstr "" + +#: config.py:595 +msgid "Plugin Defaults" +msgstr "" + +#: config.py:611 dialogs.py:530 dialogs.py:633 +msgid "OK" +msgstr "" + +#: config.py:631 +msgid "These settings provide integration with the %(rl)s Plugin. %(rl)s can automatically send to devices and change custom columns. You have to create and configure the lists in %(rl)s to be useful." +msgstr "" + +#: config.py:636 +msgid "Add new/updated stories to \"Send to Device\" Reading List(s)." +msgstr "" + +#: config.py:637 +msgid "Automatically add new/updated stories to these lists in the %(rl)s plugin." +msgstr "" + +#: config.py:642 +msgid "\"Send to Device\" Reading Lists" +msgstr "" + +#: config.py:643 config.py:646 config.py:659 config.py:662 +msgid "When enabled, new/updated stories will be automatically added to these lists." +msgstr "" + +#: config.py:652 +msgid "Add new/updated stories to \"To Read\" Reading List(s)." +msgstr "" + +#: config.py:653 +msgid "" +"Automatically add new/updated stories to these lists in the %(rl)s plugin.\n" +"Also offers menu option to remove stories from the \"To Read\" lists." +msgstr "" + +#: config.py:658 +msgid "\"To Read\" Reading Lists" +msgstr "" + +#: config.py:668 +msgid "Add stories back to \"Send to Device\" Reading List(s) when marked \"Read\"." +msgstr "" + +#: config.py:669 +msgid "Menu option to remove from \"To Read\" lists will also add stories back to \"Send to Device\" Reading List(s)" +msgstr "" + +#: config.py:691 +msgid "The %(gc)s plugin can create cover images for books using various metadata and configurations. If you have GC installed, FFDL can run GC on new downloads and metadata updates. Pick a GC setting by site or Default." +msgstr "" + +#: config.py:709 config.py:713 +msgid "Default" +msgstr "" + +#: config.py:714 +msgid "On Metadata update, run %(gc)s with this setting, if not selected for specific site." +msgstr "" + +#: config.py:717 +msgid "On Metadata update, run %(gc)s with this setting for %(site)s stories." +msgstr "" + +#: config.py:735 +msgid "Run %(gc)s Only on New Books" +msgstr "" + +#: config.py:736 +msgid "Default is to run GC any time the calibre metadata is updated." +msgstr "" + +#: config.py:740 +msgid "Allow %(gcset)s from %(pini)s to override" +msgstr "" + +#: config.py:741 +msgid "The %(pini)s parameter %(gcset)s allows you to choose a GC setting based on metadata rather than site, but it's much more complex.
    %(gcset)s is ignored when this is off." +msgstr "" + +#: config.py:755 +msgid "These settings provide integration with the %(cp)s Plugin. %(cp)s can automatically update custom columns with page, word and reading level statistics. You have to create and configure the columns in %(cp)s first." +msgstr "" + +#: config.py:760 +msgid "If any of the settings below are checked, when stories are added or updated, the %(cp)s Plugin will be called to update the checked statistics." +msgstr "" + +#: config.py:766 +msgid "Which column and algorithm to use are configured in %(cp)s." +msgstr "" + +#: config.py:774 +msgid "Will overwrite word count from FFDL metadata if set to update the same custom column." +msgstr "" + +#: config.py:805 +msgid "These controls aren't plugin settings as such, but convenience buttons for setting Keyboard shortcuts and getting all the FanFictionDownLoader confirmation dialogs back again." +msgstr "" + +#: config.py:810 +msgid "Keyboard shortcuts..." +msgstr "" + +#: config.py:811 +msgid "Edit the keyboard shortcuts associated with this plugin" +msgstr "" + +#: config.py:815 +msgid "Reset disabled &confirmation dialogs" +msgstr "" + +#: config.py:816 +msgid "Reset all show me again dialogs for the FanFictionDownLoader plugin" +msgstr "" + +#: config.py:820 +msgid "&View library preferences..." +msgstr "" + +#: config.py:821 +msgid "View data stored in the library database for this plugin" +msgstr "" + +#: config.py:832 +msgid "Done" +msgstr "" + +#: config.py:833 +msgid "Confirmation dialogs have all been reset" +msgstr "" + +#: config.py:881 +msgid "Category" +msgstr "" + +#: config.py:882 +msgid "Genre" +msgstr "" + +#: config.py:883 +msgid "Language" +msgstr "" + +#: config.py:884 ffdl_plugin.py:1104 ffdl_plugin.py:1263 ffdl_plugin.py:1293 +msgid "Status" +msgstr "" + +#: config.py:885 +msgid "Status:%(cmplt)s" +msgstr "" + +#: config.py:886 +msgid "Status:%(inprog)s" +msgstr "" + +#: config.py:887 config.py:1021 +msgid "Series" +msgstr "" + +#: config.py:888 +msgid "Characters" +msgstr "" + +#: config.py:889 +msgid "Relationships" +msgstr "" + +#: config.py:890 +msgid "Published" +msgstr "" + +#: config.py:891 ffdl_plugin.py:1377 ffdl_plugin.py:1393 +msgid "Updated" +msgstr "" + +#: config.py:892 +msgid "Created" +msgstr "" + +#: config.py:893 +msgid "Rating" +msgstr "" + +#: config.py:894 +msgid "Warnings" +msgstr "" + +#: config.py:895 +msgid "Chapters" +msgstr "" + +#: config.py:896 +msgid "Words" +msgstr "" + +#: config.py:897 +msgid "Site" +msgstr "" + +#: config.py:898 +msgid "Story ID" +msgstr "" + +#: config.py:899 +msgid "Author ID" +msgstr "" + +#: config.py:900 +msgid "Extra Tags" +msgstr "" + +#: config.py:901 config.py:1013 dialogs.py:792 dialogs.py:888 +#: ffdl_plugin.py:1104 ffdl_plugin.py:1263 ffdl_plugin.py:1293 +msgid "Title" +msgstr "" + +#: config.py:902 +msgid "Story URL" +msgstr "" + +#: config.py:903 +msgid "Description" +msgstr "" + +#: config.py:904 dialogs.py:792 dialogs.py:888 ffdl_plugin.py:1104 +#: ffdl_plugin.py:1263 ffdl_plugin.py:1293 +msgid "Author" +msgstr "" + +#: config.py:905 +msgid "Author URL" +msgstr "" + +#: config.py:906 +msgid "File Format" +msgstr "" + +#: config.py:907 +msgid "File Extension" +msgstr "" + +#: config.py:908 +msgid "Site Abbrev" +msgstr "" + +#: config.py:909 +msgid "FFDL Version" +msgstr "" + +#: config.py:924 +msgid "If you have custom columns defined, they will be listed below. Choose a metadata value type to fill your columns automatically." +msgstr "" + +#: config.py:949 +msgid "Update this %s column(%s) with..." +msgstr "" + +#: config.py:959 +msgid "Values that aren't valid for this enumeration column will be ignored." +msgstr "" + +#: config.py:959 config.py:961 +msgid "Metadata values valid for this type of column." +msgstr "" + +#: config.py:964 config.py:1040 +msgid "New Only" +msgstr "" + +#: config.py:965 +msgid "" +"Write to %s(%s) only for new\n" +"books, not updates to existing books." +msgstr "" + +#: config.py:976 +msgid "Allow %(ccset)s from %(pini)s to override" +msgstr "" + +#: config.py:977 +msgid "The %(pini)s parameter %(ccset)s allows you to set custom columns to site specific values that aren't common to all sites.
    %(ccset)s is ignored when this is off." +msgstr "" + +#: config.py:982 +msgid "Special column:" +msgstr "" + +#: config.py:987 +msgid "Update/Overwrite Error Column:" +msgstr "" + +#: config.py:988 +msgid "" +"When an update or overwrite of an existing story fails, record the reason in this column.\n" +"(Text and Long Text columns only.)" +msgstr "" + +#: config.py:1014 +msgid "Author(s)" +msgstr "" + +#: config.py:1015 +msgid "Publisher" +msgstr "" + +#: config.py:1016 +msgid "Tags" +msgstr "" + +#: config.py:1017 +msgid "Languages" +msgstr "" + +#: config.py:1018 +msgid "Published Date" +msgstr "" + +#: config.py:1019 +msgid "Date" +msgstr "" + +#: config.py:1020 +msgid "Comments" +msgstr "" + +#: config.py:1022 +msgid "Ids(url id only)" +msgstr "" + +#: config.py:1027 +msgid "The standard calibre metadata columns are listed below. You may choose whether FFDL will fill each column automatically on updates or only for new books." +msgstr "" + +#: config.py:1041 +msgid "" +"Write to %s only for new\n" +"books, not updates to existing books." +msgstr "" + +#: dialogs.py:45 +msgid "Skip" +msgstr "" + +#: dialogs.py:46 +msgid "Add New Book" +msgstr "" + +#: dialogs.py:47 +msgid "Update EPUB if New Chapters" +msgstr "" + +#: dialogs.py:48 +msgid "Update EPUB Always" +msgstr "" + +#: dialogs.py:49 +msgid "Overwrite if Newer" +msgstr "" + +#: dialogs.py:50 +msgid "Overwrite Always" +msgstr "" + +#: dialogs.py:51 +msgid "Update Calibre Metadata Only" +msgstr "" + +#: dialogs.py:139 ffdl_plugin.py:1943 +msgid "%s by %s" +msgstr "" + +#: dialogs.py:227 ffdl_plugin.py:86 +msgid "FanFictionDownLoader" +msgstr "" + +#: dialogs.py:244 dialogs.py:691 +msgid "Show Download Options" +msgstr "" + +#: dialogs.py:263 dialogs.py:708 +msgid "Output &Format:" +msgstr "" + +#: dialogs.py:271 dialogs.py:716 +msgid "Choose output format to create. May set default from plugin configuration." +msgstr "" + +#: dialogs.py:299 dialogs.py:733 +msgid "Update Calibre &Metadata?" +msgstr "" + +#: dialogs.py:300 dialogs.py:734 +msgid "" +"Update metadata for existing stories in Calibre from web site?\n" +"(Columns set to 'New Only' in the column tabs will only be set for new books.)" +msgstr "" + +#: dialogs.py:306 dialogs.py:738 +msgid "Update EPUB Cover?" +msgstr "" + +#: dialogs.py:307 dialogs.py:739 +msgid "Update book cover image from site or defaults (if found) inside the EPUB when EPUB is updated." +msgstr "" + +#: dialogs.py:354 +msgid "Story URL(s) for anthology, one per line:" +msgstr "" + +#: dialogs.py:355 +msgid "" +"URLs for stories to include in the anthology, one per line.\n" +"Will take URLs from clipboard, but only valid URLs." +msgstr "" + +#: dialogs.py:356 +msgid "If Story Already Exists in Anthology?" +msgstr "" + +#: dialogs.py:357 +msgid "What to do if there's already an existing story with the same URL in the anthology." +msgstr "" + +#: dialogs.py:366 +msgid "Story URL(s), one per line:" +msgstr "" + +#: dialogs.py:367 +msgid "" +"URLs for stories, one per line.\n" +"Will take URLs from clipboard, but only valid URLs.\n" +"Add [1,5] after the URL to limit the download to chapters 1-5." +msgstr "" + +#: dialogs.py:368 +msgid "If Story Already Exists?" +msgstr "" + +#: dialogs.py:369 +msgid "What to do if there's already an existing story with the same URL or title and author." +msgstr "" + +#: dialogs.py:469 +msgid "For Individual Books" +msgstr "" + +#: dialogs.py:470 +msgid "Get URLs and go to dialog for individual story downloads." +msgstr "" + +#: dialogs.py:474 +msgid "For Anthology Epub" +msgstr "" + +#: dialogs.py:475 +msgid "" +"Get URLs and go to dialog for Anthology download.\n" +"Requires %s plugin." +msgstr "" + +#: dialogs.py:480 dialogs.py:534 +msgid "Cancel" +msgstr "" + +#: dialogs.py:512 +msgid "Password" +msgstr "" + +#: dialogs.py:513 +msgid "Author requires a password for this story(%s)." +msgstr "" + +#: dialogs.py:518 +msgid "User/Password" +msgstr "" + +#: dialogs.py:519 +msgid "%s requires you to login to download this story." +msgstr "" + +#: dialogs.py:521 +msgid "User:" +msgstr "" + +#: dialogs.py:525 +msgid "Password:" +msgstr "" + +#: dialogs.py:556 +msgid "Fetching metadata for stories..." +msgstr "" + +#: dialogs.py:557 +msgid "Downloading metadata for stories" +msgstr "" + +#: dialogs.py:558 +msgid "Fetched metadata for" +msgstr "" + +#: dialogs.py:628 ffdl_plugin.py:322 +msgid "About FanFictionDownLoader" +msgstr "" + +#: dialogs.py:682 +msgid "Remove selected books from the list" +msgstr "" + +#: dialogs.py:721 +msgid "Update Mode:" +msgstr "" + +#: dialogs.py:724 +msgid "What sort of update to perform. May set default from plugin configuration." +msgstr "" + +#: dialogs.py:792 ffdl_plugin.py:1104 ffdl_plugin.py:1263 ffdl_plugin.py:1293 +msgid "Comment" +msgstr "" + +#: dialogs.py:860 +msgid "Are you sure you want to remove this book from the list?" +msgstr "" + +#: dialogs.py:862 +msgid "Are you sure you want to remove the selected %d books from the list?" +msgstr "" + +#: dialogs.py:888 +msgid "Note" +msgstr "" + +#: dialogs.py:930 +msgid "Select or Edit Reject Note." +msgstr "" + +#: dialogs.py:938 +msgid "Are you sure you want to remove this URL from the list?" +msgstr "" + +#: dialogs.py:940 +msgid "Are you sure you want to remove the %d selected URLs from the list?" +msgstr "" + +#: dialogs.py:958 +msgid "List of Books to Reject" +msgstr "" + +#: dialogs.py:971 +msgid "FFDL will remember these URLs and display the note and offer to reject them if you try to download them again later." +msgstr "" + +#: dialogs.py:985 +msgid "Remove selected URL(s) from the list" +msgstr "" + +#: dialogs.py:1003 dialogs.py:1007 +msgid "This will be added to whatever note you've set for each URL above." +msgstr "" + +#: dialogs.py:1016 +msgid "Delete Books (including books without FanFiction URLs)?" +msgstr "" + +#: dialogs.py:1017 +msgid "Delete the selected books after adding them to the Rejected URLs list." +msgstr "" + +#: ffdl_plugin.py:87 +msgid "Download FanFiction stories from various web sites" +msgstr "" + +#: ffdl_plugin.py:117 +msgid "FanFictionDL" +msgstr "" + +#: ffdl_plugin.py:240 +msgid "&Add New from URL(s)" +msgstr "" + +#: ffdl_plugin.py:242 +msgid "Add New FanFiction Book(s) from URL(s)" +msgstr "" + +#: ffdl_plugin.py:245 +msgid "&Update Existing FanFiction Book(s)" +msgstr "" + +#: ffdl_plugin.py:251 +msgid "Get Story URLs to Download from Web Page" +msgstr "" + +#: ffdl_plugin.py:255 +msgid "&Make Anthology Epub Manually from URL(s)" +msgstr "" + +#: ffdl_plugin.py:257 +msgid "Make FanFiction Anthology Epub Manually from URL(s)" +msgstr "" + +#: ffdl_plugin.py:260 +msgid "&Update Anthology Epub" +msgstr "" + +#: ffdl_plugin.py:262 +msgid "Update FanFiction Anthology Epub" +msgstr "" + +#: ffdl_plugin.py:270 +msgid "Add to \"To Read\" and \"Send to Device\" Lists" +msgstr "" + +#: ffdl_plugin.py:272 +msgid "Remove from \"To Read\" and add to \"Send to Device\" Lists" +msgstr "" + +#: ffdl_plugin.py:274 ffdl_plugin.py:279 +msgid "Remove from \"To Read\" Lists" +msgstr "" + +#: ffdl_plugin.py:276 +msgid "Add Selected to \"Send to Device\" Lists" +msgstr "" + +#: ffdl_plugin.py:278 +msgid "Add to \"To Read\" Lists" +msgstr "" + +#: ffdl_plugin.py:294 +msgid "Get URLs from Selected Books" +msgstr "" + +#: ffdl_plugin.py:300 ffdl_plugin.py:393 +msgid "Get Story URLs from Web Page" +msgstr "" + +#: ffdl_plugin.py:305 +msgid "Reject Selected Books" +msgstr "" + +#: ffdl_plugin.py:313 +msgid "&Configure Plugin" +msgstr "" + +#: ffdl_plugin.py:316 +msgid "Configure FanFictionDownLoader" +msgstr "" + +#: ffdl_plugin.py:319 +msgid "About Plugin" +msgstr "" + +#: ffdl_plugin.py:376 +msgid "Cannot Update Reading Lists from Device View" +msgstr "" + +#: ffdl_plugin.py:380 +msgid "No Selected Books to Update Reading Lists" +msgstr "" + +#: ffdl_plugin.py:404 ffdl_plugin.py:456 +msgid "List of Story URLs" +msgstr "" + +#: ffdl_plugin.py:405 +msgid "No Valid Story URLs found on given page." +msgstr "" + +#: ffdl_plugin.py:420 +msgid "No Selected Books to Get URLs From" +msgstr "" + +#: ffdl_plugin.py:438 +msgid "Collecting URLs for stories..." +msgstr "" + +#: ffdl_plugin.py:439 +msgid "Get URLs for stories" +msgstr "" + +#: ffdl_plugin.py:440 ffdl_plugin.py:487 ffdl_plugin.py:674 +msgid "URL retrieved" +msgstr "" + +#: ffdl_plugin.py:460 +msgid "List of URLs" +msgstr "" + +#: ffdl_plugin.py:461 +msgid "No Story URLs found in selected books." +msgstr "" + +#: ffdl_plugin.py:477 +msgid "No Selected Books have URLs to Reject" +msgstr "" + +#: ffdl_plugin.py:485 +msgid "Collecting URLs for Reject List..." +msgstr "" + +#: ffdl_plugin.py:486 +msgid "Get URLs for Reject List" +msgstr "" + +#: ffdl_plugin.py:521 +msgid "Proceed to Remove?" +msgstr "" + +#: ffdl_plugin.py:521 +msgid "Rejecting FFDL URLs: None of the books selected have FanFiction URLs." +msgstr "" + +#: ffdl_plugin.py:543 +msgid "Cannot Make Anthologys without %s" +msgstr "" + +#: ffdl_plugin.py:547 ffdl_plugin.py:651 +msgid "Cannot Update Books from Device View" +msgstr "" + +#: ffdl_plugin.py:551 +msgid "Can only update 1 anthology at a time" +msgstr "" + +#: ffdl_plugin.py:560 +msgid "Can only Update Epub Anthologies" +msgstr "" + +#: ffdl_plugin.py:578 ffdl_plugin.py:579 +msgid "Cannot Update Anthology" +msgstr "" + +#: ffdl_plugin.py:579 +msgid "Book isn't an FFDL Anthology or contains book(s) without valid FFDL URLs." +msgstr "" + +#: ffdl_plugin.py:637 +msgid "There are %d stories in the current anthology that are not going to be kept if you go ahead." +msgstr "" + +#: ffdl_plugin.py:638 +msgid "Story URLs that will be removed:" +msgstr "" + +#: ffdl_plugin.py:640 +msgid "Update anyway?" +msgstr "" + +#: ffdl_plugin.py:641 +msgid "Stories Removed" +msgstr "" + +#: ffdl_plugin.py:658 +msgid "No Selected Books to Update" +msgstr "" + +#: ffdl_plugin.py:672 +msgid "Collecting stories for update..." +msgstr "" + +#: ffdl_plugin.py:673 +msgid "Get stories for updates" +msgstr "" + +#: ffdl_plugin.py:683 +msgid "Update Existing List" +msgstr "" + +#: ffdl_plugin.py:732 +msgid "Started fetching metadata for %s stories." +msgstr "" + +#: ffdl_plugin.py:738 +msgid "No valid story URLs entered." +msgstr "" + +#: ffdl_plugin.py:763 ffdl_plugin.py:769 +msgid "Reject URL?" +msgstr "" + +#: ffdl_plugin.py:770 ffdl_plugin.py:788 +msgid "%s is on your Reject URL list:" +msgstr "" + +#: ffdl_plugin.py:772 +msgid "Click 'Yes' to Reject." +msgstr "" + +#: ffdl_plugin.py:773 ffdl_plugin.py:857 +msgid "Click 'No' to download anyway." +msgstr "" + +#: ffdl_plugin.py:775 +msgid "Story on Reject URLs list (%s)." +msgstr "" + +#: ffdl_plugin.py:778 +msgid "Rejected" +msgstr "" + +#: ffdl_plugin.py:781 +msgid "Remove Reject URL?" +msgstr "" + +#: ffdl_plugin.py:787 +msgid "Remove URL from Reject List?" +msgstr "" + +#: ffdl_plugin.py:790 +msgid "Click 'Yes' to remove it from the list," +msgstr "" + +#: ffdl_plugin.py:791 +msgid "Click 'No' to leave it on the list." +msgstr "" + +#: ffdl_plugin.py:808 +msgid "Cannot update non-epub format." +msgstr "" + +#: ffdl_plugin.py:833 +msgid "Are You an Adult?" +msgstr "" + +#: ffdl_plugin.py:834 +msgid "%s requires that you be an adult. Please confirm you are an adult in your locale:" +msgstr "" + +#: ffdl_plugin.py:848 +msgid "Skip Story?" +msgstr "" + +#: ffdl_plugin.py:854 +msgid "Skip Anthology Story?" +msgstr "" + +#: ffdl_plugin.py:855 +msgid "\"%s\" is in series \"%s\" that you have an anthology book for." +msgstr "" + +#: ffdl_plugin.py:856 +msgid "Click 'Yes' to Skip." +msgstr "" + +#: ffdl_plugin.py:859 +msgid "Story in Series Anthology(%s)." +msgstr "" + +#: ffdl_plugin.py:864 +msgid "Skipped" +msgstr "" + +#: ffdl_plugin.py:892 +msgid "Add" +msgstr "" + +#: ffdl_plugin.py:905 +msgid "Meta" +msgstr "" + +#: ffdl_plugin.py:943 +msgid "Skipping duplicate story." +msgstr "" + +#: ffdl_plugin.py:957 +msgid "Update" +msgstr "" + +#: ffdl_plugin.py:962 ffdl_plugin.py:969 +msgid "Change Story URL?" +msgstr "" + +#: ffdl_plugin.py:970 +msgid "%s by %s is already in your library with a different source URL:" +msgstr "" + +#: ffdl_plugin.py:971 +msgid "In library: %(liburl)s" +msgstr "" + +#: ffdl_plugin.py:972 ffdl_plugin.py:986 +msgid "New URL: %(newurl)s" +msgstr "" + +#: ffdl_plugin.py:973 +msgid "Click 'Yes' to update/overwrite book with new URL." +msgstr "" + +#: ffdl_plugin.py:974 +msgid "Click 'No' to skip updating/overwriting this book." +msgstr "" + +#: ffdl_plugin.py:976 ffdl_plugin.py:983 +msgid "Download as New Book?" +msgstr "" + +#: ffdl_plugin.py:984 +msgid "%s by %s is already in your library with a different source URL." +msgstr "" + +#: ffdl_plugin.py:985 +msgid "You chose not to update the existing book. Do you want to add a new book for this URL?" +msgstr "" + +#: ffdl_plugin.py:987 +msgid "Click 'Yes' to a new book with new URL." +msgstr "" + +#: ffdl_plugin.py:988 +msgid "Click 'No' to skip URL." +msgstr "" + +#: ffdl_plugin.py:994 +msgid "Update declined by user due to differing story URL(%s)" +msgstr "" + +#: ffdl_plugin.py:997 +msgid "Different URL" +msgstr "" + +#: ffdl_plugin.py:1002 +msgid "Metadata collected." +msgstr "" + +#: ffdl_plugin.py:1018 +msgid "Already contains %d chapters." +msgstr "" + +#: ffdl_plugin.py:1023 +msgid "Existing epub contains %d chapters, web site only has %d. Use Overwrite to force update." +msgstr "" + +#: ffdl_plugin.py:1025 +msgid "FFDL doesn't recognize chapters in existing epub, epub is probably from a different source. Use Overwrite to force update." +msgstr "" + +#: ffdl_plugin.py:1033 +msgid "Not Overwriting, web site is not newer." +msgstr "" + +#: ffdl_plugin.py:1100 +msgid "None of the %d URLs/stories given can be/need to be downloaded." +msgstr "" + +#: ffdl_plugin.py:1101 ffdl_plugin.py:1259 ffdl_plugin.py:1289 +msgid "See log for details." +msgstr "" + +#: ffdl_plugin.py:1102 +msgid "Proceed with updating your library(Error Column, if configured)?" +msgstr "" + +#: ffdl_plugin.py:1109 ffdl_plugin.py:1271 +msgid "Bad" +msgstr "" + +#: ffdl_plugin.py:1117 +msgid "FFDL download ended" +msgstr "" + +#: ffdl_plugin.py:1117 ffdl_plugin.py:1314 +msgid "FFDL log" +msgstr "" + +#: ffdl_plugin.py:1125 +msgid "Download FanFiction Book" +msgstr "" + +#: ffdl_plugin.py:1131 +msgid "Starting %d FanFictionDownLoads" +msgstr "" + +#: ffdl_plugin.py:1161 +msgid "Story Details:" +msgstr "" + +#: ffdl_plugin.py:1164 +msgid "Error Updating Metadata" +msgstr "" + +#: ffdl_plugin.py:1165 +msgid "An error has occurred while FFDL was updating calibre's metadata for %s." +msgstr "" + +#: ffdl_plugin.py:1166 +msgid "The ebook has been updated, but the metadata has not." +msgstr "" + +#: ffdl_plugin.py:1218 +msgid "Finished Adding/Updating %d books." +msgstr "" + +#: ffdl_plugin.py:1243 +msgid "No Good Stories for Anthology" +msgstr "" + +#: ffdl_plugin.py:1244 +msgid "No good stories/updates where downloaded, Anthology creation/update aborted." +msgstr "" + +#: ffdl_plugin.py:1249 ffdl_plugin.py:1288 +msgid "FFDL found %s good and %s bad updates." +msgstr "" + +#: ffdl_plugin.py:1256 +msgid "Are you sure you want to continue with creating/updating this Anthology?" +msgstr "" + +#: ffdl_plugin.py:1257 +msgid "Any updates that failed will not be included in the Anthology." +msgstr "" + +#: ffdl_plugin.py:1258 +msgid "However, if there's an older version, it will still be included." +msgstr "" + +#: ffdl_plugin.py:1261 +msgid "Proceed with updating this anthology and your library?" +msgstr "" + +#: ffdl_plugin.py:1269 +msgid "Good" +msgstr "" + +#: ffdl_plugin.py:1290 +msgid "Proceed with updating your library?" +msgstr "" + +#: ffdl_plugin.py:1314 +msgid "FFDL download complete" +msgstr "" + +#: ffdl_plugin.py:1327 +msgid "Merging %s books." +msgstr "" + +#: ffdl_plugin.py:1368 +msgid "FFDL Adding/Updating books." +msgstr "" + +#: ffdl_plugin.py:1375 +msgid "Updating calibre for FanFiction stories..." +msgstr "" + +#: ffdl_plugin.py:1376 +msgid "Update calibre for FanFiction stories" +msgstr "" + +#: ffdl_plugin.py:1385 +msgid "Adding/Updating %s BAD books." +msgstr "" + +#: ffdl_plugin.py:1391 +msgid "Updating calibre for BAD FanFiction stories..." +msgstr "" + +#: ffdl_plugin.py:1392 +msgid "Update calibre for BAD FanFiction stories" +msgstr "" + +#: ffdl_plugin.py:1420 +msgid "Adding format to book failed for some reason..." +msgstr "" + +#: ffdl_plugin.py:1423 +msgid "Error" +msgstr "" + +#: ffdl_plugin.py:1653 +msgid "You configured FanFictionDownLoader to automatically update Reading Lists, but you don't have the %s plugin installed anymore?" +msgstr "" + +#: ffdl_plugin.py:1665 +msgid "You configured FanFictionDownLoader to automatically update \"To Read\" Reading Lists, but you don't have any lists set?" +msgstr "" + +#: ffdl_plugin.py:1675 ffdl_plugin.py:1693 +msgid "You configured FanFictionDownLoader to automatically update Reading List '%s', but you don't have a list of that name?" +msgstr "" + +#: ffdl_plugin.py:1681 +msgid "You configured FanFictionDownLoader to automatically update \"Send to Device\" Reading Lists, but you don't have any lists set?" +msgstr "" + +#: ffdl_plugin.py:1800 +msgid "No story URL found." +msgstr "" + +#: ffdl_plugin.py:1803 +msgid "Not Found" +msgstr "" + +#: ffdl_plugin.py:1809 +msgid "URL is not a valid story URL." +msgstr "" + +#: ffdl_plugin.py:1812 +msgid "Bad URL" +msgstr "" + +#: ffdl_plugin.py:1942 +msgid "Anthology containing:" +msgstr "" + +#: ffdl_plugin.py:1963 +msgid " Anthology" +msgstr "" + +#: ffdl_plugin.py:2000 +msgid "(was set, removed for security)" +msgstr "" + diff --git a/calibre-plugin/translations/zz.po b/calibre-plugin/translations/zz.po new file mode 100644 index 00000000..24f1bc88 --- /dev/null +++ b/calibre-plugin/translations/zz.po @@ -0,0 +1,1744 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: FanFictionDownLoader 1.8\n" +"POT-Creation-Date: 2013-11-15 13:29+Central Standard Time\n" +"PO-Revision-Date: 2013-11-15 13:29-0600\n" +"Last-Translator: Jim Miller \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: pygettext.py 1.5\n" +"X-Generator: Poedit 1.5.7\n" + +#: __init__.py:42 +msgid "UI plugin to download FanFiction stories from various sites." +msgstr "zzUI plugin to download FanFiction stories from various sites." + +#: __init__.py:109 +msgid "" +"Path to the calibre library. Default is to use the path stored in the " +"settings." +msgstr "" +"zzPath to the calibre library. Default is to use the path stored in the " +"settings." + +#: config.py:155 +msgid "FAQs" +msgstr "zzFAQs" + +#: config.py:155 +msgid "List of Supported Sites" +msgstr "zzList of Supported Sites" + +#: config.py:169 +msgid "Basic" +msgstr "zzBasic" + +#: config.py:190 +msgid "Standard Columns" +msgstr "zzStandard Columns" + +#: config.py:193 +msgid "Custom Columns" +msgstr "zzCustom Columns" + +#: config.py:196 +msgid "Other" +msgstr "zzOther" + +#: config.py:314 +msgid "" +"These settings control the basic features of the plugin--downloading " +"FanFiction." +msgstr "" +"zzThese settings control the basic features of the plugin--downloading " +"FanFiction." + +#: config.py:318 +msgid "Defaults Options on Download" +msgstr "zzDefaults Options on Download" + +#: config.py:322 +msgid "" +"On each download, FFDL offers an option to select the output format.
    This sets what that option will default to." +msgstr "" +"zzOn each download, FFDL offers an option to select the output format.
    This sets what that option will default to." + +#: config.py:324 +msgid "Default Output &Format:" +msgstr "zzDefault Output &Format:" + +#: config.py:339 +msgid "" +"On each download, FFDL offers an option of what happens if that story " +"already exists.
    This sets what that option will default to." +msgstr "" +"zzOn each download, FFDL offers an option of what happens if that story " +"already exists.
    This sets what that option will default to." + +#: config.py:341 +msgid "Default If Story Already Exists?" +msgstr "zzDefault If Story Already Exists?" + +#: config.py:355 +msgid "Default Update Calibre &Metadata?" +msgstr "zzDefault Update Calibre &Metadata?" + +#: config.py:356 +msgid "" +"On each download, FFDL offers an option to update Calibre's metadata (title, " +"author, URL, tags, custom columns, etc) from the web site.
    This sets " +"whether that will default to on or off.
    Columns set to 'New Only' in " +"the column tabs will only be set for new books." +msgstr "" +"zzOn each download, FFDL offers an option to update Calibre's metadata " +"(title, author, URL, tags, custom columns, etc) from the web site.
    This sets whether that will default to on or off.
    Columns set to 'New " +"Only' in the column tabs will only be set for new books." + +#: config.py:360 +msgid "Default Update EPUB Cover when Updating EPUB?" +msgstr "zzDefault Update EPUB Cover when Updating EPUB?" + +#: config.py:361 +msgid "" +"On each download, FFDL offers an option to update the book cover image " +"inside the EPUB from the web site when the EPUB is updated.
    This " +"sets whether that will default to on or off." +msgstr "" +"zzOn each download, FFDL offers an option to update the book cover image " +"inside the EPUB from the web site when the EPUB is updated.
    This " +"sets whether that will default to on or off." + +#: config.py:365 +msgid "Smarten Punctuation (EPUB only)" +msgstr "zzSmarten Punctuation (EPUB only)" + +#: config.py:366 +msgid "" +"Run Smarten Punctuation from Calibre's Polish Book feature on each EPUB " +"download and update." +msgstr "" +"zzRun Smarten Punctuation from Calibre's Polish Book feature on each EPUB " +"download and update." + +#: config.py:371 +msgid "Updating Calibre Options" +msgstr "zzUpdating Calibre Options" + +#: config.py:375 +msgid "Delete other existing formats?" +msgstr "zzDelete other existing formats?" + +#: config.py:376 +msgid "" +"Check this to automatically delete all other ebook formats when updating an " +"existing book.\n" +"Handy if you have both a Nook(epub) and Kindle(mobi), for example." +msgstr "" +"zzCheck this to automatically delete all other ebook formats when updating " +"an existing book.\n" +"Handy if you have both a Nook(epub) and Kindle(mobi), for example." + +#: config.py:380 +msgid "Update Calibre Cover when Updating Metadata?" +msgstr "zzUpdate Calibre Cover when Updating Metadata?" + +#: config.py:381 +msgid "" +"Update calibre book cover image from EPUB when metadata is updated. (EPUB " +"only.)\n" +"Doesn't go looking for new images on 'Update Calibre Metadata Only'." +msgstr "" +"zzUpdate calibre book cover image from EPUB when metadata is updated. (EPUB " +"only.)\n" +"Doesn't go looking for new images on 'Update Calibre Metadata Only'." + +#: config.py:385 +msgid "Keep Existing Tags when Updating Metadata?" +msgstr "zzKeep Existing Tags when Updating Metadata?" + +#: config.py:386 +msgid "" +"Existing tags will be kept and any new tags added.\n" +"%(cmplt)s and %(inprog)s tags will be still be updated, if known.\n" +"%(lul)s tags will be updated if %(lus)s in %(is)s.\n" +"(If Tags is set to 'New Only' in the Standard Columns tab, this has no " +"effect.)" +msgstr "" +"zzExisting tags will be kept and any new tags added.\n" +"%(cmplt)s and %(inprog)s tags will be still be updated, if known.\n" +"%(lul)s tags will be updated if %(lus)s in %(is)s.\n" +"(If Tags is set to 'New Only' in the Standard Columns tab, this has no " +"effect.)" + +#: config.py:390 +msgid "Force Author into Author Sort?" +msgstr "zzForce Author into Author Sort?" + +#: config.py:391 +msgid "" +"If checked, the author(s) as given will be used for the Author Sort, too.\n" +"If not checked, calibre will apply it's built in algorithm which makes 'Bob " +"Smith' sort as 'Smith, Bob', etc." +msgstr "" +"zzIf checked, the author(s) as given will be used for the Author Sort, too.\n" +"If not checked, calibre will apply it's built in algorithm which makes 'Bob " +"Smith' sort as 'Smith, Bob', etc." + +#: config.py:395 +msgid "Force Title into Title Sort?" +msgstr "zzForce Title into Title Sort?" + +#: config.py:396 +msgid "" +"If checked, the title as given will be used for the Title Sort, too.\n" +"If not checked, calibre will apply it's built in algorithm which makes 'The " +"Title' sort as 'Title, The', etc." +msgstr "" +"zzIf checked, the title as given will be used for the Title Sort, too.\n" +"If not checked, calibre will apply it's built in algorithm which makes 'The " +"Title' sort as 'Title, The', etc." + +#: config.py:400 +msgid "Check for existing Series Anthology books?" +msgstr "zzCheck for existing Series Anthology books?" + +#: config.py:401 +msgid "" +"Check for existings Series Anthology books using each new story's series URL " +"before downloading.\n" +"Offer to skip downloading if a Series Anthology is found." +msgstr "" +"zzCheck for existings Series Anthology books using each new story's series " +"URL before downloading.\n" +"Offer to skip downloading if a Series Anthology is found." + +#: config.py:405 +msgid "Check for changed Story URL?" +msgstr "zzCheck for changed Story URL?" + +#: config.py:406 +msgid "Warn you if an update will change the URL of an existing book." +msgstr "zzWarn you if an update will change the URL of an existing book." + +#: config.py:410 +msgid "Search EPUB text for Story URL?" +msgstr "zzSearch EPUB text for Story URL?" + +#: config.py:411 +msgid "" +"Look for first valid story URL inside EPUB text if not found in metadata.\n" +"Somewhat risky, could find wrong URL depending on EPUB content.\n" +"Also finds and corrects bad ffnet URLs from ficsaver.com files." +msgstr "" +"zzLook for first valid story URL inside EPUB text if not found in metadata.\n" +"Somewhat risky, could find wrong URL depending on EPUB content.\n" +"Also finds and corrects bad ffnet URLs from ficsaver.com files." + +#: config.py:415 +msgid "Mark added/updated books when finished?" +msgstr "zzMark added/updated books when finished?" + +#: config.py:416 +msgid "" +"Mark added/updated books when finished. Use with option below.\n" +"You can also manually search for 'marked:ffdl_success'.\n" +"'marked:ffdl_failed' is also available, or search 'marked:ffdl' for both." +msgstr "" +"zzMark added/updated books when finished. Use with option below.\n" +"You can also manually search for 'marked:ffdl_success'.\n" +"'marked:ffdl_failed' is also available, or search 'marked:ffdl' for both." + +#: config.py:420 +msgid "Show Marked books when finished?" +msgstr "zzShow Marked books when finished?" + +#: config.py:421 +msgid "" +"Show Marked added/updated books only when finished.\n" +"You can also manually search for 'marked:ffdl_success'.\n" +"'marked:ffdl_failed' is also available, or search 'marked:ffdl' for both." +msgstr "" +"zzShow Marked added/updated books only when finished.\n" +"You can also manually search for 'marked:ffdl_success'.\n" +"'marked:ffdl_failed' is also available, or search 'marked:ffdl' for both." + +#: config.py:425 +msgid "GUI Options" +msgstr "zzGUI Options" + +#: config.py:429 +msgid "Take URLs from Clipboard?" +msgstr "zzTake URLs from Clipboard?" + +#: config.py:430 +msgid "Prefill URLs from valid URLs in Clipboard when Adding New." +msgstr "zzPrefill URLs from valid URLs in Clipboard when Adding New." + +#: config.py:434 +msgid "Default to Update when books selected?" +msgstr "zzDefault to Update when books selected?" + +#: config.py:435 +msgid "" +"The top FanFictionDownLoader plugin button will start Update if\n" +"books are selected. If unchecked, it will always bring up 'Add New'." +msgstr "" +"zzThe top FanFictionDownLoader plugin button will start Update if\n" +"books are selected. If unchecked, it will always bring up 'Add New'." + +#: config.py:439 +msgid "Keep 'Add New from URL(s)' dialog on top?" +msgstr "zzKeep 'Add New from URL(s)' dialog on top?" + +#: config.py:440 +msgid "" +"Instructs the OS and Window Manager to keep the 'Add New from URL(s)'\n" +"dialog on top of all other windows. Useful for dragging URLs onto it." +msgstr "" +"zzInstructs the OS and Window Manager to keep the 'Add New from URL(s)'\n" +"dialog on top of all other windows. Useful for dragging URLs onto it." + +#: config.py:444 +msgid "Misc Options" +msgstr "zzMisc Options" + +#: config.py:449 +msgid "Include images in EPUBs?" +msgstr "zzInclude images in EPUBs?" + +#: config.py:450 +msgid "" +"Download and include images in EPUB stories. This is equivalent to adding:" +"%(imgset)s ...to the top of %(pini)s. Your settings in %(pini)s will " +"override this." +msgstr "" +"zzDownload and include images in EPUB stories. This is equivalent to adding:" +"%(imgset)s ...to the top of %(pini)s. Your settings in %(pini)s will " +"override this." + +#: config.py:454 +msgid "Inject calibre Series when none found?" +msgstr "zzInject calibre Series when none found?" + +#: config.py:455 +msgid "" +"If no series is found, inject the calibre series (if there is one) so it " +"appears on the FFDL title page(not cover)." +msgstr "" +"zzIf no series is found, inject the calibre series (if there is one) so it " +"appears on the FFDL title page(not cover)." + +#: config.py:459 +msgid "Reject List" +msgstr "zzReject List" + +#: config.py:463 +msgid "Edit Reject URL List" +msgstr "zzEdit Reject URL List" + +#: config.py:464 +msgid "Edit list of URLs FFDL will automatically Reject." +msgstr "zzEdit list of URLs FFDL will automatically Reject." + +#: config.py:468 config.py:537 +msgid "Add Reject URLs" +msgstr "zzAdd Reject URLs" + +#: config.py:469 +msgid "Add additional URLs to Reject as text." +msgstr "zzAdd additional URLs to Reject as text." + +#: config.py:473 +msgid "Edit Reject Reasons List" +msgstr "zzEdit Reject Reasons List" + +#: config.py:474 config.py:528 +msgid "Customize the Reasons presented when Rejecting URLs" +msgstr "zzCustomize the Reasons presented when Rejecting URLs" + +#: config.py:512 +msgid "Edit Reject URLs List" +msgstr "zzEdit Reject URLs List" + +#: config.py:526 +msgid "Reject Reasons" +msgstr "zzReject Reasons" + +#: config.py:527 +msgid "Customize Reject List Reasons" +msgstr "zzCustomize Reject List Reasons" + +#: config.py:535 +msgid "Reason why I rejected it" +msgstr "zzReason why I rejected it" + +#: config.py:535 +msgid "Title by Author" +msgstr "zzTitle by Author" + +#: config.py:538 +msgid "" +"Add Reject URLs. Use: http://...,note or http://...,title by " +"author - note
    Invalid story URLs will be ignored." +msgstr "" +"zzAdd Reject URLs. Use: http://...,note or http://...,title by " +"author - note
    Invalid story URLs will be ignored." + +#: config.py:539 +msgid "" +"One URL per line:\n" +"http://...,note\n" +"http://...,title by author - note" +msgstr "" +"zzOne URL per line:\n" +"http://...,note\n" +"http://...,title by author - note" + +#: config.py:541 dialogs.py:980 +msgid "Add this reason to all URLs added:" +msgstr "zzAdd this reason to all URLs added:" + +#: config.py:556 +msgid "" +"These settings provide more detailed control over what metadata will be " +"displayed inside the ebook as well as let you set %(isa)s and %(u)s/%(p)s " +"for different sites." +msgstr "" +"zzThese settings provide more detailed control over what metadata will be " +"displayed inside the ebook as well as let you set %(isa)s and %(u)s/%(p)s " +"for different sites." + +#: config.py:574 +msgid "View Defaults" +msgstr "zzView Defaults" + +#: config.py:575 +msgid "" +"View all of the plugin's configurable settings\n" +"and their default settings." +msgstr "" +"zzView all of the plugin's configurable settings\n" +"and their default settings." + +#: config.py:593 +msgid "Plugin Defaults (%s) (Read-Only)" +msgstr "zzPlugin Defaults (%s) (Read-Only)" + +#: config.py:594 config.py:600 +msgid "" +"These are all of the plugin's configurable options\n" +"and their default settings." +msgstr "" +"zzThese are all of the plugin's configurable options\n" +"and their default settings." + +#: config.py:595 +msgid "Plugin Defaults" +msgstr "zzPlugin Defaults" + +#: config.py:611 dialogs.py:504 dialogs.py:607 +msgid "OK" +msgstr "zzOK" + +# %(rl)s = Reading List. Keep as is. +#: config.py:631 +msgid "" +"These settings provide integration with the %(rl)s Plugin. %(rl)s can " +"automatically send to devices and change custom columns. You have to create " +"and configure the lists in %(rl)s to be useful." +msgstr "" +"zzThese settings provide integration with the %(rl)s Plugin. %(rl)s can " +"automatically send to devices and change custom columns. You have to create " +"and configure the lists in %(rl)s to be useful." + +#: config.py:636 +msgid "Add new/updated stories to \"Send to Device\" Reading List(s)." +msgstr "zzAdd new/updated stories to \"Send to Device\" Reading List(s)." + +# %(rl)s = Reading List. Keep as is. +#: config.py:637 +msgid "" +"Automatically add new/updated stories to these lists in the %(rl)s plugin." +msgstr "" +"zzAutomatically add new/updated stories to these lists in the %(rl)s plugin." + +#: config.py:642 +msgid "\"Send to Device\" Reading Lists" +msgstr "zz\"Send to Device\" Reading Lists" + +#: config.py:643 config.py:646 config.py:659 config.py:662 +msgid "" +"When enabled, new/updated stories will be automatically added to these lists." +msgstr "" +"zzWhen enabled, new/updated stories will be automatically added to these " +"lists." + +#: config.py:652 +msgid "Add new/updated stories to \"To Read\" Reading List(s)." +msgstr "zzAdd new/updated stories to \"To Read\" Reading List(s)." + +# %(rl)s = Reading List. Keep as is. +#: config.py:653 +msgid "" +"Automatically add new/updated stories to these lists in the %(rl)s plugin.\n" +"Also offers menu option to remove stories from the \"To Read\" lists." +msgstr "" +"zzAutomatically add new/updated stories to these lists in the %(rl)s " +"plugin.\n" +"Also offers menu option to remove stories from the \"To Read\" lists." + +#: config.py:658 +msgid "\"To Read\" Reading Lists" +msgstr "zz\"To Read\" Reading Lists" + +#: config.py:668 +msgid "" +"Add stories back to \"Send to Device\" Reading List(s) when marked \"Read\"." +msgstr "" +"zzAdd stories back to \"Send to Device\" Reading List(s) when marked \"Read" +"\"." + +#: config.py:669 +msgid "" +"Menu option to remove from \"To Read\" lists will also add stories back to " +"\"Send to Device\" Reading List(s)" +msgstr "" +"zzMenu option to remove from \"To Read\" lists will also add stories back to " +"\"Send to Device\" Reading List(s)" + +# %(gc)s = Generate Cover. Keep as is. +#: config.py:691 +msgid "" +"The %(gc)s plugin can create cover images for books using various metadata " +"and configurations. If you have GC installed, FFDL can run GC on new " +"downloads and metadata updates. Pick a GC setting by site or Default." +msgstr "" +"zzThe %(gc)s plugin can create cover images for books using various metadata " +"and configurations. If you have GC installed, FFDL can run GC on new " +"downloads and metadata updates. Pick a GC setting by site or Default." + +#: config.py:709 config.py:713 +msgid "Default" +msgstr "zzDefault" + +# %(gc)s = Generate Cover. Keep as is. +#: config.py:714 +msgid "" +"On Metadata update, run %(gc)s with this setting, if not selected for " +"specific site." +msgstr "" +"zzOn Metadata update, run %(gc)s with this setting, if not selected for " +"specific site." + +# %(gc)s = Generate Cover. Keep as is. +#: config.py:717 +msgid "On Metadata update, run %(gc)s with this setting for %(site)s stories." +msgstr "" +"zzOn Metadata update, run %(gc)s with this setting for %(site)s stories." + +# %(gc)s = Generate Cover. Keep as is. +#: config.py:735 +msgid "Run %(gc)s Only on New Books" +msgstr "zzRun %(gc)s Only on New Books" + +#: config.py:736 +msgid "Default is to run GC any time the calibre metadata is updated." +msgstr "zzDefault is to run GC any time the calibre metadata is updated." + +#: config.py:740 +msgid "Allow %(gcset)s from %(pini)s to override" +msgstr "zzAllow %(gcset)s from %(pini)s to override" + +#: config.py:741 +msgid "" +"The %(pini)s parameter %(gcset)s allows you to choose a GC setting based on " +"metadata rather than site, but it's much more complex.
    %(gcset)s is " +"ignored when this is off." +msgstr "" +"zzThe %(pini)s parameter %(gcset)s allows you to choose a GC setting based " +"on metadata rather than site, but it's much more complex.
    %(gcset)s is " +"ignored when this is off." + +#: config.py:755 +msgid "" +"These settings provide integration with the %(cp)s Plugin. %(cp)s can " +"automatically update custom columns with page, word and reading level " +"statistics. You have to create and configure the columns in %(cp)s first." +msgstr "" +"zzThese settings provide integration with the %(cp)s Plugin. %(cp)s can " +"automatically update custom columns with page, word and reading level " +"statistics. You have to create and configure the columns in %(cp)s first." + +#: config.py:760 +msgid "" +"If any of the settings below are checked, when stories are added or updated, " +"the %(cp)s Plugin will be called to update the checked statistics." +msgstr "" +"zzIf any of the settings below are checked, when stories are added or " +"updated, the %(cp)s Plugin will be called to update the checked statistics." + +#: config.py:766 +msgid "Which column and algorithm to use are configured in %(cp)s." +msgstr "zzWhich column and algorithm to use are configured in %(cp)s." + +#: config.py:774 +msgid "" +"Will overwrite word count from FFDL metadata if set to update the same " +"custom column." +msgstr "" +"zzWill overwrite word count from FFDL metadata if set to update the same " +"custom column." + +#: config.py:805 +msgid "" +"These controls aren't plugin settings as such, but convenience buttons for " +"setting Keyboard shortcuts and getting all the FanFictionDownLoader " +"confirmation dialogs back again." +msgstr "" +"zzThese controls aren't plugin settings as such, but convenience buttons for " +"setting Keyboard shortcuts and getting all the FanFictionDownLoader " +"confirmation dialogs back again." + +#: config.py:810 +msgid "Keyboard shortcuts..." +msgstr "zzKeyboard shortcuts..." + +#: config.py:811 +msgid "Edit the keyboard shortcuts associated with this plugin" +msgstr "zzEdit the keyboard shortcuts associated with this plugin" + +#: config.py:815 +msgid "Reset disabled &confirmation dialogs" +msgstr "zzReset disabled &confirmation dialogs" + +#: config.py:816 +msgid "Reset all show me again dialogs for the FanFictionDownLoader plugin" +msgstr "zzReset all show me again dialogs for the FanFictionDownLoader plugin" + +#: config.py:820 +msgid "&View library preferences..." +msgstr "zz&View library preferences..." + +#: config.py:821 +msgid "View data stored in the library database for this plugin" +msgstr "zzView data stored in the library database for this plugin" + +#: config.py:832 +msgid "Done" +msgstr "zzDone" + +#: config.py:833 +msgid "Confirmation dialogs have all been reset" +msgstr "zzConfirmation dialogs have all been reset" + +#: config.py:881 +msgid "Category" +msgstr "zzCategory" + +#: config.py:882 +msgid "Genre" +msgstr "zzGenre" + +#: config.py:883 +msgid "Language" +msgstr "zzLanguage" + +#: config.py:884 ffdl_plugin.py:1103 ffdl_plugin.py:1262 ffdl_plugin.py:1292 +msgid "Status" +msgstr "zzStatus" + +#: config.py:885 +msgid "Status:%(cmplt)s" +msgstr "zzStatus:%(cmplt)s" + +#: config.py:886 +msgid "Status:%(inprog)s" +msgstr "zzStatus:%(inprog)s" + +#: config.py:887 config.py:1021 +msgid "Series" +msgstr "zzSeries" + +#: config.py:888 +msgid "Characters" +msgstr "zzCharacters" + +#: config.py:889 +msgid "Relationships" +msgstr "zzRelationships" + +#: config.py:890 +msgid "Published" +msgstr "zzPublished" + +#: config.py:891 ffdl_plugin.py:1376 ffdl_plugin.py:1392 +msgid "Updated" +msgstr "zzUpdated" + +#: config.py:892 +msgid "Created" +msgstr "zzCreated" + +#: config.py:893 +msgid "Rating" +msgstr "zzRating" + +#: config.py:894 +msgid "Warnings" +msgstr "zzWarnings" + +#: config.py:895 +msgid "Chapters" +msgstr "zzChapters" + +#: config.py:896 +msgid "Words" +msgstr "zzWords" + +#: config.py:897 +msgid "Site" +msgstr "zzSite" + +#: config.py:898 +msgid "Story ID" +msgstr "zzStory ID" + +#: config.py:899 +msgid "Author ID" +msgstr "zzAuthor ID" + +#: config.py:900 +msgid "Extra Tags" +msgstr "zzExtra Tags" + +#: config.py:901 config.py:1013 dialogs.py:766 dialogs.py:862 +#: ffdl_plugin.py:1103 ffdl_plugin.py:1262 ffdl_plugin.py:1292 +msgid "Title" +msgstr "zzTitle" + +#: config.py:902 +msgid "Story URL" +msgstr "zzStory URL" + +#: config.py:903 +msgid "Description" +msgstr "zzDescription" + +#: config.py:904 dialogs.py:766 dialogs.py:862 ffdl_plugin.py:1103 +#: ffdl_plugin.py:1262 ffdl_plugin.py:1292 +msgid "Author" +msgstr "zzAuthor" + +#: config.py:905 +msgid "Author URL" +msgstr "zzAuthor URL" + +#: config.py:906 +msgid "File Format" +msgstr "zzFile Format" + +#: config.py:907 +msgid "File Extension" +msgstr "zzFile Extension" + +#: config.py:908 +msgid "Site Abbrev" +msgstr "zzSite Abbrev" + +#: config.py:909 +msgid "FFDL Version" +msgstr "zzFFDL Version" + +#: config.py:924 +msgid "" +"If you have custom columns defined, they will be listed below. Choose a " +"metadata value type to fill your columns automatically." +msgstr "" +"zzIf you have custom columns defined, they will be listed below. Choose a " +"metadata value type to fill your columns automatically." + +#: config.py:949 +msgid "Update this %s column(%s) with..." +msgstr "zzUpdate this %s column(%s) with..." + +#: config.py:959 +msgid "Values that aren't valid for this enumeration column will be ignored." +msgstr "" +"zzValues that aren't valid for this enumeration column will be ignored." + +#: config.py:959 config.py:961 +msgid "Metadata values valid for this type of column." +msgstr "zzMetadata values valid for this type of column." + +#: config.py:964 config.py:1040 +msgid "New Only" +msgstr "zzNew Only" + +#: config.py:965 +msgid "" +"Write to %s(%s) only for new\n" +"books, not updates to existing books." +msgstr "" +"zzWrite to %s(%s) only for new\n" +"books, not updates to existing books." + +#: config.py:976 +msgid "Allow %(ccset)s from %(pini)s to override" +msgstr "zzAllow %(ccset)s from %(pini)s to override" + +#: config.py:977 +msgid "" +"The %(pini)s parameter %(ccset)s allows you to set custom columns to site " +"specific values that aren't common to all sites.
    %(ccset)s is ignored " +"when this is off." +msgstr "" +"zzThe %(pini)s parameter %(ccset)s allows you to set custom columns to site " +"specific values that aren't common to all sites.
    %(ccset)s is ignored " +"when this is off." + +#: config.py:982 +msgid "Special column:" +msgstr "zzSpecial column:" + +#: config.py:987 +msgid "Update/Overwrite Error Column:" +msgstr "zzUpdate/Overwrite Error Column:" + +#: config.py:988 +msgid "" +"When an update or overwrite of an existing story fails, record the reason in " +"this column.\n" +"(Text and Long Text columns only.)" +msgstr "" +"zzWhen an update or overwrite of an existing story fails, record the reason " +"in this column.\n" +"(Text and Long Text columns only.)" + +#: config.py:1014 +msgid "Author(s)" +msgstr "zzAuthor(s)" + +#: config.py:1015 +msgid "Publisher" +msgstr "zzPublisher" + +#: config.py:1016 +msgid "Tags" +msgstr "zzTags" + +#: config.py:1017 +msgid "Languages" +msgstr "zzLanguages" + +#: config.py:1018 +msgid "Published Date" +msgstr "zzPublished Date" + +#: config.py:1019 +msgid "Date" +msgstr "zzDate" + +#: config.py:1020 +msgid "Comments" +msgstr "zzComments" + +#: config.py:1022 +msgid "Ids(url id only)" +msgstr "zzIds(url id only)" + +#: config.py:1027 +msgid "" +"The standard calibre metadata columns are listed below. You may choose " +"whether FFDL will fill each column automatically on updates or only for new " +"books." +msgstr "" +"zzThe standard calibre metadata columns are listed below. You may choose " +"whether FFDL will fill each column automatically on updates or only for new " +"books." + +#: config.py:1041 +msgid "" +"Write to %s only for new\n" +"books, not updates to existing books." +msgstr "" +"zzWrite to %s only for new\n" +"books, not updates to existing books." + +#: dialogs.py:45 +msgid "Skip" +msgstr "zzSkip" + +#: dialogs.py:46 +msgid "Add New Book" +msgstr "zzAdd New Book" + +#: dialogs.py:47 +msgid "Update EPUB if New Chapters" +msgstr "zzUpdate EPUB if New Chapters" + +#: dialogs.py:48 +msgid "Update EPUB Always" +msgstr "zzUpdate EPUB Always" + +#: dialogs.py:49 +msgid "Overwrite if Newer" +msgstr "zzOverwrite if Newer" + +#: dialogs.py:50 +msgid "Overwrite Always" +msgstr "zzOverwrite Always" + +#: dialogs.py:51 +msgid "Update Calibre Metadata Only" +msgstr "zzUpdate Calibre Metadata Only" + +# title by author +#: dialogs.py:113 +msgid "%s by %s" +msgstr "zz%s by %s" + +#: dialogs.py:201 ffdl_plugin.py:86 +msgid "FanFictionDownLoader" +msgstr "zzFanFictionDownLoader" + +#: dialogs.py:218 dialogs.py:665 +msgid "Show Download Options" +msgstr "zzShow Download Options" + +#: dialogs.py:237 dialogs.py:682 +msgid "Output &Format:" +msgstr "zzOutput &Format:" + +#: dialogs.py:245 dialogs.py:690 +msgid "" +"Choose output format to create. May set default from plugin configuration." +msgstr "" +"zzChoose output format to create. May set default from plugin configuration." + +#: dialogs.py:273 dialogs.py:707 +msgid "Update Calibre &Metadata?" +msgstr "zzUpdate Calibre &Metadata?" + +#: dialogs.py:274 dialogs.py:708 +msgid "" +"Update metadata for existing stories in Calibre from web site?\n" +"(Columns set to 'New Only' in the column tabs will only be set for new " +"books.)" +msgstr "" +"zzUpdate metadata for existing stories in Calibre from web site?\n" +"(Columns set to 'New Only' in the column tabs will only be set for new " +"books.)" + +#: dialogs.py:280 dialogs.py:712 +msgid "Update EPUB Cover?" +msgstr "zzUpdate EPUB Cover?" + +#: dialogs.py:281 dialogs.py:713 +msgid "" +"Update book cover image from site or defaults (if found) inside the " +"EPUB when EPUB is updated." +msgstr "" +"zzUpdate book cover image from site or defaults (if found) inside the " +"EPUB when EPUB is updated." + +#: dialogs.py:328 +msgid "Story URL(s) for anthology, one per line:" +msgstr "zzStory URL(s) for anthology, one per line:" + +#: dialogs.py:329 +msgid "" +"URLs for stories to include in the anthology, one per line.\n" +"Will take URLs from clipboard, but only valid URLs." +msgstr "" +"zzURLs for stories to include in the anthology, one per line.\n" +"Will take URLs from clipboard, but only valid URLs." + +#: dialogs.py:330 +msgid "If Story Already Exists in Anthology?" +msgstr "zzIf Story Already Exists in Anthology?" + +#: dialogs.py:331 +msgid "" +"What to do if there's already an existing story with the same URL in the " +"anthology." +msgstr "" +"zzWhat to do if there's already an existing story with the same URL in the " +"anthology." + +#: dialogs.py:340 +msgid "Story URL(s), one per line:" +msgstr "zzStory URL(s), one per line:" + +#: dialogs.py:341 +msgid "" +"URLs for stories, one per line.\n" +"Will take URLs from clipboard, but only valid URLs.\n" +"Add [1,5] after the URL to limit the download to chapters 1-5." +msgstr "" +"zzURLs for stories, one per line.\n" +"Will take URLs from clipboard, but only valid URLs.\n" +"Add [1,5] after the URL to limit the download to chapters 1-5." + +#: dialogs.py:342 +msgid "If Story Already Exists?" +msgstr "zzIf Story Already Exists?" + +#: dialogs.py:343 +msgid "" +"What to do if there's already an existing story with the same URL or title " +"and author." +msgstr "" +"zzWhat to do if there's already an existing story with the same URL or title " +"and author." + +#: dialogs.py:443 +msgid "For Individual Books" +msgstr "zzFor Individual Books" + +#: dialogs.py:444 +msgid "Get URLs and go to dialog for individual story downloads." +msgstr "zzGet URLs and go to dialog for individual story downloads." + +#: dialogs.py:448 +msgid "For Anthology Epub" +msgstr "zzFor Anthology Epub" + +#: dialogs.py:449 +msgid "" +"Get URLs and go to dialog for Anthology download.\n" +"Requires %s plugin." +msgstr "" +"zzGet URLs and go to dialog for Anthology download.\n" +"Requires %s plugin." + +#: dialogs.py:454 dialogs.py:508 +msgid "Cancel" +msgstr "zzCancel" + +#: dialogs.py:486 +msgid "Password" +msgstr "zzPassword" + +#: dialogs.py:487 +msgid "Author requires a password for this story(%s)." +msgstr "zzAuthor requires a password for this story(%s)." + +#: dialogs.py:492 +msgid "User/Password" +msgstr "zzUser/Password" + +#: dialogs.py:493 +msgid "%s requires you to login to download this story." +msgstr "zz%s requires you to login to download this story." + +#: dialogs.py:495 +msgid "User:" +msgstr "zzUser:" + +#: dialogs.py:499 +msgid "Password:" +msgstr "zzPassword:" + +#: dialogs.py:530 +msgid "Fetching metadata for stories..." +msgstr "zzFetching metadata for stories..." + +#: dialogs.py:531 +msgid "Downloading metadata for stories" +msgstr "zzDownloading metadata for stories" + +#: dialogs.py:532 +msgid "Fetched metadata for" +msgstr "zzFetched metadata for" + +#: dialogs.py:602 ffdl_plugin.py:321 +msgid "About FanFictionDownLoader" +msgstr "zzAbout FanFictionDownLoader" + +#: dialogs.py:656 +msgid "Remove selected books from the list" +msgstr "zzRemove selected books from the list" + +#: dialogs.py:695 +msgid "Update Mode:" +msgstr "zzUpdate Mode:" + +#: dialogs.py:698 +msgid "" +"What sort of update to perform. May set default from plugin configuration." +msgstr "" +"zzWhat sort of update to perform. May set default from plugin configuration." + +#: dialogs.py:766 ffdl_plugin.py:1103 ffdl_plugin.py:1262 ffdl_plugin.py:1292 +msgid "Comment" +msgstr "zzComment" + +#: dialogs.py:834 +msgid "Are you sure you want to remove this book from the list?" +msgstr "zzAre you sure you want to remove this book from the list?" + +#: dialogs.py:836 +msgid "Are you sure you want to remove the selected %d books from the list?" +msgstr "zzAre you sure you want to remove the selected %d books from the list?" + +#: dialogs.py:862 +msgid "Note" +msgstr "zzNote" + +#: dialogs.py:904 +msgid "Select or Edit Reject Note." +msgstr "zzSelect or Edit Reject Note." + +#: dialogs.py:912 +msgid "Are you sure you want to remove this URL from the list?" +msgstr "zzAre you sure you want to remove this URL from the list?" + +#: dialogs.py:914 +msgid "Are you sure you want to remove the %d selected URLs from the list?" +msgstr "zzAre you sure you want to remove the %d selected URLs from the list?" + +#: dialogs.py:932 +msgid "List of Books to Reject" +msgstr "zzList of Books to Reject" + +#: dialogs.py:945 +msgid "" +"FFDL will remember these URLs and display the note and offer to reject them " +"if you try to download them again later." +msgstr "" +"zzFFDL will remember these URLs and display the note and offer to reject " +"them if you try to download them again later." + +#: dialogs.py:959 +msgid "Remove selected URL(s) from the list" +msgstr "zzRemove selected URL(s) from the list" + +#: dialogs.py:977 dialogs.py:981 +msgid "This will be added to whatever note you've set for each URL above." +msgstr "zzThis will be added to whatever note you've set for each URL above." + +#: dialogs.py:990 +msgid "Delete Books (including books without FanFiction URLs)?" +msgstr "zzDelete Books (including books without FanFiction URLs)?" + +#: dialogs.py:991 +msgid "Delete the selected books after adding them to the Rejected URLs list." +msgstr "" +"zzDelete the selected books after adding them to the Rejected URLs list." + +#: ffdl_plugin.py:87 +msgid "Download FanFiction stories from various web sites" +msgstr "zzDownload FanFiction stories from various web sites" + +# This is what appears on the plugin button/menu when added to calibre's main toolbar or menu. +#: ffdl_plugin.py:117 +msgid "FanFictionDL" +msgstr "zzFanFictionDL" + +#: ffdl_plugin.py:240 +msgid "&Add New from URL(s)" +msgstr "zz&Add New from URL(s)" + +#: ffdl_plugin.py:242 +msgid "Add New FanFiction Book(s) from URL(s)" +msgstr "zzAdd New FanFiction Book(s) from URL(s)" + +#: ffdl_plugin.py:245 +msgid "&Update Existing FanFiction Book(s)" +msgstr "zz&Update Existing FanFiction Book(s)" + +#: ffdl_plugin.py:251 +msgid "Get Story URLs to Download from Web Page" +msgstr "zzGet Story URLs to Download from Web Page" + +#: ffdl_plugin.py:255 +msgid "&Make Anthology Epub Manually from URL(s)" +msgstr "zz&Make Anthology Epub Manually from URL(s)" + +#: ffdl_plugin.py:257 +msgid "Make FanFiction Anthology Epub Manually from URL(s)" +msgstr "zzMake FanFiction Anthology Epub Manually from URL(s)" + +#: ffdl_plugin.py:260 +msgid "&Update Anthology Epub" +msgstr "zz&Update Anthology Epub" + +#: ffdl_plugin.py:262 +msgid "Update FanFiction Anthology Epub" +msgstr "zzUpdate FanFiction Anthology Epub" + +#: ffdl_plugin.py:269 +msgid "Add to \"To Read\" and \"Send to Device\" Lists" +msgstr "zzAdd to \"To Read\" and \"Send to Device\" Lists" + +#: ffdl_plugin.py:271 +msgid "Remove from \"To Read\" and add to \"Send to Device\" Lists" +msgstr "zzRemove from \"To Read\" and add to \"Send to Device\" Lists" + +#: ffdl_plugin.py:273 ffdl_plugin.py:278 +msgid "Remove from \"To Read\" Lists" +msgstr "zzRemove from \"To Read\" Lists" + +#: ffdl_plugin.py:275 +msgid "Add Selected to \"Send to Device\" Lists" +msgstr "zzAdd Selected to \"Send to Device\" Lists" + +#: ffdl_plugin.py:277 +msgid "Add to \"To Read\" Lists" +msgstr "zzAdd to \"To Read\" Lists" + +#: ffdl_plugin.py:293 +msgid "Get URLs from Selected Books" +msgstr "zzGet URLs from Selected Books" + +#: ffdl_plugin.py:299 ffdl_plugin.py:392 +msgid "Get Story URLs from Web Page" +msgstr "zzGet Story URLs from Web Page" + +#: ffdl_plugin.py:304 +msgid "Reject Selected Books" +msgstr "zzReject Selected Books" + +#: ffdl_plugin.py:312 +msgid "&Configure Plugin" +msgstr "zz&Configure Plugin" + +#: ffdl_plugin.py:315 +msgid "Configure FanFictionDownLoader" +msgstr "zzConfigure FanFictionDownLoader" + +#: ffdl_plugin.py:318 +msgid "About Plugin" +msgstr "zzAbout Plugin" + +#: ffdl_plugin.py:375 +msgid "Cannot Update Reading Lists from Device View" +msgstr "zzCannot Update Reading Lists from Device View" + +#: ffdl_plugin.py:379 +msgid "No Selected Books to Update Reading Lists" +msgstr "zzNo Selected Books to Update Reading Lists" + +#: ffdl_plugin.py:403 ffdl_plugin.py:455 +msgid "List of Story URLs" +msgstr "zzList of Story URLs" + +#: ffdl_plugin.py:404 +msgid "No Valid Story URLs found on given page." +msgstr "zzNo Valid Story URLs found on given page." + +#: ffdl_plugin.py:419 +msgid "No Selected Books to Get URLs From" +msgstr "zzNo Selected Books to Get URLs From" + +#: ffdl_plugin.py:437 +msgid "Collecting URLs for stories..." +msgstr "zzCollecting URLs for stories..." + +#: ffdl_plugin.py:438 +msgid "Get URLs for stories" +msgstr "zzGet URLs for stories" + +#: ffdl_plugin.py:439 ffdl_plugin.py:486 ffdl_plugin.py:673 +msgid "URL retrieved" +msgstr "zzURL retrieved" + +#: ffdl_plugin.py:459 +msgid "List of URLs" +msgstr "zzList of URLs" + +#: ffdl_plugin.py:460 +msgid "No Story URLs found in selected books." +msgstr "zzNo Story URLs found in selected books." + +#: ffdl_plugin.py:476 +msgid "No Selected Books have URLs to Reject" +msgstr "zzNo Selected Books have URLs to Reject" + +#: ffdl_plugin.py:484 +msgid "Collecting URLs for Reject List..." +msgstr "zzCollecting URLs for Reject List..." + +#: ffdl_plugin.py:485 +msgid "Get URLs for Reject List" +msgstr "zzGet URLs for Reject List" + +#: ffdl_plugin.py:520 +msgid "Proceed to Remove?" +msgstr "zzProceed to Remove?" + +#: ffdl_plugin.py:520 +msgid "Rejecting FFDL URLs: None of the books selected have FanFiction URLs." +msgstr "" +"zzRejecting FFDL URLs: None of the books selected have FanFiction URLs." + +# %s = EpubMerge +#: ffdl_plugin.py:542 +msgid "Cannot Make Anthologys without %s" +msgstr "zzCannot Make Anthologys without %s" + +#: ffdl_plugin.py:546 ffdl_plugin.py:650 +msgid "Cannot Update Books from Device View" +msgstr "zzCannot Update Books from Device View" + +#: ffdl_plugin.py:550 +msgid "Can only update 1 anthology at a time" +msgstr "zzCan only update 1 anthology at a time" + +#: ffdl_plugin.py:559 +msgid "Can only Update Epub Anthologies" +msgstr "zzCan only Update Epub Anthologies" + +#: ffdl_plugin.py:577 ffdl_plugin.py:578 +msgid "Cannot Update Anthology" +msgstr "zzCannot Update Anthology" + +#: ffdl_plugin.py:578 +msgid "" +"Book isn't an FFDL Anthology or contains book(s) without valid FFDL URLs." +msgstr "" +"zzBook isn't an FFDL Anthology or contains book(s) without valid FFDL URLs." + +#: ffdl_plugin.py:636 +msgid "" +"There are %d stories in the current anthology that are not going to " +"be kept if you go ahead." +msgstr "" +"zzThere are %d stories in the current anthology that are not going to " +"be kept if you go ahead." + +#: ffdl_plugin.py:637 +msgid "Story URLs that will be removed:" +msgstr "zzStory URLs that will be removed:" + +#: ffdl_plugin.py:639 +msgid "Update anyway?" +msgstr "zzUpdate anyway?" + +#: ffdl_plugin.py:640 +msgid "Stories Removed" +msgstr "zzStories Removed" + +#: ffdl_plugin.py:657 +msgid "No Selected Books to Update" +msgstr "zzNo Selected Books to Update" + +#: ffdl_plugin.py:671 +msgid "Collecting stories for update..." +msgstr "zzCollecting stories for update..." + +#: ffdl_plugin.py:672 +msgid "Get stories for updates" +msgstr "zzGet stories for updates" + +#: ffdl_plugin.py:682 +msgid "Update Existing List" +msgstr "zzUpdate Existing List" + +#: ffdl_plugin.py:731 +msgid "Started fetching metadata for %s stories." +msgstr "zzStarted fetching metadata for %s stories." + +#: ffdl_plugin.py:737 +msgid "No valid story URLs entered." +msgstr "zzNo valid story URLs entered." + +#: ffdl_plugin.py:762 ffdl_plugin.py:768 +msgid "Reject URL?" +msgstr "zzReject URL?" + +#: ffdl_plugin.py:769 ffdl_plugin.py:787 +msgid "%s is on your Reject URL list:" +msgstr "zz%s is on your Reject URL list:" + +#: ffdl_plugin.py:771 +msgid "Click 'Yes' to Reject." +msgstr "zzClick 'Yes' to Reject." + +#: ffdl_plugin.py:772 ffdl_plugin.py:856 +msgid "Click 'No' to download anyway." +msgstr "zzClick 'No' to download anyway." + +#: ffdl_plugin.py:774 +msgid "Story on Reject URLs list (%s)." +msgstr "zzStory on Reject URLs list (%s)." + +#: ffdl_plugin.py:777 +msgid "Rejected" +msgstr "zzRejected" + +#: ffdl_plugin.py:780 +msgid "Remove Reject URL?" +msgstr "zzRemove Reject URL?" + +#: ffdl_plugin.py:786 +msgid "Remove URL from Reject List?" +msgstr "zzRemove URL from Reject List?" + +#: ffdl_plugin.py:789 +msgid "Click 'Yes' to remove it from the list," +msgstr "zzClick 'Yes' to remove it from the list," + +#: ffdl_plugin.py:790 +msgid "Click 'No' to leave it on the list." +msgstr "zzClick 'No' to leave it on the list." + +#: ffdl_plugin.py:807 +msgid "Cannot update non-epub format." +msgstr "zzCannot update non-epub format." + +#: ffdl_plugin.py:832 +msgid "Are You an Adult?" +msgstr "zzAre You an Adult?" + +#: ffdl_plugin.py:833 +msgid "" +"%s requires that you be an adult. Please confirm you are an adult in your " +"locale:" +msgstr "" +"zz%s requires that you be an adult. Please confirm you are an adult in your " +"locale:" + +#: ffdl_plugin.py:847 +msgid "Skip Story?" +msgstr "zzSkip Story?" + +#: ffdl_plugin.py:853 +msgid "Skip Anthology Story?" +msgstr "zzSkip Anthology Story?" + +#: ffdl_plugin.py:854 +msgid "" +"\"%s\" is in series \"%s\" that you have an " +"anthology book for." +msgstr "" +"zz\"%s\" is in series \"%s\" that you have " +"an anthology book for." + +#: ffdl_plugin.py:855 +msgid "Click 'Yes' to Skip." +msgstr "zzClick 'Yes' to Skip." + +#: ffdl_plugin.py:858 +msgid "Story in Series Anthology(%s)." +msgstr "zzStory in Series Anthology(%s)." + +#: ffdl_plugin.py:863 +msgid "Skipped" +msgstr "zzSkipped" + +#: ffdl_plugin.py:891 +msgid "Add" +msgstr "zzAdd" + +#: ffdl_plugin.py:904 +msgid "Meta" +msgstr "zzMeta" + +#: ffdl_plugin.py:942 +msgid "Skipping duplicate story." +msgstr "zzSkipping duplicate story." + +#: ffdl_plugin.py:956 +msgid "Update" +msgstr "zzUpdate" + +#: ffdl_plugin.py:961 ffdl_plugin.py:968 +msgid "Change Story URL?" +msgstr "zzChange Story URL?" + +#: ffdl_plugin.py:969 +msgid "" +"%s by %s is already in your library with a different source " +"URL:" +msgstr "" +"zz%s by %s is already in your library with a different source " +"URL:" + +#: ffdl_plugin.py:970 +msgid "In library: %(liburl)s" +msgstr "zzIn library: %(liburl)s" + +#: ffdl_plugin.py:971 ffdl_plugin.py:985 +msgid "New URL: %(newurl)s" +msgstr "zzNew URL: %(newurl)s" + +#: ffdl_plugin.py:972 +msgid "Click 'Yes' to update/overwrite book with new URL." +msgstr "zzClick 'Yes' to update/overwrite book with new URL." + +#: ffdl_plugin.py:973 +msgid "Click 'No' to skip updating/overwriting this book." +msgstr "zzClick 'No' to skip updating/overwriting this book." + +#: ffdl_plugin.py:975 ffdl_plugin.py:982 +msgid "Download as New Book?" +msgstr "zzDownload as New Book?" + +#: ffdl_plugin.py:983 +msgid "" +"%s by %s is already in your library with a different source " +"URL." +msgstr "" +"zz%s by %s is already in your library with a different source " +"URL." + +#: ffdl_plugin.py:984 +msgid "" +"You chose not to update the existing book. Do you want to add a new book " +"for this URL?" +msgstr "" +"zzYou chose not to update the existing book. Do you want to add a new book " +"for this URL?" + +#: ffdl_plugin.py:986 +msgid "Click 'Yes' to a new book with new URL." +msgstr "zzClick 'Yes' to a new book with new URL." + +#: ffdl_plugin.py:987 +msgid "Click 'No' to skip URL." +msgstr "zzClick 'No' to skip URL." + +#: ffdl_plugin.py:993 +msgid "Update declined by user due to differing story URL(%s)" +msgstr "zzUpdate declined by user due to differing story URL(%s)" + +#: ffdl_plugin.py:996 +msgid "Different URL" +msgstr "zzDifferent URL" + +#: ffdl_plugin.py:1001 +msgid "Metadata collected." +msgstr "zzMetadata collected." + +#: ffdl_plugin.py:1017 +msgid "Already contains %d chapters." +msgstr "zzAlready contains %d chapters." + +#: ffdl_plugin.py:1022 +msgid "" +"Existing epub contains %d chapters, web site only has %d. Use Overwrite to " +"force update." +msgstr "" +"zzExisting epub contains %d chapters, web site only has %d. Use Overwrite to " +"force update." + +#: ffdl_plugin.py:1024 +msgid "" +"FFDL doesn't recognize chapters in existing epub, epub is probably from a " +"different source. Use Overwrite to force update." +msgstr "" +"zzFFDL doesn't recognize chapters in existing epub, epub is probably from a " +"different source. Use Overwrite to force update." + +#: ffdl_plugin.py:1032 +msgid "Not Overwriting, web site is not newer." +msgstr "zzNot Overwriting, web site is not newer." + +#: ffdl_plugin.py:1099 +msgid "None of the %d URLs/stories given can be/need to be downloaded." +msgstr "" +"zzNone of the %d URLs/stories given can be/need to be downloaded." + +#: ffdl_plugin.py:1100 ffdl_plugin.py:1258 ffdl_plugin.py:1288 +msgid "See log for details." +msgstr "zzSee log for details." + +#: ffdl_plugin.py:1101 +msgid "Proceed with updating your library(Error Column, if configured)?" +msgstr "zzProceed with updating your library(Error Column, if configured)?" + +#: ffdl_plugin.py:1108 ffdl_plugin.py:1270 +msgid "Bad" +msgstr "zzBad" + +#: ffdl_plugin.py:1116 +msgid "FFDL download ended" +msgstr "zzFFDL download ended" + +#: ffdl_plugin.py:1116 ffdl_plugin.py:1313 +msgid "FFDL log" +msgstr "zzFFDL log" + +#: ffdl_plugin.py:1124 +msgid "Download FanFiction Book" +msgstr "zzDownload FanFiction Book" + +#: ffdl_plugin.py:1130 +msgid "Starting %d FanFictionDownLoads" +msgstr "zzStarting %d FanFictionDownLoads" + +#: ffdl_plugin.py:1160 +msgid "Story Details:" +msgstr "zzStory Details:" + +#: ffdl_plugin.py:1163 +msgid "Error Updating Metadata" +msgstr "zzError Updating Metadata" + +#: ffdl_plugin.py:1164 +msgid "" +"An error has occurred while FFDL was updating calibre's metadata for %s." +msgstr "" +"zzAn error has occurred while FFDL was updating calibre's metadata for %s." + +#: ffdl_plugin.py:1165 +msgid "The ebook has been updated, but the metadata has not." +msgstr "zzThe ebook has been updated, but the metadata has not." + +#: ffdl_plugin.py:1217 +msgid "Finished Adding/Updating %d books." +msgstr "zzFinished Adding/Updating %d books." + +#: ffdl_plugin.py:1242 +msgid "No Good Stories for Anthology" +msgstr "zzNo Good Stories for Anthology" + +#: ffdl_plugin.py:1243 +msgid "" +"No good stories/updates where downloaded, Anthology creation/update aborted." +msgstr "" +"zzNo good stories/updates where downloaded, Anthology creation/update " +"aborted." + +#: ffdl_plugin.py:1248 ffdl_plugin.py:1287 +msgid "FFDL found %s good and %s bad updates." +msgstr "zzFFDL found %s good and %s bad updates." + +#: ffdl_plugin.py:1255 +msgid "" +"Are you sure you want to continue with creating/updating this Anthology?" +msgstr "" +"zzAre you sure you want to continue with creating/updating this Anthology?" + +#: ffdl_plugin.py:1256 +msgid "Any updates that failed will not be included in the Anthology." +msgstr "" +"zzAny updates that failed will not be included in the Anthology." + +#: ffdl_plugin.py:1257 +msgid "However, if there's an older version, it will still be included." +msgstr "zzHowever, if there's an older version, it will still be included." + +#: ffdl_plugin.py:1260 +msgid "Proceed with updating this anthology and your library?" +msgstr "zzProceed with updating this anthology and your library?" + +#: ffdl_plugin.py:1268 +msgid "Good" +msgstr "zzGood" + +#: ffdl_plugin.py:1289 +msgid "Proceed with updating your library?" +msgstr "zzProceed with updating your library?" + +#: ffdl_plugin.py:1313 +msgid "FFDL download complete" +msgstr "zzFFDL download complete" + +#: ffdl_plugin.py:1326 +msgid "Merging %s books." +msgstr "zzMerging %s books." + +#: ffdl_plugin.py:1367 +msgid "FFDL Adding/Updating books." +msgstr "zzFFDL Adding/Updating books." + +#: ffdl_plugin.py:1374 +msgid "Updating calibre for FanFiction stories..." +msgstr "zzUpdating calibre for FanFiction stories..." + +#: ffdl_plugin.py:1375 +msgid "Update calibre for FanFiction stories" +msgstr "zzUpdate calibre for FanFiction stories" + +#: ffdl_plugin.py:1384 +msgid "Adding/Updating %s BAD books." +msgstr "zzAdding/Updating %s BAD books." + +#: ffdl_plugin.py:1390 +msgid "Updating calibre for BAD FanFiction stories..." +msgstr "zzUpdating calibre for BAD FanFiction stories..." + +#: ffdl_plugin.py:1391 +msgid "Update calibre for BAD FanFiction stories" +msgstr "zzUpdate calibre for BAD FanFiction stories" + +#: ffdl_plugin.py:1419 +msgid "Adding format to book failed for some reason..." +msgstr "zzAdding format to book failed for some reason..." + +#: ffdl_plugin.py:1422 +msgid "Error" +msgstr "zzError" + +#: ffdl_plugin.py:1652 +msgid "" +"You configured FanFictionDownLoader to automatically update Reading Lists, " +"but you don't have the %s plugin installed anymore?" +msgstr "" +"zzYou configured FanFictionDownLoader to automatically update Reading Lists, " +"but you don't have the %s plugin installed anymore?" + +#: ffdl_plugin.py:1664 +msgid "" +"You configured FanFictionDownLoader to automatically update \"To Read\" " +"Reading Lists, but you don't have any lists set?" +msgstr "" +"zzYou configured FanFictionDownLoader to automatically update \"To Read\" " +"Reading Lists, but you don't have any lists set?" + +#: ffdl_plugin.py:1674 ffdl_plugin.py:1692 +msgid "" +"You configured FanFictionDownLoader to automatically update Reading List " +"'%s', but you don't have a list of that name?" +msgstr "" +"zzYou configured FanFictionDownLoader to automatically update Reading List " +"'%s', but you don't have a list of that name?" + +#: ffdl_plugin.py:1680 +msgid "" +"You configured FanFictionDownLoader to automatically update \"Send to Device" +"\" Reading Lists, but you don't have any lists set?" +msgstr "" +"zzYou configured FanFictionDownLoader to automatically update \"Send to " +"Device\" Reading Lists, but you don't have any lists set?" + +#: ffdl_plugin.py:1799 +msgid "No story URL found." +msgstr "zzNo story URL found." + +#: ffdl_plugin.py:1802 +msgid "Not Found" +msgstr "zzNot Found" + +#: ffdl_plugin.py:1808 +msgid "URL is not a valid story URL." +msgstr "zzURL is not a valid story URL." + +#: ffdl_plugin.py:1811 +msgid "Bad URL" +msgstr "zzBad URL" + +#: ffdl_plugin.py:1941 +msgid "Anthology containing:" +msgstr "zzAnthology containing:" + +#: ffdl_plugin.py:1962 +msgid " Anthology" +msgstr "zz Anthology" + +#: ffdl_plugin.py:1999 +msgid "(was set, removed for security)" +msgstr "zz(was set, removed for security)" diff --git a/makeplugin.py b/makeplugin.py index d13439b6..b6e588c7 100644 --- a/makeplugin.py +++ b/makeplugin.py @@ -24,14 +24,14 @@ from makezip import createZipFile if __name__=="__main__": filename="FanFictionDownLoader.zip" - exclude=['*.pyc','*~','*.xcf','*[0-9].png'] + exclude=['*.pyc','*~','*.xcf','*[0-9].png','*.po','*.pot','*default.mo'] # from top dir. 'w' for overwrite createZipFile(filename,"w", ['plugin-defaults.ini','plugin-example.ini','fanficdownloader','downloader.py','defaults.ini'], exclude=exclude) #from calibre-plugin dir. 'a' for append os.chdir('calibre-plugin') - files=['about.txt','images',] + files=['about.txt','images','translations'] files.extend(glob('*.py')) files.extend(glob('plugin-import-name-*.txt')) createZipFile("../"+filename,"a",
    '+_('Status')+''+_('Title')+''+_('Author')+''+_('Comment')+'URL