Compare commits

...
9 changed files with 68 additions and 33 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# ffd-retief-hrd fanfictiondownloader
application: fanfictiondownloader
version: 4-4-56
version: 4-4-57
runtime: python27
api_version: 1
threadsafe: true
+1 -1
View File
@@ -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, 23)
version = (1, 7, 24)
minimum_calibre_version = (0, 8, 57)
#: This field defines the GUI plugin class that contains all the code
+16 -4
View File
@@ -53,13 +53,14 @@ class RejectUrlEntry:
matchpat=re.compile(r"^(?P<url>[^,]+)(,(?P<fullnote>(((?P<title>.+) by (?P<auth>.+?)( - (?P<note>.+))?)|.*)))?$")
def __init__(self,url_or_line,note=None,title=None,auth=None,
addreasontext=None,fromline=False):
addreasontext=None,fromline=False,book_id=None):
self.url=url_or_line
self.note=note
self.title=title
self.auth=auth
self.valid=False
self.book_id=book_id
if fromline:
mc = re.match(self.matchpat,url_or_line)
@@ -828,7 +829,9 @@ class RejectListTableWidget(QTableWidget):
def populate_table_row(self, row, rej):
self.setItem(row, 0, ReadOnlyTableWidgetItem(rej.url))
url_cell = ReadOnlyTableWidgetItem(rej.url)
url_cell.setData(Qt.UserRole, QVariant(rej.book_id))
self.setItem(row, 0, url_cell)
self.setItem(row, 1, ReadOnlyTableWidgetItem(rej.title))
self.setItem(row, 2, ReadOnlyTableWidgetItem(rej.auth))
@@ -950,10 +953,19 @@ class RejectListDialog(SizePersistedDialog):
rejectrows = []
for row in range(self.rejects_table.rowCount()):
url = unicode(self.rejects_table.item(row, 0).text()).strip()
book_id = self.rejects_table.item(row, 0).data(Qt.UserRole).toPyObject()
title = unicode(self.rejects_table.item(row, 1).text()).strip()
auth = unicode(self.rejects_table.item(row, 2).text()).strip()
note = unicode(self.rejects_table.cellWidget(row, 3).currentText()).strip()
rejectrows.append(RejectUrlEntry(url,note,title,auth,self.get_reason_text()))
rejectrows.append(RejectUrlEntry(url,note,title,auth,self.get_reason_text(),book_id=book_id))
return rejectrows
def get_reject_list_ids(self):
rejectrows = []
for row in range(self.rejects_table.rowCount()):
book_id = self.rejects_table.item(row, 0).data(Qt.UserRole).toPyObject()
if book_id:
rejectrows.append(book_id)
return rejectrows
def get_reason_text(self):
+32 -6
View File
@@ -408,12 +408,12 @@ class FanFictionDownLoaderPlugin(InterfaceAction):
def reject_list_urls_finish(self, book_list):
# construct reject list of tuples:
# (calibre_id, url, "title, authors", old reject note).
# construct reject list of objects
reject_list = [ RejectUrlEntry(x['url'],
x['oldrejnote'],
x['title'],
', '.join(x['author']))
', '.join(x['author']),
book_id=x['calibre_id'])
for x in book_list if x['good'] ]
if reject_list:
d = RejectListDialog(self.gui,reject_list,
@@ -426,7 +426,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction):
rejecturllist.add(d.get_reject_list())
if d.get_deletebooks():
self.gui.iactions['Remove Books'].delete_books()
self.gui.iactions['Remove Books'].do_library_delete(d.get_reject_list_ids())
else:
message="<p>Rejecting FFDL URLs: None of the books selected have FanFiction URLs.</p><p>Proceed to Remove?</p>"
@@ -661,6 +661,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction):
url = book['url']
print("url:%s"%url)
mi = None
if not merge: # skip reject list when merging.
if rejecturllist.check(url):
@@ -845,6 +846,28 @@ class FanFictionDownLoaderPlugin(InterfaceAction):
book['icon'] = 'edit-redo.png'
book['status'] = 'Update'
if book_id and mi: # book_id and mi only set if matched by title/author.
liburl = self.get_story_url(db,book_id)
if book['url'] != liburl:
if collision in (OVERWRITE,OVERWRITEALWAYS):
updat="overwrit"
else:
updat="updat"
if not question_dialog(self.gui, 'Change Story URL?',
'<h3>Change Story URL?</h3>'+
'<p><b>%s</b> by <b>%s</b> is already in your library with a different source URL:</p>'%
(mi.title,', '.join(mi.author))+
'<p>In library: <a href="%(liburl)s">%(liburl)s</a></p><p>New URL: <a href="%(newurl)s">%(newurl)s</a></p>'%
{'liburl':liburl,'newurl':book['url']}+
"<p>Click '<b>Yes</b>' to %se book with new URL.</p>"%updat+
"<p>Click '<b>No</b>' to skip %sing this book.</p>"%updat,
show_copy_button=False):
book['comment'] = "Update declined by user due to differing story URL(%s)"%liburl
book['good']=False
book['icon']='rotate-right.png'
book['status'] = 'Different URL'
return
if book_id != None and collision != ADDNEW:
if collision in (CALIBREONLY):
book['comment'] = 'Metadata collected.'
@@ -889,7 +912,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction):
db.copy_format_to(book_id,fileform,tmp,index_is_id=True)
print("existing epub tmp:"+tmp.name)
book['epub_for_update'] = tmp.name
if book_id != None and prefs['injectseries']:
mi = db.get_metadata(book_id,index_is_id=True)
if not book['series'] and mi.series != None:
@@ -1281,7 +1304,10 @@ class FanFictionDownLoaderPlugin(InterfaceAction):
existingepub = db.format(book_id,'EPUB',index_is_id=True, as_file=True)
epubmi = get_metadata(existingepub,'EPUB')
if epubmi.cover_data[1] is not None:
db.set_cover(book_id, epubmi.cover_data[1])
try:
db.set_cover(book_id, epubmi.cover_data[1])
except:
print("Failed to set_cover, skipping")
# set author link if found. All current adapters have authorUrl, except anonymous on AO3.
if 'authorUrl' in book['all_metadata']:
+3 -1
View File
@@ -169,6 +169,8 @@ extratags: FanFiction
## *Five* part lines. Effect only when trailing conditional key=>regexp matches
## metakey[,metakey]=>pattern=>replacement[&&conditionalkey=>regexp]
## Note that if metakey == conditionalkey the conditional is ignored.
## You can use \s in the replacement to add explicit spaces. (The config parser
## tends to discard trailing spaces.)
#replace_metadata:
# genre,category=>Sci-Fi=>SF
# Puella Magi Madoka Magica.* => Madoka
@@ -273,7 +275,7 @@ output_css:
[txt]
## Add URLs since there aren't links.
titlepage_entries: series,seriesUrl,category,genre,language,status,datePublished,dateUpdated,dateCreated,rating,warnings,numChapters,numWords,site,storyUrl, authorUrl, description
titlepage_entries: series,seriesUrl,category,genre,language,characters,ships,status,datePublished,dateUpdated,dateCreated,rating,warnings,numChapters,numWords,site,storyUrl, authorUrl, description
## Width to word wrap text output. 0 indicates no wrapping.
wrap_width: 78
@@ -139,6 +139,7 @@ Some more longer description. "I suck at summaries!" "Better than it sounds!"
self.story.addToList('characters','J. Rizzoli')
self.story.addToList('category',u'Pitch Perfect')
self.story.addToList('characters','Chloe B.')
self.story.addToList('ships','Chloe B. &amp; J. Rizzoli')
elif self.story.getMetadata('storyId') == '82':
self.story.addToList('characters','Henry (Once Upon a Time)')
self.story.addToList('category',u'Once Upon a Time (TV)')
+7 -3
View File
@@ -280,10 +280,10 @@ class Story(Configurable):
for line in replace.splitlines():
(metakeys,regexp,replacement,condkey,condregexp)=(None,None,None,None,None)
if "&&" in line:
(line,conditional) = map( lambda x: x.strip(), line.split("&&") )
(condkey,condregexp) = map( lambda x: x.strip(), conditional.split("=>") )
(line,conditional) = line.split("&&")
(condkey,condregexp) = conditional.split("=>")
if "=>" in line:
parts = map( lambda x: x.strip(), line.split("=>") )
parts = line.split("=>")
if len(parts) > 2:
metakeys = map( lambda x: x.strip(), parts[0].split(",") )
(regexp,replacement)=parts[1:]
@@ -294,6 +294,10 @@ class Story(Configurable):
regexp = re.compile(regexp)
if condregexp:
condregexp = re.compile(condregexp)
# A way to explicitly include spaces in the
# replacement string. The .ini parser eats any
# trailing spaces.
replacement=replacement.replace('\s',' ')
self.replacements.append([metakeys,regexp,replacement,condkey,condregexp])
def doReplacments(self,value,key):
+4 -16
View File
@@ -57,19 +57,7 @@
<h3>Changes:</h3>
<p>
<ul>
<li>New site: netraptor.org<li>
<li>New site: asr3.slashzone.org<li>
<li>New site: tokra.fandomnet.com<li>
<li>Remove defunct site: www.jlaunlimited.com</li>
<li>Fix author URLs for several sites with leading 'dir' in URL.</li>
<li>Fix for no chapter name for one chapter stories on TtH.</li>
<li>Improved error handling for mobi issues.</li>
<li>Add 'url' to chapter custom formats and class="skip_on_ffdl_update" for updates.</li>
<dd>
Use the URL of the story's first chapter, such as
<br /><a href="http://www.jlaunlimited.com/eFiction1.1/viewstory.php?sid=1234">http://www.jlaunlimited.com/eFiction1.1/viewstory.php?sid=1234</a>
</dd>
<li>Don't strip lead/trail whitespace from replace_metadata, add feature \s->' ' in replace_metadata replacements.</li>
</ul>
</p>
<p>
@@ -80,7 +68,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-55.fanfictiondownloader.appspot.com">Previous Version</a> is also available for you to use if necessary.
<a href="http://4-4-56.fanfictiondownloader.appspot.com">Previous Version</a> is also available for you to use if necessary.
</p>
<div id='error'>
{{ error_message }}
@@ -604,12 +592,12 @@
Use the URL of the story's chapter list, such as
<br /><a href="http://www.henneth-annun.net/stories/chapter.cfm?stid=1234">http://www.henneth-annun.net/stories/chapter.cfm?stid=1234</a>
</dd>
<dt>http://www.psychfic.com</dt>
<dt>www.psychfic.com</dt>
<dd>
Use the URL of the story's chapter list, such as
<br /><a href="http://www.psychfic.com/viewstory.php?sid=1234">http://www.psychfic.com/viewstory.php?sid=1234</a>
</dd>
<dt>http://tokra.fandomnet.com</dt>
<dt>tokra.fandomnet.com</dt>
<dd>
Use the URL of the story's chapter list, such as
<br /><a href="http://tokra.fandomnet.com/viewstory.php?sid=1234">http://tokra.fandomnet.com/viewstory.php?sid=1234</a>
+3 -1
View File
@@ -139,6 +139,8 @@ extratags: FanFiction
## *Five* part lines. Effect only when trailing conditional key=>regexp matches
## metakey[,metakey]=>pattern=>replacement[&&conditionalkey=>regexp]
## Note that if metakey == conditionalkey the conditional is ignored.
## You can use \s in the replacement to add explicit spaces. (The config parser
## tends to discard trailing spaces.)
#replace_metadata:
# genre,category=>Sci-Fi=>SF
# Puella Magi Madoka Magica.* => Madoka
@@ -257,7 +259,7 @@ output_css:
[txt]
## Add URLs since there aren't links.
titlepage_entries: series,seriesUrl,category,genre,language,status,datePublished,dateUpdated,dateCreated,rating,warnings,numChapters,numWords,site,storyUrl, authorUrl, description
titlepage_entries: series,seriesUrl,category,genre,language,characters,ships,status,datePublished,dateUpdated,dateCreated,rating,warnings,numChapters,numWords,site,storyUrl, authorUrl, description
## Width to word wrap text output. 0 indicates no wrapping.
wrap_width: 78