embedded itch.io game

small-nav
chimchooree 2 years ago
parent 0ba64fc6c0
commit fc928148ad

@ -1,506 +0,0 @@
import datetime, os, re
from bottle import error, response, route, run, static_file, template, TEMPLATE_PATH
def clean_tags(raw):
cleanr = re.compile('<.*?>')
cleantext = re.sub(cleanr, '', raw)
return cleantext
# rss feed
# RSS Generation
def make_rss():
loc = 'diary/entries/'
info = {'items': list_items(gather_and_sort(loc)[0:15])}
# Delete old version
def clear_file(f_name):
if os.path.exists(f_name):
print("removing " + f_name)
os.remove(f_name)
f = open(f_name, 'a+')
def format_rss_time(date):
return datetime.datetime.strptime(date, '%y%m%d').strftime('%a') + ', ' + datetime.datetime.strptime(date, '%y%m%d').strftime('%d %b %Y') + " 05:00:05 GMT"
# Return list of items using list of articles
def list_items(articles):
f_name = "static/xml/blessfrey.xml"
loc2 = 'https://www.blessfrey.me'
loc = 'diary/entries/'
loc3 = loc2 + loc
result = []
for article in articles:
path = loc + article
text = []
a = []
length = 0
text = article2list(article, loc)
a.append(find_title(text))
a.append(find_url(path))
a.append(clean_tags(prepare_rss_summary(text, path)))
a.append(find_timestamp(text))
result.append(a)
clear_file(f_name)
f = open(f_name, 'w')
f.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>" + '\n')
f.write("<rss version=\"2.0\">" + '\n')
f.write("<channel>" + '\n')
f.write("<title>blessfrey.me</title>" + '\n')
f.write("<link>https://www.blessfrey.me/</link>" + '\n')
f.write("<description>chimchooree's dev space</description>" + '\n')
f.write("<language>en-us</language>" + '\n')
f.write("<webMaster>chimchooree@mail.com (chimchooree)</webMaster>" + '\n')
for r in result:
f.write("<item>" + '\n')
f.write("<title>" + r[0] + "</title>" + '\n')
f.write("<link>" + loc2 + r[1] + "</link>" + '\n')
f.write("<description>" + r[2] + "</description>" + '\n')
code = r[1].replace(loc,'')
code = code.replace('/','')
f.write("<pubDate>" + format_rss_time(code) + "</pubDate>" + '\n')
f.write("<guid>" + loc2 + r[1] + "</guid>" + '\n')
f.write("</item>" + '\n')
f.write("</channel>" + '\n')
f.write("</rss>" + '\n')
f.close()
return result
# recommendations
def list_rec(page):
loc = 'diary/entries/'
result = []
rec = []
comment = ""
if isinstance(page, int):
# Collect recommended articles from comment line
with open('diary/entries/' + 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
# List latest 5 articles as headline links
def list_headlines(articles):
loc = 'diary/entries/'
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
def find_tags(text):
new = text[3].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(text):
return text[2].replace('<br>','')
# Return clean title
def find_title(text):
return clean(text[1])
# Return article as list of lines of text
def article2list(article, loc):
text = []
with open(loc + article) as f:
text = f.readlines()
return text
def retrieve_article(page, loc):
text = []
string = ""
with open(loc + str(page)) as f:
text = f.readlines()
for line in text:
string += line
return string
def retrieve_diary_entry_content(page,loc):
text = []
string = ""
with open(loc + str(page)) as f:
lines = f.readlines()
for line in lines:
if lines.index(line) >= 4:
string += line
return string
def prepare_diary_entry(page, loc):
result = []
with open(loc + str(page)) as f:
text = []
text = article2list(str(page), loc)
result.append(find_title(text))
result.append(retrieve_diary_entry_content(page, loc))
result.append(find_timestamp(text))
result.append(find_url(loc + str(page)))
result.append(find_social_title(text))
result.append(find_tags(text))
return result
# Return list of snippets using list of articles
def list_snippets(articles):
loc = 'diary/entries/'
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(text))
a.append(find_url(path))
a.append(find_social_title(text))
a.append(find_tags(text))
result.append(a)
return result
# Return list of files with given tag
def pull_tag(files, tag):
pull = []
for f in files:
tags = find_tags(article2list(str(f), 'diary/entries/'))
if "#" + tag in tags:
pull.append(f)
pull.sort(reverse=True)
return pull
# Return line count of file
def count_lines(fname):
with open(fname) as f:
for linenum, line in enumerate(f,1):
pass
return linenum
# 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 > 4 and pos < length:
content += line
pos += 1
return content
# Snip article and close any open list tags
def prepare_rss_summary(text, path):
content = snip_sentence(find_content(text), path)
if content.count('<ul>') > content.count('</ul>'):
content += '</ul>'
return content
# Snip article and close any open list tags
def prepare_article(text, path):
content = snip_article(find_content(text), path)
if content.count('<ul>') > content.count('</ul>'):
content += '</ul>'
return content
# 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
# 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 + " ... "
# Sort diary - newest to oldest
def sort_files(files):
files.sort(reverse=True)
return files
def curate_files(files):
# remove folders
if 'raw' in files:
files.remove('raw')
if 'extra' in files:
files.remove('extra')
# remove
clean = []
for f in files:
if is_it_time(f):
clean.append(f)
return clean
def is_it_time(date):
today = datetime.datetime.now()
today_string = today.strftime("%y") + today.strftime("%m") + today.strftime("%d")
return int(date) <= int(today_string)
# 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 fill_box(new_file):
box = []
with open(new_file) as f:
for line in f:
box.append(line)
box.sort()
return box
# return list of diary entry tags, sorted by frequency
def fill_word_cloud(files):
tags = []
for f in files:
temp = find_tags(article2list(str(f), 'diary/entries/'))
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 find_year():
now = datetime.datetime.now()
return now.strftime('%Y')
## Static ##
# Serve CSS
@route('/static/css/<filename:path>')
def serve_css(filename):
return static_file(filename, root='static/css')
# Serve images
@route('/static/img/<filename:path>')
def serve_img(filename):
return static_file(filename, root='static/img')
# Serve unlisted articles
@route('/static/extra/<filename:re:.*\.cpp>')
def serve_extra(filename):
return static_file(filename, root='static/extra', mimetype='text/plain', download=True)
# Serve XML
@route('/static/xml/<filename:path>')#re:.*\.xml>')
def serve_xml(filename):
return static_file(filename, root='static/xml', mimetype='text/xml')
## Routes ##
# Error Page
@error(404)
def error404(error):
return "unfortunately, a 404 error. the page you're searching for doesn't exist. (or am I just hiding it for now?) try another page! "
@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=https://www.blessfrey.me/>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>"
# Downloads
@route('/download/<filename:path>')
def download(filename):
return static_file(filename, root='static/extra', download=filename)
# Home Page - Index Template
@route('/')
def index():
"""home page"""
loc = 'diary/entries/'
info = {'css': 'index', 'news': list_headlines(gather_and_sort(loc)[0:10]), 'title': 'chimchooree\'s dev space - blessfrey', 'year': find_year()}
return template('index.tpl', info)
# Projects Page - Game Template - system, character, story info
@route('/projects')
def projects():
"""projects page"""
info = {'css': 'projects', 'title': 'chimchooree projects', 'year': find_year()}
return template('projects.tpl', info)
# Presskit Page - Presskit Template - product, developer info
@route('/presskit')
def presskit():
"""press page"""
info = {'css': 'presskit', 'title': 'blessfrey - presskit', 'year': find_year()}
return template('presskit.tpl', info)
# Start on first Diary page if no page given
@route('/diary')
def diary2():
return diary(0)
# Slash is optional
@route('/diary/')
def diary3():
return diary(0)
# Diary Page - Diary Template - list all articles
@route('/diary/<page:int>')
def diary(page):
"""diary page"""
loc = 'diary/entries/'
assert isinstance(page, int)
info = {'css': 'diary', 'title': 'blessfrey - developer diary', 'year': find_year(), 'snippets': list_snippets(gather_and_sort(loc)), 'latest': list_headlines(gather_and_sort(loc)[0:5]), 'tags': fill_word_cloud(curate_files(gather_files(loc))), 'total': len(curate_files(gather_files(loc))), 'limit': 8, 'cluster': 3, 'page': page}
return template('diary.tpl', info)
# Entry Page - Feature Template - for articles
@route('/diary/entries/<page:int>')
def entry(page):
"""diary entry"""
if not is_it_time(page):
return error404(404)
loc = 'diary/entries/'
info = {'css': 'feature', 'title': 'blessfrey - developer diary', 'year': find_year(), 'entry': prepare_diary_entry(page, loc), 'recommends': list_rec(page), 'articles': "Articles", 'latest': list_headlines(gather_and_sort(loc)[0:5]), 'tags': fill_word_cloud(curate_files(gather_files(loc))), 'page': page}
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,'feature.tpl'), info)
# Extra Page - Feature Template - for unlisted articles
@route('/diary/entries/extra/<page>')
def extra(page):
"""diary extra"""
loc = 'diary/entries/extra/'
info = {'css': 'feature', 'title': 'blessfrey - developer diary', 'year': find_year(), 'entry': retrieve_article(page, loc), 'recommends': list_rec(page), 'articles': "Articles", 'latest': list_headlines(gather_and_sort(loc)[0:5]), 'tags': fill_word_cloud(curate_files(gather_files(loc))), 'page': page}
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,'feature.tpl'), info)
# Start on first Diary tag page if no page given
@route('/diary/tag/<tagin>')
def tag2(tagin):
return tag(tagin, 0)
# Tag Page - Diary Tag Template - list all articles for tag
@route('/diary/tag/<tagin>/<page:int>')
def tag(tagin, page):
"""tag page"""
loc = 'diary/entries/'
assert isinstance(tagin, str)
assert isinstance(page, int)
info = {'css': 'diary', 'title': 'blessfrey - developer diary', 'year': find_year(), 'snippets': list_snippets(pull_tag(gather_and_sort(loc), tagin)), 'latest': list_headlines(gather_and_sort(loc)[0:5]), 'tags': fill_word_cloud(curate_files(gather_files(loc))), 'total': len(curate_files(gather_files(loc))), 'limit': 8, 'cluster': 3, 'page': page}
return template('diary.tpl', info)
# Personal Page - Box Template
@route('/box')
def box():
"""personal page"""
info = {'css': 'box', 'title': 'chimchooree\'s personal page', 'year': find_year()}
return template('box.tpl', info)
# Credits Page - Credits Template
@route('/credits')
def credits():
"""credits page"""
info = {'css': 'contact', 'title': 'blessfrey - credits', 'year': find_year()}
return template('credits.tpl', info)
# Contact Page - Contact Template
@route('/contact')
def contact():
"""contact page"""
info = {'css': 'contact', 'title': 'blessfrey - contact chimchooree', 'year': find_year()}
return template('contact.tpl', info)
# Idea Box Page - Box Template
@route('/ideabox')
def ideabox():
"""idea box page"""
info = {'css': 'box', 'title': 'blessfrey - idea box - a collection of inspiring concepts', 'words': fill_box('diary/entries/extra/ideabox'), 'limit': 5, 'year': find_year()}
return template('ideabox.tpl', info)
# Task Box Page - Box Template
@route('/taskbox')
def taskbox():
"""task box page"""
info = {'css': 'box', 'title': 'blessfrey - task box - everything needed to complete blessfrey', 'game_words': fill_box('diary/entries/extra/taskbox'), 'web_words': fill_box('diary/entries/extra/websitebox'), 'limit': 5, 'year': find_year()}
return template('taskbox.tpl', info)
## Main ##
if __name__ == '__main__':
make_rss()
run(host='127.0.0.1', port=9001)

@ -48,12 +48,19 @@ def error502(error):
def char(char_name):
"""character page"""
loc = 'char/'
info = {'css': 'nothing', 'title': 'blessfrey - character - ' + char_name, 'year': find_year(), 'profile': prepare_profile(loc, char_name)}
info = {'css': 'nothing', 'title': 'blessfrey - meet ' + char_name, 'year': find_year(), 'profile': prepare_profile(loc, 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 Demo Page
@route('/demo')
def demo():
"""demo"""
info = {'css': 'demo', 'title': 'blessfrey demo', 'year': find_year()}
return template('demo.tpl', info)
# Home Page - Index Template
@route('/')
def home():
@ -72,4 +79,4 @@ def me():
## Main ##
if __name__ == '__main__':
run(host='127.0.0.1', port=8080)
run(host='127.0.0.1', port=9001)

@ -8,14 +8,6 @@
a {
text-decoration: none;
}
.centered {
text-align: center;
}
#poltics {
height: auto;
width: 100%;
}
.nav-grid img {
height: 100%;
width: 100%;
@ -125,116 +117,27 @@ a {
}
.content-grid {
grid-area: 3 / 2 / 4 / 3;
grid-area: 3 / 1 / 4 / 4;
display: grid;
grid-template-columns: 25% 75%;
grid-template-rows: auto;
grid-template-columns: 1fr;
grid-template-rows: repeat(6, auto);
grid-column-gap: 0px;
grid-row-gap: 0px;
color: white
}
.content-left {
.banner {
grid-area: 1 / 1 / 2 / 2;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: repeat(3, 1fr);
grid-column-gap: 0px;
grid-row-gap: 0px;
}
.contentlogo {
grid-area: 2 / 1 / 3 / 2;
background-image: url(../img/prom/BlessFREY_logo.png);
background-size: 100%;
background-repeat: no-repeat;
background-position: center;
}
.content-right {
grid-area: 1 / 2 / 2 / 3;
background-image: url(../img/prom/runebless.png);
background-size: 80% auto;
background-repeat: no-repeat;
background-position: center;
}
/*display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
grid-column-gap: 0px;
grid-row-gap: 0px;
}
.weaponmaster {
grid-area: 1 / 1 / 2 / 2;
background-color: red;
background-image: url(../img/prom/w_thumb.png);
}
.tamer {
grid-area: 1 / 2 / 2 / 3;
background-color: yellow;
background-image: url(../img/prom/t_thumb.png);
}
.disciple {
grid-area: 1 / 3 / 2 / 4;
background-color: orange;
background-image: url(../img/prom/d_thumb.png);
}
.streetfighter {
grid-area: 2 / 1 / 3 / 2;
background-color: green;
background-image: url(../img/prom/s_thumb.png);
}
.hacker {
grid-area: 2 / 2 / 3 / 3;
background-color: blue;
background-image: url(../img/prom/h_thumb.png);
}
.chemist {
grid-area: 2 / 3 / 3 / 4;
background-color: purple;
background-image: url(../img/prom/c_thumb.png);
} */
.latest {
background-color: #bd97a4;
color: black;
}
.latest-grid {
width: 50%;
background-color: #bd97a4;
grid-area: 4 / 2 / 5 / 3;
overflow-y: scroll;
margin-right: 0px;
margin-left: 5%;
margin-top: 3%;
margin-bottom: 0px;
padding-top: 4%;
padding-right: 1%;
padding-bottom: 1%;
padding-left: 2%;
}
.latest-grid a:link {
color: black;
background-color: #bd97a4;
}
.latest-grid a:visited {
color: black;
background-color: #bd97a4;
}
.latest-grid a:hover {
color: #F9B3D7;
background-color: #bd97a4;
}
.latest-grid a:active {
color: #f463ad;
background-color: #bd97a4;
}
.latest-grid ul {
background-color: #bd97a4;
list-style-type: none;
}
.latest-grid li {
background-color: #bd97a4;
padding-left: 5%;
}
.latest-grid b {
background-color: #bd97a4;
}
text-align: center;
margin-top: 2em;
}
.banner img { width: 15em; }
.demo { grid-area: 2 / 1 / 3 / 2; }
.controls { grid-area: 3 / 1 / 4 / 2; }
.system { grid-area: 4 / 1 / 5 / 2; }
.story { grid-area: 5 / 1 / 6 / 2; }
.characters { grid-area: 6 / 1 / 7 / 2; }
.info { grid-area: 7 / 1 / 8 / 2; }
.footer-content {
color: white;
padding-top: 5px;

@ -1,28 +1,43 @@
% rebase('frame.tpl')
% import random
<div class="latest-row"></div>
<div class="content-grid">
<div class="content-left">
<div class="contentlogo"></div>
<div class="banner">
<img src="/static/img/prom/BlessFREY_logo.png" alt="(link: BLESSFREY" class="logo"><br>
jump to <a href="#demo">demo</a> • <a href="#controls">controls</a> • <a href="#system">system</a> • <a href="#story">story</a> • <a href="#characters">characters</a> • <a href="#info">info</a><br>
</div>
<div class="content-right">
<div class="weaponmaster"></div>
<div class="tamer"></div>
<div class="disciple"></div>
<div class="streetfighter"></div>
<div class="hacker"></div>
<div class="chemist"></div>
<div class="demo" id="demo">
<h1>demo</h1>
<p>Pass the time waiting for Blessfrey's first demo by playing Legless the Cat!<br></p>
<iframe src="https://itch.io/embed-upload/6141043?color=333333" allowfullscreen="" width="1024" height="620" frameborder="0"><a href="https://chimchooree.itch.io/legless-the-cat">Play Legless the Cat on itch.io</a></iframe><br>
<p>Poltics Cat lost his legs!! Push him around using WASD to find them. Eat any breakfasts you can find along the way! <br></p>
</div>
<div class="controls" id="controls">
<h2>controls</h2>
<ul>
<li>WASD - run up, left, down, right </li>
<li>space - move to target. If attackable, attack </li>
<li>c - target nearest foe </li>
<li>shift + click, shift + c, shift + tab - target without moving </li>
</ul>
</div>
<div class="system" id="system">
<h2>system</h2>
<p> </p>
</div>
<div class="story" id="story">
<h2>story</h2>
</div>
<div class="characters" id="characters">
<h2>characters</h2>
</div>
<div class="info" id="info">
<h2>info</h2>
</div>
</div>
<div class="latest-grid">
<div class="latest centered">. •        . <b>latest</b> ☆      .. . <br></div>
<br>
<ul class="latest">
% for n in news:
% bullet = random.choice(['.','•','☆','★'])
<li class="latest">{{bullet}}&#9;<a href={{n[0]}} rel="nofollow">{{!n[1]}}</a><br></li>
% end
</ul>
<br>
<div class="latest centered">.       ★      .. •     .       ☆</div>
</div>

Loading…
Cancel
Save