diff --git a/calibre-plugin/config.py b/calibre-plugin/config.py index cb00f68e..5f5f4ca8 100644 --- a/calibre-plugin/config.py +++ b/calibre-plugin/config.py @@ -4,7 +4,7 @@ from __future__ import (unicode_literals, division, absolute_import, print_function) __license__ = 'GPL v3' -__copyright__ = '2015, Jim Miller' +__copyright__ = '2016, Jim Miller' __docformat__ = 'restructuredtext en' import logging @@ -81,8 +81,8 @@ no_trans = { 'pini':'personal.ini', STD_COLS_SKIP = ['size','cover','news','ondevice','path','series_sort','sort'] from calibre_plugins.fanficfare_plugin.prefs \ - import (prefs, PREFS_NAMESPACE, updatecalcover_order, calcover_save_options, - gencalcover_order, SAVE_YES, SAVE_NO) + import (prefs, PREFS_NAMESPACE, prefs_save_options, updatecalcover_order, + gencalcover_order, do_wordcount_order, SAVE_YES, SAVE_NO) from calibre_plugins.fanficfare_plugin.dialogs \ import (UPDATE, UPDATEALWAYS, collision_order, save_collisions, RejectListDialog, @@ -261,6 +261,7 @@ class ConfigWidget(QWidget): prefs['checkforurlchange'] = self.basic_tab.checkforurlchange.isChecked() prefs['injectseries'] = self.basic_tab.injectseries.isChecked() prefs['matchtitleauth'] = self.basic_tab.matchtitleauth.isChecked() + prefs['do_wordcount'] = prefs_save_options[unicode(self.basic_tab.do_wordcount.currentText())] prefs['smarten_punctuation'] = self.basic_tab.smarten_punctuation.isChecked() prefs['reject_always'] = self.basic_tab.reject_always.isChecked() @@ -286,10 +287,10 @@ class ConfigWidget(QWidget): prefs['cal_cols_pass_in'] = self.personalini_tab.cal_cols_pass_in.isChecked() # Covers tab - prefs['updatecalcover'] = calcover_save_options[unicode(self.calibrecover_tab.updatecalcover.currentText())] + prefs['updatecalcover'] = prefs_save_options[unicode(self.calibrecover_tab.updatecalcover.currentText())] # for backward compatibility: prefs['updatecover'] = prefs['updatecalcover'] == SAVE_YES - prefs['gencalcover'] = calcover_save_options[unicode(self.calibrecover_tab.gencalcover.currentText())] + prefs['gencalcover'] = prefs_save_options[unicode(self.calibrecover_tab.gencalcover.currentText())] prefs['calibre_gen_cover'] = self.calibrecover_tab.calibre_gen_cover.isChecked() prefs['plugin_gen_cover'] = self.calibrecover_tab.plugin_gen_cover.isChecked() prefs['gcnewonly'] = self.calibrecover_tab.gcnewonly.isChecked() @@ -478,6 +479,10 @@ class BasicTab(QWidget): self.lookforurlinhtml.setChecked(prefs['lookforurlinhtml']) self.l.addWidget(self.lookforurlinhtml) + proc_gb = groupbox = QGroupBox(_("Post Processing Options")) + self.l = QVBoxLayout() + groupbox.setLayout(self.l) + 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:fff_success'.\n'marked:fff_failed' is also available, or search 'marked:fff' for both.")) self.mark.setChecked(prefs['mark']) @@ -493,6 +498,24 @@ class BasicTab(QWidget): self.smarten_punctuation.setChecked(prefs['smarten_punctuation']) self.l.addWidget(self.smarten_punctuation) + + tooltip = _("Calculate Word Counts using Calibre internal methods.\n" + "Many sites include Word Count, but many do not.\n" + "This will count the words in each book and include it as if it came from the site.") + horz = QHBoxLayout() + label = QLabel(_('Calculate Word Count:')) + label.setToolTip(tooltip) + horz.addWidget(label) + self.do_wordcount = QComboBox(self) + for i in do_wordcount_order: + self.do_wordcount.addItem(i) + self.do_wordcount.setCurrentIndex(self.do_wordcount.findText(prefs_save_options[prefs['do_wordcount']])) + self.do_wordcount.setToolTip(tooltip) + label.setBuddy(self.do_wordcount) + horz.addWidget(self.do_wordcount) + self.l.addLayout(horz) + + self.autoconvert = QCheckBox(_("Automatically Convert new/update books?"),self) self.autoconvert.setToolTip(_("Automatically call calibre's Convert for new/update books.\nConverts to the current output format as chosen in calibre's\nPreferences->Behavior settings.")) self.autoconvert.setChecked(prefs['autoconvert']) @@ -564,14 +587,17 @@ class BasicTab(QWidget): horz = QHBoxLayout() - horz.addWidget(cali_gb) + vertleft = QVBoxLayout() + vertleft.addWidget(cali_gb) + vertleft.addWidget(proc_gb) - vert = QVBoxLayout() - vert.addWidget(gui_gb) - vert.addWidget(misc_gb) - vert.addWidget(rej_gb) + vertright = QVBoxLayout() + vertright.addWidget(gui_gb) + vertright.addWidget(misc_gb) + vertright.addWidget(rej_gb) - horz.addLayout(vert) + horz.addLayout(vertleft) + horz.addLayout(vertright) topl.addLayout(horz) topl.insertStretch(-1) @@ -840,11 +866,11 @@ class CalibreCoverTab(QWidget): self.updatecalcover.addItem(i) # back compat. If has own value, use. if prefs['updatecalcover']: - self.updatecalcover.setCurrentIndex(self.updatecalcover.findText(calcover_save_options[prefs['updatecalcover']])) + self.updatecalcover.setCurrentIndex(self.updatecalcover.findText(prefs_save_options[prefs['updatecalcover']])) elif prefs['updatecover']: # doesn't have own val, set YES if old value set. - self.updatecalcover.setCurrentIndex(self.updatecalcover.findText(calcover_save_options[SAVE_YES])) + self.updatecalcover.setCurrentIndex(self.updatecalcover.findText(prefs_save_options[SAVE_YES])) else: # doesn't have own value, old value not set, NO. - self.updatecalcover.setCurrentIndex(self.updatecalcover.findText(calcover_save_options[SAVE_NO])) + self.updatecalcover.setCurrentIndex(self.updatecalcover.findText(prefs_save_options[SAVE_NO])) self.updatecalcover.setToolTip(tooltip) label.setBuddy(self.updatecalcover) horz.addWidget(self.updatecalcover) @@ -862,11 +888,11 @@ class CalibreCoverTab(QWidget): self.gencalcover.addItem(i) # back compat. If has own value, use. # if prefs['gencalcover']: - self.gencalcover.setCurrentIndex(self.gencalcover.findText(calcover_save_options[prefs['gencalcover']])) + self.gencalcover.setCurrentIndex(self.gencalcover.findText(prefs_save_options[prefs['gencalcover']])) # elif prefs['gencover']: # doesn't have own val, set YES if old value set. - # self.gencalcover.setCurrentIndex(self.gencalcover.findText(calcover_save_options[SAVE_YES])) + # self.gencalcover.setCurrentIndex(self.gencalcover.findText(prefs_save_options[SAVE_YES])) # else: # doesn't have own value, old value not set, NO. - # self.gencalcover.setCurrentIndex(self.gencalcover.findText(calcover_save_options[SAVE_NO])) + # self.gencalcover.setCurrentIndex(self.gencalcover.findText(prefs_save_options[SAVE_NO])) self.gencalcover.setToolTip(tooltip) label.setBuddy(self.gencalcover) @@ -990,7 +1016,7 @@ class CalibreCoverTab(QWidget): ## First, cover gen on/off for e in self.gencov_elements: - e.setEnabled(calcover_save_options[unicode(self.gencalcover.currentText())] != SAVE_NO) + e.setEnabled(prefs_save_options[unicode(self.gencalcover.currentText())] != SAVE_NO) # next, disable plugin settings when using calibre gen cov. if not self.plugin_gen_cover.isChecked(): diff --git a/calibre-plugin/dialogs.py b/calibre-plugin/dialogs.py index 2f57a289..1ec21217 100644 --- a/calibre-plugin/dialogs.py +++ b/calibre-plugin/dialogs.py @@ -4,7 +4,7 @@ from __future__ import (unicode_literals, division, print_function) __license__ = 'GPL v3' -__copyright__ = '2015, Jim Miller' +__copyright__ = '2016, Jim Miller' __docformat__ = 'restructuredtext en' import traceback, re @@ -73,55 +73,30 @@ from calibre_plugins.fanficfare_plugin.fanficfare.configurable \ from inihighlighter import IniHighlighter -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 from Web Site') -CALIBREONLYSAVECOL=_('Update Calibre Metadata from Saved Metadata Column') -collision_order=[SKIP, - ADDNEW, - UPDATE, - UPDATEALWAYS, - OVERWRITE, - OVERWRITEALWAYS, - CALIBREONLY, - CALIBREONLYSAVECOL,] - -# 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_CALIBREONLYSAVECOL='Update Calibre Metadata Only(Saved Column)' -save_collisions={ - SKIP:SAVE_SKIP, - ADDNEW:SAVE_ADDNEW, - UPDATE:SAVE_UPDATE, - UPDATEALWAYS:SAVE_UPDATEALWAYS, - OVERWRITE:SAVE_OVERWRITE, - OVERWRITEALWAYS:SAVE_OVERWRITEALWAYS, - CALIBREONLY:SAVE_CALIBREONLY, - CALIBREONLYSAVECOL:SAVE_CALIBREONLYSAVECOL, - SAVE_SKIP:SKIP, - SAVE_ADDNEW:ADDNEW, - SAVE_UPDATE:UPDATE, - SAVE_UPDATEALWAYS:UPDATEALWAYS, - SAVE_OVERWRITE:OVERWRITE, - SAVE_OVERWRITEALWAYS:OVERWRITEALWAYS, - SAVE_CALIBREONLY:CALIBREONLY, - SAVE_CALIBREONLYSAVECOL:CALIBREONLYSAVECOL, - } - -anthology_collision_order=[UPDATE, - UPDATEALWAYS, - OVERWRITEALWAYS] +## moved to prefs.py so they can be included in jobs.py. +from calibre_plugins.fanficfare_plugin.prefs import \ + ( SAVE_YES, + SAVE_YES_UNLESS_SITE, + SKIP, + ADDNEW, + UPDATE, + UPDATEALWAYS, + OVERWRITE, + OVERWRITEALWAYS, + CALIBREONLY, + CALIBREONLYSAVECOL, + collision_order, + SAVE_SKIP, + SAVE_ADDNEW, + SAVE_UPDATE, + SAVE_UPDATEALWAYS, + SAVE_OVERWRITE, + SAVE_OVERWRITEALWAYS, + SAVE_CALIBREONLY, + SAVE_CALIBREONLYSAVECOL, + save_collisions, + anthology_collision_order, + ) gpstyle='QGroupBox {border:0; padding-top:10px; padding-bottom:0px; margin-bottom:0px;}' # background-color:red; @@ -473,8 +448,9 @@ class AddNewDialog(SizePersistedDialog): 'updatemeta': self.updatemeta.isChecked(), 'bgmeta': False, # self.bgmeta.isChecked(), 'updateepubcover': self.updateepubcover.isChecked(), - 'smarten_punctuation':self.prefs['smarten_punctuation'] - } + 'smarten_punctuation':self.prefs['smarten_punctuation'], + 'do_wordcount':self.prefs['do_wordcount'], + } if self.merge: retval['fileform']=='epub' @@ -898,7 +874,8 @@ class UpdateExistingDialog(SizePersistedDialog): 'updatemeta': self.updatemeta.isChecked(), 'bgmeta': self.bgmeta.isChecked(), 'updateepubcover': self.updateepubcover.isChecked(), - 'smarten_punctuation':self.prefs['smarten_punctuation'] + 'smarten_punctuation':self.prefs['smarten_punctuation'], + 'do_wordcount':self.prefs['do_wordcount'], } class StoryListTableWidget(QTableWidget): diff --git a/calibre-plugin/fff_plugin.py b/calibre-plugin/fff_plugin.py index 238d01a5..4133403f 100644 --- a/calibre-plugin/fff_plugin.py +++ b/calibre-plugin/fff_plugin.py @@ -4,7 +4,7 @@ from __future__ import (unicode_literals, division, absolute_import, print_function) __license__ = 'GPL v3' -__copyright__ = '2015, Jim Miller' +__copyright__ = '2016, Jim Miller' __docformat__ = 'restructuredtext en' import logging @@ -476,7 +476,8 @@ class FanFicFarePlugin(InterfaceAction): 'updatemeta': prefs['updatemeta'], 'bgmeta': False, 'updateepubcover': prefs['updateepubcover'], - 'smarten_punctuation':prefs['smarten_punctuation'] + 'smarten_punctuation':prefs['smarten_punctuation'], + 'do_wordcount':prefs['do_wordcount'], },"\n".join(url_list)) else: self.gui.status_bar.show_message(_('Finished Fetching Story URLs from Email.'),3000) diff --git a/calibre-plugin/jobs.py b/calibre-plugin/jobs.py index 2bbe44d9..cf69b5ae 100644 --- a/calibre-plugin/jobs.py +++ b/calibre-plugin/jobs.py @@ -4,7 +4,7 @@ from __future__ import (unicode_literals, division, absolute_import, print_function) __license__ = 'GPL v3' -__copyright__ = '2015, Jim Miller, 2011, Grant Drake ' +__copyright__ = '2016, Jim Miller, 2011, Grant Drake ' __docformat__ = 'restructuredtext en' import logging @@ -20,6 +20,9 @@ from calibre.constants import numeric_version as calibre_version from calibre.utils.date import local_tz from calibre.library.comments import sanitize_comments_html +from calibre_plugins.fanficfare_plugin.wordcount import get_word_count +from calibre_plugins.fanficfare_plugin.prefs import (SAVE_YES, SAVE_YES_UNLESS_SITE) + # ------------------------------------------------------------------------------ # # Functions to perform downloads using worker jobs @@ -148,7 +151,7 @@ def do_download_for_worker(book,options,merge,notification=lambda x,y:x): adapter.setChaptersRange(book['begin'],book['end']) adapter.load_cookiejar(options['cookiejarfile']) - logger.debug("cookiejar:%s"%adapter.cookiejar) + #logger.debug("cookiejar:%s"%adapter.cookiejar) adapter.set_pagecache(options['pagecache']) story = adapter.getStoryMetadataOnly() @@ -217,6 +220,7 @@ def do_download_for_worker(book,options,merge,notification=lambda x,y:x): logger.info("write to %s"%outfile) inject_cal_cols(book,story,configuration) writer.writeStory(outfilename=outfile, forceOverwrite=True) + book['comment'] = 'Download %s completed, %s chapters.'%(options['fileform'],story.getMetadata("numChapters")) book['all_metadata'] = story.getAllMetadata(removeallentities=True) if options['savemetacol'] != '': @@ -271,6 +275,16 @@ def do_download_for_worker(book,options,merge,notification=lambda x,y:x): if options['savemetacol'] != '': book['savemetacol'] = story.dump_html_metadata() + if options['do_wordcount'] == SAVE_YES or ( + options['do_wordcount'] == SAVE_YES_UNLESS_SITE and not story.getMetadataRaw('numWords') ): + wordcount = get_word_count(outfile) + logger.info("get_word_count:%s"%wordcount) + story.setMetadata('numWords',wordcount) + writer.writeStory(outfilename=outfile, forceOverwrite=True) + book['all_metadata'] = story.getAllMetadata(removeallentities=True) + if options['savemetacol'] != '': + book['savemetacol'] = story.dump_html_metadata() + if options['smarten_punctuation'] and options['fileform'] == "epub" \ and calibre_version >= (0, 9, 39): # for smarten punc @@ -286,8 +300,7 @@ def do_download_for_worker(book,options,merge,notification=lambda x,y:x): opts = O(**opts) log = Log(level=Log.DEBUG) - # report = [] - polish({outfile:outfile}, opts, log, logger.info) # report.append + polish({outfile:outfile}, opts, log, logger.info) except NotGoingToDownload as d: book['good']=False diff --git a/calibre-plugin/prefs.py b/calibre-plugin/prefs.py index df4b6ac3..e71be689 100644 --- a/calibre-plugin/prefs.py +++ b/calibre-plugin/prefs.py @@ -4,7 +4,7 @@ from __future__ import (unicode_literals, division, absolute_import, print_function) __license__ = 'GPL v3' -__copyright__ = '2015, Jim Miller' +__copyright__ = '2016, Jim Miller' __docformat__ = 'restructuredtext en' import logging @@ -15,9 +15,59 @@ import copy from calibre.utils.config import JSONConfig from calibre.gui2.ui import get_gui -from calibre_plugins.fanficfare_plugin.dialogs import SAVE_UPDATE from calibre_plugins.fanficfare_plugin.common_utils import get_library_uuid +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 from Web Site') +CALIBREONLYSAVECOL=_('Update Calibre Metadata from Saved Metadata Column') +collision_order=[SKIP, + ADDNEW, + UPDATE, + UPDATEALWAYS, + OVERWRITE, + OVERWRITEALWAYS, + CALIBREONLY, + CALIBREONLYSAVECOL,] + +# 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_CALIBREONLYSAVECOL='Update Calibre Metadata Only(Saved Column)' +save_collisions={ + SKIP:SAVE_SKIP, + ADDNEW:SAVE_ADDNEW, + UPDATE:SAVE_UPDATE, + UPDATEALWAYS:SAVE_UPDATEALWAYS, + OVERWRITE:SAVE_OVERWRITE, + OVERWRITEALWAYS:SAVE_OVERWRITEALWAYS, + CALIBREONLY:SAVE_CALIBREONLY, + CALIBREONLYSAVECOL:SAVE_CALIBREONLYSAVECOL, + SAVE_SKIP:SKIP, + SAVE_ADDNEW:ADDNEW, + SAVE_UPDATE:UPDATE, + SAVE_UPDATEALWAYS:UPDATEALWAYS, + SAVE_OVERWRITE:OVERWRITE, + SAVE_OVERWRITEALWAYS:OVERWRITEALWAYS, + SAVE_CALIBREONLY:CALIBREONLY, + SAVE_CALIBREONLYSAVECOL:CALIBREONLYSAVECOL, + } + +anthology_collision_order=[UPDATE, + UPDATEALWAYS, + OVERWRITEALWAYS] + + # Show translated strings, but save the same string in prefs so your # prefs are the same in different languages. YES=_('Yes, Always') @@ -26,9 +76,11 @@ YES_IF_IMG=_('Yes, if EPUB has a cover image') SAVE_YES_IF_IMG='Yes, if img' YES_UNLESS_IMG=_('Yes, unless FanFicFare found a cover image') SAVE_YES_UNLESS_IMG='Yes, unless img' +YES_UNLESS_SITE=_('Yes, unless found on site') +SAVE_YES_UNLESS_SITE='Yes, unless site' NO=_('No') SAVE_NO='No' -calcover_save_options = { +prefs_save_options = { YES:SAVE_YES, SAVE_YES:YES, YES_IF_IMG:SAVE_YES_IF_IMG, @@ -37,9 +89,12 @@ calcover_save_options = { SAVE_YES_UNLESS_IMG:YES_UNLESS_IMG, NO:SAVE_NO, SAVE_NO:NO, + YES_UNLESS_SITE:SAVE_YES_UNLESS_SITE, + SAVE_YES_UNLESS_SITE:YES_UNLESS_SITE, } updatecalcover_order=[YES,YES_IF_IMG,NO] gencalcover_order=[YES,YES_UNLESS_IMG,NO] +do_wordcount_order=[YES,YES_UNLESS_SITE,NO] # if don't have any settings for FanFicFarePlugin, copy from # predecessor FanFictionDownLoaderPlugin. @@ -78,6 +133,7 @@ default_prefs['checkforseriesurlid'] = True default_prefs['checkforurlchange'] = True default_prefs['injectseries'] = False default_prefs['matchtitleauth'] = True +default_prefs['do_wordcount'] = SAVE_YES_UNLESS_SITE default_prefs['smarten_punctuation'] = False default_prefs['show_est_time'] = False diff --git a/calibre-plugin/translations/messages.pot b/calibre-plugin/translations/messages.pot index a5b5ca5e..84e8dde5 100644 --- a/calibre-plugin/translations/messages.pot +++ b/calibre-plugin/translations/messages.pot @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2015-12-13 10:41+Central Standard Time\n" +"POT-Creation-Date: 2016-01-29 13:56+Central Standard Time\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -103,73 +103,73 @@ msgstr "" msgid "Other" msgstr "" -#: config.py:383 +#: config.py:384 msgid "These settings control the basic features of the plugin--downloading FanFiction." msgstr "" -#: config.py:387 +#: config.py:388 msgid "Defaults Options on Download" msgstr "" -#: config.py:391 +#: config.py:392 msgid "On each download, FanFicFare offers an option to select the output format.
This sets what that option will default to." msgstr "" -#: config.py:393 +#: config.py:394 msgid "Default Output &Format:" msgstr "" -#: config.py:408 +#: config.py:409 msgid "On each download, FanFicFare offers an option of what happens if that story already exists.
This sets what that option will default to." msgstr "" -#: config.py:410 +#: config.py:411 msgid "Default If Story Already Exists?" msgstr "" -#: config.py:425 +#: config.py:426 msgid "Default Update Calibre &Metadata?" msgstr "" -#: config.py:426 +#: config.py:427 msgid "On each download, FanFicFare 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:430 +#: config.py:431 msgid "Default Update EPUB Cover when Updating EPUB?" msgstr "" -#: config.py:431 +#: config.py:432 msgid "On each download, FanFicFare 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:435 +#: config.py:436 msgid "Default Background Metadata?" msgstr "" -#: config.py:436 +#: config.py:437 msgid "On each download, FanFicFare offers an option to Collect Metadata from sites in a Background process.
This returns control to you quicker while updating, but you won't be asked for username/passwords or if you are an adult--stories that need those will just fail.
Only available for Update/Overwrite of existing books in case URL given isn't canonical or matches to existing book by Title/Author." msgstr "" -#: config.py:442 +#: config.py:443 msgid "Updating Calibre Options" msgstr "" -#: config.py:446 +#: config.py:447 msgid "Delete other existing formats?" msgstr "" -#: config.py:447 +#: config.py:448 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:451 +#: config.py:452 msgid "Keep Existing Tags when Updating Metadata?" msgstr "" -#: config.py:452 +#: config.py:453 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" @@ -177,345 +177,360 @@ msgid "" "(If Tags is set to 'New Only' in the Standard Columns tab, this has no effect.)" msgstr "" -#: config.py:456 +#: config.py:457 msgid "Force Author into Author Sort?" msgstr "" -#: config.py:457 +#: config.py:458 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:461 +#: config.py:462 msgid "Force Title into Title Sort?" msgstr "" -#: config.py:462 +#: config.py:463 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:466 +#: config.py:467 msgid "Check for existing Series Anthology books?" msgstr "" -#: config.py:467 +#: config.py:468 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.\n" "Doesn't work when Collect Metadata in Background is selected." msgstr "" -#: config.py:471 +#: config.py:472 msgid "Check for changed Story URL?" msgstr "" -#: config.py:472 +#: config.py:473 msgid "" "Warn you if an update will change the URL of an existing book.\n" "fanfiction.net URLs will change from http to https silently." msgstr "" -#: config.py:476 +#: config.py:477 msgid "Search EPUB text for Story URL?" msgstr "" -#: config.py:477 +#: config.py:478 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:481 +#: config.py:482 +msgid "Post Processing Options" +msgstr "" + +#: config.py:486 msgid "Mark added/updated books when finished?" msgstr "" -#: config.py:482 +#: config.py:487 msgid "" "Mark added/updated books when finished. Use with option below.\n" "You can also manually search for 'marked:fff_success'.\n" "'marked:fff_failed' is also available, or search 'marked:fff' for both." msgstr "" -#: config.py:486 +#: config.py:491 msgid "Show Marked books when finished?" msgstr "" -#: config.py:487 +#: config.py:492 msgid "" "Show Marked added/updated books only when finished.\n" "You can also manually search for 'marked:fff_success'.\n" "'marked:fff_failed' is also available, or search 'marked:fff' for both." msgstr "" -#: config.py:491 +#: config.py:496 msgid "Smarten Punctuation (EPUB only)" msgstr "" -#: config.py:492 +#: config.py:497 msgid "Run Smarten Punctuation from Calibre's Polish Book feature on each EPUB download and update." msgstr "" -#: config.py:496 +#: config.py:502 +msgid "" +"Calculate Word Counts using Calibre internal methods.\n" +"Many sites include Word Count, but many do not.\n" +"This will count the words in each book and include it as if it came from the site." +msgstr "" + +#: config.py:506 +msgid "Calculate Word Count:" +msgstr "" + +#: config.py:519 msgid "Automatically Convert new/update books?" msgstr "" -#: config.py:497 +#: config.py:520 msgid "" "Automatically call calibre's Convert for new/update books.\n" "Converts to the current output format as chosen in calibre's\n" "Preferences->Behavior settings." msgstr "" -#: config.py:501 +#: config.py:524 msgid "GUI Options" msgstr "" -#: config.py:505 +#: config.py:528 msgid "Take URLs from Clipboard?" msgstr "" -#: config.py:506 +#: config.py:529 msgid "Prefill URLs from valid URLs in Clipboard when Adding New." msgstr "" -#: config.py:510 +#: config.py:533 msgid "Default to Update when books selected?" msgstr "" -#: config.py:511 +#: config.py:534 msgid "" "The top FanFicFare plugin button will start Update if\n" "books are selected. If unchecked, it will always bring up 'Add New'." msgstr "" -#: config.py:515 +#: config.py:538 msgid "Keep 'Add New from URL(s)' dialog on top?" msgstr "" -#: config.py:516 +#: config.py:539 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:520 +#: config.py:543 msgid "Show estimated time left?" msgstr "" -#: config.py:521 +#: config.py:544 msgid "When a Progress Bar is shown, show a rough estimate of the time left." msgstr "" -#: config.py:525 +#: config.py:548 msgid "Misc Options" msgstr "" -#: config.py:529 +#: config.py:552 msgid "Inject calibre Series when none found?" msgstr "" -#: config.py:530 +#: config.py:553 msgid "" "If no series is found, inject the calibre series (if there is one) so \n" "it appears on the FanFicFare title page(not cover)." msgstr "" -#: config.py:534 +#: config.py:557 msgid "Search by Title/Author(s) for If Story Already Exists?" msgstr "" -#: config.py:535 +#: config.py:558 msgid "When checking If Story Already Exists FanFicFare will first match by URL Identifier. But if not found, it can also search existing books by Title and Author(s)." msgstr "" -#: config.py:539 +#: config.py:562 msgid "Reject List" msgstr "" -#: config.py:543 +#: config.py:566 msgid "Edit Reject URL List" msgstr "" -#: config.py:544 +#: config.py:567 msgid "Edit list of URLs FanFicFare will automatically Reject." msgstr "" -#: config.py:548 config.py:619 +#: config.py:571 config.py:645 msgid "Add Reject URLs" msgstr "" -#: config.py:549 +#: config.py:572 msgid "Add additional URLs to Reject as text." msgstr "" -#: config.py:553 +#: config.py:576 msgid "Edit Reject Reasons List" msgstr "" -#: config.py:554 config.py:609 +#: config.py:577 config.py:635 msgid "Customize the Reasons presented when Rejecting URLs" msgstr "" -#: config.py:558 +#: config.py:581 msgid "Reject Without Confirmation?" msgstr "" -#: config.py:559 +#: config.py:582 msgid "Always reject URLs on the Reject List without stopping and asking." msgstr "" -#: config.py:593 +#: config.py:619 msgid "Edit Reject URLs List" msgstr "" -#: config.py:607 +#: config.py:633 msgid "Reject Reasons" msgstr "" -#: config.py:608 +#: config.py:634 msgid "Customize Reject List Reasons" msgstr "" -#: config.py:617 +#: config.py:643 msgid "Reason why I rejected it" msgstr "" -#: config.py:617 +#: config.py:643 msgid "Title by Author" msgstr "" -#: config.py:620 +#: config.py:646 msgid "Add Reject URLs. Use: http://...,note or http://...,title by author - note
Invalid story URLs will be ignored." msgstr "" -#: config.py:621 +#: config.py:647 msgid "" "One URL per line:\n" "http://...,note\n" "http://...,title by author - note" msgstr "" -#: config.py:623 dialogs.py:1123 +#: config.py:649 dialogs.py:1099 msgid "Add this reason to all URLs added:" msgstr "" -#: config.py:639 +#: config.py:665 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:644 +#: config.py:670 msgid "FanFicFare now includes find, color coding, and error checking for personal.ini editing. Red generally indicates errors." msgstr "" -#: config.py:663 config.py:704 config.py:705 +#: config.py:689 config.py:730 config.py:731 msgid "Edit personal.ini" msgstr "" -#: config.py:668 +#: config.py:694 msgid "Changes will only be saved if you click 'OK' to leave Customize FanFicFare." msgstr "" -#: config.py:672 +#: config.py:698 msgid "View Defaults" msgstr "" -#: config.py:673 +#: config.py:699 msgid "" "View all of the plugin's configurable settings\n" "and their default settings." msgstr "" -#: config.py:677 +#: config.py:703 msgid "Pass Calibre Columns into FanFicFare on Update/Overwrite" msgstr "" -#: config.py:678 +#: config.py:704 msgid "If checked, when updating/overwriting an existing book, FanFicFare will have the Calibre Columns available to use in replace_metadata, title_page, etc.
Click the button below to see the Calibre Column namess." msgstr "" -#: config.py:682 +#: config.py:708 msgid "Show Calibre Column Names" msgstr "" -#: config.py:683 +#: config.py:709 msgid "FanFicFare can pass the Calibre Columns into the download/update process.
This will show you the columns available by name." msgstr "" -#: config.py:694 +#: config.py:720 msgid "Plugin Defaults" msgstr "" -#: config.py:695 +#: config.py:721 msgid "Plugin Defaults (%s) (Read-Only)" msgstr "" -#: config.py:728 +#: config.py:754 msgid "Calibre Column Entry Names" msgstr "" -#: config.py:729 +#: config.py:755 msgid "Label (entry_name)" msgstr "" -#: config.py:749 +#: config.py:775 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:754 +#: config.py:780 msgid "Add new/updated stories to \"Send to Device\" Reading List(s)." msgstr "" -#: config.py:755 +#: config.py:781 msgid "Automatically add new/updated stories to these lists in the %(rl)s plugin." msgstr "" -#: config.py:760 +#: config.py:786 msgid "\"Send to Device\" Reading Lists" msgstr "" -#: config.py:761 config.py:764 config.py:778 config.py:781 +#: config.py:787 config.py:790 config.py:804 config.py:807 msgid "When enabled, new/updated stories will be automatically added to these lists." msgstr "" -#: config.py:771 +#: config.py:797 msgid "Add new/updated stories to \"To Read\" Reading List(s)." msgstr "" -#: config.py:772 +#: config.py:798 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:777 +#: config.py:803 msgid "\"To Read\" Reading Lists" msgstr "" -#: config.py:788 +#: config.py:814 msgid "Add stories back to \"Send to Device\" Reading List(s) when marked \"Read\"." msgstr "" -#: config.py:789 +#: config.py:815 msgid "Menu option to remove from \"To Read\" lists will also add stories back to \"Send to Device\" Reading List(s)" msgstr "" -#: config.py:793 +#: config.py:819 msgid "Automatically run Remove \"New\" Chapter Marks when marking books \"Read\"." msgstr "" -#: config.py:794 +#: config.py:820 msgid "Menu option to remove from \"To Read\" lists will also remove \"(new)\" chapter marks created by personal.ini mark_new_chapters setting." msgstr "" -#: config.py:822 +#: config.py:848 msgid "The Calibre cover image for a downloaded book can come from the story site(if EPUB and images are enabled), or from either Calibre's built-in random cover generator or the %(gc)s plugin." msgstr "" -#: config.py:830 +#: config.py:856 msgid "" "Update Calibre book cover image from EPUB when Calibre metadata is updated.\n" "Doesn't go looking for new images on 'Update Calibre Metadata Only'.\n" @@ -523,754 +538,722 @@ msgid "" "This comes before Generate Cover so %(gc)s(Plugin) use the image if configured to." msgstr "" -#: config.py:835 +#: config.py:861 msgid "Update Calibre Cover (from EPUB):" msgstr "" -#: config.py:853 +#: config.py:879 msgid "Generate a Calibre book cover image when Calibre metadata is updated.
Defaults to 'Yes, Always' for backward compatibility and because %(gc)s(Plugin) will only run if configured for Default or site." msgstr "" -#: config.py:857 +#: config.py:883 msgid "Generate Calibre Cover:" msgstr "" -#: config.py:884 +#: config.py:910 msgid "Plugin %(gc)s" msgstr "" -#: config.py:885 +#: config.py:911 msgid "Use plugin to create covers. Additional settings are below." msgstr "" -#: config.py:892 +#: config.py:918 msgid "Calibre Generate Cover" msgstr "" -#: config.py:893 +#: config.py:919 msgid "Call Calibre's Edit Metadata Generate cover feature to create a random cover each time a story is downloaded or updated.
Right click or long click the 'Generate cover' button in Calibre's Edit Metadata to customize." msgstr "" -#: config.py:907 +#: config.py:933 msgid "Generate Covers Only for New Books" msgstr "" -#: config.py:908 +#: config.py:934 msgid "Default is to generate a cover any time the calibre metadata is updated.
Used for both Calibre and Plugin generated covers." msgstr "" -#: config.py:914 +#: config.py:940 msgid "Inject/update the cover inside EPUB" msgstr "" -#: config.py:915 +#: config.py:941 msgid "Calibre's Polish feature will be used to inject or update the generated cover into the EPUB ebook file.
Used for both Calibre and Plugin generated covers." msgstr "" -#: config.py:921 +#: config.py:947 msgid "%(gc)s(Plugin) Settings" msgstr "" -#: config.py:929 +#: config.py:955 msgid "The %(gc)s plugin can create cover images for books using various metadata (including existing cover image). If you have %(gc)s installed, FanFicFare can run %(gc)s on new downloads and metadata updates. Pick a %(gc)s setting by site and/or one to use by Default." msgstr "" -#: config.py:947 config.py:951 config.py:964 +#: config.py:973 config.py:977 config.py:990 msgid "Default" msgstr "" -#: config.py:952 +#: config.py:978 msgid "On Metadata update, run %(gc)s with this setting, if there isn't a more specific setting below." msgstr "" -#: config.py:955 +#: config.py:981 msgid "On Metadata update, run %(gc)s with this setting for %(site)s stories." msgstr "" -#: config.py:978 +#: config.py:1004 msgid "Allow %(gcset)s from %(pini)s to override" msgstr "" -#: config.py:979 +#: config.py:1005 msgid "The %(pini)s parameter %(gcset)s allows you to choose a %(gc)s setting based on metadata rather than site, but it's much more complex.
%(gcset)s is ignored when this is off." msgstr "" -#: config.py:1017 +#: config.py:1043 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:1022 +#: config.py:1048 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:1028 +#: config.py:1054 msgid "Which column and algorithm to use are configured in %(cp)s." msgstr "" -#: config.py:1038 +#: config.py:1064 msgid "Will overwrite word count from FanFicFare metadata if set to update the same custom column." msgstr "" -#: config.py:1043 +#: config.py:1069 msgid "Only run Count Page's Word Count if checked and FanFicFare metadata doesn't already have a word count. If this is used with one of the other Page Counts, the Page Count plugin will be called twice." msgstr "" -#: config.py:1079 +#: config.py:1105 msgid "These controls aren't plugin settings as such, but convenience buttons for setting Keyboard shortcuts and getting all the FanFicFare confirmation dialogs back again." msgstr "" -#: config.py:1084 +#: config.py:1110 msgid "Keyboard shortcuts..." msgstr "" -#: config.py:1085 +#: config.py:1111 msgid "Edit the keyboard shortcuts associated with this plugin" msgstr "" -#: config.py:1089 +#: config.py:1115 msgid "Reset disabled &confirmation dialogs" msgstr "" -#: config.py:1090 +#: config.py:1116 msgid "Reset all show me again dialogs for the FanFicFare plugin" msgstr "" -#: config.py:1094 +#: config.py:1120 msgid "&View library preferences..." msgstr "" -#: config.py:1095 +#: config.py:1121 msgid "View data stored in the library database for this plugin" msgstr "" -#: config.py:1106 +#: config.py:1132 msgid "Done" msgstr "" -#: config.py:1107 +#: config.py:1133 msgid "Confirmation dialogs have all been reset" msgstr "" -#: config.py:1155 +#: config.py:1181 msgid "Category" msgstr "" -#: config.py:1156 +#: config.py:1182 msgid "Genre" msgstr "" -#: config.py:1157 +#: config.py:1183 msgid "Language" msgstr "" -#: config.py:1158 fff_plugin.py:1441 fff_plugin.py:1640 fff_plugin.py:1670 +#: config.py:1184 fff_plugin.py:1443 fff_plugin.py:1642 fff_plugin.py:1672 msgid "Status" msgstr "" -#: config.py:1159 +#: config.py:1185 msgid "Status:%(cmplt)s" msgstr "" -#: config.py:1160 +#: config.py:1186 msgid "Status:%(inprog)s" msgstr "" -#: config.py:1161 config.py:1309 +#: config.py:1187 config.py:1335 msgid "Series" msgstr "" -#: config.py:1162 +#: config.py:1188 msgid "Characters" msgstr "" -#: config.py:1163 +#: config.py:1189 msgid "Relationships" msgstr "" -#: config.py:1164 +#: config.py:1190 msgid "Published" msgstr "" -#: config.py:1165 fff_plugin.py:1753 fff_plugin.py:1772 +#: config.py:1191 fff_plugin.py:1755 fff_plugin.py:1774 msgid "Updated" msgstr "" -#: config.py:1166 +#: config.py:1192 msgid "Created" msgstr "" -#: config.py:1167 +#: config.py:1193 msgid "Rating" msgstr "" -#: config.py:1168 +#: config.py:1194 msgid "Warnings" msgstr "" -#: config.py:1169 +#: config.py:1195 msgid "Chapters" msgstr "" -#: config.py:1170 +#: config.py:1196 msgid "Words" msgstr "" -#: config.py:1171 +#: config.py:1197 msgid "Site" msgstr "" -#: config.py:1172 +#: config.py:1198 msgid "Story ID" msgstr "" -#: config.py:1173 +#: config.py:1199 msgid "Author ID" msgstr "" -#: config.py:1174 +#: config.py:1200 msgid "Extra Tags" msgstr "" -#: config.py:1175 config.py:1301 dialogs.py:914 dialogs.py:1010 -#: fff_plugin.py:1441 fff_plugin.py:1640 fff_plugin.py:1670 +#: config.py:1201 config.py:1327 dialogs.py:890 dialogs.py:986 +#: fff_plugin.py:1443 fff_plugin.py:1642 fff_plugin.py:1672 msgid "Title" msgstr "" -#: config.py:1176 +#: config.py:1202 msgid "Story URL" msgstr "" -#: config.py:1177 +#: config.py:1203 msgid "Description" msgstr "" -#: config.py:1178 dialogs.py:914 dialogs.py:1010 fff_plugin.py:1441 -#: fff_plugin.py:1640 fff_plugin.py:1670 +#: config.py:1204 dialogs.py:890 dialogs.py:986 fff_plugin.py:1443 +#: fff_plugin.py:1642 fff_plugin.py:1672 msgid "Author" msgstr "" -#: config.py:1179 +#: config.py:1205 msgid "Author URL" msgstr "" -#: config.py:1180 +#: config.py:1206 msgid "File Format" msgstr "" -#: config.py:1181 +#: config.py:1207 msgid "File Extension" msgstr "" -#: config.py:1182 +#: config.py:1208 msgid "Site Abbrev" msgstr "" -#: config.py:1183 +#: config.py:1209 msgid "FanFicFare Version" msgstr "" -#: config.py:1198 +#: config.py:1224 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:1223 +#: config.py:1249 msgid "Update this %s column(%s) with..." msgstr "" -#: config.py:1233 +#: config.py:1259 msgid "Values that aren't valid for this enumeration column will be ignored." msgstr "" -#: config.py:1233 config.py:1235 +#: config.py:1259 config.py:1261 msgid "Metadata values valid for this type of column." msgstr "" -#: config.py:1238 config.py:1328 +#: config.py:1264 config.py:1354 msgid "New Only" msgstr "" -#: config.py:1239 +#: config.py:1265 msgid "" "Write to %s(%s) only for new\n" "books, not updates to existing books." msgstr "" -#: config.py:1250 +#: config.py:1276 msgid "Allow %(ccset)s from %(pini)s to override" msgstr "" -#: config.py:1251 +#: config.py:1277 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:1255 +#: config.py:1281 msgid "Special column:" msgstr "" -#: config.py:1260 +#: config.py:1286 msgid "Update/Overwrite Error Column:" msgstr "" -#: config.py:1261 +#: config.py:1287 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:1275 +#: config.py:1301 msgid "Saved Metadata Column:" msgstr "" -#: config.py:1276 +#: config.py:1302 msgid "If set, FanFicFare will save a copy of all its metadata in this column when the book is downloaded or updated.
The metadata from this column can later be used to update custom columns without having to request the metadata from the server again.
(Long Text columns only.)" msgstr "" -#: config.py:1302 +#: config.py:1328 msgid "Author(s)" msgstr "" -#: config.py:1303 +#: config.py:1329 msgid "Publisher" msgstr "" -#: config.py:1304 +#: config.py:1330 msgid "Tags" msgstr "" -#: config.py:1305 +#: config.py:1331 msgid "Languages" msgstr "" -#: config.py:1306 +#: config.py:1332 msgid "Published Date" msgstr "" -#: config.py:1307 +#: config.py:1333 msgid "Date" msgstr "" -#: config.py:1308 +#: config.py:1334 msgid "Comments" msgstr "" -#: config.py:1310 +#: config.py:1336 msgid "Ids(url id only)" msgstr "" -#: config.py:1315 +#: config.py:1341 msgid "The standard calibre metadata columns are listed below. You may choose whether FanFicFare will fill each column automatically on updates or only for new books." msgstr "" -#: config.py:1329 +#: config.py:1355 msgid "" "Write to %s only for new\n" "books, not updates to existing books." msgstr "" -#: config.py:1338 +#: config.py:1364 msgid "Other Standard Column Options" msgstr "" -#: config.py:1343 +#: config.py:1369 msgid "Set Calibre Author URL" msgstr "" -#: config.py:1344 +#: config.py:1370 msgid "Set Calibre Author URL to Author's URL on story site." msgstr "" -#: config.py:1361 +#: config.py:1387 msgid "These settings will allow FanFicFare to fetch story URLs from your email account. It will only look for story URLs in unread emails in the folder specified below." msgstr "" -#: config.py:1366 +#: config.py:1392 msgid "IMAP Server Name" msgstr "" -#: config.py:1367 +#: config.py:1393 msgid "Name of IMAP server--must allow IMAP4 with SSL. Eg: imap.gmail.com" msgstr "" -#: config.py:1376 +#: config.py:1402 msgid "IMAP User Name" msgstr "" -#: config.py:1377 +#: config.py:1403 msgid "" "Name of IMAP user. Eg: yourname@gmail.com\n" "Note that Gmail accounts need to have IMAP enabled in Gmail Settings first." msgstr "" -#: config.py:1386 +#: config.py:1412 msgid "IMAP User Password" msgstr "" -#: config.py:1387 +#: config.py:1413 msgid "IMAP password. If left empty, FanFicFare will ask you for your password when you use the feature." msgstr "" -#: config.py:1397 +#: config.py:1423 msgid "Remember Password for Session (when not saved above)" msgstr "" -#: config.py:1398 +#: config.py:1424 msgid "If checked, and no password is entered above, FanFicFare will remember your password until you close calibre or change Libraries." msgstr "" -#: config.py:1403 +#: config.py:1429 msgid "IMAP Folder Name" msgstr "" -#: config.py:1404 +#: config.py:1430 msgid "Name of IMAP folder to search for new emails. The folder (or label) has to already exist. Use INBOX for your default inbox." msgstr "" -#: config.py:1413 +#: config.py:1439 msgid "Mark Emails Read" msgstr "" -#: config.py:1414 +#: config.py:1440 msgid "If checked, emails will be marked as having been read if they contain any story URLs." msgstr "" -#: config.py:1419 +#: config.py:1445 msgid "Discard URLs on Reject List" msgstr "" -#: config.py:1420 +#: config.py:1446 msgid "If checked, FanFicFare will silently discard story URLs from emails that are on your Reject URL List.
Otherwise they will appear and you will see the normal Reject URL dialog.
The Emails will still be marked Read if configured to." msgstr "" -#: config.py:1425 +#: config.py:1451 msgid "Download from Email Immediately" msgstr "" -#: config.py:1426 +#: config.py:1452 msgid "If checked, FanFicFare will start downloading story URLs from emails immediately.
Otherwise the usual Download from URLs dialog will appear." msgstr "" -#: config.py:1431 +#: config.py:1457 msgid "It's safest if you create a separate email account that you use only for your story update notices. FanFicFare and calibre cannot guarantee that malicious code cannot get your email password once you've entered it.
Use this feature at your own risk.
" msgstr "" -#: dialogs.py:76 -msgid "Skip" -msgstr "" - -#: dialogs.py:77 -msgid "Add New Book" -msgstr "" - -#: dialogs.py:78 -msgid "Update EPUB if New Chapters" -msgstr "" - -#: dialogs.py:79 -msgid "Update EPUB Always" -msgstr "" - -#: dialogs.py:80 -msgid "Overwrite if Newer" -msgstr "" - -#: dialogs.py:81 -msgid "Overwrite Always" -msgstr "" - -#: dialogs.py:82 -msgid "Update Calibre Metadata from Web Site" -msgstr "" - -#: dialogs.py:83 -msgid "Update Calibre Metadata from Saved Metadata Column" -msgstr "" - -#: dialogs.py:269 dialogs.py:795 +#: dialogs.py:244 dialogs.py:770 msgid "Show Download Options" msgstr "" -#: dialogs.py:288 dialogs.py:815 +#: dialogs.py:263 dialogs.py:790 msgid "Output &Format:" msgstr "" -#: dialogs.py:296 dialogs.py:823 +#: dialogs.py:271 dialogs.py:798 msgid "Choose output format to create. May set default from plugin configuration." msgstr "" -#: dialogs.py:324 dialogs.py:843 +#: dialogs.py:299 dialogs.py:818 msgid "Update Calibre &Metadata?" msgstr "" -#: dialogs.py:325 dialogs.py:844 +#: dialogs.py:300 dialogs.py:819 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:331 dialogs.py:848 +#: dialogs.py:306 dialogs.py:823 msgid "Update EPUB Cover?" msgstr "" -#: dialogs.py:332 dialogs.py:849 +#: dialogs.py:307 dialogs.py:824 msgid "Update book cover image from site or defaults (if found) inside the EPUB when EPUB is updated." msgstr "" -#: dialogs.py:394 +#: dialogs.py:369 msgid "Story URLs for anthology, one per line:" msgstr "" -#: dialogs.py:395 +#: dialogs.py:370 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:396 +#: dialogs.py:371 msgid "If Story Already Exists in Anthology?" msgstr "" -#: dialogs.py:397 +#: dialogs.py:372 msgid "What to do if there's already an existing story with the same URL in the anthology." msgstr "" -#: dialogs.py:406 +#: dialogs.py:381 msgid "Story URLs, one per line:" msgstr "" -#: dialogs.py:407 +#: dialogs.py:382 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:408 +#: dialogs.py:383 msgid "If Story Already Exists?" msgstr "" -#: dialogs.py:409 +#: dialogs.py:384 msgid "What to do if there's already an existing story with the same URL or title and author." msgstr "" -#: dialogs.py:528 +#: dialogs.py:503 msgid "For Individual Books" msgstr "" -#: dialogs.py:529 +#: dialogs.py:504 msgid "Get URLs and go to dialog for individual story downloads." msgstr "" -#: dialogs.py:534 +#: dialogs.py:509 msgid "For Anthology Epub" msgstr "" -#: dialogs.py:535 +#: dialogs.py:510 msgid "" "Get URLs and go to dialog for Anthology download.\n" "Requires %s plugin." msgstr "" -#: dialogs.py:539 dialogs.py:593 dialogs.py:620 dialogs.py:1525 +#: dialogs.py:514 dialogs.py:568 dialogs.py:595 dialogs.py:1501 msgid "Cancel" msgstr "" -#: dialogs.py:571 dialogs.py:1513 +#: dialogs.py:546 dialogs.py:1489 msgid "Password" msgstr "" -#: dialogs.py:572 +#: dialogs.py:547 msgid "Author requires a password for this story(%s)." msgstr "" -#: dialogs.py:577 +#: dialogs.py:552 msgid "User/Password" msgstr "" -#: dialogs.py:578 +#: dialogs.py:553 msgid "%s requires you to login to download this story." msgstr "" -#: dialogs.py:580 +#: dialogs.py:555 msgid "User:" msgstr "" -#: dialogs.py:584 +#: dialogs.py:559 msgid "Password:" msgstr "" -#: dialogs.py:589 dialogs.py:737 dialogs.py:1521 +#: dialogs.py:564 dialogs.py:712 dialogs.py:1497 msgid "OK" msgstr "" -#: dialogs.py:615 fff_plugin.py:940 +#: dialogs.py:590 fff_plugin.py:942 msgid "Fetching metadata for stories..." msgstr "" -#: dialogs.py:616 fff_plugin.py:941 +#: dialogs.py:591 fff_plugin.py:943 msgid "Downloading metadata for stories" msgstr "" -#: dialogs.py:617 fff_plugin.py:942 +#: dialogs.py:592 fff_plugin.py:944 msgid "Fetched metadata for" msgstr "" -#: dialogs.py:647 +#: dialogs.py:622 msgid " - %s estimated until done" msgstr "" -#: dialogs.py:697 +#: dialogs.py:672 msgid "%d day" msgstr "" -#: dialogs.py:697 +#: dialogs.py:672 msgid "%d days" msgstr "" -#: dialogs.py:698 +#: dialogs.py:673 msgid "%d hour" msgstr "" -#: dialogs.py:698 +#: dialogs.py:673 msgid "%d hours" msgstr "" -#: dialogs.py:699 +#: dialogs.py:674 msgid "%d minute" msgstr "" -#: dialogs.py:699 +#: dialogs.py:674 msgid "%d minutes" msgstr "" -#: dialogs.py:700 +#: dialogs.py:675 msgid "%d second" msgstr "" -#: dialogs.py:700 +#: dialogs.py:675 msgid "%d seconds" msgstr "" -#: dialogs.py:715 +#: dialogs.py:690 msgid "less than 1 second" msgstr "" -#: dialogs.py:732 fff_plugin.py:365 fff_plugin.py:368 +#: dialogs.py:707 fff_plugin.py:365 fff_plugin.py:368 msgid "About FanFicFare" msgstr "" -#: dialogs.py:786 +#: dialogs.py:761 msgid "Remove selected books from the list" msgstr "" -#: dialogs.py:828 +#: dialogs.py:803 msgid "Update Mode:" msgstr "" -#: dialogs.py:831 +#: dialogs.py:806 msgid "What sort of update to perform. May set default from plugin configuration." msgstr "" -#: dialogs.py:853 +#: dialogs.py:828 msgid "Background Metadata?" msgstr "" -#: dialogs.py:854 +#: dialogs.py:829 msgid "Collect Metadata from sites in a Background process.
This returns control to you quicker while updating, but you won't be asked for username/passwords or if you are an adult--stories that need those will just fail." msgstr "" -#: dialogs.py:914 fff_plugin.py:1441 fff_plugin.py:1640 fff_plugin.py:1670 +#: dialogs.py:890 fff_plugin.py:1443 fff_plugin.py:1642 fff_plugin.py:1672 msgid "Comment" msgstr "" -#: dialogs.py:982 +#: dialogs.py:958 msgid "Are you sure you want to remove this book from the list?" msgstr "" -#: dialogs.py:984 +#: dialogs.py:960 msgid "Are you sure you want to remove the selected %d books from the list?" msgstr "" -#: dialogs.py:1010 +#: dialogs.py:986 msgid "Note" msgstr "" -#: dialogs.py:1049 +#: dialogs.py:1025 msgid "Select or Edit Reject Note." msgstr "" -#: dialogs.py:1058 +#: dialogs.py:1034 msgid "Are you sure you want to remove this URL from the list?" msgstr "" -#: dialogs.py:1060 +#: dialogs.py:1036 msgid "Are you sure you want to remove the %d selected URLs from the list?" msgstr "" -#: dialogs.py:1078 +#: dialogs.py:1054 msgid "List of Books to Reject" msgstr "" -#: dialogs.py:1091 +#: dialogs.py:1067 msgid "FFF will remember these URLs and display the note and offer to reject them if you try to download them again later." msgstr "" -#: dialogs.py:1105 +#: dialogs.py:1081 msgid "Remove selected URLs from the list" msgstr "" -#: dialogs.py:1120 dialogs.py:1124 +#: dialogs.py:1096 dialogs.py:1100 msgid "This will be added to whatever note you've set for each URL above." msgstr "" -#: dialogs.py:1134 +#: dialogs.py:1110 msgid "Delete Books (including books without FanFiction URLs)?" msgstr "" -#: dialogs.py:1135 +#: dialogs.py:1111 msgid "Delete the selected books after adding them to the Rejected URLs list." msgstr "" -#: dialogs.py:1291 +#: dialogs.py:1267 msgid "Search for string in edit box." msgstr "" -#: dialogs.py:1294 +#: dialogs.py:1270 msgid "Find:" msgstr "" -#: dialogs.py:1299 +#: dialogs.py:1275 msgid "Find" msgstr "" -#: dialogs.py:1309 +#: dialogs.py:1285 msgid "Case sensitive" msgstr "" -#: dialogs.py:1310 +#: dialogs.py:1286 msgid "Search for case sensitive string; don't treat Harry, HARRY and harry all the same." msgstr "" -#: dialogs.py:1339 +#: dialogs.py:1315 msgid "Go back to fix errors?" msgstr "" -#: dialogs.py:1451 +#: dialogs.py:1427 msgid "Click an error below to return to Editing directly on that line:" msgstr "" -#: dialogs.py:1465 +#: dialogs.py:1441 msgid "Click to go to line %s" msgstr "" -#: dialogs.py:1481 +#: dialogs.py:1457 msgid "Return to Editing" msgstr "" -#: dialogs.py:1485 +#: dialogs.py:1461 msgid "Save Anyway" msgstr "" -#: dialogs.py:1514 +#: dialogs.py:1490 msgid "Enter Email Password for %s:" msgstr "" @@ -1298,7 +1281,7 @@ msgstr "" msgid "Get Story URLs from &Email" msgstr "" -#: fff_plugin.py:291 fff_plugin.py:505 +#: fff_plugin.py:291 fff_plugin.py:506 msgid "Get Story URLs from Web Page" msgstr "" @@ -1382,559 +1365,559 @@ msgstr "" msgid "Fetching Story URLs from Email..." msgstr "" -#: fff_plugin.py:467 fff_plugin.py:488 +#: fff_plugin.py:467 fff_plugin.py:489 msgid "No Valid Story URLs Found in Unread Emails." msgstr "" -#: fff_plugin.py:482 +#: fff_plugin.py:483 msgid "Finished Fetching Story URLs from Email." msgstr "" -#: fff_plugin.py:490 +#: fff_plugin.py:491 msgid "(%d Story URLs Skipped, on Rejected URL List)" msgstr "" -#: fff_plugin.py:491 +#: fff_plugin.py:492 msgid "Get Story URLs from Email" msgstr "" -#: fff_plugin.py:514 +#: fff_plugin.py:515 msgid "Fetching Story URLs from Page..." msgstr "" -#: fff_plugin.py:518 +#: fff_plugin.py:519 msgid "Finished Fetching Story URLs from Page." msgstr "" -#: fff_plugin.py:524 fff_plugin.py:577 +#: fff_plugin.py:525 fff_plugin.py:578 msgid "List of Story URLs" msgstr "" -#: fff_plugin.py:525 +#: fff_plugin.py:526 msgid "No Valid Story URLs found on given page." msgstr "" -#: fff_plugin.py:541 fff_plugin.py:594 +#: fff_plugin.py:542 fff_plugin.py:595 msgid "No Selected Books to Get URLs From" msgstr "" -#: fff_plugin.py:559 +#: fff_plugin.py:560 msgid "Collecting URLs for stories..." msgstr "" -#: fff_plugin.py:560 +#: fff_plugin.py:561 msgid "Get URLs for stories" msgstr "" -#: fff_plugin.py:561 fff_plugin.py:672 fff_plugin.py:865 +#: fff_plugin.py:562 fff_plugin.py:674 fff_plugin.py:867 msgid "URL retrieved" msgstr "" -#: fff_plugin.py:581 +#: fff_plugin.py:582 msgid "List of URLs" msgstr "" -#: fff_plugin.py:582 +#: fff_plugin.py:583 msgid "No Story URLs found in selected books." msgstr "" -#: fff_plugin.py:589 +#: fff_plugin.py:590 msgid "Can only UnNew books in library" msgstr "" -#: fff_plugin.py:606 +#: fff_plugin.py:607 msgid "UnNewing books..." msgstr "" -#: fff_plugin.py:607 +#: fff_plugin.py:608 msgid "UnNew Books" msgstr "" -#: fff_plugin.py:608 +#: fff_plugin.py:609 msgid "Books UnNewed" msgstr "" -#: fff_plugin.py:647 fff_plugin.py:1599 +#: fff_plugin.py:649 fff_plugin.py:1601 msgid "Starting auto conversion of %d books." msgstr "" -#: fff_plugin.py:662 +#: fff_plugin.py:664 msgid "No Selected Books have URLs to Reject" msgstr "" -#: fff_plugin.py:670 +#: fff_plugin.py:672 msgid "Collecting URLs for Reject List..." msgstr "" -#: fff_plugin.py:671 +#: fff_plugin.py:673 msgid "Get URLs for Reject List" msgstr "" -#: fff_plugin.py:706 +#: fff_plugin.py:708 msgid "Proceed to Remove?" msgstr "" -#: fff_plugin.py:706 +#: fff_plugin.py:708 msgid "Rejecting FanFicFare URLs: None of the books selected have FanFiction URLs." msgstr "" -#: fff_plugin.py:728 +#: fff_plugin.py:730 msgid "Cannot Make Anthologys without %s" msgstr "" -#: fff_plugin.py:732 fff_plugin.py:842 +#: fff_plugin.py:734 fff_plugin.py:844 msgid "Cannot Update Books from Device View" msgstr "" -#: fff_plugin.py:736 +#: fff_plugin.py:738 msgid "Can only update 1 anthology at a time" msgstr "" -#: fff_plugin.py:745 +#: fff_plugin.py:747 msgid "Can only Update Epub Anthologies" msgstr "" -#: fff_plugin.py:763 fff_plugin.py:764 +#: fff_plugin.py:765 fff_plugin.py:766 msgid "Cannot Update Anthology" msgstr "" -#: fff_plugin.py:764 +#: fff_plugin.py:766 msgid "Book isn't an FanFicFare Anthology or contains book(s) without valid Story URLs." msgstr "" -#: fff_plugin.py:771 +#: fff_plugin.py:773 msgid "Fetching Story URLs for Series..." msgstr "" -#: fff_plugin.py:781 +#: fff_plugin.py:783 msgid "Finished Fetching Story URLs for Series." msgstr "" -#: fff_plugin.py:828 +#: fff_plugin.py:830 msgid "There are %d stories in the current anthology that are not going to be kept if you go ahead." msgstr "" -#: fff_plugin.py:829 +#: fff_plugin.py:831 msgid "Story URLs that will be removed:" msgstr "" -#: fff_plugin.py:831 +#: fff_plugin.py:833 msgid "Update anyway?" msgstr "" -#: fff_plugin.py:832 +#: fff_plugin.py:834 msgid "Stories Removed" msgstr "" -#: fff_plugin.py:849 +#: fff_plugin.py:851 msgid "No Selected Books to Update" msgstr "" -#: fff_plugin.py:863 +#: fff_plugin.py:865 msgid "Collecting stories for update..." msgstr "" -#: fff_plugin.py:864 +#: fff_plugin.py:866 msgid "Get stories for updates" msgstr "" -#: fff_plugin.py:874 +#: fff_plugin.py:876 msgid "Update Existing List" msgstr "" -#: fff_plugin.py:934 +#: fff_plugin.py:936 msgid "Start queuing downloading for %s stories." msgstr "" -#: fff_plugin.py:935 +#: fff_plugin.py:937 msgid "Queuing download for stories..." msgstr "" -#: fff_plugin.py:936 +#: fff_plugin.py:938 msgid "Queuing download for stories" msgstr "" -#: fff_plugin.py:937 +#: fff_plugin.py:939 msgid "Queued download for" msgstr "" -#: fff_plugin.py:939 +#: fff_plugin.py:941 msgid "Started fetching metadata for %s stories." msgstr "" -#: fff_plugin.py:953 +#: fff_plugin.py:955 msgid "No valid story URLs entered." msgstr "" -#: fff_plugin.py:963 fff_plugin.py:969 +#: fff_plugin.py:965 fff_plugin.py:971 msgid "Reject URL?" msgstr "" -#: fff_plugin.py:970 fff_plugin.py:988 +#: fff_plugin.py:972 fff_plugin.py:990 msgid "%s is on your Reject URL list:" msgstr "" -#: fff_plugin.py:972 +#: fff_plugin.py:974 msgid "Click 'Yes' to Reject." msgstr "" -#: fff_plugin.py:973 fff_plugin.py:1140 +#: fff_plugin.py:975 fff_plugin.py:1142 msgid "Click 'No' to download anyway." msgstr "" -#: fff_plugin.py:975 +#: fff_plugin.py:977 msgid "Story on Reject URLs list (%s)." msgstr "" -#: fff_plugin.py:978 +#: fff_plugin.py:980 msgid "Rejected" msgstr "" -#: fff_plugin.py:981 +#: fff_plugin.py:983 msgid "Remove Reject URL?" msgstr "" -#: fff_plugin.py:987 +#: fff_plugin.py:989 msgid "Remove URL from Reject List?" msgstr "" -#: fff_plugin.py:990 +#: fff_plugin.py:992 msgid "Click 'Yes' to remove it from the list," msgstr "" -#: fff_plugin.py:991 +#: fff_plugin.py:993 msgid "Click 'No' to leave it on the list." msgstr "" -#: fff_plugin.py:1033 +#: fff_plugin.py:1035 msgid "Cannot update non-epub format." msgstr "" -#: fff_plugin.py:1108 +#: fff_plugin.py:1110 msgid "Are You an Adult?" msgstr "" -#: fff_plugin.py:1109 +#: fff_plugin.py:1111 msgid "%s requires that you be an adult. Please confirm you are an adult in your locale:" msgstr "" -#: fff_plugin.py:1131 +#: fff_plugin.py:1133 msgid "Skip Story?" msgstr "" -#: fff_plugin.py:1137 +#: fff_plugin.py:1139 msgid "Skip Anthology Story?" msgstr "" -#: fff_plugin.py:1138 +#: fff_plugin.py:1140 msgid "\"%s\" is in series \"%s\" that you have an anthology book for." msgstr "" -#: fff_plugin.py:1139 +#: fff_plugin.py:1141 msgid "Click 'Yes' to Skip." msgstr "" -#: fff_plugin.py:1142 +#: fff_plugin.py:1144 msgid "Story in Series Anthology(%s)." msgstr "" -#: fff_plugin.py:1148 +#: fff_plugin.py:1150 msgid "Skipped" msgstr "" -#: fff_plugin.py:1158 +#: fff_plugin.py:1160 msgid "Add" msgstr "" -#: fff_plugin.py:1194 +#: fff_plugin.py:1196 msgid "Meta" msgstr "" -#: fff_plugin.py:1223 +#: fff_plugin.py:1225 msgid "Skipping duplicate story." msgstr "" -#: fff_plugin.py:1226 +#: fff_plugin.py:1228 msgid "More than one identical book by Identifer URL or title/author(s)--can't tell which book to update/overwrite." msgstr "" -#: fff_plugin.py:1237 +#: fff_plugin.py:1239 msgid "Update" msgstr "" -#: fff_plugin.py:1245 fff_plugin.py:1252 +#: fff_plugin.py:1247 fff_plugin.py:1254 msgid "Change Story URL?" msgstr "" -#: fff_plugin.py:1253 +#: fff_plugin.py:1255 msgid "%s by %s is already in your library with a different source URL:" msgstr "" -#: fff_plugin.py:1254 +#: fff_plugin.py:1256 msgid "In library: %(liburl)s" msgstr "" -#: fff_plugin.py:1255 fff_plugin.py:1269 +#: fff_plugin.py:1257 fff_plugin.py:1271 msgid "New URL: %(newurl)s" msgstr "" -#: fff_plugin.py:1256 +#: fff_plugin.py:1258 msgid "Click 'Yes' to update/overwrite book with new URL." msgstr "" -#: fff_plugin.py:1257 +#: fff_plugin.py:1259 msgid "Click 'No' to skip updating/overwriting this book." msgstr "" -#: fff_plugin.py:1259 fff_plugin.py:1266 +#: fff_plugin.py:1261 fff_plugin.py:1268 msgid "Download as New Book?" msgstr "" -#: fff_plugin.py:1267 +#: fff_plugin.py:1269 msgid "%s by %s is already in your library with a different source URL." msgstr "" -#: fff_plugin.py:1268 +#: fff_plugin.py:1270 msgid "You chose not to update the existing book. Do you want to add a new book for this URL?" msgstr "" -#: fff_plugin.py:1270 +#: fff_plugin.py:1272 msgid "Click 'Yes' to a new book with new URL." msgstr "" -#: fff_plugin.py:1271 +#: fff_plugin.py:1273 msgid "Click 'No' to skip URL." msgstr "" -#: fff_plugin.py:1277 +#: fff_plugin.py:1279 msgid "Update declined by user due to differing story URL(%s)" msgstr "" -#: fff_plugin.py:1280 +#: fff_plugin.py:1282 msgid "Different URL" msgstr "" -#: fff_plugin.py:1285 +#: fff_plugin.py:1287 msgid "Metadata collected." msgstr "" -#: fff_plugin.py:1301 jobs.py:252 +#: fff_plugin.py:1303 jobs.py:256 msgid "Already contains %d chapters." msgstr "" -#: fff_plugin.py:1303 jobs.py:254 +#: fff_plugin.py:1305 jobs.py:258 msgid "Existing epub contains %d chapters, web site only has %d. Use Overwrite to force update." msgstr "" -#: fff_plugin.py:1305 jobs.py:256 +#: fff_plugin.py:1307 jobs.py:260 msgid "FanFicFare doesn't recognize chapters in existing epub, epub is probably from a different source. Use Overwrite to force update." msgstr "" -#: fff_plugin.py:1319 jobs.py:214 +#: fff_plugin.py:1321 jobs.py:217 msgid "Not Overwriting, web site is not newer." msgstr "" -#: fff_plugin.py:1437 +#: fff_plugin.py:1439 msgid "None of the %d URLs/stories given can be/need to be downloaded." msgstr "" -#: fff_plugin.py:1438 fff_plugin.py:1636 fff_plugin.py:1666 +#: fff_plugin.py:1440 fff_plugin.py:1638 fff_plugin.py:1668 msgid "See log for details." msgstr "" -#: fff_plugin.py:1439 +#: fff_plugin.py:1441 msgid "Proceed with updating your library(Error Column, if configured)?" msgstr "" -#: fff_plugin.py:1446 fff_plugin.py:1648 +#: fff_plugin.py:1448 fff_plugin.py:1650 msgid "Bad" msgstr "" -#: fff_plugin.py:1454 +#: fff_plugin.py:1456 msgid "FanFicFare download ended" msgstr "" -#: fff_plugin.py:1454 fff_plugin.py:1691 +#: fff_plugin.py:1456 fff_plugin.py:1693 msgid "FanFicFare log" msgstr "" -#: fff_plugin.py:1474 +#: fff_plugin.py:1476 msgid "Download FanFiction Book" msgstr "" -#: fff_plugin.py:1481 +#: fff_plugin.py:1483 msgid "Starting %d FanFicFare Downloads" msgstr "" -#: fff_plugin.py:1512 +#: fff_plugin.py:1514 msgid "Story Details:" msgstr "" -#: fff_plugin.py:1515 +#: fff_plugin.py:1517 msgid "Error Updating Metadata" msgstr "" -#: fff_plugin.py:1516 +#: fff_plugin.py:1518 msgid "An error has occurred while FanFicFare was updating calibre's metadata for %s." msgstr "" -#: fff_plugin.py:1517 +#: fff_plugin.py:1519 msgid "The ebook has been updated, but the metadata has not." msgstr "" -#: fff_plugin.py:1569 +#: fff_plugin.py:1571 msgid "Finished Adding/Updating %d books." msgstr "" -#: fff_plugin.py:1620 +#: fff_plugin.py:1622 msgid "No Good Stories for Anthology" msgstr "" -#: fff_plugin.py:1621 +#: fff_plugin.py:1623 msgid "No good stories/updates where downloaded, Anthology creation/update aborted." msgstr "" -#: fff_plugin.py:1626 fff_plugin.py:1665 +#: fff_plugin.py:1628 fff_plugin.py:1667 msgid "FanFicFare found %s good and %s bad updates." msgstr "" -#: fff_plugin.py:1633 +#: fff_plugin.py:1635 msgid "Are you sure you want to continue with creating/updating this Anthology?" msgstr "" -#: fff_plugin.py:1634 +#: fff_plugin.py:1636 msgid "Any updates that failed will not be included in the Anthology." msgstr "" -#: fff_plugin.py:1635 +#: fff_plugin.py:1637 msgid "However, if there's an older version, it will still be included." msgstr "" -#: fff_plugin.py:1638 +#: fff_plugin.py:1640 msgid "Proceed with updating this anthology and your library?" msgstr "" -#: fff_plugin.py:1646 +#: fff_plugin.py:1648 msgid "Good" msgstr "" -#: fff_plugin.py:1667 +#: fff_plugin.py:1669 msgid "Proceed with updating your library?" msgstr "" -#: fff_plugin.py:1691 +#: fff_plugin.py:1693 msgid "FanFicFare download complete" msgstr "" -#: fff_plugin.py:1704 +#: fff_plugin.py:1706 msgid "Merging %s books." msgstr "" -#: fff_plugin.py:1744 +#: fff_plugin.py:1746 msgid "FanFicFare Adding/Updating books." msgstr "" -#: fff_plugin.py:1751 +#: fff_plugin.py:1753 msgid "Updating calibre for FanFiction stories..." msgstr "" -#: fff_plugin.py:1752 +#: fff_plugin.py:1754 msgid "Update calibre for FanFiction stories" msgstr "" -#: fff_plugin.py:1761 +#: fff_plugin.py:1763 msgid "Adding/Updating %s BAD books." msgstr "" -#: fff_plugin.py:1770 +#: fff_plugin.py:1772 msgid "Updating calibre for BAD FanFiction stories..." msgstr "" -#: fff_plugin.py:1771 +#: fff_plugin.py:1773 msgid "Update calibre for BAD FanFiction stories" msgstr "" -#: fff_plugin.py:1797 +#: fff_plugin.py:1799 msgid "Adding format to book failed for some reason..." msgstr "" -#: fff_plugin.py:1800 +#: fff_plugin.py:1802 msgid "Error" msgstr "" -#: fff_plugin.py:2114 +#: fff_plugin.py:2116 msgid "You configured FanFicFare to automatically update Reading Lists, but you don't have the %s plugin installed anymore?" msgstr "" -#: fff_plugin.py:2126 +#: fff_plugin.py:2128 msgid "You configured FanFicFare to automatically update \"To Read\" Reading Lists, but you don't have any lists set?" msgstr "" -#: fff_plugin.py:2136 fff_plugin.py:2154 +#: fff_plugin.py:2138 fff_plugin.py:2156 msgid "You configured FanFicFare to automatically update Reading List '%s', but you don't have a list of that name?" msgstr "" -#: fff_plugin.py:2142 +#: fff_plugin.py:2144 msgid "You configured FanFicFare to automatically update \"Send to Device\" Reading Lists, but you don't have any lists set?" msgstr "" -#: fff_plugin.py:2265 +#: fff_plugin.py:2267 msgid "No story URL found." msgstr "" -#: fff_plugin.py:2268 +#: fff_plugin.py:2270 msgid "Not Found" msgstr "" -#: fff_plugin.py:2274 +#: fff_plugin.py:2276 msgid "URL is not a valid story URL." msgstr "" -#: fff_plugin.py:2277 +#: fff_plugin.py:2279 msgid "Bad URL" msgstr "" -#: fff_plugin.py:2416 fff_plugin.py:2419 +#: fff_plugin.py:2418 fff_plugin.py:2421 msgid "Anthology containing:" msgstr "" -#: fff_plugin.py:2417 +#: fff_plugin.py:2419 msgid "%s by %s" msgstr "" -#: fff_plugin.py:2439 +#: fff_plugin.py:2441 msgid " Anthology" msgstr "" -#: fff_plugin.py:2482 +#: fff_plugin.py:2484 msgid "(was set, removed for security)" msgstr "" -#: jobs.py:66 +#: jobs.py:69 msgid "Downloading FanFiction Stories" msgstr "" -#: jobs.py:94 +#: jobs.py:97 msgid "Download Results:" msgstr "" -#: jobs.py:96 +#: jobs.py:99 msgid "Successful:" msgstr "" -#: jobs.py:97 +#: jobs.py:100 msgid "Unsuccessful:" msgstr "" -#: jobs.py:122 +#: jobs.py:125 msgid "Download started..." msgstr "" -#: jobs.py:245 +#: jobs.py:249 msgid "Already contains %d chapters. Reuse as is." msgstr "" -#: jobs.py:268 +#: jobs.py:272 msgid "Update %s completed, added %s chapters for %s total." msgstr "" diff --git a/calibre-plugin/wordcount.py b/calibre-plugin/wordcount.py new file mode 100644 index 00000000..5ec46b08 --- /dev/null +++ b/calibre-plugin/wordcount.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2016, Jim Miller, 2011, Grant Drake ' +__docformat__ = 'restructuredtext en' + +''' +A lot of this is lifted from Count Pages plugin by Grant Drake (with +some changes from davidfor.) +''' + +import logging +logger = logging.getLogger(__name__) + +import re + +from calibre.ebooks.oeb.iterator import EbookIterator + +RE_HTML_BODY = re.compile(u']*>(.*)', re.UNICODE | re.DOTALL | re.IGNORECASE) +RE_STRIP_MARKUP = re.compile(u'<[^>]+>', re.UNICODE) + + +def get_word_count(book_path): + ''' + Estimate a word count + ''' + from calibre.utils.localization import get_lang + + iterator = _open_epub_file(book_path) + + lang = iterator.opf.language + lang = get_lang() if not lang else lang + count = _get_epub_standard_word_count(iterator, lang) + + return count + +def _open_epub_file(book_path, strip_html=False): + ''' + Given a path to an EPUB file, read the contents into a giant block of text + ''' + iterator = EbookIterator(book_path) + iterator.__enter__(only_input_plugin=True, run_char_count=True, + read_anchor_map=False) + return iterator + +def _get_epub_standard_word_count(iterator, lang='en'): + ''' + This algorithm counts individual words instead of pages + ''' + + book_text = _read_epub_contents(iterator, strip_html=True) + + try: + from calibre.spell.break_iterator import count_words + wordcount = count_words(book_text, lang) + logger.debug('\tWord count - count_words method:%s'%wordcount) + except: + try: # The above method is new and no-one will have it as of 08/01/2016. Use an older method for a beta. + from calibre.spell.break_iterator import split_into_words_and_positions + wordcount = len(split_into_words_and_positions(book_text, lang)) + logger.debug('\tWord count - split_into_words_and_positions method:%s'%wordcount) + except: + from calibre.utils.wordcount import get_wordcount_obj + wordcount = get_wordcount_obj(book_text) + wordcount = wordcount.words + logger.debug('\tWord count - old method:%s'%wordcount) + + return wordcount + +def _read_epub_contents(iterator, strip_html=False): + ''' + Given an iterator for an ePub file, read the contents into a giant block of text + ''' + book_files = [] + for path in iterator.spine: + with open(path, 'rb') as f: + html = f.read().decode('utf-8', 'replace') + if strip_html: + html = unicode(_extract_body_text(html)).strip() + #print('FOUND HTML:', html) + book_files.append(html) + return ''.join(book_files) + +def _extract_body_text(data): + ''' + Get the body text of this html content wit any html tags stripped + ''' + body = RE_HTML_BODY.findall(data) + if body: + return RE_STRIP_MARKUP.sub('', body[0]).replace('.','. ') + return '' + diff --git a/fanficfare/story.py b/fanficfare/story.py index 4ef19cef..b8488f72 100644 --- a/fanficfare/story.py +++ b/fanficfare/story.py @@ -646,10 +646,8 @@ class Story(Configurable): elif self.metadata.has_key(key): value = self.metadata[key] if value: - if key == "numWords": - value = commaGroups(value) - if key == "numChapters": - value = commaGroups("%d"%value) + if key in ("numWords","numChapters"): + value = commaGroups(unicode(value)) if key in ("dateCreated"): value = value.strftime(self.getConfig(key+"_format","%Y-%m-%d %H:%M:%S")) if key in ("datePublished","dateUpdated"):