You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

798 lines
33 KiB
Python

import datetime, os, re
from bottle import error, redirect, response, route, run, static_file, template, TEMPLATE_PATH
# Remove links, line breaks from snippet
def clean(result):
result = result.replace('\n','')
result = result.replace('<br>','')
result = re.sub(r'<a href=.*?>', '', result)
result = re.sub(r'<img src=.*?>', '', result)
result = re.sub(r'<a target="_blank" href=.*?>', '', result)
result = result.replace('</a>','')
result = re.sub(r'<h\d>','',result)
result = re.sub(r'</h\d>','',result)
result = result.replace('<center>','')
result = result.replace('</center>','')
result = result.replace('<b>','')
result = result.replace('</b>','')
return result
def clean_tags(raw):
cleanr = re.compile('<.*?>')
cleantext = re.sub(cleanr, '', raw)
return cleantext
def find_year():
now = datetime.datetime.now()
return now.strftime('%Y')
def to_table(l, cols):
l.sort(key=str.lower)
# Return it as one row here if the list is too small
if len(l) < cols:
return [l]
newlist = []
# Step over every row of the list
for i in range(0, len(l), cols):
# Get the next row of the list
sublist = l[i : i + cols]
# If it's too short, add it to the end of the last row
if len(sublist) < cols:
newlist[-1] += sublist
# Add the next row in the list to the table
else:
newlist += [sublist]
return newlist
def his_to_table(l, cols):
l.sort(key=str.lower)
# Return it as one row here if the list is too small
if len(l) < cols:
return [l]
newlist = []
# Step over every row of the list
for i in range(0, len(l), cols):
# Get the next row of the list
sublist = l[i : i + cols]
# If it's too short, add it to the end of the last row
if len(sublist) < cols:
newlist[-1] += sublist
# Add the next row in the list to the table
else:
newlist += [sublist]
return newlist
def get_gdd_topics(topics, cols):
return to_table(topics, int(len(topics) / cols))
def find_gallery(name):
gal = [name]
if name == "Abbey":
gal.append("FlightRising")
gal.append([["stilllife.png","Still Life"],["dragon.png","lazy Abbey"], ["FlightRising.png","Abbey's sprite in FlightRising"],["BlackReshiram_Artfight.png","2022 Artfight attack by BlackReshiram"]])
if name == "Aloin":
gal.append("Sims")
gal.append([["alchemy.png", "Late night alchemy"], ["dream.jpg","Dreaming"]])
if name == "Angel":
gal.append("Blessfrey")
gal.append([["Chibipixel.png","One of Angel's sprites. I prefer taller, less cartoony sprites, but this style is so popular it was worth trying."],["pixelangel.png","Pixelart"],["AngelHeadphones.png","Pencil sketch"],["AngelHeadshot.png","Headshot of Angel and all her hair"],["picrew.png","made in あの子がこっちを見ている on Picrew"],["AriesAngel.png","made in なさや式CPメーカー on Picrew"]])
if name == "Aries":
gal.append("Blessfrey")
gal.append([["picrew.png","made in あの子がこっちを見ている on Picrew"],["AriesAngel.png","made in なさや式CPメーカー on Picrew"]])
if name == "Aristen":
gal.append("Black Desert Online")
gal.append([["menu.jpg","Aristen's fancy set"], ["scarf.jpg", "Newbie Aristen"], ["marine.jpg","Aristen in the Epheria Marine Classic Set"]])
if name == "Bijoux":
gal.append("Sims")
gal.append([["picrew.png","made in あの子がこっちを見ている on Picrew"]])
if name == "Bless":
gal.append("Blessfrey")
gal.append([["Bless+Rune.png","Bless and her Canaanite giant son"]])
if name == "Calder":
gal.append("FlightRising")
gal.append([["pixelheadshot.png", "Calder's human form"], ["FlightRising.png","Calder\'s sprite in FlightRising"]])
if name == "CatMan":
gal.append("City of Heroes")
gal.append([["selectscreen.png","Cat Man"],["hidden.png","Cat Man never turns off Hide"]])
if name == "Chimchooree":
gal.append("Aion")
gal.append([["couture.jpg","Chimchooree in her oyster pink tiered couture dress"],["Headshot.jpg","Her closeup."]])
if name == "Chloe":
gal.append("Blessfrey")
gal.append([["girls.png","Angel, Chloe, and Tessa"], ["pencil.png","Pencil"], ["picrew.png","made in あの子がこっちを見ている on Picrew"]])
if name == "Dia":
gal.append("Blessfrey")
gal.append([["name.png","desc"]])
if name == "Eden":
gal.append("Blessfrey")
gal.append([["name.png","desc"]])
if name == "Fifi":
gal.append("Sims")
gal.append([["mirrorofvenus.jpg","The mirror of Venus"], ["guitarpractice.jpg", "Guitar practice"], ["dream.jpg","Dreaming"]])
if name == "Freya":
gal.append("Guild Wars")
gal.append([["dance.png","Freya's dance"],["scythe.png","Freya's scythe"]])
if name == "Helia":
gal.append("Blessfrey")
gal.append([["AnimeEnding.png","A still from an attempt to emulate the Little Busters ending animation. Man, animating is hard."],["Scary.png","The banner for my Artfight Vampire team profile."],["wm.png","wip lol"],["Helia_walk.gif","Walk animation, a 2023 Artfight attack by MaxieWest"],["Girls.png","Helia and Tessa"],["Headshot.png","emulating the art style of Battle Girl High School"]])
if name == "Lune":
gal.append("Persona")
gal.append([["RingOfFire.jpg","Lune in the Ring of Fire in her Vabbian"],["HallOfMonuments.png","My Guild Wars Necromancer showing off her Hall of Monuments"],["PhariseeFlying.jpg","My Aion Elysian Spiritmaster with really pretty hair"],["LuneMarine.png","Lune Marine, my gold side resistance Water Controller in City of Heroes"],["ArcheageGuild.jpg","My ArcheAge dwarf ghost girl with gold-dipped hair and a frilly gown, plus her guildmates"],["Pixelmon.png","Customs Officer Lune and her sidekick Lilligant in Pixelmon"],["tinypool.png","Bikini Lune in a tiny pool with her kitty in Minecraft"]])
if name == "Night":
gal.append("Blessfrey")
gal.append([])
if name == "Rune":
gal.append("Blessfrey")
gal.append([["AnimeEnding.png","A still from an attempt to emulate the Little Busters ending animation. Man, animating is hard."],["Scary.png","The banner for my Artfight Vampire team profile."],["Bless+Rune.png","Rune and his dinosaur mother"],["RuneHeadshot.png","emulating the art style of Battle Girl High School"],["Blessfrey.png","Emulating old RPG coverart like Elden Gate in mixed media. Don't feel like working on it anymore."],["Rune_bank.png", "A comic"],["FlightRising.png","his dragon form in FlightRising"],["CawfeeCakes_Artfight.png","2022 Artfight attack by CawfeeCakes"],["Teriuuuu_Artfight.png","2020 Artfight attack by Teriuuuu"]])
if name == "Silke":
gal.append("Verpets")
gal.append([["Silke.png","emulating the art style of Yuu Watase in pixelart"],["Silke_png.png","her face is stuck like that"],["Verpets.png","Silke's sprite in Verpets"],["pets.png","Silke's pets"]])
if name == "Tessa":
gal.append("Blessfrey")
gal.append([["Tessa.png","Pixelart of Tessa in athletic wear"],["Rune_bank.png", "A comic"],["picrew.png","made in あの子がこっちを見ている on Picrew"],["FlightRising.png","her dragon form in FlightRising"],["RamblingRoses_Artfight.png","2020 Artfight attack by RamblingRoses"],["Lune_Archon_Artfight.jpeg","2022 Artfight attack by Lune_Archon"],["ElissaKarminakria_Artfight.png","2020 Artfight attack by ElissaKarminakria"],["gemhue_Artfight.png","2020 Artfight attack by gemhue"],["Cyan_moo_Artfight.png","2020 Artfight attack by Cyan_moo"]])
if name == "WISE":
gal.append("Blessfrey")
gal.append([["WISE.png","WISE processing a query"],["WISE!.png","2023 Artfight by Rzxcts"],["CityOfHeroes.png","I made WISE in City of Heroes, too. She's an Electric/Empathy Controller."]])
return gal
def prepare_profile(loc, char_name):
result = []
for i in ["label","basics","story","desc"]:
string = ""
with open(loc + char_name + "-" + i) as f:
lines = f.readlines()
for line in lines:
string += line
result.append(string)
return result
# Return list of snippets using list of articles
def list_snippets(articles, loc):
limit = 4
total = len(articles)
result = []
for article in articles:
path = loc + article
text = []
a = []
length = 0
text = article2list(article, loc)
a.append(find_title(text))
a.append(prepare_article(text, path))
a.append(find_timestamp(article))
a.append(find_url(path))
a.append(find_social_title(text))
a.append(find_tags(text))
result.append(a)
return result
# List latest 5 articles as headline links
def list_headlines(articles, loc):
result = []
text = []
for article in articles:
path = loc + article
b = []
b.append(path)
with open(path) as f:
f.readline()
text = f.readline()
b.append(clean(text.replace('<br>','')))
result.append(b)
return result
# Return first two sentences of article + " ... "
def snip_sentence(article, path):
article = clean(article)
limit = 100
result = article[0:min(len(article),limit)]
result = result.rsplit(' ',1)[0]
return result + " ... "
# Return first 300 words of article + " ... "
def snip_article(article, path):
article = clean(article)
limit = 300
result = article[0:min(len(article),limit)]
result = result.rsplit(' ',1)[0]
return result + " ... "
# Snip article and close any open list tags
def prepare_article(text, path):
content = snip_article(find_content(text), path)
#if content.count('<code>') > content.count('</code>'):
# content += '</code>'
#if content.count('<pre>') > content.count('</pre>'):
# content += '</pre>'
# if code, add <br> every few characters to not break the snippet format
cleanr = re.compile('<pre>')
content = re.sub(cleanr, '', content)
cleanr = re.compile('<code>')
content = re.sub(cleanr, '', content)
if content.count('<ul>') > content.count('</ul>'):
content += '</ul>'
return content
# Return article text without HTML header
def find_content(text):
length = len(text)
content = ""
# form a string from relevant lines of the article
pos = 0
for line in text:
# skip to line 5
if pos > 3 and pos < length:
content += line
pos += 1
return content
def find_tags(text):
new = text[2].replace('<br>','')
new = new.replace('\n','')
new = new.split(" ")
final = []
for n in new:
if len(n) <= 0:
new.remove(n)
if '#' in n:
final.append(n)
final.sort()
return final
# Return title of article, formatted for sharing via social media
def find_social_title(text):
return clean(text[1]).replace(' ','+')
# Return URL of article
def find_url(path):
return '/' + path.replace('.tpl','')
# Return clean timestamp
def find_timestamp(page):
try:
date = datetime.datetime.strptime(page[2:4], "%m").strftime("%B").lower() + " " + re.sub("^0+(?!$)", "", (page)[4:]) + ", 20" + (page)[:2]
except ValueError:
return ""
#timestamp is based off file name. Leading zeroes are removed from day; year assumes 21th century.
return date
# Return clean title
def find_title(text):
return clean(text[1])
# Return list of files with given tag
def pull_tag(files, tag, loc):
pull = []
for f in files:
tags = find_tags(article2list(str(f), loc))
if "#" + tag in tags:
pull.append(f)
pull.sort(reverse=True)
return pull
def retrieve_diary_entry_content(page,loc):
text = []
string = ""
with open(loc + page) as f:
lines = f.readlines()
for line in lines:
if lines.index(line) >= 4:
string += line
return string
def list_rec(page, loc):
result = []
rec = []
comment = ""
if isinstance(page, int):
# Collect recommended articles from comment line
with open(loc + str(page)) as f:
comment = f.readline()
comment = comment.replace('<!--','')
comment = comment.replace('-->','')
comment = comment.replace(' ','')
comment = clean(comment)
rec = comment.split(',')
# Convert into array for template to display
for article in rec:
if is_it_time(article):
path = loc + article
data = []
try:
with open(path) as f:
f.readline()
data.append(clean(f.readline().replace('<br>','')))
data.append(path)
result.append(data)
except EnvironmentError:
print("No article @ " + path)
return result
def prepare_diary_entry(page, loc):
result = []
try:
with open(loc + page) as f:
text = []
text = article2list(page, loc)
result.append(find_title(text))
result.append(retrieve_diary_entry_content(page, loc))
result.append(find_timestamp(page))
result.append(find_url(loc + page))
result.append(find_social_title(text))
result.append(find_tags(text))
except FileNotFoundError as e:
print("HEY - Error: " + str(e))
print("HEY - loc: " + loc)
print("HEY - page: " + page)
return result
# Return article as list of lines of text
def article2list(article, loc):
text = []
with open(loc + article) as f:
text = f.readlines()
return text
# return list of diary entry tags, sorted by frequency
def fill_word_cloud(files, loc):
tags = []
for f in files:
temp = find_tags(article2list(str(f), loc))
for t in temp:
tags.append(t)
tags.sort()
cloud = []
i = 0
while i < 24:
if len(tags) > 0:
top = max(set(tags), key = tags.count)
cloud.append(top)
tags[:] = [x for x in tags if x != top]
i += 1
return cloud
def curate_files(files):
# remove folders
if 'hold' in files:
files.remove('hold')
# remove
clean = []
for f in files:
if f == '':
files.remove(f)
if is_it_time(f):
clean.append(f)
return clean
# Sort diary - newest to oldest
def sort_files(files):
files.sort(reverse=True)
return files
# Return list of all diary entries (exclude raws + extras)
def gather_files(loc):
files = os.listdir(loc)
return files
def gather_and_sort(loc):
return sort_files(curate_files(gather_files(loc)))
def is_it_time(date):
if date == '':
return False
today = datetime.datetime.now()
today_string = today.strftime("%y") + today.strftime("%m") + today.strftime("%d")
try:
outcome = int(date) <= int(today_string)
except ValueError:
return True
return outcome
def prepare_gdd_page(page, loc):
result = []
with open(loc + page) as f:
result = f.readlines()
content = ''.join(result)
return content
## Static ##
# Serve CSS
@route('/static/css/<filename:path>')
def serve_css(filename):
return static_file(filename, root='static/css')
# Serve fonts
@route('/static/font/<filename:path>')
def serve_font(filename):
return static_file(filename, root='static/font', mimetype='text/ttf')
# Serve images
@route('/static/img/<filename:path>')
def serve_img(filename):
return static_file(filename, root='static/img')
# Favico
@route('/favicon.ico', method='GET')
def get_favicon():
return static_file('favicon.ico', root='static/img')
# Serve XML
@route('/static/xml/<filename:path>')
def serve_xml(filename):
return static_file(filename, root='static/xml', mimetype='text/xml')
# Downloads
@route('/download/<filename:path>')
def download(filename):
return static_file(filename, root='static/extra', download=filename)
# Robots
@route('/robots.txt', method='GET')
def get_robots():
return static_file('robots.txt', root='static')
## Routes ##
# Error Page
@error(404)
def error404(error):
return "Unfortunately, a 404 error. The page you're searching for doesn't exist. (Or is it just in hiding?) Try another page! <a href=/>Return to Blessfrey.me.</a> "
@error(500)
def error500(error):
return "Unfortunately, a 500 error. Something is wrong with the page you're trying to find, if it exists at all. Try another page! <a href=/>Return to Blessfrey.me.</a>"
@error(502)
def error502(error):
return "Unfortunately, a 502 error. This was likely due to website maintenance. Usually it'll be back up before you finish reading this, but otherwise, I'll notice something's wrong soon! <a href=https://www.blessfrey.me/>Return to Blessfrey.me.</a>"
# About Blessfrey Page
@route('/about')
def about():
"""about"""
info = {'css': 'doc', 'preview': 'Learn more about Blessfrey by Chimchooree, an action RPG made in Godot 4.', 'title': 'about blessfrey', 'year': find_year()}
return template('about.tpl', info)
# Art Gallery Page
@route('/art')
def art():
"""art"""
info = {'css': 'art', 'preview': 'Chimchooree\'s art, sewing projects, and screenshots.', 'title': 'blessfrey art gallery', 'year': find_year()}
return template('art.tpl', info)
# OC Page
@route('/characters') # redirect
def char3():
return char("Helia")
@route('/char/') # if no OC given
def char2():
return char("Helia")
@route('/char/<char_name:path>')
def char(char_name):
"""character page"""
loc = 'char/'
info = {'css': 'char', 'preview': 'Chimchooree\'s OC database. Meet ' + char_name + "!", 'title': 'blessfrey - characters | meet ' + char_name, 'year': find_year(), 'ocs': ["Helia", "Rune", "Angel", "Tessa", "Chloe", "Aries", "Night", "Dia", "Bless", "WISE", "Abbey", "Calder", "Silke", "Aloin", "Fifi", "Bijoux", "CatMan", "Belfry", "Aristen", "Chimchooree", "Freya", "Lune", "Trace", "Freefall", "Chandra", "Colt", "Cass", "Katherine", "Lisbet"], 'name': char_name, 'profile': prepare_profile(loc, char_name), 'gallery': find_gallery(char_name)}
abs_app_dir_path = os.path.dirname(os.path.realpath(__file__))
abs_views_path = os.path.join(abs_app_dir_path, 'views')
TEMPLATE_PATH.insert(0, abs_views_path )
return template(os.path.join(abs_views_path,'char.tpl'), info)
# Blessfrey Credits Page
@route('/credits')
def credits():
"""credits"""
info = {'css': 'doc', 'preview': 'Keeping track of everyone who contributed to Blessfrey...even though none of them are even aware of my existence lol', 'title': 'blessfrey credits', 'year': find_year()}
return template('credits.tpl', info)
# Blessfrey Games Page
@route('/games')
def games():
"""games"""
info = {'css': 'games', 'preview': 'Play Chimchooree\'s HTML5 games in the browser! Best played on the desktop.', 'title': 'blessfrey games', 'year': find_year()}
return template('games.tpl', info)
@route('/blue-planet')
def bp():
"""game"""
info = {'css': 'games', 'preview': 'Play Blue Planet by Chimchooree, an HTML5 dressup prototype in the browser. Made in Godot 3.', 'title': 'blue planet - blessfrey games', 'year': find_year()}
return template('games-bp.tpl', info)
@route('/cheeryOS')
def co():
"""game"""
info = {'css': 'games', 'preview': 'Play CheeryOS by Chimchooree, an HTML5 pretend OS prototype in the browser. Made in Godot 3.', 'title': 'cheeryOS - blessfrey games', 'year': find_year()}
return template('games-co.tpl', info)
@route('/no-legs-the-cat')
def nltc():
"""game"""
info = {'css': 'games', 'preview': 'Play No-Legs the Cat by Chimchooree, an HTML5 maze game in the browser. Made in Godot 3.', 'title': 'no-legs the cat - blessfrey games', 'year': find_year()}
return template('games-nltc.tpl', info)
@route('/small-thing-that-makes-things')
def sttmt():
"""game"""
info = {'css': 'games', 'preview': 'Play Small Thing That Makes Things, an HTML5 adventure platformer in the browser. Made in Godot 3 for #WeeklyGameJam.', 'title': 'small thing that makes things - blessfrey games', 'year': find_year()}
return template('games-sttmt.tpl', info)
@route('/stoplight')
def sl():
"""game"""
info = {'css': 'games', 'preview': 'Play Stoplight, an HTML5 coroutines prototype in the browser. Made in Godot 3.', 'title': 'stoplight - blessfrey games', 'year': find_year()}
return template('games-sl.tpl', info)
@route('/thunderspy')
def ts():
"""game"""
info = {'css': 'games', 'preview': 'Play Thunderspy, a City of Heroes private server.', 'title': 'thunderspy - blessfrey games', 'year': find_year()}
return template('games-ts.tpl', info)
# Japanese Learning Page
@route('/japanese')
def japanese():
"""japanese"""
redirect('diary/entries/240220')
# Diary Page
@route('/')
def home():
return diary(0)
@route('/diary') # Start on first Diary page if no page given
def diary2():
return diary(0)
@route('/diary/') # Slash is optional
def diary3():
return diary(0)
@route('/diary/<page:int>')
def diary(page):
"""diary"""
loc = 'diary/entries/'
assert isinstance(page, int)
info = {'css': 'diary', 'title': 'chimchooree\'s diary', 'preview': 'Chimchooree\'s diary, sharing gamedev, webdev, Bible study, and personal reflections.', 'year': find_year(), 'snippets': list_snippets(gather_and_sort(loc), loc), 'latest': list_headlines(gather_and_sort(loc)[0:5], loc), 'tags': fill_word_cloud(curate_files(gather_files(loc)), loc), 'total': len(curate_files(gather_files(loc))), 'limit': 8, 'cluster': 3, 'page': page, 'category': "diary"}
return template('diary.tpl', info)
# Entry Page - Feature Template - for articles
@route('/diary/entries/<page_t:int>')
def entry(page_t):
"""diary entry"""
if not is_it_time(page_t):
return error404(404)
page = str(page_t)
loc = 'diary/entries/'
entry = prepare_diary_entry(page, loc)
# link preview
preview_t = prepare_article(entry[1], loc + page)
preview = preview_t.replace('<p>','')
preview = preview.replace('</p>','')
preview = preview.replace('&lt;p&gt;','')
preview = preview[:246] + " ..."
info = {'css': 'entry', 'title': entry[0], 'year': find_year(), 'preview': preview, 'entry': entry, 'recommends': list_rec(page, loc), 'articles': "Articles", 'latest': list_headlines(gather_and_sort(loc)[0:5], loc), 'tags': fill_word_cloud(curate_files(gather_files(loc)), loc), 'page': page, 'category': "diary"}
abs_app_dir_path = os.path.dirname(os.path.realpath(__file__))
abs_views_path = os.path.join(abs_app_dir_path, 'views')
TEMPLATE_PATH.insert(0, abs_views_path )
return template(os.path.join(abs_views_path,'entry.tpl'), info)
# Blessfrey Game Design Document Page - change the 5 for more or less columns
@route('/blessfrey-gdd')
def gddbf():
"""Game Design Document"""
info = {'css': 'doc', 'title': 'blessfrey gdd', 'preview': 'Blessfrey\'s game design document', 'year': find_year(), 'topics': get_gdd_topics(
["achievement", "ai", "armor-rating", "attack-loop", "attribute", "attribute-point", "cast", "character", "collision", "controls", "credits", "damage-type", "death-penalty", "design-philosophy", "dialogue", "docs", "environment-effect", "fog-of-war", "gear", "gig", "groups", "highlight", "ID", "inspect menu", "inventory", "item", "job", "keyword", "KnowledgeBase", "language", "life", "marketing", "mechanics", "MessageBus", "Mercur", "milestones", "miracles", "pathfinding", "perk", "pip", "projectile", "proxemics", "punishment", "setting", "skill", "smartphone", "spirit", "status-effect", "store", "story", "style guide", "terms", "ui", "vibe", "website", "xp", "xp-bar", "zone"],3
)}
return template('bf-gdd.tpl', info)
@route('/gdd')
def gdd():
return gddbf()
@route('/blessfrey-gdd/<page>')
def page(page):
if page.lower() == "credits":
return credits()
if page.lower() == "cast":
return char2()
if page.lower() == "milestones":
return milestones()
if page.lower() == "setting":
return setting()
if page.lower() in ["style","style guide", "style%20guide"]:
return style()
if page.lower() in ["mechanics","game-mechanics","game_mechanics"]:
return mech()
# if page.lower() in ["job","keyword","skill"]:
# return mechpage(page)
loc = 'blessfrey-gdd/'
info = {'css': 'doc', 'title': 'Blessfrey GDD - ' + page, 'preview': 'Blessfrey\'s GDD - ' + page, 'year': find_year(), 'topic': page.lower(), 'writeup': prepare_gdd_page(page, loc)}
return template('page.tpl', info)
# Blessfrey Docs (Objects, Variables, & Methods)
@route('/blessfrey-gdd/docs')
def docs():
"""docs"""
info = {'css': 'doc', 'title': 'Blessfrey Documentation', 'preview': 'Blessfrey Documentation', 'year': find_year(), 'topic': 'docs', 'writeup': prepare_gdd_page('docs', 'blessfrey-gdd/docs/')}
return template('page.tpl', info)
@route('/blessfrey-gdd/docs/<page>')
def docpage(page):
loc = 'blessfrey-gdd/docs/'
info = {'css': 'doc', 'title': 'Blessfrey GDD - ' + page, 'preview': 'Blessfrey GDD - ' + page, 'year': find_year(), 'topic': '<a href="/blessfrey-gdd/docs">docs</a> ~ ' + page.lower(), 'writeup': prepare_gdd_page(page, loc)}
return template('page.tpl', info)
# Blessfrey Mechanics
@route('/blessfrey-gdd/mechanics')
def mech():
"""mechanics"""
info = {'css': 'doc', 'title': 'game mechanics (blessfrey GDD)', 'preview': 'Blessfrey game design document - game mechanics', 'year': find_year(), 'topic': 'game mechanics', 'writeup': prepare_gdd_page('mechanics', 'blessfrey-gdd/mechanics/')}
return template('page.tpl', info)
@route('/blessfrey-gdd/mechanics/<page>')
def mechpage(page):
loc = 'blessfrey-gdd/mechanics/'
info = {'css': 'doc', 'title': 'blessfrey GDD - ' + page, 'preview': 'Blessfrey GDD' + page, 'year': find_year(), 'topic': '<a href="/blessfrey-gdd/mechanics">game mechanic</a> ~ ' + page.lower(), 'writeup': prepare_gdd_page(page, loc)}
return template('page.tpl', info)
# Blessfrey Style Guide Page
@route('/blessfrey-style-guide')
def style3():
return style()
@route('/blessfrey-style')
def style2():
return style()
@route('/style-guide')
def style1():
return style()
@route('/style')
def style():
"""style guide"""
info = {'css': 'doc', 'title': 'blessfrey style guide', 'preview': 'Blessfrey\'s style guide', 'year': find_year()}
return template('style-guide.tpl', info)
# Me Page
@route('/about-me')
def me():
"""me"""
info = {'css': 'me', 'title': 'meet me, chimchooree', 'preview': 'Meet me, Chimchooree, and learn more about my projects - gamedev, webdev, Bible study, creative writing, pixel art, and more!', 'year': find_year()}
return template('me.tpl', info)
# Feature Requirements
@route('/milestones')
def milestones():
"""feature requirements"""
info = {'css': 'doc', 'title': 'blessfrey milestones', 'preview': 'Blessfrey milestones', 'year': find_year()}
return template('milestones.tpl', info)
# Blessfrey - Feature Requirements Page
@route('/blessfrey-milestones')
def milestones():
info = {'css': 'doc', 'title': 'blessfrey milestones', 'preview': 'Blessfrey milestones', 'year': find_year()}
return template('milestones-bf.tpl', info)
# Lemonland - Feature Requirements Page
@route('/lemonland-milestones')
def milestones():
info = {'css': 'doc', 'title': 'lemonland milestones', 'preview': 'Lemonland milestones', 'year': find_year()}
return template('milestones-ll.tpl', info)
# Blue Planet - Feature Requirements Page
@route('/blueplanet-milestones')
def milestones():
info = {'css': 'doc', 'title': 'blue planet milestones', 'preview': 'Blue Planet milestones', 'year': find_year()}
return template('milestones-bp.tpl', info)
# LazyWiki - Feature Requirements Page
@route('/lazywiki-milestones')
def milestones():
"""feature requirements"""
info = {'css': 'doc', 'title': 'lazywiki milestones', 'preview': 'LazyWiki milestones', 'year': find_year()}
return template('milestones-lw.tpl', info)
# Sitemap
@route('/sitemap')
def sitemap():
"""sitemap"""
info = {'css': 'doc', 'title': 'blessfrey sitemap', 'preview': 'Blessfrey\'s sitemap', 'year': find_year()}
return template('sitemap.tpl', info)
# Species Page
@route('/race/') # if no species given
def spec4():
return species("human")
@route('/race/<species_name:path>')
def spec3(species_name):
return species(species_name)
@route('/species/') # if no species given
def spec2():
return species("human")
@route('/species/<species_name:path>')
def spec(species_name):
"""species page"""
loc = 'species/'
info = {'css': 'char', 'title': 'blessfrey - species | meet ' + species_name, 'preview': 'Blessfrey - species | Meet ' + species_name, 'year': find_year(), 'ocs': ["human","giant","serpent"], 'name': species_name, 'profile': prepare_profile(loc, species_name), 'gallery': find_gallery(species_name)}
abs_app_dir_path = os.path.dirname(os.path.realpath(__file__))
abs_views_path = os.path.join(abs_app_dir_path, 'views')
TEMPLATE_PATH.insert(0, abs_views_path )
return template(os.path.join(abs_views_path,'species.tpl'), info)
# Blessfrey - Setting Page
@route('/setting')
def setting2():
return setting()
@route('/blessfrey-gdd/setting')
def setting():
"""setting"""
info = {'css': 'doc', 'title': 'blessfrey gdd - setting', 'preview': 'Blessfrey GDD - Setting', 'year': find_year()}
return template('setting.tpl', info)
# Story Pages
@route('/story')
@route('/story/')
def stories_redirect():
return stories2(0)
@route('/story/<page:int>')
def stories2(page):
assert isinstance(page, int)
loc = 'story/'
css = 'diary'
title = 'chimchooree\'s creative writing'
preview = 'Chimchooree\'s creative writing'
year = find_year()
snippets = list_snippets(gather_and_sort(loc), loc)
latest_temp1 = list_headlines(gather_and_sort(loc), loc)
latest = []
for late in latest_temp1:
if "chapter" not in late[1].lower():
latest.append(late)
tags = fill_word_cloud(curate_files(gather_files(loc)), loc)
total = len(curate_files(gather_files(loc)))
info = {'css': css, 'title': title, 'preview': preview, 'year': year, 'snippets': snippets, 'latest': latest, 'tags': tags, 'total': total, 'limit': 8, 'cluster': 3, 'page': page, 'category': "story"}
return template('diary.tpl', info)
@route('/story/<story>')
def story2(story):
"""story"""
loc = 'story/'
entry = prepare_diary_entry(story, loc)
info = {'css': 'entry', 'title': entry[0], 'preview': entry[1], 'year': find_year(), 'entry': entry, 'recommends': list_rec(story, loc), 'articles': "Articles", 'latest': list_headlines(gather_and_sort(loc)[0:5], loc), 'tags': fill_word_cloud(curate_files(gather_files(loc)), loc), 'page': story, 'category': "story"}
abs_app_dir_path = os.path.dirname(os.path.realpath(__file__))
abs_views_path = os.path.join(abs_app_dir_path, 'views')
TEMPLATE_PATH.insert(0, abs_views_path )
return template(os.path.join(abs_views_path,'entry.tpl'), info)
# Search Story by Tag
@route('/story/tag/<tagin>') # Start on first Story tag page if no page given
def story_tag2(tagin):
return story_tag(tagin, 0, 'story/')
@route('/story/tag/<tagin>/<page>') # Tag Page - Story Tag Template - list all articles for tag
def story_tag(tagin, page, loc):
"""tag page"""
print("PASS - TAG - " + tagin)
assert isinstance(tagin, str)
assert isinstance(page, int)
info = {'css': 'diary', 'title': 'Blessfrey stories', 'preview': 'Chimchooree\'s creative writing', 'year': find_year(), 'snippets': list_snippets(pull_tag(gather_and_sort(loc), tagin, loc), loc), 'latest': list_headlines(gather_and_sort(loc)[0:5], loc), 'tags': fill_word_cloud(curate_files(gather_files(loc)), loc), 'total': len(curate_files(gather_files(loc))), 'limit': 8, 'cluster': 3, 'page': page, 'category': "story"}
return template('diary.tpl', info)
# Blessfrey Wiki Page
@route('/study')
def study():
"""study"""
redirect('wiki.blessfrey.me/view/Blessfrey')
# Search Diary by Tag
@route('/diary/tag/<tagin>') # Start on first Diary tag page if no page given
def diary_tag2(tagin):
return diary_tag(tagin, 0, 'diary/entries/')
@route('/diary/tag/<tagin>/<page:int>') # Tag Page - Diary Tag Template - list all articles for tag
def diary_tag(tagin, page, loc):
"""tag page"""
print("PASS - TAG - " + tagin)
assert isinstance(tagin, str)
assert isinstance(page, int)
info = {'css': 'diary', 'title': 'blessfrey developer diary', 'preview': 'Search Chimchooree\'s diary by tag', 'year': find_year(), 'snippets': list_snippets(pull_tag(gather_and_sort(loc), tagin, loc), loc), 'latest': list_headlines(gather_and_sort(loc)[0:5], loc), 'tags': fill_word_cloud(curate_files(gather_files(loc)), loc), 'total': len(curate_files(gather_files(loc))), 'limit': 8, 'cluster': 3, 'page': page, 'category': "diary"}
return template('diary.tpl', info)
## Main ##
if __name__ == '__main__':
run(host='0.0.0.0', port=9001)