import datetime , os , re
from bottle import error , response , route , run , static_file , template , TEMPLATE_PATH
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 :
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
# 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
# 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 ) )
result . append ( a )
return result
# 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_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> ' , ' ' )
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
# Return list of all diary entries (exclude raws + extras)
def gather_files ( loc ) :
files = os . listdir ( loc )
if ' raw ' in files :
files . remove ( ' raw ' )
if ' extra ' in files :
files . remove ( ' extra ' )
return files
## 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 )
## Routes ##
# 404 Error Page
@error ( 404 )
def error404 ( error ) :
return " unfortunately, a 404 error "
# Home Page - Index Template
@route ( ' / ' )
def index ( ) :
""" home page """
loc = ' diary/entries/ '
info = { ' css ' : ' index ' , ' news ' : list_headlines ( sort_files ( gather_files ( loc ) ) [ 0 : 10 ] ) , ' title ' : ' chimchooree \' s dev space - blessfrey ' , ' year ' : datetime . datetime . now ( ) }
return template ( ' index.tpl ' , info )
# Game Page - Game Template - system, character, story info
@route ( ' /game ' )
def game ( ) :
""" game page """
info = { ' css ' : ' game ' , ' title ' : ' blessfrey - about the game ' , ' year ' : datetime . datetime . now ( ) }
return template ( ' game.tpl ' , info )
# Presskit Page - Presskit Template - product, developer info
@route ( ' /presskit ' )
def presskit ( ) :
""" press page """
info = { ' css ' : ' presskit ' , ' title ' : ' blessfrey - presskit ' , ' year ' : datetime . datetime . now ( ) }
return template ( ' presskit.tpl ' , info )
# Start on first Diary page if no page given
@route ( ' /diary ' )
def diary2 ( ) :
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 ' : datetime . datetime . now ( ) , ' snippets ' : list_snippets ( sort_files ( gather_files ( loc ) ) ) , ' latest ' : list_headlines ( sort_files ( gather_files ( loc ) ) [ 0 : 5 ] ) , ' total ' : len ( gather_files ( loc ) ) , ' limit ' : 4 , ' 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 """
loc = ' diary/entries/ '
info = { ' css ' : ' feature ' , ' title ' : ' blessfrey - developer diary ' , ' year ' : datetime . datetime . now ( ) , ' entry ' : retrieve_article ( page , loc ) , ' recommends ' : list_rec ( page ) , ' articles ' : " Articles " , ' latest ' : list_headlines ( sort_files ( gather_files ( loc ) ) [ 0 : 5 ] ) , ' 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 ' : datetime . datetime . now ( ) , ' entry ' : retrieve_article ( page , loc ) , ' recommends ' : list_rec ( page ) , ' articles ' : " Articles " , ' latest ' : list_headlines ( sort_files ( gather_files ( ' diary/entries/ ' ) ) [ 0 : 5 ] ) , ' 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 )
# Personal Page - Box Template
@route ( ' /box ' )
def box ( ) :
""" personal page """
info = { ' css ' : ' box ' , ' title ' : ' chimchooree \' s personal page ' , ' year ' : datetime . datetime . now ( ) }
return template ( ' box.tpl ' , info )
# Credits Page - Credits Template
@route ( ' /credits ' )
def credits ( ) :
""" credits page """
info = { ' css ' : ' box ' , ' title ' : ' blessfrey - credits ' , ' year ' : datetime . datetime . now ( ) }
return template ( ' credits.tpl ' , info )
# Contact Page - Contact Template
@route ( ' /contact ' )
def contact ( ) :
""" contact page """
info = { ' css ' : ' box ' , ' title ' : ' blessfrey - contact chimchooree ' , ' year ' : datetime . datetime . now ( ) }
return template ( ' contact.tpl ' , info )
## Main ##
if __name__ == ' __main__ ' :
run ( host = ' 127.0.0.1 ' , port = 9001 )