mirror of
https://github.com/wassname/FanFicFare.git
synced 2026-09-16 11:47:12 +08:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17ab4a3d25 | ||
|
|
2566e434ee | ||
|
|
91f5269453 | ||
|
|
235f00a5e6 | ||
|
|
aad4a26131 | ||
|
|
f20a02a2bc | ||
|
|
1ba1da4d65 |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
@@ -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. & 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)')
|
||||
|
||||
@@ -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
-11
@@ -57,14 +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>
|
||||
<li>Don't strip lead/trail whitespace from replace_metadata, add feature \s->' ' in replace_metadata replacements.</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
@@ -75,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 }}
|
||||
@@ -599,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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user