Hello community,

here is the log from the commit of package python-fanficfare for 
openSUSE:Factory checked in at 2019-09-13 15:02:54
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-fanficfare (Old)
 and      /work/SRC/openSUSE:Factory/.python-fanficfare.new.7948 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-fanficfare"

Fri Sep 13 15:02:54 2019 rev:12 rq:730595 version:3.11.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-fanficfare/python-fanficfare.changes      
2019-08-06 17:27:27.636686174 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-fanficfare.new.7948/python-fanficfare.changes
    2019-09-13 15:04:22.017268871 +0200
@@ -1,0 +2,12 @@
+Fri Sep 13 07:48:06 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Update to 3.11.0:
+  * Install attached plugin zip file, or use Calibre's 'Get plugins' feature.
+  * Add URL prefix for XF2 authorUrl if relative. Circa Aug 23, 2019 SV 
changed the author URL FFF collects to a relative link and I didn't notice it 
until now.
+  * Add dedup_chapter_list option for buggy chapter lists. Optional in case 
they're not buggy.
+  * Add fetch_last_page for base_xenforo--SB doesn't send notice emails if 
user not up-to-date now.
+  * Fix for corner-case with deleting Rejects.
+  * Fix for XF1 regression caused by XF2 threadmarks metadata code.
+  * Add XF2 threadmarks_cover/status/desc/title options.
+
+-------------------------------------------------------------------

Old:
----
  FanFicFare-3.10.5.tar.gz

New:
----
  FanFicFare-3.11.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-fanficfare.spec ++++++
--- /var/tmp/diff_new_pack.Pq376i/_old  2019-09-13 15:04:22.649268737 +0200
+++ /var/tmp/diff_new_pack.Pq376i/_new  2019-09-13 15:04:22.653268736 +0200
@@ -20,7 +20,7 @@
 %define modnamedown fanficfare
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-fanficfare
-Version:        3.10.5
+Version:        3.11.0
 Release:        0
 Summary:        Tool for making eBooks from stories on fanfiction and other 
web sites
 License:        GPL-3.0-only

++++++ FanFicFare-3.10.5.tar.gz -> FanFicFare-3.11.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/FanFicFare-3.10.5/calibre-plugin/__init__.py 
new/FanFicFare-3.11.0/calibre-plugin/__init__.py
--- old/FanFicFare-3.10.5/calibre-plugin/__init__.py    2019-07-30 
16:06:56.000000000 +0200
+++ new/FanFicFare-3.11.0/calibre-plugin/__init__.py    2019-09-04 
16:44:56.000000000 +0200
@@ -33,7 +33,7 @@
 from calibre.customize import InterfaceActionBase
 
 # pulled out from FanFicFareBase for saving in prefs.py
-__version__ = (3, 10, 5)
+__version__ = (3, 11, 0)
 
 ## Apparently the name for this class doesn't matter--it was still
 ## 'demo' for the first few versions.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/FanFicFare-3.10.5/calibre-plugin/dialogs.py 
new/FanFicFare-3.11.0/calibre-plugin/dialogs.py
--- old/FanFicFare-3.10.5/calibre-plugin/dialogs.py     2019-07-30 
16:06:56.000000000 +0200
+++ new/FanFicFare-3.11.0/calibre-plugin/dialogs.py     2019-09-04 
16:44:56.000000000 +0200
@@ -148,7 +148,7 @@
 
     def to_line(self):
         # always 'url,'
-        return self.url+","+self.fullnote()
+        return "%s,%s"%(self.url,self.fullnote())
 
     @classmethod
     def from_data(cls,data):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/FanFicFare-3.10.5/calibre-plugin/plugin-defaults.ini 
new/FanFicFare-3.11.0/calibre-plugin/plugin-defaults.ini
--- old/FanFicFare-3.10.5/calibre-plugin/plugin-defaults.ini    2019-07-30 
16:06:56.000000000 +0200
+++ new/FanFicFare-3.11.0/calibre-plugin/plugin-defaults.ini    2019-09-04 
16:44:56.000000000 +0200
@@ -263,6 +263,10 @@
 # https://forums.spacebattles.com/posts/10157299/
 # 
https://forums.spacebattles.com/threads/lengthy-thread-name.100849/#post-10157400
 
+## Rarely, some stories on some sites (observed on SpaceBattles) might
+## have the same chapter URL listed more than once.  Set true for
+## those stories.
+#dedup_chapter_list:false
 
 ## Some readers don't show horizontal rule (<hr />) tags correctly.
 ## This replaces them all with a centered '* * *'.  (Note centering
@@ -756,7 +760,36 @@
 # .bbCodeSpoilerContainer { border: 1px solid black; padding: 2px; }
 
 [base_xenforo2forum]
-## So far, only SV. [base_xenforoforum] also applied.
+## [base_xenforoforum] also applied, but [base_xenforo2forum] takes
+## precedence.  SV is the only XF2 site as of Jul 2019.
+
+## Some additional 'thread' metadata entries.
+add_to_extra_valid_entries:,threadmarks_title,threadmarks_description,threadmarks_status
+#add_to_extra_titlepage_entries:,threadmarks_title,threadmarks_description,threadmarks_status
+
+# Just to remove '_'.
+threadmarks_title_label:Threadmarks Title
+threadmarks_description_label:Threadmarks Description
+threadmarks_status_label:Threadmarks Status
+
+## When use_threadmarks_description is set true,
+## threadmarks_description will be used to fill in the standard
+## description metadata entry.  Some stories have poor
+## threadmarks_description, you can use this setting to avoid using
+## it.
+use_threadmarks_description:true
+## Increasing description_limit from base_xenforoforum's default of
+## 500 is also useful with use_threadmarks_description
+description_limit:1000
+
+## When use_threadmarks_status is set true, a normalized version of
+## threadmarks_status will be used to fill in the standard status
+## metadata entry. (In-Progress, Completed plus site statuses.)
+use_threadmarks_status:true
+
+## When use_threadmarks_cover is set true, the threadmarks image will
+## be used to fill in the cover image.  Set true by default.
+use_threadmarks_cover:true
 
 [epub]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/FanFicFare-3.10.5/calibre-plugin/translations/ca.po 
new/FanFicFare-3.11.0/calibre-plugin/translations/ca.po
--- old/FanFicFare-3.10.5/calibre-plugin/translations/ca.po     2019-07-30 
16:06:56.000000000 +0200
+++ new/FanFicFare-3.11.0/calibre-plugin/translations/ca.po     2019-09-04 
16:44:56.000000000 +0200
@@ -2,7 +2,7 @@
 # Copyright (C) YEAR ORGANIZATION
 # 
 # Translators:
-# Fito JB, 2014
+# Adolfo Jayme-Barrientos, 2014
 # jmontane, 2014
 # Queralt Iglesias <[email protected]>, 2016
 # Robert Antoni Buj Gelonch <[email protected]>, 2016-2017
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/FanFicFare-3.10.5/calibre-plugin/translations/es.po 
new/FanFicFare-3.11.0/calibre-plugin/translations/es.po
--- old/FanFicFare-3.10.5/calibre-plugin/translations/es.po     2019-07-30 
16:06:56.000000000 +0200
+++ new/FanFicFare-3.11.0/calibre-plugin/translations/es.po     2019-09-04 
16:44:56.000000000 +0200
@@ -2,7 +2,7 @@
 # Copyright (C) YEAR ORGANIZATION
 # 
 # Translators:
-# Fito JB, 2014
+# Adolfo Jayme-Barrientos, 2014
 # Albert, 2016
 # Darío Hereñú, 2015-2016,2018
 # Darío Hereñú, 2018
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/FanFicFare-3.10.5/calibre-plugin/translations/nl.po 
new/FanFicFare-3.11.0/calibre-plugin/translations/nl.po
--- old/FanFicFare-3.10.5/calibre-plugin/translations/nl.po     2019-07-30 
16:06:56.000000000 +0200
+++ new/FanFicFare-3.11.0/calibre-plugin/translations/nl.po     2019-09-04 
16:44:56.000000000 +0200
@@ -10,6 +10,7 @@
 # M. de Boer <[email protected]>, 2018-2019
 # Nathan Follens, 2015
 # Nathan Follens, 2016
+# Meteor0id, 2019
 # Rodolfo_Jadon, 2014-2015
 # Volluta <[email protected]>, 2015
 # W.P.M.E. Hofland <[email protected]>, 2015
@@ -17,8 +18,8 @@
 msgstr ""
 "Project-Id-Version: calibre-plugins\n"
 "POT-Creation-Date: 2019-07-12 21:47+Central Daylight Time\n"
-"PO-Revision-Date: 2019-07-14 02:10+0000\n"
-"Last-Translator: Kovid Goyal <[email protected]>\n"
+"PO-Revision-Date: 2019-08-20 15:17+0000\n"
+"Last-Translator: Meteor0id\n"
 "Language-Team: Dutch 
(http://www.transifex.com/calibre/calibre-plugins/language/nl/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -187,7 +188,7 @@
 
 #: config.py:470
 msgid "Default Update Calibre &Metadata?"
-msgstr "Standaard update Calibre &Metadata?"
+msgstr "Standaard update Calibre &Metagegevens?"
 
 #: config.py:471
 msgid ""
@@ -195,7 +196,7 @@
 "(title, author, URL, tags, custom columns, etc) from the web site. <br "
 "/>This sets whether that will default to on or off. <br />Columns set to "
 "'New Only' in the column tabs will only be set for new books."
-msgstr "Bij elke download biedt FanFicFare een optie om Calibre metadata 
(titel, auteur, URL, tags, aangepaste kolommen, enz.) van de website bij te 
werken. <br />Hiermee wordt de standaard ingesteld op aan of uit.<br /> 
Kolommen die zijn ingesteld als 'Alleen Nieuw' in de kolomtabs, worden alleen 
ingesteld voor nieuwe boeken."
+msgstr "Bij elke download biedt FanFicFare een optie om Calibre metagegevens 
(titel, auteur, URL, tags, aangepaste kolommen, enz.) van de website bij te 
werken. <br />Hiermee wordt de standaard ingesteld op aan of uit.<br /> 
Kolommen die zijn ingesteld als 'Alleen Nieuw' in de kolomtabs, worden alleen 
ingesteld voor nieuwe boeken."
 
 #: config.py:475
 msgid "Default Update EPUB Cover when Updating EPUB?"
@@ -210,7 +211,7 @@
 
 #: config.py:480
 msgid "Default Background Metadata?"
-msgstr "Standaard achtergrond Metadata?"
+msgstr "Standaard achtergrond Metagegevens?"
 
 #: config.py:481
 msgid ""
@@ -238,7 +239,7 @@
 
 #: config.py:496
 msgid "Keep Existing Tags when Updating Metadata?"
-msgstr "Bestaande Tags behouden wanneer Metadata wordt geüpdatet? "
+msgstr "Bestaande Tags behouden wanneer Metagegevens wordt geüpdatet? "
 
 #: config.py:497
 msgid ""
@@ -257,7 +258,7 @@
 "Check for existing 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 "Controleer voor bestaande series bloemlezing-boeken de URL van elk 
nieuw verhaal voordat je het downloadt. \nAanbieden om het downloaden over te 
slaan als een bloemlezing serie is gevonden.\nWerkt niet wanneer Collect 
Metadata in achtergrond is geselecteerd."
+msgstr "Controleer voor bestaande series bloemlezing-boeken de URL van elk 
nieuw verhaal voordat je het downloadt. \nAanbieden om het downloaden over te 
slaan als een bloemlezing serie is gevonden.\nWerkt niet wanneer Collect 
Metagegevens in achtergrond is geselecteerd."
 
 #: config.py:506 config.py:623
 msgid "Reject Without Confirmation?"
@@ -268,7 +269,7 @@
 "Automatically reject storys with existing Series Anthology books.\n"
 "Only works if 'Check for existing Series Anthology books' is on.\n"
 "Doesn't work when Collect Metadata in Background is selected."
-msgstr "Verwerp automatisch verhalen met bestaande series 
bloemlezing-boeken.\n Werkt alleen als 'Zoeken naar bestaande bloemlezing 
boeken' is ingeschakeld. \nWerkt niet wanneer Collect Metadata in achtergrond 
is geselecteerd."
+msgstr "Verwerp automatisch verhalen met bestaande series 
bloemlezing-boeken.\n Werkt alleen als 'Zoeken naar bestaande bloemlezing 
boeken' is ingeschakeld. \nWerkt niet wanneer Collect Metagegevens in 
achtergrond is geselecteerd."
 
 #: config.py:514
 msgid "Check for changed Story URL?"
@@ -288,7 +289,7 @@
 msgid ""
 "Look for first valid story URL inside EPUB, ZIP(HTML) or TXT ebook formats if 
not found in metadata.\n"
 "Somewhat risky, could find wrong URL depending on ebook content."
-msgstr "Zoek naar de eerste geldige Story-URL in EPUB-, ZIP (HTML) of TXT 
ebook-formaten indien niet gevonden in metadata.\nEnigszins riskant, zou een 
verkeerde URL kunnen vinden afhankelijk van de inhoud van het e-boek."
+msgstr "Zoek naar de eerste geldige Story-URL in EPUB-, ZIP (HTML) of TXT 
ebook-formaten indien niet gevonden in metagegevens.\nEnigszins riskant, zou 
een verkeerde URL kunnen vinden afhankelijk van de inhoud van het e-boek."
 
 #: config.py:524
 msgid "Post Processing Options"
@@ -658,7 +659,7 @@
 "Doesn't go looking for new images on 'Update Calibre Metadata Only'.\n"
 "Cover in EPUB could be from site or previously injected into the EPUB.\n"
 "This comes before Generate Cover so %(gc)s(Plugin) use the image if 
configured to."
-msgstr "Werkt de afbeelding van de Calibre-boekomslag bij vanuit EPUB wanneer 
Calibre metagegevens worden bijgewerkt.\nZoekt niet naar nieuwe afbeeldingen 
bij 'Update Calibre Metadata Only'. \nDe omslag in EPUB kan van de site zijn of 
eerder zijn ingevoegd in de EPUB.\nDit gebeurt voordat u de omslag genereert, 
dus %(gc)s(Plugin) gebruikt de afbeelding indien daartoe geconfigureerd."
+msgstr "Werkt de afbeelding van de Calibre-boekomslag bij vanuit EPUB wanneer 
Calibre metagegevens worden bijgewerkt.\nZoekt niet naar nieuwe afbeeldingen 
bij 'Update Calibre Metagegevens Only'. \nDe omslag in EPUB kan van de site 
zijn of eerder zijn ingevoegd in de EPUB.\nDit gebeurt voordat u de omslag 
genereert, dus %(gc)s(Plugin) gebruikt de afbeelding indien daartoe 
geconfigureerd."
 
 #: config.py:960
 msgid "Update Calibre Cover (from EPUB):"
@@ -692,7 +693,7 @@
 "Call Calibre's Edit Metadata Generate cover feature to create a random cover"
 " each time a story is downloaded or updated.<br />Right click or long click "
 "the 'Generate cover' button in Calibre's Edit Metadata to customize."
-msgstr "Voer Calibre's Metadata bewerken omslag genereren functie uit om een 
​​willekeurige cover te maken elke keer dat een verhaal wordt gedownload of 
bijgewerkt. <br />Klik met de rechtermuisknop of lang-klik op de knop 'Genereer 
omslag' in Calibre's Metadata bewerken om aan te passen."
+msgstr "Voer Calibre's Metagegevens bewerken omslag genereren functie uit om 
een ​​willekeurige cover te maken elke keer dat een verhaal wordt gedownload of 
bijgewerkt. <br />Klik met de rechtermuisknop of lang-klik op de knop 'Genereer 
omslag' in Calibre's Metagegevens bewerken om aan te passen."
 
 #: config.py:1032
 msgid "Generate Covers Only for New Books"
@@ -702,7 +703,7 @@
 msgid ""
 "Default is to generate a cover any time the calibre metadata is updated.<br "
 "/>Used for both Calibre and Plugin generated covers."
-msgstr "Standaard is om een ​​omslag te genereren iedere keer dat de Calibre 
metadata wordt bijgewerkt. <br />Wordt gebruikt voor zowel door Calibre als 
Plugin gegenereerde omslagen."
+msgstr "Standaard is om een ​​omslag te genereren iedere keer dat de Calibre 
metagegevens wordt bijgewerkt. <br />Wordt gebruikt voor zowel door Calibre als 
Plugin gegenereerde omslagen."
 
 #: config.py:1039
 msgid "Inject/update the cover inside EPUB"
@@ -725,7 +726,7 @@
 "(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 "De %(gc)splug-in kan omslagafbeeldingen voor boeken maken met 
verschillende metagegevens (inclusief bestaande omslagafbeelding). Als je 
%(gc)sgeïnstalleerd hebt, kan FanFicFare %(gc)sdraaien op nieuwe  downloads en 
updates van metadata. Kies een %(gc)sinstelling per site en/of een om standaard 
te gebruiken."
+msgstr "De %(gc)splug-in kan omslagafbeeldingen voor boeken maken met 
verschillende metagegevens (inclusief bestaande omslagafbeelding). Als je 
%(gc)sgeïnstalleerd hebt, kan FanFicFare %(gc)sdraaien op nieuwe  downloads en 
updates van metagegevens. Kies een %(gc)sinstelling per site en/of een om 
standaard te gebruiken."
 
 #: config.py:1072 config.py:1076 config.py:1089
 msgid "Default"
@@ -780,7 +781,7 @@
 "Only run Count Page's Word Count if checked <i>and</i> 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 "Voer alleen de woordtelling van Count Page uit wanneer 
gecontroleerd<i>en</i>FanFicFare-metadata nog geen woordentelling heeft. Als 
dit wordt gebruikt met één van de andere pagina tellingen, wordt de 
paginatelling-plug-in tweemaal aangeroepen."
+msgstr "Voer alleen de woordtelling van Count Page uit wanneer 
gecontroleerd<i>en</i>FanFicFare-metagegevens nog geen woordentelling heeft. 
Als dit wordt gebruikt met één van de andere pagina tellingen, wordt de 
paginatelling-plug-in tweemaal aangeroepen."
 
 #: config.py:1204
 msgid ""
@@ -811,7 +812,7 @@
 
 #: config.py:1220
 msgid "View data stored in the library database for this plugin"
-msgstr "Bekijk gegevens opgeslagen in de bibliotheekdatabase voor deze plugin"
+msgstr "Bekijk gegevens opgeslagen in de bibliotheekgegevensbank voor deze 
plugin"
 
 #: config.py:1230
 msgid "Done"
@@ -947,7 +948,7 @@
 msgid ""
 "If you have custom columns defined, they will be listed below.  Choose a "
 "metadata value type to fill your columns automatically."
-msgstr "Als je eigen kolommen hebt gedefinieerd, zullen ze hieronder worden 
weergegeven. Kies een metadatawaardesoort om je kolommen automatisch in te 
vullen."
+msgstr "Als je eigen kolommen hebt gedefinieerd, zullen ze hieronder worden 
weergegeven. Kies een metagegevenswaardesoort om je kolommen automatisch in te 
vullen."
 
 #: config.py:1349
 msgid "Update this %s column(%s) with..."
@@ -959,7 +960,7 @@
 
 #: config.py:1359 config.py:1361
 msgid "Metadata values valid for this type of column."
-msgstr "Metadatawaarden geldig voor deze soort van kolom."
+msgstr "Metagegevenswaarden geldig voor deze soort van kolom."
 
 #: config.py:1364 config.py:1488
 msgid "New Only"
@@ -1022,7 +1023,7 @@
 "the book is downloaded or updated.<br/>The metadata from this column can "
 "later be used to update custom columns without having to request the "
 "metadata from the server again.<br/>(Long Text columns only.)"
-msgstr "Indien ingesteld, zal FanFicFare een kopie van alle metadata opslaan 
in deze kolom wanneer het boek wordt gedownload of bijgewerkt. <br/>De 
metagegevens uit deze kolom kunnen later worden gebruikt om aangepaste kolommen 
bij te werken zonder opnieuw de metagegevens van de server op te vragen.<br/> 
(alleen kolommen.)"
+msgstr "Indien ingesteld, zal FanFicFare een kopie van alle metagegevens 
opslaan in deze kolom wanneer het boek wordt gedownload of bijgewerkt. <br/>De 
metagegevens uit deze kolom kunnen later worden gebruikt om aangepaste kolommen 
bij te werken zonder opnieuw de metagegevens van de server op te vragen.<br/> 
(alleen kolommen.)"
 
 #: config.py:1430
 msgid "Last Checked Column:"
@@ -1279,13 +1280,13 @@
 
 #: dialogs.py:324 dialogs.py:877
 msgid "Update Calibre &Metadata?"
-msgstr "Calibre &Metadata bijwerken?"
+msgstr "Calibre &Metagegevens bijwerken?"
 
 #: dialogs.py:325 dialogs.py:878
 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 "Metadata voor bestaande verhalen in Calibre bijwerken van website? 
(Kolommen ingesteld als 'Alleen Nieuw' in de kolomtabbladen worden alleen 
ingesteld voor nieuwe boeken.)"
+msgstr "Metagegevens voor bestaande verhalen in Calibre bijwerken van website? 
(Kolommen ingesteld als 'Alleen Nieuw' in de kolomtabbladen worden alleen 
ingesteld voor nieuwe boeken.)"
 
 #: dialogs.py:331 dialogs.py:882
 msgid "Update EPUB Cover?"
@@ -1390,15 +1391,15 @@
 
 #: dialogs.py:619 dialogs.py:643 fff_plugin.py:975
 msgid "Fetching metadata for stories..."
-msgstr "Bezig met ophalen van metadata voor verhalen..."
+msgstr "Bezig met ophalen van metagegevens voor verhalen..."
 
 #: dialogs.py:620 dialogs.py:644 fff_plugin.py:976
 msgid "Downloading metadata for stories"
-msgstr "Bezig met downloaden van metadata voor verhalen"
+msgstr "Bezig met downloaden van metagegevens voor verhalen"
 
 #: dialogs.py:621 dialogs.py:645 fff_plugin.py:977
 msgid "Fetched metadata for"
-msgstr "Metadata opgehaald voor"
+msgstr "Metagegevens opgehaald voor"
 
 #: dialogs.py:675
 msgid " - %s estimated until done"
@@ -1467,7 +1468,7 @@
 
 #: dialogs.py:887
 msgid "Background Metadata?"
-msgstr "Achtergrond metadata?"
+msgstr "Achtergrond metagegevens?"
 
 #: dialogs.py:888
 msgid ""
@@ -1475,7 +1476,7 @@
 "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 "Verzamel metadata van sites in een achtergrondproces. <br />Dit geeft 
u sneller controle terug tijdens het bijwerken, maar u wordt niet gevraagd om 
gebruikersnaam / wachtwoorden of als u een volwassene bent zullen verhalen die 
dit nodig hebben, gewoon falen"
+msgstr "Verzamel metagegevens van sites in een achtergrondproces. <br />Dit 
geeft u sneller controle terug tijdens het bijwerken, maar u wordt niet 
gevraagd om gebruikersnaam / wachtwoorden of als u een volwassene bent zullen 
verhalen die dit nodig hebben, gewoon falen"
 
 #: dialogs.py:953 fff_plugin.py:1501 fff_plugin.py:1710 fff_plugin.py:1733
 msgid "Comment"
@@ -2044,7 +2045,7 @@
 
 #: fff_plugin.py:1334
 msgid "Metadata collected."
-msgstr "Metadata verzameld."
+msgstr "Metagegevens verzameld."
 
 #: fff_plugin.py:1354 jobs.py:284
 msgid ""
@@ -2094,13 +2095,13 @@
 
 #: fff_plugin.py:1584
 msgid "Error Updating Metadata"
-msgstr "Fout tijdens metadata bijwerken"
+msgstr "Fout tijdens metagegevens bijwerken"
 
 #: fff_plugin.py:1585
 msgid ""
 "An error has occurred while FanFicFare was updating calibre's metadata for "
 "<a href='%s'>%s</a>."
-msgstr "Er is een fout opgetreden terwijl FanFicFare de metadata van calibre 
aan het bijwerken was<a href='%s'>%s</a>."
+msgstr "Er is een fout opgetreden terwijl FanFicFare de metagegevens van 
calibre aan het bijwerken was<a href='%s'>%s</a>."
 
 #: fff_plugin.py:1586
 msgid "The ebook has been updated, but the metadata has not."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/FanFicFare-3.10.5/fanficfare/adapters/base_adapter.py 
new/FanFicFare-3.11.0/fanficfare/adapters/base_adapter.py
--- old/FanFicFare-3.10.5/fanficfare/adapters/base_adapter.py   2019-07-30 
16:06:56.000000000 +0200
+++ new/FanFicFare-3.11.0/fanficfare/adapters/base_adapter.py   2019-09-04 
16:44:56.000000000 +0200
@@ -154,8 +154,16 @@
         ## Normalize chapter urls, both from list and passed in, but
         ## don't save them that way to match previous behavior.
         if self.ignore_chapter_url_list == None:
-            self.ignore_chapter_url_list = [ self.normalize_chapterurl(u) for 
u in self.getConfig('ignore_chapter_url_list').splitlines() ]
-        if self.normalize_chapterurl(url) not in self.ignore_chapter_url_list:
+            self.ignore_chapter_url_list = {}
+            for u in self.getConfig('ignore_chapter_url_list').splitlines():
+                self.ignore_chapter_url_list[self.normalize_chapterurl(u)] = 
True
+
+        normal_chap_url = self.normalize_chapterurl(url)
+        if normal_chap_url not in self.ignore_chapter_url_list:
+            if self.getConfig('dedup_chapter_list',False):
+                # leverage ignore list to implement dedup'ing
+                self.ignore_chapter_url_list[normal_chap_url] = True
+
             meta = defaultdict(unicode,othermeta) # copy othermeta
             if title:
                 title = stripHTML(title,remove_all_entities=False)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/FanFicFare-3.10.5/fanficfare/adapters/base_xenforo2forum_adapter.py 
new/FanFicFare-3.11.0/fanficfare/adapters/base_xenforo2forum_adapter.py
--- old/FanFicFare-3.10.5/fanficfare/adapters/base_xenforo2forum_adapter.py     
2019-07-30 16:06:56.000000000 +0200
+++ new/FanFicFare-3.11.0/fanficfare/adapters/base_xenforo2forum_adapter.py     
2019-09-04 16:44:56.000000000 +0200
@@ -37,7 +37,6 @@
 class BaseXenForo2ForumAdapter(BaseXenForoForumAdapter):
 
     def __init__(self, config, url):
-        logger.info("init url: "+url)
         BaseXenForoForumAdapter.__init__(self, config, url)
 
     @classmethod
@@ -45,9 +44,14 @@
         "Only needs to be overriden if has additional ini sections."
         return super(BaseXenForo2ForumAdapter, cls).getConfigSections() + 
['base_xenforo2forum']
 
-    def performLogin(self):
+    def performLogin(self,data):
         params = {}
 
+        if data and "Log in" not in data:
+            ## already logged in.
+            logger.debug("Already Logged In")
+            return
+
         if self.password:
             params['login'] = self.username
             params['password'] = self.password
@@ -77,7 +81,7 @@
         d = self._postUrl(loginUrl, params)# , headers={ 
'referer':self.getURLPrefix() + '/login',
                                            #            
'origin':self.getURLPrefix() })
 
-        if "Log In" in d:
+        if "Log in" in d:
             # logger.debug(d)
             logger.info("Failed to login to URL %s as %s" % (self.url,
                                                              params['login']))
@@ -98,6 +102,44 @@
         self.story.setMetadata('title',stripHTML(h1))
         # logger.debug(stripHTML(h1))
 
+    def set_threadmarks_metadata(self,useurl,topsoup):
+        header = topsoup.find('div',{'class':'threadmarkListingHeader'})
+        if header:
+            # logger.debug(header)
+            desc = self.get_post_body(header)
+            if desc:
+                self.story.setMetadata("threadmarks_description",desc)
+                if self.getConfig('use_threadmarks_description'):
+                    self.setDescription(useurl,desc)
+            # logger.debug(desc)
+            title = header.find('h1',{'class':'threadmarkListingHeader-name'})
+            if title:
+                self.story.setMetadata("threadmarks_title",stripHTML(title))
+            statusdt = header.find('dt',text="Index progress")
+            if statusdt:
+                statusdd = statusdt.find_next_sibling('dd')
+                if statusdd:
+                    threadmarks_status = stripHTML(statusdd)
+                    
self.story.setMetadata("threadmarks_status",threadmarks_status)
+                    if self.getConfig('use_threadmarks_status'):
+                        if 'Complete' in threadmarks_status:
+                            self.story.setMetadata('status','Completed')
+                        elif 'Incomplete' in threadmarks_status:
+                            self.story.setMetadata('status','In-Progress')
+                        else:
+                            self.story.setMetadata('status',threadmarks_status)
+            if self.getConfig('use_threadmarks_cover'):
+                cover = 
header.find('span',{'class':'threadmarkListingHeader-icon'})
+                # logger.debug(cover)
+                if cover:
+                    img = cover.find('img')
+                    if img:
+                        src = img['src']
+                        if img.has_attr('srcset'):
+                            src = img['srcset']
+                        self.setCoverImage(useurl,src)
+        return
+
     def get_forumtags(self,topsoup):
         return 
topsoup.find('div',{'class':'p-description'}).findAll('a',{'class':'tagItem'})
 
@@ -105,7 +147,9 @@
         a = 
souptag.find('section',{'class':'message-user'}).find('a',{'class':'username'})
         # logger.debug(a)
         self.story.addToList('authorId',a['href'].split('/')[-2])
-        authorUrl = a['href'] # self.getURLPrefix()+'/'+a['href']
+        authorUrl = a['href']
+        if not authorUrl.startswith('http'):
+            authorUrl = self.getURLPrefix()+authorUrl
         self.story.addToList('authorUrl',authorUrl)
         self.story.addToList('author',a.text)
 
@@ -186,7 +230,7 @@
             # not paying any attention to TZ issues.
             return datetime.fromtimestamp(float(datetag['data-time']))
         except:
-            logger.warn('No date found in %s'%parenttag,exc_info=True)
+            # logger.warn('No date found in %s'%parenttag,exc_info=True)
             return None
 
     def make_reader_url(self,tmcat_num,reader_page_num):
@@ -204,3 +248,12 @@
         ## as XF1.
         for tag in soup.find_all('div', class_="bbCodeBlock-expandContent"):
             tag.name='blockquote'
+
+    def get_last_page_url(self,topsoup):
+        ## <ul class="pageNav-main">
+        ul = topsoup.find('ul',{'class':'pageNav-main'})
+        # logger.debug(ul)
+        lastpage = ul.find_all('a',href=re.compile(r'page-'))[-1]
+        # logger.debug(lastpage)
+        # doing make_soup will also cache posts from that last page.
+        return lastpage['href']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/FanFicFare-3.10.5/fanficfare/adapters/base_xenforoforum_adapter.py 
new/FanFicFare-3.11.0/fanficfare/adapters/base_xenforoforum_adapter.py
--- old/FanFicFare-3.10.5/fanficfare/adapters/base_xenforoforum_adapter.py      
2019-07-30 16:06:56.000000000 +0200
+++ new/FanFicFare-3.11.0/fanficfare/adapters/base_xenforoforum_adapter.py      
2019-09-04 16:44:56.000000000 +0200
@@ -185,9 +185,14 @@
         '''
         return True
 
-    def performLogin(self):
+    def performLogin(self,data):
         params = {}
 
+        if data and "Log Out" in data:
+            ## already logged in.
+            logger.debug("Already Logged In")
+            return
+
         if self.password:
             params['login'] = self.username
             params['password'] = self.password
@@ -211,6 +216,7 @@
         d = self._fetchUrl(loginUrl, params)
 
         if "Log Out" not in d:
+            logger.debug(d)
             logger.info("Failed to login to URL %s as %s" % (self.url,
                                                              params['login']))
             raise exceptions.FailedToLogin(self.url,params['login'])
@@ -232,6 +238,9 @@
         for noscript in soup.find_all('noscript'):
             noscript.extract()
 
+        for iframe in soup.find_all('iframe'):
+            iframe.extract() # calibre book reader & editor don't like iframes 
to youtube.
+
         for qdiv in self.get_quote_expand_tag(soup):
             qdiv.extract() # Remove <div class="...">click to expand</div>
 
@@ -378,9 +387,35 @@
                 tmcat_index += 1
         return threadmarks
 
+
+    def get_last_page_url(self,topsoup):
+        span = topsoup.find('span',{'class':'pageNavHeader'})
+        # logger.debug(span)
+        # span class="pageNavHeader" - not present if no pages
+        # first <nav>?
+        # last not class=text?
+        nav = span.find_next('nav')
+        # logger.debug(nav)
+        lastpage = nav.find_all('a',href=re.compile(r'page-'))[-2]
+        # logger.debug(lastpage)
+        return lastpage['href']
+
+    ## Aug 2019 - SB doesn't send update emails for threads it doesn't
+    ## think you've seen all of since the last email anymore.  Fetch
+    ## the last page of the thread to reset it.  This requires login
+    ## to already have been done.
+    def fetch_last_page(self,topsoup):
+        logger.debug("Perform fetch_last_page")
+        try:
+            # doing make_soup will also cache posts from that last page.
+            
self.make_soup(self._fetchUrl(self.getURLPrefix()+'/'+self.get_last_page_url(topsoup)))
+        except:
+            logger.info("fetch_last_page failed, continuing")
+
     ## Getting the chapter list and the meta data, plus 'is adult' checking.
     def extractChapterUrlsAndMetadata(self):
 
+        data = topsoup = souptag = None
         useurl = self.url
         logger.info("url: "+useurl)
 
@@ -388,10 +423,16 @@
             (data,opened) = self._fetchUrlOpened(useurl)
             useurl = opened.geturl()
             logger.info("use useurl: "+useurl)
+            # can't login before initial fetch--need a cookie.
+            if self.getConfig('always_login',False) or 
self.getConfig('fetch_last_page',False):
+                self.performLogin(data)
+                (data,opened) = self._fetchUrlOpened(useurl)
+                useurl = opened.geturl()
+                logger.info("use useurl: "+useurl)
         except HTTPError as e:
             # QQ gives 403, SV at least gives 404.  Which unfortunately
             if e.code == 403 or self.getConfig('always_login',False):
-                self.performLogin()
+                self.performLogin(data)
                 (data,opened) = self._fetchUrlOpened(useurl)
                 useurl = opened.geturl()
                 logger.info("use useurl: "+useurl)
@@ -399,12 +440,17 @@
                 raise exceptions.StoryDoesNotExist(self.url)
             else:
                 raise
-        if '#' not in useurl and '/posts/' not in useurl:
-            self._setURL(useurl) ## for when threadmarked thread name changes.
 
         # use BeautifulSoup HTML parser to make everything easier to find.
         topsoup = souptag = self.make_soup(data)
 
+        if '#' not in useurl and '/posts/' not in useurl:
+            self._setURL(useurl) ## for when threadmarked thread name changes.
+
+            # only apply fetch_last_page when not a post url.
+            if self.getConfig('fetch_last_page',False):
+                self.fetch_last_page(topsoup)
+
         self.parse_title(topsoup)
 
         first_post_title = self.getConfig('first_post_title','First Post')
@@ -466,6 +512,9 @@
                     self.story.setMetadata('numWords',words)
             souptag = self.get_first_post(topsoup)
 
+        if use_threadmark_chaps:
+            self.set_threadmarks_metadata(useurl,topsoup)
+
         if use_threadmark_chaps or self.getConfig('always_use_forumtags'):
             ## only use tags if threadmarks for chapters or 
always_use_forumtags is on.
             for tag in self.get_forumtags(topsoup):
@@ -493,13 +542,8 @@
         # using threadmarks.
         index_post = self.get_post_body(souptag)
 
-        for iframe in index_post.find_all('iframe'):
-            iframe.extract() # calibre book reader & editor don't like iframes 
to youtube.
-
-        for qdiv in index_post.find_all('div',{'class':'quoteExpand'}):
-            qdiv.extract() # Remove <div class="quoteExpand">click to 
expand</div>
-
-        self.setDescription(useurl,index_post)
+        if not self.story.getMetadata('description'):
+            self.setDescription(useurl,index_post)
 
         # otherwise, use first post links--include first post since
         # that's often also the first chapter.
@@ -539,6 +583,10 @@
             tag.extract()
         self.story.setMetadata('title',stripHTML(h1))
 
+    def set_threadmarks_metadata(self,useurl,topsoup):
+        # None in XF1.
+        return
+
     def get_forumtags(self,topsoup):
         return topsoup.findAll('a',{'class':'tag'}) + 
topsoup.findAll('span',{'class':'prefix'})
 
@@ -671,9 +719,6 @@
 
         postbody = self.get_post_body(souptag)
 
-        for iframe in postbody.find_all('iframe'):
-            iframe.extract() # calibre book reader & editor don't like iframes 
to youtube.
-
         # XenForo uses <base href="https://forums.spacebattles.com/"; />
         return self.utf8FromSoup(self.getURLPrefix()+'/',postbody)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/FanFicFare-3.10.5/fanficfare/cli.py 
new/FanFicFare-3.11.0/fanficfare/cli.py
--- old/FanFicFare-3.10.5/fanficfare/cli.py     2019-07-30 16:06:56.000000000 
+0200
+++ new/FanFicFare-3.11.0/fanficfare/cli.py     2019-09-04 16:44:56.000000000 
+0200
@@ -39,7 +39,7 @@
     def pickle_load(f):
         return pickle.load(f,encoding="bytes")
 
-version="3.10.5"
+version="3.11.0"
 os.environ['CURRENT_VERSION_ID']=version
 
 global_cache = 'global_cache'
@@ -457,7 +457,9 @@
                     metadata = adapter.story.getAllMetadata()
                 
call(string.Template(adapter.getConfig('pre_process_cmd')).substitute(metadata),
 shell=True)
 
-                write_story(configuration, adapter, 'epub')
+                output_filename = write_story(configuration, adapter, 'epub')
+                logger.debug("Successfully wrote '%s'"%output_filename)
+
 
         else:
             if not options.metaonly and adapter.getConfig('pre_process_cmd'):
@@ -468,6 +470,7 @@
                 
call(string.Template(adapter.getConfig('pre_process_cmd')).substitute(metadata),
 shell=True)
 
             output_filename = write_story(configuration, adapter, 
options.format, options.metaonly)
+            logger.debug("Successfully wrote '%s'"%output_filename)
 
             if options.metaonly and not options.jsonmeta:
                 metadata = adapter.getStoryMetadataOnly().getAllMetadata()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/FanFicFare-3.10.5/fanficfare/configurable.py 
new/FanFicFare-3.11.0/fanficfare/configurable.py
--- old/FanFicFare-3.10.5/fanficfare/configurable.py    2019-07-30 
16:06:56.000000000 +0200
+++ new/FanFicFare-3.11.0/fanficfare/configurable.py    2019-09-04 
16:44:56.000000000 +0200
@@ -171,9 +171,11 @@
                  ])
 
 boollist=['true','false']
-base_xenforo_list=['base_xenforoforum',
-                   'forums.spacebattles.com',
+base_xenforo2_list=['base_xenforo2forum',
                    'forums.sufficientvelocity.com',
+                   ]
+base_xenforo_list=base_xenforo2_list+['base_xenforoforum',
+                   'forums.spacebattles.com',
                    'forum.questionablequesting.com',
                    'www.alternatehistory.com',
                    ]
@@ -212,6 +214,7 @@
                'use_ssl_unverified_context':(None,None,boollist),
                'continue_on_chapter_error':(None,None,boollist),
                'conditionals_use_lists':(None,None,boollist),
+               'dedup_chapter_list':(None,None,boollist),
 
                'add_chapter_numbers':(None,None,boollist+['toconly']),
 
@@ -279,6 +282,10 @@
                
'replace_failed_smilies_with_alt_text':(base_xenforo_list,None,boollist),
                'use_threadmark_wordcounts':(base_xenforo_list,None,boollist),
                
'always_include_first_post_chapters':(base_xenforo_list,None,boollist),
+               'fetch_last_page':(base_xenforo_list,None,boollist),
+               
'use_threadmarks_description':(base_xenforo2_list,None,boollist),
+               'use_threadmarks_status':(base_xenforo2_list,None,boollist),
+               'use_threadmarks_cover':(base_xenforo2_list,None,boollist),
                'fix_pseudo_html': (['webnovel.com'], None, boollist),
                'fix_excess_space': (['novelonlinefull.com', 'novelall.com'], 
['epub', 'html'], boollist)
                }
@@ -488,10 +495,15 @@
                  'replace_failed_smilies_with_alt_text',
                  'use_threadmark_wordcounts',
                  'always_include_first_post_chapters',
+                 'use_threadmarks_description',
+                 'use_threadmarks_status',
+                 'use_threadmarks_cover',
                  'datethreadmark_format',
+                 'fetch_last_page',
                  'fix_pseudo_html',
                  'fix_excess_space',
                  'ignore_chapter_url_list',
+                 'dedup_chapter_list',
                  'max_zalgo',
                  ])
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/FanFicFare-3.10.5/fanficfare/defaults.ini 
new/FanFicFare-3.11.0/fanficfare/defaults.ini
--- old/FanFicFare-3.10.5/fanficfare/defaults.ini       2019-07-30 
16:06:56.000000000 +0200
+++ new/FanFicFare-3.11.0/fanficfare/defaults.ini       2019-09-04 
16:44:56.000000000 +0200
@@ -319,6 +319,10 @@
 # https://forums.spacebattles.com/posts/10157299/
 # 
https://forums.spacebattles.com/threads/lengthy-thread-name.100849/#post-10157400
 
+## Rarely, some stories on some sites (observed on SpaceBattles) might
+## have the same chapter URL listed more than once.  Set true for
+## those stories.
+#dedup_chapter_list:false
 
 ## Some readers don't show horizontal rule (<hr />) tags correctly.
 ## This replaces them all with a centered '* * *'.  (Note centering
@@ -783,7 +787,36 @@
 # .bbCodeSpoilerContainer { border: 1px solid black; padding: 2px; }
 
 [base_xenforo2forum]
-## So far, only SV. [base_xenforoforum] also applied.
+## [base_xenforoforum] also applied, but [base_xenforo2forum] takes
+## precedence.  SV is the only XF2 site as of Jul 2019.
+
+## Some additional 'thread' metadata entries.
+add_to_extra_valid_entries:,threadmarks_title,threadmarks_description,threadmarks_status
+#add_to_extra_titlepage_entries:,threadmarks_title,threadmarks_description,threadmarks_status
+
+# Just to remove '_'.
+threadmarks_title_label:Threadmarks Title
+threadmarks_description_label:Threadmarks Description
+threadmarks_status_label:Threadmarks Status
+
+## When use_threadmarks_description is set true,
+## threadmarks_description will be used to fill in the standard
+## description metadata entry.  Some stories have poor
+## threadmarks_description, you can use this setting to avoid using
+## it.
+use_threadmarks_description:true
+## Increasing description_limit from base_xenforoforum's default of
+## 500 is also useful with use_threadmarks_description
+description_limit:1000
+
+## When use_threadmarks_status is set true, a normalized version of
+## threadmarks_status will be used to fill in the standard status
+## metadata entry. (In-Progress, Completed plus site statuses.)
+use_threadmarks_status:true
+
+## When use_threadmarks_cover is set true, the threadmarks image will
+## be used to fill in the cover image.  Set true by default.
+use_threadmarks_cover:true
 
 [epub]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/FanFicFare-3.10.5/setup.py 
new/FanFicFare-3.11.0/setup.py
--- old/FanFicFare-3.10.5/setup.py      2019-07-30 16:06:56.000000000 +0200
+++ new/FanFicFare-3.11.0/setup.py      2019-09-04 16:44:56.000000000 +0200
@@ -27,7 +27,7 @@
     name=package_name,
 
     # Versions should comply with PEP440.
-    version="3.10.5",
+    version="3.11.0",
 
     description='A tool for downloading fanfiction to eBook formats',
     long_description=long_description,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/FanFicFare-3.10.5/webservice/app.yaml 
new/FanFicFare-3.11.0/webservice/app.yaml
--- old/FanFicFare-3.10.5/webservice/app.yaml   2019-07-30 16:06:56.000000000 
+0200
+++ new/FanFicFare-3.11.0/webservice/app.yaml   2019-09-04 16:44:56.000000000 
+0200
@@ -1,6 +1,6 @@
 # ffd-retief-hrd fanficfare
 application: fanficfare
-version: 3-10-5
+version: 3-11-0
 runtime: python27
 api_version: 1
 threadsafe: true


Reply via email to