mirror of
https://github.com/JimmXinu/FanFicFare.git
synced 2026-05-08 12:36:11 +02:00
Merge branch 'master' of https://github.com/JimmXinu/FanFicFare
This commit is contained in:
commit
c1465af849
2 changed files with 53 additions and 5 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -17,6 +17,9 @@
|
|||
*.back
|
||||
*.bak
|
||||
|
||||
# pycharm project specific settings files
|
||||
.idea
|
||||
|
||||
cleanup.sh
|
||||
FanFictionDownLoader.zip
|
||||
*.epub
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
# music / audio embeds
|
||||
# per-user achivement tracking with fancy achievement-get animations
|
||||
# story scripting (shows script tags visible in the text, not computed values or input fields)
|
||||
# multiroute stories (won't download them at all)
|
||||
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
|
@ -87,9 +86,15 @@ class FictionLiveAdapter(BaseSiteAdapter):
|
|||
|
||||
data = json.loads(response)
|
||||
|
||||
# I have no idea how you'd make this work in a book.
|
||||
## get metadata for multi route chapters
|
||||
if 'multiRoute' in data and data['multiRoute'] == True:
|
||||
raise NotImplementedError("Multiple-route fiction.live stories are not supported.")
|
||||
route_metadata_url = "https://fiction.live/api/anonkun/routes/{s_id}/"
|
||||
response = self._fetchUrl(route_metadata_url.format(s_id = self.story_id))
|
||||
|
||||
if not response: # this is how fiction.live responds to nonsense urls -- HTTP200 with empty response
|
||||
raise exceptions.StoryDoesNotExist("Empty response for " + self.url)
|
||||
|
||||
data["route_metadata"] = json.loads(response)
|
||||
|
||||
self.extract_metadata(data, get_cover)
|
||||
self.add_chapters(data)
|
||||
|
|
@ -172,20 +177,38 @@ class FictionLiveAdapter(BaseSiteAdapter):
|
|||
## chapter urls are for the api. they return json and aren't user-navigatable, or the same as on the website
|
||||
chunkrange_url = "https://fiction.live/api/anonkun/chapters/{s_id}/{start}/{end}/"
|
||||
|
||||
## api url to get content of a multi route chapter. requires only the route id and no timestamps
|
||||
route_chunkrange_url = "https://fiction.live/api/anonkun/route/{c_id}/chapters"
|
||||
|
||||
def add_chapter_url(title, start, end):
|
||||
"Adds a chapter url based on the start/end chunk-range timestamps."
|
||||
chapter_url = chunkrange_url.format(s_id = data['_id'], start = start, end = end)
|
||||
self.add_chapter(title, chapter_url)
|
||||
|
||||
def add_route_chapter_url(title, route_id):
|
||||
"Adds a route chapter url based on the route id."
|
||||
chapter_url = route_chunkrange_url.format(c_id = route_id)
|
||||
self.add_chapter(title, chapter_url)
|
||||
|
||||
### chapter addition loop. bit complex, as both first and last chapters have special handling
|
||||
|
||||
## first thing to do is seperate out the appendices
|
||||
appendices, maintext = [], []
|
||||
chapters = data['bm'] if 'bm' in data else [{"title": "Home", "ct": data['ct']}]
|
||||
appendices, maintext, routes = [], [], []
|
||||
chapters = data['bm'] if 'bm' in data else [{"title": "Home", "ct": data['ct']}]
|
||||
|
||||
for c in chapters:
|
||||
appendices.append(c) if c['title'].startswith('#special') else maintext.append(c)
|
||||
|
||||
## not all stories use multiple routes. Those that do have a route id and a title for each route
|
||||
if 'route_metadata' in data and data['route_metadata']:
|
||||
for r in data['route_metadata']:
|
||||
# checking if route title even exists or is None, since most things in the api are optional
|
||||
if 't' in r and r['t'] is not None:
|
||||
title = r['t']
|
||||
else:
|
||||
title = ""
|
||||
routes.append({{"id": r['_id'], "title": title}})
|
||||
|
||||
# loop setup
|
||||
chapter_iter = iter(maintext)
|
||||
first_chapter = next(chapter_iter)
|
||||
|
|
@ -214,6 +237,11 @@ class FictionLiveAdapter(BaseSiteAdapter):
|
|||
chapter_title = "Appendix: " + a['title'][9:] # 'Appendix: ' rather than '#special' at beginning of name
|
||||
add_chapter_url(chapter_title, chapter_start, chapter_start + 1) # 1 msec range = this one chunk only
|
||||
|
||||
for r in routes: # add route at the end, after appendices
|
||||
route_id = r['id'] # to get route chapter content, the route id is needed, not the timestamp
|
||||
chapter_title = "Route: " + r['title'] # 'Route: ' at beginning of name, since it's a multiroute chapter
|
||||
add_route_chapter_url(chapter_title, route_id)
|
||||
|
||||
def getChapterText(self, url):
|
||||
|
||||
chunk_handler = {
|
||||
|
|
@ -349,6 +377,23 @@ class FictionLiveAdapter(BaseSiteAdapter):
|
|||
total_votes = counter(chunk['votes'] if 'votes' in chunk else {})
|
||||
verified_votes = counter(chunk['userVotes'] if 'userVotes' in chunk else {})
|
||||
|
||||
# Choices can link to route chapters, where the index of the choice in list 'choices' is a key in the
|
||||
# 'routes' dict and the dict value is the route id.
|
||||
# That route id is needed for the url to create the internal link from the choice to the route chapter.
|
||||
routes = chunk['routes'] if 'routes' in chunk else {}
|
||||
if choices and len(routes) > 0:
|
||||
altered_choices = []
|
||||
for i, choice in enumerate(choices):
|
||||
choice_index = str(i)
|
||||
if choice_index in routes.keys():
|
||||
route_chunkrange_url = "https://fiction.live/api/anonkun/route/{c_id}/chapters"
|
||||
route_url = route_chunkrange_url.format(c_id=routes[choice_index])
|
||||
choice_link = "<a data-orighref='" + route_url + "' >" + choice + "</a>"
|
||||
altered_choices.append(choice_link)
|
||||
else:
|
||||
altered_choices.append(choice)
|
||||
choices = altered_choices
|
||||
|
||||
return zip(choices, verified_votes, total_votes)
|
||||
|
||||
def format_choice(self, chunk):
|
||||
|
|
|
|||
Loading…
Reference in a new issue