Compare commits

...
12 changed files with 1953 additions and 59 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# ffd-retief-hrd fanfictiondownloader
application: fanfictiondownloader
version: 4-4-89
version: 4-4-90
runtime: python27
api_version: 1
threadsafe: true
+1 -1
View File
@@ -42,7 +42,7 @@ class FanFictionDownLoaderBase(InterfaceActionBase):
description = _('UI plugin to download FanFiction stories from various sites.')
supported_platforms = ['windows', 'osx', 'linux']
author = 'Jim Miller'
version = (1, 8, 06)
version = (1, 8, 07)
minimum_calibre_version = (1, 13, 0)
#: This field defines the GUI plugin class that contains all the code
+8 -7
View File
@@ -1393,7 +1393,10 @@ class FanFictionDownLoaderPlugin(InterfaceAction):
if prefs['mark'] or (prefs['errorcol'] != '' and prefs['errorcol'] in custom_columns):
self.previous = self.gui.library_view.currentIndex() # used by update_books_finish.
self.gui.status_bar.show_message(_('Adding/Updating %s BAD books.')%len(book_list))
label = custom_columns[prefs['errorcol']]['label']
if (prefs['errorcol'] != '' and prefs['errorcol'] in custom_columns):
label = custom_columns[prefs['errorcol']]['label']
else:
label = None
LoopProgressDialog(self.gui,
book_list,
partial(self.update_error_column_loop, db=self.gui.current_db, label=label),
@@ -1402,12 +1405,10 @@ class FanFictionDownLoaderPlugin(InterfaceAction):
win_title=_("Update calibre for BAD FanFiction stories"),
status_prefix=_("Updated"))
def update_error_column_loop(self,book,db=None,label='errorcol'):
if book['calibre_id']:
custom_columns = self.gui.library_view.model().custom_columns
if (prefs['errorcol'] != '' and prefs['errorcol'] in custom_columns):
logger.debug("add/update bad %s %s %s"%(book['title'],book['url'],book['comment']))
db.set_custom(book['calibre_id'], book['comment'], label=label, commit=True)
def update_error_column_loop(self,book,db=None,label=None):
if book['calibre_id'] and label:
logger.debug("add/update bad %s %s %s"%(book['title'],book['url'],book['comment']))
db.set_custom(book['calibre_id'], book['comment'], label=label, commit=True)
def add_book_or_update_format(self,book,options,prefs,mi=None):
db = self.gui.current_db
File diff suppressed because it is too large Load Diff
+14 -2
View File
@@ -817,12 +817,24 @@ dislikes_label:Dislikes
## Clear FanFiction from defaults, site is original fiction.
extratags:
extra_valid_entries:size,universe,codes
#extra_titlepage_entries:size,universe,codes
extra_valid_entries:size,universe,universeUrl,universeHTML,codes,notice
#extra_titlepage_entries:size,universeHTML,codes,notice
size_label:Size
universe_label:Universe
universeUrl_label:Universe URL
universeHTML_label:Universe
codes_label:Codes
notice_label:Notice
## Assume entryUrl, apply to "<a class='%slink' href='%s'>%s</a>" to
## make entryHTML.
make_linkhtml_entries:universe
## storiesonline.net stories can be in a series or a universe, but not
## both. By default, universe will be populated in 'series' with
## index=0
universe_as_series: true
[grangerenchanted.com]
## Some sites require login (or login for some rated stories) The
Binary file not shown.
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright 2012 Fanficdownloader team
# Copyright 2013 Fanficdownloader team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -37,11 +37,6 @@ class FineStoriesComAdapter(BaseSiteAdapter):
def __init__(self, config, url):
BaseSiteAdapter.__init__(self, config, url)
self.decode = ["Windows-1252",
"utf8"] # 1252 is a superset of iso-8859-1.
# Most sites that claim to be
# iso-8859-1 (and some that claim to be
# utf8) are really windows-1252.
self.username = "NoneGiven" # if left empty, site doesn't return any message at all.
self.password = ""
self.is_adult=False
@@ -51,7 +46,6 @@ class FineStoriesComAdapter(BaseSiteAdapter):
if 'storyInfo' in self.story.getMetadata('storyId'):
self.story.setMetadata('storyId',self.parsedUrl.query.split('=',)[1])
# normalized story URL.
self._setURL('http://' + self.getSiteDomain() + '/s/storyInfo.php?id='+self.story.getMetadata('storyId'))
@@ -128,23 +128,22 @@ class HPFanficArchiveComAdapter(BaseSiteAdapter):
# <span class="label">Rated:</span> NC-17<br /> etc
labels = soup.findAll('span',{'class':'label'})
for labelspan in labels:
value = labelspan.nextSibling
val = labelspan.nextSibling
value = unicode('')
while val and not defaultGetattr(val,'class') == 'label':
value += unicode(val)
val = val.nextSibling
label = labelspan.string
#print("label:%s\nvalue:%s"%(label,value))
if 'Summary' in label:
## Everything until the next span class='label'
svalue = ""
while not defaultGetattr(value,'class') == 'label':
svalue += str(value)
value = value.nextSibling
self.setDescription(url,svalue)
#self.story.setMetadata('description',stripHTML(svalue))
self.setDescription(url,value)
if 'Rated' in label:
self.story.setMetadata('rating', value)
self.story.setMetadata('rating', stripHTML(value))
if 'Word count' in label:
self.story.setMetadata('numWords', value)
self.story.setMetadata('numWords', stripHTML(value))
if 'Categories' in label:
cats = labelspan.parent.findAll('a',href=re.compile(r'browse.php\?type=categories'))
@@ -167,7 +166,7 @@ class HPFanficArchiveComAdapter(BaseSiteAdapter):
self.story.addToList('warnings',warning.string)
if 'Completed' in label:
if 'Yes' in value:
if 'Yes' in stripHTML(value):
self.story.setMetadata('status', 'Completed')
else:
self.story.setMetadata('status', 'In-Progress')
@@ -37,11 +37,6 @@ class StoriesOnlineNetAdapter(BaseSiteAdapter):
def __init__(self, config, url):
BaseSiteAdapter.__init__(self, config, url)
self.decode = ["Windows-1252",
"utf8"] # 1252 is a superset of iso-8859-1.
# Most sites that claim to be
# iso-8859-1 (and some that claim to be
# utf8) are really windows-1252.
self.username = "NoneGiven" # if left empty, site doesn't return any message at all.
self.password = ""
self.is_adult=False
@@ -147,6 +142,10 @@ class StoriesOnlineNetAdapter(BaseSiteAdapter):
a = soup.find('h1')
self.story.setMetadata('title',stripHTML(a))
notice = soup.find('div', {'class' : 'notice'})
if notice:
self.story.setMetadata('notice',unicode(notice))
# Find authorid and URL from... author url.
a = soup.find('a', href=re.compile(r"/a/\w+"))
self.story.setMetadata('authorId',a['href'].split('/')[2])
@@ -185,23 +184,74 @@ class StoriesOnlineNetAdapter(BaseSiteAdapter):
self.story.setMetadata('size', lc2.findNext('td', {'class' : 'num'}).text)
lc4 = lc2.findNext('td', {'class' : 'lc4'})
desc = lc4.contents[0]
try:
a = lc4.find('a', href=re.compile(r"/library/show_series.php\?id=\d+"))
i = a.parent.text.split('(')[1].split(')')[0]
self.setSeries(stripHTML(a), i)
self.story.setMetadata('seriesUrl','http://'+self.host+a['href'])
if a:
# if there's a number after the series name, series_contents is a two element list:
# [<a href="...">Title</a>, u' (2)']
series_contents = a.parent.contents
i = 0 if len(series_contents) == 1 else series_contents[1].strip(' ()')
seriesUrl = 'http://'+self.host+a['href']
self.story.setMetadata('seriesUrl',seriesUrl)
series_name = stripHTML(a)
logger.debug("Series name= %s" % series_name)
series_soup = bs.BeautifulSoup(self._fetchUrl(seriesUrl))
if series_soup:
logger.debug("Retrieving Series - looking for name")
series_name = series_soup.find('span', {'id' : 'ptitle'}).text.partition('')[0]
logger.debug("Series name: '{0}'".format(series_name))
self.setSeries(series_name, i)
desc = lc4.contents[2]
# Check if series is in a universe
universes_soup = bs.BeautifulSoup(self._fetchUrl(self.story.getMetadata('authorUrl') + "&type=uni"))
# logger.debug("Universe page=", universes_soup)
if universes_soup:
universes = universes_soup.findAll('div', {'class' : 'ser-box'})
logger.debug("Number of Universes: %d" % len(universes))
for universe in universes:
logger.debug("universe.find('a')={0}".format(universe.find('a')))
# The universe id is in an "a" tag that has an id but nothing else. It is the first tag.
# The id is prefixed with the letter "u".
universe_id = universe.find('a')['id'][1:]
logger.debug("universe_id='%s'" % universe_id)
universe_name = universe.find('div', {'class' : 'ser-name'}).text.partition(' ')[2]
logger.debug("universe_name='%s'" % universe_name)
# If there is link to the story, we have the right universe
story_a = universe.find('a', {'href' : '/s/'+self.story.getMetadata('storyId')})
if story_a:
logger.debug("Story is in a series that is in a universe! The universe is '%s'" % universe_name)
self.story.setMetadata("universe", universe_name)
self.story.setMetadata('universeUrl','http://'+self.host+ '/library/universe.php?id=' + universe_id)
break
except:
pass
try:
a = lc4.find('a', href=re.compile(r"/library/universe.php\?id=\d+"))
if a:
self.story.setMetadata("universe",stripHTML(a))
desc = lc4.contents[2]
# Assumed only one universe, but it does have a URL--use universeHTML
universe_name = stripHTML(a)
universeUrl = 'http://'+self.host+a['href']
logger.debug("Retrieving Universe - about to get page")
universe_soup = bs.BeautifulSoup(self._fetchUrl(universeUrl))
logger.debug("Retrieving Universe - have page")
if universe_soup:
logger.debug("Retrieving Universe - looking for name")
universe_name = universe_soup.find('span', {'id' : 'ptitle'}).text.partition(' &mdash;')[0]
logger.debug("Universes name: '{0}'".format(universe_name))
self.story.setMetadata('universeUrl',universeUrl)
logger.debug("Setting universe name: '{0}'".format(universe_name))
self.story.setMetadata('universe',universe_name)
if self.getConfig("universe_as_series"):
self.setSeries(universe_name, 0)
self.story.setMetadata('seriesUrl',universeUrl)
except:
pass
desc = lc4.contents[0]
self.setDescription('http://'+self.host+'/s/'+self.story.getMetadata('storyId'),desc)
for b in lc4.findAll('b'):
+7 -10
View File
@@ -48,13 +48,9 @@
<h3>fanfiction.net / fimfiction.net</h3>
<p>
Fanfiction.net appears to be blocking access from Google
App Engine, 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>It appears that FimFiction.net is also blocking access from Google
App Engine now.
As of Jan 13, 2014, fanfiction.net &amp; fimfiction.net
are working again. I'd ask that users limit the number of
stories they download from those sites, thanks.
</p>
{% if authorized %}
@@ -68,8 +64,9 @@
<h3>Changes:</h3>
<p>
<ul>
<li>Alternate URL efiction.trekiverse.org for trekiverse.org/efiction/</li>
<li>Minor fixes</li>
<li>Change default encoding for finestories.com.</li>
<li>Change default encoding and improve metadata for storiesonline.net, thanks davidfor.</li>
<li>Fixes for hpfanficarchive.com changes.</li>
</ul>
</p>
@@ -81,7 +78,7 @@
If you have any problems with this application, please
report them in
the <a href="http://groups.google.com/group/fanfic-downloader">FanFictionDownLoader Google Group</a>. The
<a href="http://4-4-86.fanfictiondownloader.appspot.com">Previous Version</a> is also available for you to use if necessary.
<a href="http://4-4-89.fanfictiondownloader.appspot.com">Previous Version</a> is also available for you to use if necessary.
</p>
<div id='error'>
{{ error_message }}
+14 -2
View File
@@ -802,12 +802,24 @@ dislikes_label:Dislikes
## Clear FanFiction from defaults, site is original fiction.
extratags:
extra_valid_entries:size,universe,codes
#extra_titlepage_entries:size,universe,codes
extra_valid_entries:size,universe,universeUrl,universeHTML,codes,notice
#extra_titlepage_entries:size,universeHTML,codes,notice
size_label:Size
universe_label:Universe
universeUrl_label:Universe URL
universeHTML_label:Universe
codes_label:Codes
notice_label:Notice
## Assume entryUrl, apply to "<a class='%slink' href='%s'>%s</a>" to
## make entryHTML.
make_linkhtml_entries:universe
## storiesonline.net stories can be in a series or a universe, but not
## both. By default, universe will be populated in 'series' with
## index=0
universe_as_series: true
[grangerenchanted.com]
## Some sites require login (or login for some rated stories) The
+3 -7
View File
@@ -53,13 +53,9 @@
{% if fic.failure %}
<h3>fanfiction.net / fimfiction.net</h3>
<p>
FYI, fanfiction.net appears to be blocking access from Google
App Engine, 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>It appears that FimFiction.net is also blocking access from Google
App Engine now.
As of Jan 13, 2014, fanfiction.net &amp; fimfiction.net
are working again. I'd ask that users limit the number of
stories they download from those sites, thanks.
</p>
<span id='error'>{{ fic.failure }}</span>
{% endif %}