mirror of
https://github.com/wassname/FanFicFare.git
synced 2026-09-16 11:47:12 +08:00
Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83db111ba7 | ||
|
|
2eb8c27c80 | ||
|
|
a79066750c | ||
|
|
3857a6a89b | ||
|
|
016d4af149 | ||
|
|
a4e499866e | ||
|
|
5736f4f181 | ||
|
|
e04453d73f | ||
|
|
c3778502dc | ||
|
|
925b12e776 | ||
|
|
62ed503d10 | ||
|
|
7e35d0b710 | ||
|
|
20c7e7f075 | ||
|
|
9f61cff7cd | ||
|
|
cb5587b0c7 | ||
|
|
f2a74c9ffc | ||
|
|
eb0f013550 |
@@ -1,6 +1,6 @@
|
||||
# ffd-retief-hrd fanfictiondownloader
|
||||
application: fanfictiondownloader
|
||||
version: 4-4-68
|
||||
version: 4-4-71
|
||||
runtime: python27
|
||||
api_version: 1
|
||||
threadsafe: true
|
||||
|
||||
@@ -26,7 +26,7 @@ class FanFictionDownLoaderBase(InterfaceActionBase):
|
||||
description = 'UI plugin to download FanFiction stories from various sites.'
|
||||
supported_platforms = ['windows', 'osx', 'linux']
|
||||
author = 'Jim Miller'
|
||||
version = (1, 7, 39)
|
||||
version = (1, 7, 42)
|
||||
minimum_calibre_version = (0, 8, 57)
|
||||
|
||||
#: This field defines the GUI plugin class that contains all the code
|
||||
|
||||
@@ -1530,8 +1530,8 @@ class FanFictionDownLoaderPlugin(InterfaceAction):
|
||||
# Moved down so author's already in the DB.
|
||||
if 'authorUrl' in book['all_metadata']:
|
||||
authurls = book['all_metadata']['authorUrl'].split(", ")
|
||||
authorlist = [ a.replace('&',';') for a in book['author'] ]
|
||||
if hasattr(db, 'new_api'): # new_api starts in calibre 1.0.0
|
||||
authorlist = [ a.replace('&',';') for a in book['author'] ]
|
||||
authorids = db.new_api.get_item_ids('authors',authorlist)
|
||||
authordata = db.new_api.author_data(authorids.values())
|
||||
# print("\n\nauthorids:%s"%authorids)
|
||||
|
||||
+23
-5
@@ -16,7 +16,22 @@
|
||||
[defaults]
|
||||
|
||||
## [defaults] section applies to all formats and sites but may be
|
||||
## overridden at several levels
|
||||
## overridden at several levels. Example:
|
||||
|
||||
## [defaults]
|
||||
## titlepage_entries: category,genre, status
|
||||
## [www.whofic.com]
|
||||
## # overrides defaults.
|
||||
## titlepage_entries: category,genre, status,dateUpdated,rating
|
||||
## [epub]
|
||||
## # overrides defaults & site section
|
||||
## titlepage_entries: category,genre, status,datePublished,dateUpdated,dateCreated
|
||||
## [www.whofic.com:epub]
|
||||
## # overrides defaults, site section & format section
|
||||
## titlepage_entries: category,genre, status,datePublished
|
||||
## [overrides]
|
||||
## # overrides all other sections
|
||||
## titlepage_entries: category
|
||||
|
||||
## Some sites also require the user to confirm they are adult for
|
||||
## adult content. Uncomment by removing '#' in front of is_adult.
|
||||
@@ -262,6 +277,8 @@ sort_ships:false
|
||||
## you added calibre_author: keep_in_order_calibre_author:true
|
||||
#keep_in_order_author:true
|
||||
|
||||
## User-agent
|
||||
#user_agent:FFDL/1.7
|
||||
|
||||
## Each output format has a section that overrides [defaults]
|
||||
[html]
|
||||
@@ -450,8 +467,8 @@ nook_img_fix:true
|
||||
## mobi TOC cannot be turned off right now.
|
||||
#include_tocpage: true
|
||||
|
||||
## Each site has a section that overrides [defaults] *and* the format
|
||||
## sections test1.com specifically is not a real story site. Instead,
|
||||
## Each site has a section that overrides [defaults].
|
||||
## test1.com specifically is not a real story site. Instead,
|
||||
## it is a fake site for testing configuration and output. It uses
|
||||
## URLs like: http://test1.com?sid=12345
|
||||
[test1.com]
|
||||
@@ -508,7 +525,8 @@ extratags: FanFiction,Testing,HTML
|
||||
#is_adult:true
|
||||
|
||||
## AO3 adapter defines a few extra metadata entries.
|
||||
extra_valid_entries:fandoms,freeformtags,freefromtags,ao3categories,comments,kudos,hits,bookmarks,collections
|
||||
## If there's ever more than 4 series, add series04,series04Url etc.
|
||||
extra_valid_entries:fandoms,freeformtags,freefromtags,ao3categories,comments,kudos,hits,bookmarks,collections,series00,series01,series02,series03,series00Url,series01Url,series02Url,series03Url
|
||||
fandoms_label:Fandoms
|
||||
freeformtags_label:Freeform Tags
|
||||
freefromtags_label:Freeform Tags
|
||||
@@ -524,7 +542,7 @@ bookmarks_label:Bookmarks
|
||||
include_in_freefromtags:freeformtags
|
||||
|
||||
## adds to titlepage_entries instead of replacing it.
|
||||
#extra_titlepage_entries: fandoms,freeformtags,ao3categories,comments,kudos,hits,bookmarks
|
||||
#extra_titlepage_entries: fandoms,freeformtags,ao3categories,comments,kudos,hits,bookmarks,series00,series01,series02,series03,series00Url,series01Url,series02Url,series03Url
|
||||
|
||||
## adds to include_subject_tags instead of replacing it.
|
||||
#extra_subject_tags:fandoms,freeformtags,ao3categories
|
||||
|
||||
@@ -210,10 +210,7 @@ class ArchiveOfOurOwnOrgAdapter(BaseSiteAdapter):
|
||||
if a != None:
|
||||
warnings = a.findAll('a',{'class':"tag"})
|
||||
for warning in warnings:
|
||||
if warning.string == "Author Chose Not To Use Archive Warnings":
|
||||
warning.string = "No Archive Warnings Apply"
|
||||
if warning.string != "No Archive Warnings Apply":
|
||||
self.story.addToList('warnings',warning.string)
|
||||
self.story.addToList('warnings',warning.string)
|
||||
|
||||
a = metasoup.find('dd',{'class':"freeform tags"})
|
||||
if a != None:
|
||||
@@ -288,19 +285,19 @@ class ArchiveOfOurOwnOrgAdapter(BaseSiteAdapter):
|
||||
self.story.setMetadata('dateUpdated', makeDate(stripHTML(value), self.dateformat))
|
||||
|
||||
|
||||
try:
|
||||
# Find Series name from series URL.
|
||||
a = metasoup.find('dd',{'class':"series"})
|
||||
b = a.find('a', href=re.compile(r"/series/\d+"))
|
||||
series_name = b.string
|
||||
series_url = 'http://'+self.host+b['href']
|
||||
series_index = int(a.text.split(' ')[1])
|
||||
self.setSeries(series_name, series_index)
|
||||
self.story.setMetadata('seriesUrl',series_url)
|
||||
|
||||
except:
|
||||
# I find it hard to care if the series parsing fails
|
||||
pass
|
||||
# Find Series name from series URL.
|
||||
ddseries = metasoup.find('dd',{'class':"series"})
|
||||
|
||||
if ddseries:
|
||||
for i, a in enumerate(ddseries.findAll('a', href=re.compile(r"/series/\d+"))):
|
||||
series_name = stripHTML(a)
|
||||
series_url = 'http://'+self.host+a['href']
|
||||
series_index = int(stripHTML(a.previousSibling).replace(', ','').split(' ')[1]) # "Part # of" or ", Part #"
|
||||
self.story.setMetadata('series%02d'%i,"%s [%s]"%(series_name,series_index))
|
||||
self.story.setMetadata('series%02dUrl'%i,series_url)
|
||||
if i == 0:
|
||||
self.setSeries(series_name, series_index)
|
||||
self.story.setMetadata('seriesUrl',series_url)
|
||||
|
||||
# grab the text for an individual chapter.
|
||||
def getChapterText(self, url):
|
||||
|
||||
@@ -199,7 +199,7 @@ class FanFictionNetSiteAdapter(BaseSiteAdapter):
|
||||
for g in genrelist:
|
||||
#logger.debug("g:(%s)"%g)
|
||||
if g.strip() not in ffnetgenres:
|
||||
logger.info("g not in ffnetgenres")
|
||||
#logger.info("g not in ffnetgenres")
|
||||
goodgenres=False
|
||||
if goodgenres:
|
||||
self.story.extendList('genre',genrelist)
|
||||
@@ -266,11 +266,11 @@ class FanFictionNetSiteAdapter(BaseSiteAdapter):
|
||||
return
|
||||
|
||||
def getChapterText(self, url):
|
||||
logger.debug('Getting chapter text from: %s' % url)
|
||||
time.sleep(0.5) ## ffnet(and, I assume, fpcom) tends to fail
|
||||
time.sleep(5.0) ## ffnet(and, I assume, fpcom) tends to fail
|
||||
## more if hit too fast. This is in
|
||||
## additional to what ever the
|
||||
## slow_down_sleep_time setting is.
|
||||
logger.debug('Getting chapter text from: %s' % url)
|
||||
data = self._fetchUrl(url)
|
||||
|
||||
if "Please email this error message in full to <a href='mailto:support@fanfiction.com'>support@fanfiction.com</a>" in data:
|
||||
|
||||
@@ -131,55 +131,55 @@ class HarryPotterFanFictionComSiteAdapter(BaseSiteAdapter):
|
||||
|
||||
## Finding the metadata is a bit of a pain. Most of the meta
|
||||
## data is in a center.table without a bgcolor.
|
||||
for center in soup.findAll('center'):
|
||||
table = center.find('table',{'bgcolor':None})
|
||||
if table:
|
||||
metastr = stripHTML(str(table)).replace('\n',' ').replace('\t',' ')
|
||||
# Rating: 12+ Story Reviews: 3
|
||||
# Chapters: 3
|
||||
# Characters: Andromeda, Ted, Bellatrix, R. Lestrange, Lucius, Narcissa, OC
|
||||
# Genre(s): Fluff, Romance, Young Adult Era: OtherPairings: Other Pairing, Lucius/Narcissa
|
||||
# Status: Completed
|
||||
# First Published: 2010.09.02
|
||||
# Last Published Chapter: 2010.09.28
|
||||
# Last Updated: 2010.09.28
|
||||
# Favorite Story Of: 1 users
|
||||
# Warnings: Scenes of a Mild Sexual Nature
|
||||
#for center in soup.findAll('center'):
|
||||
table = soup.find('table',{'class':'storymaininfo'})
|
||||
if table:
|
||||
metastr = stripHTML(str(table)).replace('\n',' ').replace('\t',' ')
|
||||
# Rating: 12+ Story Reviews: 3
|
||||
# Chapters: 3
|
||||
# Characters: Andromeda, Ted, Bellatrix, R. Lestrange, Lucius, Narcissa, OC
|
||||
# Genre(s): Fluff, Romance, Young Adult Era: OtherPairings: Other Pairing, Lucius/Narcissa
|
||||
# Status: Completed
|
||||
# First Published: 2010.09.02
|
||||
# Last Published Chapter: 2010.09.28
|
||||
# Last Updated: 2010.09.28
|
||||
# Favorite Story Of: 1 users
|
||||
# Warnings: Scenes of a Mild Sexual Nature
|
||||
|
||||
m = re.match(r".*?Status: Completed.*?",metastr)
|
||||
if m:
|
||||
self.story.setMetadata('status','Completed')
|
||||
else:
|
||||
self.story.setMetadata('status','In-Progress')
|
||||
m = re.match(r".*?Status: Completed.*?",metastr)
|
||||
if m:
|
||||
self.story.setMetadata('status','Completed')
|
||||
else:
|
||||
self.story.setMetadata('status','In-Progress')
|
||||
|
||||
m = re.match(r".*?Rating: (.+?) Story Reviews.*?",metastr)
|
||||
if m:
|
||||
self.story.setMetadata('rating', m.group(1))
|
||||
m = re.match(r".*?Rating: (.+?) Story Reviews.*?",metastr)
|
||||
if m:
|
||||
self.story.setMetadata('rating', m.group(1))
|
||||
|
||||
m = re.match(r".*?Genre\(s\): (.+?) Era.*?",metastr)
|
||||
if m:
|
||||
for g in m.group(1).split(','):
|
||||
self.story.addToList('genre',g)
|
||||
|
||||
m = re.match(r".*?Characters: (.+?) Genre.*?",metastr)
|
||||
if m:
|
||||
for g in m.group(1).split(','):
|
||||
self.story.addToList('characters',g)
|
||||
|
||||
m = re.match(r".*?Warnings: (.+).*?",metastr)
|
||||
if m:
|
||||
for w in m.group(1).split(','):
|
||||
if w != 'Now Warnings':
|
||||
self.story.addToList('warnings',w)
|
||||
|
||||
m = re.match(r".*?First Published: ([0-9\.]+).*?",metastr)
|
||||
if m:
|
||||
self.story.setMetadata('datePublished',makeDate(m.group(1), "%Y.%m.%d"))
|
||||
m = re.match(r".*?Genre\(s\): (.+?) Era.*?",metastr)
|
||||
if m:
|
||||
for g in m.group(1).split(','):
|
||||
self.story.addToList('genre',g)
|
||||
|
||||
m = re.match(r".*?Characters: (.+?) Genre.*?",metastr)
|
||||
if m:
|
||||
for g in m.group(1).split(','):
|
||||
self.story.addToList('characters',g)
|
||||
|
||||
m = re.match(r".*?Warnings: (.+).*?",metastr)
|
||||
if m:
|
||||
for w in m.group(1).split(','):
|
||||
if w != 'Now Warnings':
|
||||
self.story.addToList('warnings',w)
|
||||
|
||||
m = re.match(r".*?First Published: ([0-9\.]+).*?",metastr)
|
||||
if m:
|
||||
self.story.setMetadata('datePublished',makeDate(m.group(1), "%Y.%m.%d"))
|
||||
|
||||
# Updated can have more than one space after it. <shrug>
|
||||
m = re.match(r".*?Last Updated: ([0-9\.]+).*?",metastr)
|
||||
if m:
|
||||
self.story.setMetadata('dateUpdated',makeDate(m.group(1), "%Y.%m.%d"))
|
||||
# Updated can have more than one space after it. <shrug>
|
||||
m = re.match(r".*?Last Updated: ([0-9\.]+).*?",metastr)
|
||||
if m:
|
||||
self.story.setMetadata('dateUpdated',makeDate(m.group(1), "%Y.%m.%d"))
|
||||
|
||||
def getChapterText(self, url):
|
||||
|
||||
|
||||
@@ -37,11 +37,6 @@ class HPFanficArchiveComAdapter(BaseSiteAdapter):
|
||||
def __init__(self, config, url):
|
||||
BaseSiteAdapter.__init__(self, config, url)
|
||||
|
||||
# hpfanficarchive.com blocks the default user-agent. However,
|
||||
# when asked, they said it was just general anti-spam, not
|
||||
# targeted at us. That lets me do this in good conscience:
|
||||
self.opener.addheaders = [('User-agent', 'FFDL/1.7')]
|
||||
|
||||
self.decode = ["Windows-1252",
|
||||
"utf8"] # 1252 is a superset of iso-8859-1.
|
||||
# Most sites that claim to be
|
||||
|
||||
@@ -37,11 +37,6 @@ class NCISFictionNetAdapter(BaseSiteAdapter):
|
||||
def __init__(self, config, url):
|
||||
BaseSiteAdapter.__init__(self, config, url)
|
||||
|
||||
# ncisfiction.net blocks the default user-agent. However,
|
||||
# when asked, they said it was just general anti-spam, not
|
||||
# targeted at us. That lets me do this in good conscience:
|
||||
self.opener.addheaders = [('User-agent', 'FFDL/1.7')]
|
||||
|
||||
self.decode = ["iso-8859-1",
|
||||
"Windows-1252"] # 1252 is a superset of iso-8859-1.
|
||||
# Most sites that claim to be
|
||||
|
||||
@@ -77,6 +77,8 @@ class BaseSiteAdapter(Configurable):
|
||||
self.is_adult=False
|
||||
|
||||
self.opener = u2.build_opener(u2.HTTPCookieProcessor(),GZipProcessor())
|
||||
## Specific UA because too many sites are blocking the default python UA.
|
||||
self.opener.addheaders = [('User-agent', self.getConfig('user_agent'))]
|
||||
self.storyDone = False
|
||||
self.metadataDone = False
|
||||
self.story = Story(configuration)
|
||||
|
||||
+15
-2
@@ -53,13 +53,26 @@
|
||||
<p>Hi, {{ nickname }}! This is FanFictionDownLoader, which makes reading stories from various websites
|
||||
much easier. </p>
|
||||
</div>
|
||||
<!-- put announcements here, h3 is a good title size. -->
|
||||
<!-- put announcements here, h3 is a good title size.
|
||||
<h3>Changes:</h3>
|
||||
<p>
|
||||
<ul>
|
||||
<li>Minor optimizations.</li>
|
||||
<li>Better doc section override order in ini files.</li>
|
||||
<li>Additional series as site specific data for AO3.</li>
|
||||
<li>Fix for AO3 stories without series.</li>
|
||||
<li>Fixes for changes to harrypotterfanfictioncom.</li>
|
||||
<li>Add User-agent="FFDL/1.7" for all adapters for fanfiction.net changes.<br>
|
||||
(Remove from specific adapters.)</li>
|
||||
</ul>
|
||||
</p>
|
||||
-->
|
||||
<h3>fanfiction.net</h3>
|
||||
<p>
|
||||
Fanfiction.net appears to be blocking access from Google
|
||||
App Engine IPs, which prevents this web service. There's
|
||||
nothing I can do about it. At the time of writing, the
|
||||
latest CLI and calibre plugin versions worked.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Questions? Check out our
|
||||
|
||||
+24
-5
@@ -16,7 +16,22 @@
|
||||
[defaults]
|
||||
|
||||
## [defaults] section applies to all formats and sites but may be
|
||||
## overridden at several levels
|
||||
## overridden at several levels. Example:
|
||||
|
||||
## [defaults]
|
||||
## titlepage_entries: category,genre, status
|
||||
## [www.whofic.com]
|
||||
## # overrides defaults.
|
||||
## titlepage_entries: category,genre, status,dateUpdated,rating
|
||||
## [epub]
|
||||
## # overrides defaults & site section
|
||||
## titlepage_entries: category,genre, status,datePublished,dateUpdated,dateCreated
|
||||
## [www.whofic.com:epub]
|
||||
## # overrides defaults, site section & format section
|
||||
## titlepage_entries: category,genre, status,datePublished
|
||||
## [overrides]
|
||||
## # overrides all other sections
|
||||
## titlepage_entries: category
|
||||
|
||||
## Some sites also require the user to confirm they are adult for
|
||||
## adult content. Uncomment by removing '#' in front of is_adult.
|
||||
@@ -249,6 +264,9 @@ sort_ships:false
|
||||
## you added calibre_author: keep_in_order_calibre_author:true
|
||||
#keep_in_order_author:true
|
||||
|
||||
## User-agent
|
||||
#user_agent:FFDL/1.7
|
||||
|
||||
|
||||
## Each output format has a section that overrides [defaults]
|
||||
[html]
|
||||
@@ -419,8 +437,8 @@ nook_img_fix:true
|
||||
## mobi TOC cannot be turned off right now.
|
||||
#include_tocpage: true
|
||||
|
||||
## Each site has a section that overrides [defaults] *and* the format
|
||||
## sections test1.com specifically is not a real story site. Instead,
|
||||
## Each site has a section that overrides [defaults].
|
||||
## test1.com specifically is not a real story site. Instead,
|
||||
## it is a fake site for testing configuration and output. It uses
|
||||
## URLs like: http://test1.com?sid=12345
|
||||
[test1.com]
|
||||
@@ -477,7 +495,8 @@ extratags: FanFiction,Testing,HTML
|
||||
#is_adult:true
|
||||
|
||||
## AO3 adapter defines a few extra metadata entries.
|
||||
extra_valid_entries:fandoms,freeformtags,freefromtags,ao3categories,comments,kudos,hits,bookmarks,collections
|
||||
## If there's ever more than 4 series, add series04,series04Url etc.
|
||||
extra_valid_entries:fandoms,freeformtags,freefromtags,ao3categories,comments,kudos,hits,bookmarks,collections,series00,series01,series02,series03,series00Url,series01Url,series02Url,series03Url
|
||||
fandoms_label:Fandoms
|
||||
freeformtags_label:Freeform Tags
|
||||
freefromtags_label:Freeform Tags
|
||||
@@ -493,7 +512,7 @@ bookmarks_label:Bookmarks
|
||||
include_in_freefromtags:freeformtags
|
||||
|
||||
## adds to titlepage_entries instead of replacing it.
|
||||
#extra_titlepage_entries: fandoms,freeformtags,ao3categories,comments,kudos,hits,bookmarks
|
||||
#extra_titlepage_entries: fandoms,freeformtags,ao3categories,comments,kudos,hits,bookmarks,series00,series01,series02,series03,series00Url,series01Url,series02Url,series03Url
|
||||
|
||||
## adds to include_subject_tags instead of replacing it.
|
||||
#extra_subject_tags:fandoms,freeformtags,ao3categories
|
||||
|
||||
@@ -2,6 +2,24 @@
|
||||
## like. Uncomment options by removing the '#' in front of them.
|
||||
|
||||
[defaults]
|
||||
## [defaults] section applies to all formats and sites but may be
|
||||
## overridden at several levels. Example:
|
||||
|
||||
## [defaults]
|
||||
## titlepage_entries: category,genre, status
|
||||
## [www.whofic.com]
|
||||
## # overrides defaults.
|
||||
## titlepage_entries: category,genre, status,dateUpdated,rating
|
||||
## [epub]
|
||||
## # overrides defaults & site section
|
||||
## titlepage_entries: category,genre, status,datePublished,dateUpdated,dateCreated
|
||||
## [www.whofic.com:epub]
|
||||
## # overrides defaults, site section & format section
|
||||
## titlepage_entries: category,genre, status,datePublished
|
||||
## [overrides]
|
||||
## # overrides all other sections
|
||||
## titlepage_entries: category
|
||||
|
||||
## Some sites also require the user to confirm they are adult for
|
||||
## adult content. Uncomment by removing '#' in front of is_adult.
|
||||
#is_adult:true
|
||||
|
||||
Reference in New Issue
Block a user