423 lines
27 KiB
Python
423 lines
27 KiB
Python
import datetime, os
|
|
from importlib import import_module
|
|
|
|
def classgen(string):
|
|
return string.replace(" ","").replace("#","").replace("-","").replace("ç","c").replace("’","").replace("é","e").replace("(","").replace(")","").replace(":","").lower()
|
|
|
|
def stringno(theno):
|
|
if theno < 10:
|
|
return "00" + str(theno)
|
|
elif theno < 100:
|
|
return "0" + str(theno)
|
|
else:
|
|
return str(theno)
|
|
|
|
ficcount = 999
|
|
ficlist = []
|
|
while ficcount > 0:
|
|
ficcount -= 1
|
|
ficcountstring = stringno(ficcount)
|
|
if os.path.exists("files/originalsmeta/" + ficcountstring + ".py"):
|
|
ficfile = "files.originalsmeta." + ficcountstring
|
|
fileread = import_module(ficfile)
|
|
try:
|
|
if fileread.revealdate <= datetime.datetime.now():
|
|
goahead = True
|
|
else:
|
|
goahead = False
|
|
except:
|
|
goahead = True
|
|
if goahead == True:
|
|
ficdict = {}
|
|
ficdict["id"] = ficcount
|
|
if fileread.showtitle:
|
|
ficdict["title"] = fileread.title
|
|
if fileread.language == "fr":
|
|
ficdict["french"] = "original"
|
|
else:
|
|
ficdict["french"] = False
|
|
sumwords = 0
|
|
for instalment in fileread.datewords:
|
|
sumwords = sumwords + instalment["words"]
|
|
ficdict["totalwords"] = sumwords
|
|
ficdict["startdate"] = fileread.datewords[0]["date"]
|
|
ficdict["latestdate"] = fileread.datewords[-1]["date"]
|
|
try:
|
|
ficdict["approxdate"] = fileread.approxdate
|
|
except:
|
|
pass
|
|
if len(fileread.datewords) > 1:
|
|
ficdict["chaptered"] = True
|
|
else:
|
|
ficdict["chaptered"] = False
|
|
try:
|
|
ficdict["completion"] = fileread.status
|
|
except:
|
|
ficdict["completion"] = "complete"
|
|
ficdict["fandoms"] = []
|
|
for fandom in fileread.fandom:
|
|
if fandom == "FF15":
|
|
ficdict["fandoms"].append("Final Fantasy XV")
|
|
elif fandom == "FF16":
|
|
ficdict["fandoms"].append("Final Fantasy XVI")
|
|
elif fandom == "FF4":
|
|
ficdict["fandoms"].append("Final Fantasy IV")
|
|
elif fandom == "FF6":
|
|
ficdict["fandoms"].append("Final Fantasy VI")
|
|
elif fandom == "FF7":
|
|
ficdict["fandoms"].append("Final Fantasy VII")
|
|
elif fandom == "FF8":
|
|
ficdict["fandoms"].append("Final Fantasy VIII")
|
|
elif fandom == "FF9":
|
|
ficdict["fandoms"].append("Final Fantasy IX")
|
|
elif fandom == "FFX":
|
|
ficdict["fandoms"].append("Final Fantasy X")
|
|
elif fandom == "LOTR":
|
|
ficdict["fandoms"].append("Lord Of The Rings")
|
|
else:
|
|
ficdict["fandoms"].append(fandom)
|
|
ficlist.append(ficdict)
|
|
ficdict["charmain"] = []
|
|
try:
|
|
for character in fileread.charpov:
|
|
ficdict["charmain"].append(character)
|
|
except:
|
|
pass
|
|
try:
|
|
for character in fileread.charmain:
|
|
ficdict["charmain"].append(character)
|
|
except:
|
|
pass
|
|
ficdict["charsec"] = []
|
|
try:
|
|
for character in fileread.charsecondary:
|
|
ficdict["charsec"].append(character)
|
|
except:
|
|
pass
|
|
try:
|
|
ficdict["ships"] = []
|
|
for ship in fileread.ship:
|
|
if ship != None:
|
|
ficdict["ships"].append(ship.replace("/"," × "))
|
|
except:
|
|
pass
|
|
if fileread.genre[0] == "slash" or fileread.genre[0] == "bl" or fileread.genre[0] == "yaoi":
|
|
ficdict["type"] = "BL"
|
|
elif fileread.genre[0] == "femslash" or fileread.genre[0] == "gl" or fileread.genre[0] == "yuri":
|
|
ficdict["type"] = "GL"
|
|
elif fileread.genre[0] == "het":
|
|
ficdict["type"] = "hetero"
|
|
else:
|
|
ficdict["type"] = "gen"
|
|
try:
|
|
if len(fileread.genre) > 1 and fileread.genre[1] != "slash":
|
|
ficdict["genre"] = fileread.genre[1]
|
|
else:
|
|
if fileread.time == "pre-canon" or fileread.time == "mid-canon" or fileread.time == "post-canon" or fileread.time == "AU":
|
|
ficdict["genre"] = fileread.time
|
|
except:
|
|
pass
|
|
try:
|
|
ficdict["summary"] = fileread.summary
|
|
except:
|
|
pass
|
|
try:
|
|
ficdict["event"] = fileread.eventname
|
|
ficdict["eventtype"] = fileread.event
|
|
except:
|
|
pass
|
|
try:
|
|
ficdict["prompt"] = fileread.prompt
|
|
except:
|
|
ficdict["prompt"] = False
|
|
if fileread.locked:
|
|
ficdict["locked"] = True
|
|
else:
|
|
ficdict["locked"] = False
|
|
if fileread.epub:
|
|
ficdict["epub"] = True
|
|
else:
|
|
ficdict["epub"] = False
|
|
if fileread.pdf:
|
|
ficdict["pdf"] = True
|
|
else:
|
|
ficdict["pdf"] = False
|
|
try:
|
|
transid = stringno(fileread.translation)
|
|
if os.path.exists("files/translationsmeta/" + transid + ".py"):
|
|
transfile = "files.translationsmeta." + transid
|
|
transread = import_module(transfile)
|
|
ficdict["transid"] = int(transid)
|
|
if transread.showtitle:
|
|
ficdict["transtitle"] = transread.title
|
|
if transread.language == "fr":
|
|
ficdict["french"] = "translation"
|
|
transwords = 0
|
|
for instalment in transread.datewords:
|
|
transwords = transwords + instalment["words"]
|
|
ficdict["transwords"] = transwords
|
|
ficdict["transstartdate"] = transread.datewords[0]["date"]
|
|
ficdict["translatestdate"] = transread.datewords[-1]["date"]
|
|
ficdict["transsummary"] = transread.summary
|
|
except:
|
|
pass
|
|
|
|
ficlist = sorted(ficlist,key=lambda d: d["latestdate"],reverse=True)
|
|
|
|
fandoms = []
|
|
challenges = []
|
|
exchanges = []
|
|
promptmemes = []
|
|
for fic in ficlist:
|
|
for fandom in fic["fandoms"]:
|
|
fandoms.append(fandom)
|
|
try:
|
|
if fic["eventtype"] == "challenge":
|
|
challenges.append(fic["event"])
|
|
elif fic["eventtype"] == "exchange" or fic["eventtype"] == "ao3exchange":
|
|
exchanges.append(fic["event"])
|
|
elif fic["eventtype"] == "prompt":
|
|
promptmemes.append(fic["event"])
|
|
except:
|
|
pass
|
|
fandoms = sorted(list(dict.fromkeys(fandoms)))
|
|
challenges = sorted(list(dict.fromkeys(challenges)))
|
|
exchanges = sorted(list(dict.fromkeys(exchanges)))
|
|
promptmemes = sorted(list(dict.fromkeys(promptmemes)))
|
|
|
|
output = open("index.html", "w")
|
|
|
|
output.write("<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>praze • Fanfiction</title>\n <meta property=\"og:title\" content=\"praze • Fanfiction\">\n <meta property=\"og:type\" content=\"website\">\n <meta property=\"og:image\" content=\"https://tre.praze.net/ab.png\">\n <meta property=\"og:url\" content=\"https://tre.praze.net/fic\">\n <meta name=\"description\" property=\"og:description\" content=\"Fanfiction on tre.praze.net\">\n <meta property=\"og:locale\" content=\"en_GB\">\n <meta property=\"og:site_name\" content=\"tre.praze.net\">\n <meta name=\"fediverse:creator\" content=\"@tre@praze.net\">\n <link rel=\"stylesheet\" href=\"/new.css\">\n <link rel=\"me\" href=\"https://kes.praze.net/@tre\">\n <link rel=\"alternate\" type=\"application/rss+xml\" title=\"tre.praze.net\" href=\"/feed.xml\">\n <meta name=\"theme-color\" content=\"#f2f2f2\" />\n <style>\n div.fic {\n margin: 20px auto;\n }\n main input:checked + label {\n text-decoration: underline;\n }\n form:has([value=\"french\"]:checked) ~ div.fic:not(.lang-french),")
|
|
|
|
for fandom in fandoms:
|
|
if fandom != "OW":
|
|
output.write("\n form:has([value=\"" + classgen(fandom) + "\"]:checked) ~ div.fic:not(.fandom-" + classgen(fandom) + "),")
|
|
|
|
for challenge in challenges:
|
|
output.write("\n form:has([value=\"" + classgen(challenge) + "\"]:checked) ~ div.fic:not(.event-" + classgen(challenge) + "),")
|
|
|
|
for exchange in exchanges:
|
|
output.write("\n form:has([value=\"" + classgen(exchange) + "\"]:checked) ~ div.fic:not(.event-" + classgen(exchange) + "),")
|
|
|
|
for promptmeme in promptmemes:
|
|
output.write("\n form:has([value=\"" + classgen(promptmeme) + "\"]:checked) ~ div.fic:not(.event-" + classgen(promptmeme) + "),")
|
|
|
|
output.write("\n form:has([value=\"unprompted\"]:checked) ~ div.fic:not(.unprompted),\n form:has([value=\"crossover\"]:checked) ~ div.fic:not(.fandom-crossover),\n form:has([value=\"ow\"]:checked) ~ div.fic:not(.fandom-ow),\n form:has([value=\"nolemons\"]:checked) ~ div.fic:has(span.lemon),\n form:has([value=\"nolimes\"]:checked) ~ div.fic:has(span.lime),\n form:has([value=\"lemonlime\"]:checked) ~ div.fic:not(:has(span.lime)),\n form:has([value=\"drabble\"]:checked) ~ div.fic:not(.format-drabble),\n form:has([value=\"drabblefam\"]:checked) ~ div.fic:not(.format-drabblefam),\n form:has([value=\"three\"]:checked) ~ div.fic:not(.format-three),\n form:has([value=\"oneshot\"]:checked) ~ div.fic:not(.format-oneshot),\n form:has([value=\"chaptered\"]:checked) ~ div.fic:not(.format-chaptered),\n form:has([value=\"unusual\"]:checked) ~ div.fic:not(.format-unusual),\n form:has([value=\"unpassword\"]:checked) ~ div.fic.locked,\n form:has([value=\"gen\"]:checked) ~ div.fic:not(:has(span.ship.gen)),\n form:has([value=\"bl\"]:checked) ~ div.fic:not(:has(span.ship.bl)),\n form:has([value=\"gl\"]:checked) ~ div.fic:not(:has(span.ship.gl)),\n form:has([value=\"hetero\"]:checked) ~ div.fic:not(:has(span.ship.hetero)) {\n display: none;\n }\n span.spoiler {\n filter: blur(5px);\n }\n span.spoiler:hover {\n filter: none;\n }\n div.fic span.warning {\n cursor: help;\n }\n span.warning.lime:not(.lemon) {\n filter: hue-rotate(70deg);\n }\n span.warning.reference, span.warning.reference.lime:not(.lemon) {\n filter: grayscale(100%);\n }\n span.warning:hover {\n filter: brightness(120%);\n }\n span.warning.lime:not(.lemon):hover {\n filter: hue-rotate(70deg) brightness(120%);\n }\n span.warning.reference:hover {\n filter: grayscale(50%);\n }\n span.warning.reference.lime:not(.lemon):hover {\n filter: hue-rotate(70deg) grayscale(50%);\n }\n span.ship {\n font-weight: bold;\n }\n span.ship:not(.gen) {\n border-bottom: 2px dotted var(--highlight-colour);\n cursor: help;\n }\n span.bl {\n color: rgb(148,187,233);\n }\n span.gl {\n color: rgb(238,174,202);\n }\n span.hetero {\n color: rgb(193,181,218)\n }\n span.minor {\n font-size: 0em;\n }\n span.minor:before {\n content: \"…\";\n font-size: 1rem;\n }\n span.minor:hover {\n font-size: 0.7rem;\n }\n span.minor:hover:before {\n content: \"\";\n }\n div#ficring {\n margin: 0 auto;\n width: fit-content;\n }\n div#ficring a {\n border: none;\n }\n </style>\n </head>\n <body>\n <nav>\n <input type=\"checkbox\" id=\"toggle\" name=\"toggle\">\n <label class=\"toggle-btn\" for=\"toggle\">Menu</label>\n <ul>\n <li>Fundamentals\n <ul>\n <li><a href=\"/\">Home</a></li>\n <li><a href=\"/about\">About + listings</a></li>\n <li><a href=\"/follow\">Follow</a></li>\n <li><a href=\"/feed.xml\">Changelog</a> <a href=\"/feed.xml\"><span class=\"rss\"></span></a></li>\n <li><a href=\"/sitemap.xml\">Sitemap</a></li>\n <li><a href=\"/siteroll\">Siteroll</a></li>\n </ul>\n </li>\n <li>Projects\n <ul>\n <li>Fanfiction <a href=\"/fic/feed.xml\"><span class=\"rss\"></span></a></li>\n <li><a href=\"/music\">Music</a></li>\n <li><a href=\"/notes\">Journal</a></li>\n <li><a href=\"/trackers\">Trackers</a></li>\n <li><a href=\"https://git.praze.net/tre\" target=\"_blank\">Code</a> <a href=\"https://git.praze.net/tre.rss\"><span class=\"rss\"></span></a></li>\n <li><a href=\"https://img.praze.net\" target=\"_blank\">Photos</a> <a href=\"https://img.praze.net/feed.php\"><span class=\"rss\"></span></a></li>\n </ul>\n </li>\n <li>Fan content\n <ul>\n <li><a href=\"/ffx\">FFX</a></li>\n <li><a href=\"/xvi\">FF16</a></li>\n <li><a href=\"https://morgan.praze.net\" target=\"_blank\">Dermot Morgan</a> <a href=\"https://morgan.praze.net/feed.xml\"><span class=\"rss\"></span></a></li>\n </ul>\n </li>\n <li>Misc.\n <ul>\n <li><a href=\"https://tcg.praze.net\" target=\"_blank\">TCG</a></li>\n <li><a href=\"https://links.praze.net\" target=\"_blank\">Bookmarks</a> <a href=\"https://links.praze.net/feed/rss\"><span class=\"rss\"></span></a></li>\n <li><a href=\"https://kes.praze.net/@tre\" target=\"_blank\">Fediverse</a> <a href=\"https://kes.praze.net/@tre/feed.rss\"><span class=\"rss\"></span></a></li>\n </ul>\n </li>\n </ul>\n </nav>\n <div>\n <main>\n <section>\n <h1>Fanfiction</h1>\n <p>I’m partway through redesigning my fic archive and plan to gradually reinstate some of the features it used to have; for now, here’s a filterable masterlist. Warnings and ratings are <b>not</b> currently implemented, browse at your own risk. Some fics will have slight inaccuracies in metadata for the time being!</p>\n <div id=\"ficring\">\n <script src=\"https://ficring.neocities.org/ring.js\"></script>\n </div>\n <form>\n <label for=\"fandoms\"><b>Fandom:</b></label>\n <select name=\"fandoms\" id=\"fandoms\">\n <option value=\"allfandoms\" selected>All</option>")
|
|
|
|
for fandom in fandoms:
|
|
if fandom != "OW":
|
|
output.write("\n <option value=\"" + classgen(fandom) + "\">" + fandom + "</option>")
|
|
|
|
output.write("\n <option value=\"crossover\">Crossovers</option>\n <option value=\"ow\">Original</option>\n </select>\n </form>\n <form>\n <label for=\"events\"><b>Written for event:</b></label>\n <select name=\"events\" id=\"events\">\n <option value=\"allevents\" selected>Any</option>\n <option value=\"unprompted\">None</option>\n <optgroup label=\"Challenges\">")
|
|
|
|
for challenge in challenges:
|
|
output.write("\n <option value=\"" + classgen(challenge) + "\">" + challenge + "</option>")
|
|
|
|
output.write("\n </optgroup>\n <optgroup label=\"Exchanges\">")
|
|
|
|
for exchange in exchanges:
|
|
output.write("\n <option value=\"" + classgen(exchange) + "\">" + exchange + "</option>")
|
|
|
|
output.write("\n </optgroup>\n <optgroup label=\"Prompt memes\">")
|
|
|
|
for promptmeme in promptmemes:
|
|
output.write("\n <option value=\"" + classgen(promptmeme) + "\">" + promptmeme + "</option>")
|
|
|
|
output.write("\n </optgroup>\n </select>\n </form>\n <form>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"alllangs\" value=\"alllangs\" checked>\n <label for=\"alllangs\"><b>All languages</b></label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"french\" value=\"french\">\n <label for=\"french\">Disponibles en français</label>\n </form>\n <!-- <form>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"allratings\" value=\"allratings\" checked>\n <label for=\"allratings\"><b>All ratings</b></label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"nolemons\" value=\"nolemons\">\n <label for=\"nolemons\">Hide sexually explicit fics</label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"nolimes\" value=\"nolimes\">\n <label for=\"nolimes\">Hide fics with any sexual content</label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"lemonlime\" value=\"lemonlime\">\n <label for=\"lemonlime\">Show only fics with sexual content</label>\n </form> -->\n <form>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"allcategories\" value=\"allcategories\" checked>\n <label for=\"allcategories\"><b>All categories</b></label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"gen\" value=\"gen\">\n <label for=\"gen\">Gen</label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"bl\" value=\"bl\">\n <label for=\"bl\"><span class=\"bl\">BL</span></label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"gl\" value=\"gl\">\n <label for=\"gl\"><span class=\"gl\">GL</span></label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"hetero\" value=\"hetero\">\n <label for=\"hetero\"><span class=\"hetero\">Hetero</span></label>\n </form>\n <form>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"allformats\" value=\"allformats\" checked>\n <label for=\"allformats\"><b>All formats</b></label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"drabble\" value=\"drabble\">\n <label for=\"drabble\">Drabbles (100 words)</label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"three\" value=\"three\">\n <label for=\"three\">Three sentence-ish</label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"drabblefam\" value=\"drabblefam\">\n <label for=\"drabblefam\">Drabble family</label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"oneshot\" value=\"oneshot\">\n <label for=\"oneshot\">Oneshots</label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"chaptered\" value=\"chaptered\">\n <label for=\"chaptered\">Chaptered fics</label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"unusual\" value=\"unusual\">\n <label for=\"unusual\">Unusual formats</label>\n </form>\n <form>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"password\" value=\"password\">\n <label for=\"password\"><b>Include password-protected</b></label>\n <input name=\"filter\" class=\"input\" type=\"radio\" id=\"unpassword\" value=\"unpassword\" checked>\n <label for=\"unpassword\">Exclude password-protected</label>\n </form>\n <!-- <details>\n <summary>Key to symbols</summary>\n <ul>\n <li><span class=\"warning lemon lime\">🍋</span> – explicit sexual content</li>\n <li><span class=\"warning lime\">🍋</span> – non-explicit sexual content</li>\n <li><span class=\"warning\">💀</span> – death</li>\n <li><span class=\"warning\">😢</span> – mental health themes (may include self-injury, suicidal ideation, suicide attempts)</li>\n <li><span class=\"warning\">🚫</span> – in-universe bigotry</li>\n <li><span class=\"warning\">🤢</span> – vomiting</li>\n <li><span class=\"warning\">⛔</span> – consent issues</li>\n <li><span class=\"warning\">👶</span> – underage sexual activity according to modern UK law</li>\n <li><span class=\"warning\">🦎</span> – incest</li>\n <li><span class=\"warning\">🦶</span> – amputation</li>\n </ul>\n <p>When a warning is shown in greyscale, this means there are references to the relevant theme but no on-screen portrayal.</p>\n </details> -->")
|
|
|
|
for fic in ficlist:
|
|
output.write("\n<div class=\"fic lang-english")
|
|
if fic["french"]:
|
|
output.write(" lang-french")
|
|
for fandom in fic["fandoms"]:
|
|
output.write(" fandom-" + classgen(fandom))
|
|
if len(fic["fandoms"]) > 1:
|
|
output.write(" fandom-crossover")
|
|
three = False
|
|
if fic["pdf"] == False:
|
|
output.write(" format-unusual") # ok for now …
|
|
elif fic["chaptered"]:
|
|
output.write(" format-chaptered")
|
|
else:
|
|
try:
|
|
if fic["event"] == "threesentenceficathon":
|
|
output.write(" format-three")
|
|
three = True
|
|
except:
|
|
pass
|
|
if three == False:
|
|
if fic["totalwords"] == 100:
|
|
output.write(" format-drabble")
|
|
elif fic["totalwords"] % 100 == 0:
|
|
output.write(" format-drabblefam")
|
|
else:
|
|
output.write(" format-oneshot")
|
|
try:
|
|
output.write(" event-" + classgen(fic["event"]))
|
|
except:
|
|
output.write(" unprompted")
|
|
if fic["locked"]:
|
|
output.write(" locked")
|
|
output.write("\">\n<h2>no. <a href=\"/fic/single/" + stringno(fic["id"]) + "\">" + stringno(fic["id"]) + "</a>")
|
|
try:
|
|
output.write("/<a href=\"/fic/single/" + stringno(fic["transid"]) + "\">" + stringno(fic["transid"]) + "</a>")
|
|
except:
|
|
pass
|
|
titles = 0
|
|
try:
|
|
if fic["title"]:
|
|
titles += 1
|
|
except:
|
|
pass
|
|
try:
|
|
if fic["transtitle"]:
|
|
titles += 1
|
|
except:
|
|
pass
|
|
if titles > 0:
|
|
output.write(": ")
|
|
try:
|
|
output.write(fic["title"])
|
|
except:
|
|
pass
|
|
if titles > 1:
|
|
output.write("/")
|
|
try:
|
|
output.write(fic["transtitle"])
|
|
except:
|
|
pass
|
|
output.write("</h2>\n<ul>\n<li>")
|
|
try:
|
|
if fic["transid"]:
|
|
if fic["french"] == "original":
|
|
output.write("French: ")
|
|
elif fic["french"] == "translation":
|
|
output.write("English: ")
|
|
except:
|
|
pass
|
|
thewords = fic["totalwords"]
|
|
output.write(str(f"{thewords:,}" + " words, "))
|
|
# output.write(str(fic["totalwords"]) + " words, ")
|
|
try:
|
|
output.write(fic["approxdate"])
|
|
except:
|
|
output.write("<code>" + datetime.datetime.strftime(fic["startdate"],"%Y-%m-%d") + "</code>")
|
|
if fic["completion"] == "incomplete":
|
|
output.write("–present")
|
|
elif fic["latestdate"] != fic["startdate"]:
|
|
output.write("–<code>" + datetime.datetime.strftime(fic["latestdate"],"%Y-%m-%d") + "</code>")
|
|
if fic["completion"] == "abandoned":
|
|
output.write(" (abandoned)")
|
|
output.write("</li>")
|
|
try:
|
|
if fic["transid"]:
|
|
output.write("\n<li>")
|
|
if fic["french"] == "original":
|
|
output.write("English: ")
|
|
elif fic["french"] == "translation":
|
|
output.write("French: ")
|
|
output.write(str(fic["transwords"]) + " words, <code>" + datetime.datetime.strftime(fic["transstartdate"],"%Y-%m-%d") + "</code>")
|
|
if fic["translatestdate"] != fic["transstartdate"]:
|
|
output.write("–<code>" + datetime.datetime.strftime(fic["translatestdate"],"%Y-%m-%d") + "</code>")
|
|
output.write("</li>")
|
|
except:
|
|
pass
|
|
output.write("\n<li><b>" + "</b>, <b>".join(fic["fandoms"]) + "</b>")
|
|
if len(fic["charmain"]) > 0:
|
|
output.write(", " + ", ".join(fic["charmain"]))
|
|
if len(fic["charsec"]) > 0:
|
|
output.write(", <span class=\"minor\">" + ", ".join(fic["charsec"]) + "</span>")
|
|
output.write("</li>\n<li><span class=\"ship " + fic["type"].lower() + "\"")
|
|
if fic["type"] != "gen":
|
|
try:
|
|
output.write(" title=\"" + ", ".join(fic["ships"]) + "\"")
|
|
except:
|
|
pass
|
|
output.write(">" + fic["type"] + "</span>")
|
|
try:
|
|
output.write(", " + fic["genre"])
|
|
except:
|
|
pass
|
|
output.write("</li>")
|
|
try:
|
|
output.write("\n<li>Written for <b>" + fic["event"] + "</b>.")
|
|
if fic["prompt"]:
|
|
output.write(" Prompt: <i>" + fic["prompt"] + "</i>.")
|
|
output.write("</li>")
|
|
except:
|
|
pass
|
|
output.write("<li>")
|
|
try:
|
|
if fic["transid"]:
|
|
if fic["french"] == "original":
|
|
output.write("French: ")
|
|
elif fic["french"] == "translation":
|
|
output.write("English: ")
|
|
except:
|
|
pass
|
|
output.write("<a href=\"https://tre.praze.net/fic/")
|
|
if fic["locked"]:
|
|
output.write("secret")
|
|
else:
|
|
output.write("files")
|
|
output.write("/" + stringno(fic["id"]) + ".html\" target=\"_blank\">HTML</a>")
|
|
if fic["pdf"]:
|
|
output.write(" • <a href=\"https://tre.praze.net/fic/")
|
|
if fic["locked"]:
|
|
output.write("secret")
|
|
else:
|
|
output.write("files")
|
|
output.write("/" + stringno(fic["id"]) + ".pdf\" target=\"_blank\">PDF</a>")
|
|
if fic["epub"]:
|
|
output.write(" • <a href=\"https://tre.praze.net/fic/")
|
|
if fic["locked"]:
|
|
output.write("secret")
|
|
else:
|
|
output.write("files")
|
|
output.write("/" + stringno(fic["id"]) + ".epub\" target=\"_blank\">EPUB</a>")
|
|
output.write("</li>")
|
|
try:
|
|
if fic["transid"]:
|
|
output.write("<li>")
|
|
if fic["french"] == "original":
|
|
output.write("English: ")
|
|
elif fic["french"] == "translation":
|
|
output.write("French: ")
|
|
output.write("<a href=\"https://tre.praze.net/fic/")
|
|
if fic["locked"]:
|
|
output.write("secret")
|
|
else:
|
|
output.write("files")
|
|
output.write("/" + stringno(fic["transid"]) + ".html\" target=\"_blank\">HTML</a>")
|
|
if fic["pdf"]:
|
|
output.write(" • <a href=\"https://tre.praze.net/fic/")
|
|
if fic["locked"]:
|
|
output.write("secret")
|
|
else:
|
|
output.write("files")
|
|
output.write("/" + stringno(fic["transid"]) + ".pdf\" target=\"_blank\">PDF</a>")
|
|
if fic["epub"]:
|
|
output.write(" • <a href=\"https://tre.praze.net/fic/")
|
|
if fic["locked"]:
|
|
output.write("secret")
|
|
else:
|
|
output.write("files")
|
|
output.write("/" + stringno(fic["transid"]) + ".epub\" target=\"_blank\">EPUB</a>")
|
|
output.write("</li>")
|
|
except:
|
|
pass
|
|
output.write("\n</ul>")
|
|
thesummary = ""
|
|
try:
|
|
thesummary += fic["summary"]
|
|
except:
|
|
pass
|
|
try:
|
|
thesummary += " " + fic["transsummary"]
|
|
except:
|
|
pass
|
|
if len(thesummary) > 0:
|
|
output.write("\n<blockquote>\n<p>" + thesummary + "</p>\n</blockquote>")
|
|
output.write("\n</div>")
|
|
|
|
output.write("\n </section>\n </main>\n <footer>\n <ul>\n <li><a href=\"/\">home</a></li>\n </ul>\n </footer>\n </div>\n <a href=\"/\"><img src=\"/a.png\" style=\"position:fixed;bottom:2px;right:2px;\" title=\"home\"></a></body>\n</html>")
|