pnbp

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit bfed1a696b790a7514711a04d18e777ac60df063
parent b42396f92a9ccccee80cbde95328efd439de359a
Author: Paul Longtine <paullongtine@gmail.com>
Date:   Fri Jun 13 11:40:16 2014

Reworked things, finished page

Diffstat:
 build.py                             | 166 +-------------------------------
 data/index.json                      |   1 +-
 data/static/styles/style.css         |  26 +-----
 data/test.json                       |   1 +-
 example/data/index.json              |   1 +-
 example/data/static/styles/style.css |  26 +++++-
 example/data/test.json               |   1 +-
 example/includes/archive.html        |  34 ++++++-
 example/includes/header.html         |  15 +++-
 example/pages.json                   |  11 ++-
 example/templates/archive.html       |  13 ++-
 example/templates/post.html          |   5 +-
 example/templates/std.html           |  13 ++-
 includes/archive.html                |  34 +------
 includes/header.html                 |  15 +---
 mod/__init__.py                      |   2 +-
 mod/blog.py                          | 101 +-------------------
 pages.json                           |  11 +--
 src/build.py                         | 195 ++++++++++++++++++++++++++++++++++++-
 src/module/__init__.py               |   2 +-
 src/module/blog.py                   | 101 +++++++++++++++++++-
 templates/archive.html               |  13 +--
 templates/post.html                  |   5 +-
 templates/std.html                   |  13 +--
 24 files changed, 417 insertions(+), 388 deletions(-)

diff --git a/build.py b/build.py @@ -1,166 +0,0 @@ -#!/usr/bin/python -''' -' pnbp - pnbp is not a blogging platform -' -' Paul Longtine - paullongtine@gmail.com -' -''' -import os, sys, shutil, mod, json, time - -def main(): - site = {} - - #Loops through defined "sites" - for name,v in pagedata.items(): - try: - template = file(v['template']).read() - - except: - print("{}: Can't open file '{}'".format(name,v['template'])) - sys.exit() - - template = generateTemplate(template,v['pagevar'],name) - - site[name] = runMod(template,v,name) - - buildSite(site) - -# Adds in variables defined in pages.json -# -# t = raw template, var = "pagevar" variables in pages.json (<pagename> -> "pagevar") -def generateTemplate(t,var,page): - if page == "index": - page = "" - - t = t.replace("%page%",page) - - t = runInlineScript(t,page) - - for search,replace in var.items(): - if search[0] == ":": - try: - t.index("%"+search+"%") - exists = True - except: - exists = False - if exists: - inc = file(replace).read() - inc = generateTemplate(inc,var,page) - t = t.replace("%"+search+"%",inc) - - else: - t = t.replace("%"+search+"%",replace) - - return t - -# Runs modules defined in pages.json -# -# t = raw template, var = "pagemod" variables in pages.json (<pagename> -> "pagemod") -def runMod(t,var,page): - subpage = {} - for name, mdata in var['pagemod'].items(): - if mdata['mod'] != "page": - try: - subpage.update(getattr(mod,mdata['mod']).getPages(t,mdata['settings'],name,page)) - - except Exception,e: - print("Error occured at {} using module {}:".format(page,mdata['mod'])) - if type(e) == KeyError: - print("Missing attribute {}".format(e)) - sys.exit() - - else: - print(e) - - elif mdata['mod'] == "page": - try: - template = file(mdata['settings']['template']).read() - - except: - print("Error occured at {} using module page".format(page)) - print("Cannot open file {}".format(mdata['settings']['template'])) - sys.exit() - - pv = var['pagevar'] - pv.update(mdata['settings']['pagevar']) - template = generateTemplate(template,pv,name) - if mdata['settings']['location'] == "": - t = {'default':template} - else: - t = {} - temp = {} - for i in mdata['settings']['location'].split("/"): - temp[i] = {} - - - subpage.update(t) - - return subpage - -def runInlineScript(template,page): - try: - index = template.index("{:")+2 - exists = True - - except: - exists = False - - if exists: - script = "" - while template[index:index+2] != ":}": - script = script + template[index] - index += 1 - - returns = "" - exec(script) - template = template.replace(template[template.index("{:"):template.index(":}")+2],returns) - - return template - -# Builds the site off of a filestructure dictionary. - -def buildSite(site): - try: - shutil.rmtree("./site/") - except: - print("No directory site/, ignoring") - - os.mkdir("./site/") - for page, subpages in site.items(): - if page == "index": - currentDir = "./site" - - else: - currentDir = "./site/"+page - os.mkdir(currentDir) - - open(currentDir+"/index.html", "w").write(subpages['default']) - - for subdir, data in subpages.items(): - if subdir != "default": - os.mkdir(currentDir+"/"+subdir) - for page, content in data.items(): - if page != "default": - os.mkdir(currentDir+"/"+subdir+"/"+page) - file(currentDir+"/"+subdir+"/"+page+"/index.html","w").write(content) - - else: - file(currentDir+"/"+subdir+"/index.html", "w").write(data['default']) - - for i in os.listdir("data/static/"): - shutil.copytree("data/static/"+i,"site/"+i) - -if __name__ == "__main__": - print("Going through pages...") - start = time.time() - try: - pages = open("pages.json") - - except: - print("Can't open file 'pages.json'") - sys.exit() - - pagedata = json.load(pages) - pages.close() - main() - print("Finished in {} ms.".format((time.time()-start)*1000)) diff --git a/data/index.json b/data/index.json @@ -1 +0,0 @@ -[{"post":"0","date":"1997-10-3","title":"I don't know what I'm doing","content":"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras blandit, orci eu consectetur eleifend, ante purus luctus leo, id gravida nulla ante ut odio. Nunc non turpis sapien. Pellentesque nec condimentum metus. Mauris vel lorem tincidunt mi tincidunt malesuada. Mauris eu luctus odio. Morbi vel ligula a eros condimentum facilisis sit amet ut ligula. Vivamus quis ultricies elit, sit amet sollicitudin justo. Etiam ac urna condimentum, tempus ipsum vitae, dapibus massa. Maecenas augue nunc, vehicula ultricies tincidunt nec, lacinia vel velit. Donec et leo venenatis, elementum felis elementum, facilisis justo. Ut egestas commodo diam eu adipiscing. Proin vestibulum velit sit amet congue semper. Cras convallis urna nec nibh consectetur bibendum. Vivamus scelerisque velit sit amet congue consequat. In posuere consectetur nisl.<\/p>\n<p>In fringilla nisl et ipsum suscipit, et interdum sem adipiscing. Aenean id turpis porttitor, imperdiet libero sit amet, ultrices augue. Donec id ultricies erat. Nam bibendum pulvinar enim. Sed egestas aliquet nunc ut rhoncus. Ut tristique at leo id condimentum. In hac habitasse platea dictumst. Phasellus eu orci blandit, ultricies dolor quis, ultricies nunc. Fusce elementum mattis nulla, vel tincidunt libero iaculis in. Donec posuere volutpat tortor sit amet auctor.<\/p>\n<p>Quisque fringilla venenatis velit, sed venenatis erat lobortis nec. Etiam fermentum ullamcorper euismod. Suspendisse vulputate lectus a turpis iaculis, nec interdum odio vestibulum. Duis fringilla porttitor dignissim. Sed at risus ac tellus gravida tincidunt. Nulla ornare dui quis nulla vehicula ornare. Etiam bibendum justo risus, et tristique quam bibendum eu. Mauris posuere orci ac enim pharetra, quis tincidunt elit tristique. Ut luctus dolor nulla, ut luctus ligula lacinia quis. Sed interdum interdum ante vel porttitor. Ut a odio ligula. Donec posuere, risus non tincidunt laoreet, nisi massa aliquet lacus, sed blandit diam ligula et lorem.<\/p>\n<p>Cras eu ullamcorper mauris. Maecenas malesuada diam in felis bibendum aliquam et laoreet dui. Pellentesque auctor accumsan diam, eu varius dui iaculis ac. Phasellus iaculis massa a nunc sollicitudin mollis. Curabitur pulvinar libero et ante ullamcorper accumsan. Maecenas non magna a elit blandit congue. Suspendisse mattis ultrices odio eu rutrum. Sed iaculis nulla eu orci ultricies, quis dapibus felis sodales. Nulla in porttitor purus. Morbi porta dictum felis, nec tristique magna posuere in. Cras arcu enim, viverra sed metus in, semper viverra nibh. Morbi rutrum at tellus nec sagittis. In purus turpis, tincidunt id posuere eget, tincidunt ac nulla. Curabitur convallis magna sed nisl congue vestibulum. Duis ut adipiscing lacus, in pharetra neque.<\/p>\n<p>Donec justo nibh, consectetur id massa id, iaculis euismod nunc. Proin pretium risus sem, sagittis luctus massa varius nec. Phasellus mollis posuere lorem, eget malesuada velit varius quis. Praesent quis quam tortor. Vivamus et sagittis odio. Morbi at sollicitudin libero, ac rutrum eros. Duis vitae pretium lorem, vehicula posuere elit. Integer faucibus tristique est nec luctus. Curabitur commodo pellentesque lacus vel feugiat. Vivamus id tellus id metus mollis vestibulum a ac dolor. <\/p>"},{"post":"1","date":"1998-9-13","title":"I might have an idea of what I'm doing.","content":"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras blandit, orci eu consectetur eleifend, ante purus luctus leo, id gravida nulla ante ut odio. Nunc non turpis sapien. Pellentesque nec condimentum metus. Mauris vel lorem tincidunt mi tincidunt malesuada. Mauris eu luctus odio. Morbi vel ligula a eros condimentum facilisis sit amet ut ligula. Vivamus quis ultricies elit, sit amet sollicitudin justo. Etiam ac urna condimentum, tempus ipsum vitae, dapibus massa. Maecenas augue nunc, vehicula ultricies tincidunt nec, lacinia vel velit. Donec et leo venenatis, elementum felis elementum, facilisis justo. Ut egestas commodo diam eu adipiscing. Proin vestibulum velit sit amet congue semper. Cras convallis urna nec nibh consectetur bibendum. Vivamus scelerisque velit sit amet congue consequat. In posuere consectetur nisl.<\/p>\n<p>In fringilla nisl et ipsum suscipit, et interdum sem adipiscing. Aenean id turpis porttitor, imperdiet libero sit amet, ultrices augue. Donec id ultricies erat. Nam bibendum pulvinar enim. Sed egestas aliquet nunc ut rhoncus. Ut tristique at leo id condimentum. In hac habitasse platea dictumst. Phasellus eu orci blandit, ultricies dolor quis, ultricies nunc. Fusce elementum mattis nulla, vel tincidunt libero iaculis in. Donec posuere volutpat tortor sit amet auctor.<\/p>\n<p>Quisque fringilla venenatis velit, sed venenatis erat lobortis nec. Etiam fermentum ullamcorper euismod. Suspendisse vulputate lectus a turpis iaculis, nec interdum odio vestibulum. Duis fringilla porttitor dignissim. Sed at risus ac tellus gravida tincidunt. Nulla ornare dui quis nulla vehicula ornare. Etiam bibendum justo risus, et tristique quam bibendum eu. Mauris posuere orci ac enim pharetra, quis tincidunt elit tristique. Ut luctus dolor nulla, ut luctus ligula lacinia quis. Sed interdum interdum ante vel porttitor. Ut a odio ligula. Donec posuere, risus non tincidunt laoreet, nisi massa aliquet lacus, sed blandit diam ligula et lorem.<\/p>\n<p>Cras eu ullamcorper mauris. Maecenas malesuada diam in felis bibendum aliquam et laoreet dui. Pellentesque auctor accumsan diam, eu varius dui iaculis ac. Phasellus iaculis massa a nunc sollicitudin mollis. Curabitur pulvinar libero et ante ullamcorper accumsan. Maecenas non magna a elit blandit congue. Suspendisse mattis ultrices odio eu rutrum. Sed iaculis nulla eu orci ultricies, quis dapibus felis sodales. Nulla in porttitor purus. Morbi porta dictum felis, nec tristique magna posuere in. Cras arcu enim, viverra sed metus in, semper viverra nibh. Morbi rutrum at tellus nec sagittis. In purus turpis, tincidunt id posuere eget, tincidunt ac nulla. Curabitur convallis magna sed nisl congue vestibulum. Duis ut adipiscing lacus, in pharetra neque.<\/p>\n<p>Donec justo nibh, consectetur id massa id, iaculis euismod nunc. Proin pretium risus sem, sagittis luctus massa varius nec. Phasellus mollis posuere lorem, eget malesuada velit varius quis. Praesent quis quam tortor. Vivamus et sagittis odio. Morbi at sollicitudin libero, ac rutrum eros. Duis vitae pretium lorem, vehicula posuere elit. Integer faucibus tristique est nec luctus. Curabitur commodo pellentesque lacus vel feugiat. Vivamus id tellus id metus mollis vestibulum a ac dolor. <\/p>"}]- \ No newline at end of file diff --git a/data/static/styles/style.css b/data/static/styles/style.css @@ -1,26 +0,0 @@ -body, div { - width:900px; - margin:0 auto; - font-family:sans-serif; -} - -a { - text-decoration:none; - color:#0000BB; -} - -a:hover { - color:#9900FF; -} - -a h1:hover { - color:#9900FF; -} - -a:visited { - color:#0000BB; -} - -a.current { - border:2px solid black; -}- \ No newline at end of file diff --git a/data/test.json b/data/test.json @@ -1 +0,0 @@ -[{"post":"0","description":"BLAHLBAH","date":"1997-10-3","title":"This is a test for tesing purposes","content":"<p>Blaugh.<\/p>"},{"post":"1","description":"BLAHBLAH","date":"2010-11-20","title":"No clue. Not one.","content":"<p>Uh. hi...<\/p>\n<p>Still...<\/p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras blandit, orci eu consectetur eleifend, ante purus luctus leo, id gravida nulla ante ut odio. Nunc non turpis sapien. Pellentesque nec condimentum metus. Mauris vel lorem tincidunt mi tincidunt malesuada. Mauris eu luctus odio. Morbi vel ligula a eros condimentum facilisis sit amet ut ligula. Vivamus quis ultricies elit, sit amet sollicitudin justo. Etiam ac urna condimentum, tempus ipsum vitae, dapibus massa. Maecenas augue nunc, vehicula ultricies tincidunt nec, lacinia vel velit. Donec et leo venenatis, elementum felis elementum, facilisis justo. Ut egestas commodo diam eu adipiscing. Proin vestibulum velit sit amet congue semper. Cras convallis urna nec nibh consectetur bibendum. Vivamus scelerisque velit sit amet congue consequat. In posuere consectetur nisl. <\/p>"}]- \ No newline at end of file diff --git a/example/data/index.json b/example/data/index.json @@ -0,0 +1 @@ +[{"post":"0","date":"1997-10-3","title":"I don't know what I'm doing","content":"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras blandit, orci eu consectetur eleifend, ante purus luctus leo, id gravida nulla ante ut odio. Nunc non turpis sapien. Pellentesque nec condimentum metus. Mauris vel lorem tincidunt mi tincidunt malesuada. Mauris eu luctus odio. Morbi vel ligula a eros condimentum facilisis sit amet ut ligula. Vivamus quis ultricies elit, sit amet sollicitudin justo. Etiam ac urna condimentum, tempus ipsum vitae, dapibus massa. Maecenas augue nunc, vehicula ultricies tincidunt nec, lacinia vel velit. Donec et leo venenatis, elementum felis elementum, facilisis justo. Ut egestas commodo diam eu adipiscing. Proin vestibulum velit sit amet congue semper. Cras convallis urna nec nibh consectetur bibendum. Vivamus scelerisque velit sit amet congue consequat. In posuere consectetur nisl.<\/p>\n<p>In fringilla nisl et ipsum suscipit, et interdum sem adipiscing. Aenean id turpis porttitor, imperdiet libero sit amet, ultrices augue. Donec id ultricies erat. Nam bibendum pulvinar enim. Sed egestas aliquet nunc ut rhoncus. Ut tristique at leo id condimentum. In hac habitasse platea dictumst. Phasellus eu orci blandit, ultricies dolor quis, ultricies nunc. Fusce elementum mattis nulla, vel tincidunt libero iaculis in. Donec posuere volutpat tortor sit amet auctor.<\/p>\n<p>Quisque fringilla venenatis velit, sed venenatis erat lobortis nec. Etiam fermentum ullamcorper euismod. Suspendisse vulputate lectus a turpis iaculis, nec interdum odio vestibulum. Duis fringilla porttitor dignissim. Sed at risus ac tellus gravida tincidunt. Nulla ornare dui quis nulla vehicula ornare. Etiam bibendum justo risus, et tristique quam bibendum eu. Mauris posuere orci ac enim pharetra, quis tincidunt elit tristique. Ut luctus dolor nulla, ut luctus ligula lacinia quis. Sed interdum interdum ante vel porttitor. Ut a odio ligula. Donec posuere, risus non tincidunt laoreet, nisi massa aliquet lacus, sed blandit diam ligula et lorem.<\/p>\n<p>Cras eu ullamcorper mauris. Maecenas malesuada diam in felis bibendum aliquam et laoreet dui. Pellentesque auctor accumsan diam, eu varius dui iaculis ac. Phasellus iaculis massa a nunc sollicitudin mollis. Curabitur pulvinar libero et ante ullamcorper accumsan. Maecenas non magna a elit blandit congue. Suspendisse mattis ultrices odio eu rutrum. Sed iaculis nulla eu orci ultricies, quis dapibus felis sodales. Nulla in porttitor purus. Morbi porta dictum felis, nec tristique magna posuere in. Cras arcu enim, viverra sed metus in, semper viverra nibh. Morbi rutrum at tellus nec sagittis. In purus turpis, tincidunt id posuere eget, tincidunt ac nulla. Curabitur convallis magna sed nisl congue vestibulum. Duis ut adipiscing lacus, in pharetra neque.<\/p>\n<p>Donec justo nibh, consectetur id massa id, iaculis euismod nunc. Proin pretium risus sem, sagittis luctus massa varius nec. Phasellus mollis posuere lorem, eget malesuada velit varius quis. Praesent quis quam tortor. Vivamus et sagittis odio. Morbi at sollicitudin libero, ac rutrum eros. Duis vitae pretium lorem, vehicula posuere elit. Integer faucibus tristique est nec luctus. Curabitur commodo pellentesque lacus vel feugiat. Vivamus id tellus id metus mollis vestibulum a ac dolor. <\/p>"},{"post":"1","date":"1998-9-13","title":"I might have an idea of what I'm doing.","content":"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras blandit, orci eu consectetur eleifend, ante purus luctus leo, id gravida nulla ante ut odio. Nunc non turpis sapien. Pellentesque nec condimentum metus. Mauris vel lorem tincidunt mi tincidunt malesuada. Mauris eu luctus odio. Morbi vel ligula a eros condimentum facilisis sit amet ut ligula. Vivamus quis ultricies elit, sit amet sollicitudin justo. Etiam ac urna condimentum, tempus ipsum vitae, dapibus massa. Maecenas augue nunc, vehicula ultricies tincidunt nec, lacinia vel velit. Donec et leo venenatis, elementum felis elementum, facilisis justo. Ut egestas commodo diam eu adipiscing. Proin vestibulum velit sit amet congue semper. Cras convallis urna nec nibh consectetur bibendum. Vivamus scelerisque velit sit amet congue consequat. In posuere consectetur nisl.<\/p>\n<p>In fringilla nisl et ipsum suscipit, et interdum sem adipiscing. Aenean id turpis porttitor, imperdiet libero sit amet, ultrices augue. Donec id ultricies erat. Nam bibendum pulvinar enim. Sed egestas aliquet nunc ut rhoncus. Ut tristique at leo id condimentum. In hac habitasse platea dictumst. Phasellus eu orci blandit, ultricies dolor quis, ultricies nunc. Fusce elementum mattis nulla, vel tincidunt libero iaculis in. Donec posuere volutpat tortor sit amet auctor.<\/p>\n<p>Quisque fringilla venenatis velit, sed venenatis erat lobortis nec. Etiam fermentum ullamcorper euismod. Suspendisse vulputate lectus a turpis iaculis, nec interdum odio vestibulum. Duis fringilla porttitor dignissim. Sed at risus ac tellus gravida tincidunt. Nulla ornare dui quis nulla vehicula ornare. Etiam bibendum justo risus, et tristique quam bibendum eu. Mauris posuere orci ac enim pharetra, quis tincidunt elit tristique. Ut luctus dolor nulla, ut luctus ligula lacinia quis. Sed interdum interdum ante vel porttitor. Ut a odio ligula. Donec posuere, risus non tincidunt laoreet, nisi massa aliquet lacus, sed blandit diam ligula et lorem.<\/p>\n<p>Cras eu ullamcorper mauris. Maecenas malesuada diam in felis bibendum aliquam et laoreet dui. Pellentesque auctor accumsan diam, eu varius dui iaculis ac. Phasellus iaculis massa a nunc sollicitudin mollis. Curabitur pulvinar libero et ante ullamcorper accumsan. Maecenas non magna a elit blandit congue. Suspendisse mattis ultrices odio eu rutrum. Sed iaculis nulla eu orci ultricies, quis dapibus felis sodales. Nulla in porttitor purus. Morbi porta dictum felis, nec tristique magna posuere in. Cras arcu enim, viverra sed metus in, semper viverra nibh. Morbi rutrum at tellus nec sagittis. In purus turpis, tincidunt id posuere eget, tincidunt ac nulla. Curabitur convallis magna sed nisl congue vestibulum. Duis ut adipiscing lacus, in pharetra neque.<\/p>\n<p>Donec justo nibh, consectetur id massa id, iaculis euismod nunc. Proin pretium risus sem, sagittis luctus massa varius nec. Phasellus mollis posuere lorem, eget malesuada velit varius quis. Praesent quis quam tortor. Vivamus et sagittis odio. Morbi at sollicitudin libero, ac rutrum eros. Duis vitae pretium lorem, vehicula posuere elit. Integer faucibus tristique est nec luctus. Curabitur commodo pellentesque lacus vel feugiat. Vivamus id tellus id metus mollis vestibulum a ac dolor. <\/p>"}]+ \ No newline at end of file diff --git a/example/data/static/styles/style.css b/example/data/static/styles/style.css @@ -0,0 +1,26 @@ +body, div { + width:900px; + margin:0 auto; + font-family:sans-serif; +} + +a { + text-decoration:none; + color:#0000BB; +} + +a:hover { + color:#9900FF; +} + +a h1:hover { + color:#9900FF; +} + +a:visited { + color:#0000BB; +} + +a.current { + border:2px solid black; +}+ \ No newline at end of file diff --git a/example/data/test.json b/example/data/test.json @@ -0,0 +1 @@ +[{"post":"0","description":"BLAHLBAH","date":"1997-10-3","title":"This is a test for tesing purposes","content":"<p>Blaugh.<\/p>"},{"post":"1","description":"BLAHBLAH","date":"2010-11-20","title":"No clue. Not one.","content":"<p>Uh. hi...<\/p>\n<p>Still...<\/p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras blandit, orci eu consectetur eleifend, ante purus luctus leo, id gravida nulla ante ut odio. Nunc non turpis sapien. Pellentesque nec condimentum metus. Mauris vel lorem tincidunt mi tincidunt malesuada. Mauris eu luctus odio. Morbi vel ligula a eros condimentum facilisis sit amet ut ligula. Vivamus quis ultricies elit, sit amet sollicitudin justo. Etiam ac urna condimentum, tempus ipsum vitae, dapibus massa. Maecenas augue nunc, vehicula ultricies tincidunt nec, lacinia vel velit. Donec et leo venenatis, elementum felis elementum, facilisis justo. Ut egestas commodo diam eu adipiscing. Proin vestibulum velit sit amet congue semper. Cras convallis urna nec nibh consectetur bibendum. Vivamus scelerisque velit sit amet congue consequat. In posuere consectetur nisl. <\/p>"}]+ \ No newline at end of file diff --git a/example/includes/archive.html b/example/includes/archive.html @@ -0,0 +1,34 @@ +<div> +{: +if page == "": + page = "index" +elif page =="archive": + page = "index" +data = json.load(open(pagedata[page]['pagemod']['content']['settings']['data'])) +a = "" +dates = {} +for i in data: + if 'date' in i: + datedata = i['date'].split("-") + if datedata[0] in dates: + if datedata[1] in dates[datedata[0]]: + dates[datedata[0]][datedata[1]][datedata[2]] = i['title'] + else: + dates[datedata[0]][datedata[1]] = {} + dates[datedata[0]][datedata[1]][datedata[2]] = i['title'] + else: + dates[datedata[0]] = {} + dates[datedata[0]][datedata[1]] = {} + dates[datedata[0]][datedata[1]][datedata[2]] = i['title'] +a = "<div id=\"archives\"><ul>" +for year,months in sorted(dates.items(),reverse=True): + a = a + "<li>{}</li><li><ul>".format(year) + for month,days in sorted(months.items(),reverse=True): + a = a + "<li>{}</li><li><ul>".format(month) + for day,title in sorted(days.items(),reverse=True): + a = a + "<li>{} - <a href=\"../post/{}\">{}</a></li>".format(day,module.blog.slug(title),title) + a = a + "</ul></li>" + a = a + "</ul></li>" +returns = a + "</div>" +:} +</div> diff --git a/example/includes/header.html b/example/includes/header.html @@ -0,0 +1,15 @@ +<div> + <h1>This is in fact not a blog. %page%</h1> + {: +for i,x in sorted(pagedata.items(),reverse=True): + l = i + if page == "":page = "index" + if str(i) == page: c = "current" + else: c = "" + + if i == "index": + i = "" + i = "/"+i + returns = "<a class=\"{}\" href=\"{}\">{}</a>&nbsp;".format(c, i, l) + returns + :} +</div> diff --git a/example/pages.json b/example/pages.json @@ -0,0 +1,11 @@ +{ +"index":{"template":"templates/std.html", + "pagevar":{":header":"./includes/header.html","title":"This is a test page"}, + "pagemod":{"content":{"mod":"blog","settings":{"defaultPostCount":"0","data":"./data/index.json"}}}}, +"archive":{"template":"templates/archive.html", + "pagevar":{":header":"./includes/header.html","title":"This is a test page"}, + "pagemod":{"archive":{"mod":"page","settings":{"pagevar":{":archive":"./includes/archive.html"},"location":"","template":"templates/archive.html"}}}}, +"test":{"template":"templates/std.html", + "pagevar":{":header":"./includes/header.html","title":"This is THE test page"}, + "pagemod":{"content":{"mod":"blog","settings":{"description":1,"defaultPostCount":"1","data":"./data/test.json"}}}} +} diff --git a/example/templates/archive.html b/example/templates/archive.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> + <head> + <title>%title%</title> + <link rel="stylesheet" type="text/css" href="/styles/style.css" /> + </head> + <body> + %:header% + <div id="split"> + %:archive% + </div> + </body> +</html> diff --git a/example/templates/post.html b/example/templates/post.html @@ -0,0 +1,5 @@ +<div> + <a href="%titlelink%"><h1>%title%</h1></a> + <p>%date:&B, &d &Y%</p> + <p>%content%</p> +</div> diff --git a/example/templates/std.html b/example/templates/std.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> + <head> + <title>%title%</title> + <link rel="stylesheet" type="text/css" href="/styles/style.css" /> + </head> + <body> + %:header% + <div id="split"> + %content% + </div> + </body> +</html> diff --git a/includes/archive.html b/includes/archive.html @@ -1,34 +0,0 @@ -<div> -{: -if page == "": - page = "index" -elif page =="archive": - page = "index" -data = json.load(open(pagedata[page]['pagemod']['content']['settings']['data'])) -a = "" -dates = {} -for i in data: - if 'date' in i: - datedata = i['date'].split("-") - if datedata[0] in dates: - if datedata[1] in dates[datedata[0]]: - dates[datedata[0]][datedata[1]][datedata[2]] = i['title'] - else: - dates[datedata[0]][datedata[1]] = {} - dates[datedata[0]][datedata[1]][datedata[2]] = i['title'] - else: - dates[datedata[0]] = {} - dates[datedata[0]][datedata[1]] = {} - dates[datedata[0]][datedata[1]][datedata[2]] = i['title'] -a = "<div id=\"archives\"><ul>" -for year,months in sorted(dates.items(),reverse=True): - a = a + "<li>{}</li><li><ul>".format(year) - for month,days in sorted(months.items(),reverse=True): - a = a + "<li>{}</li><li><ul>".format(month) - for day,title in sorted(days.items(),reverse=True): - a = a + "<li>{} - <a href=\"../post/{}\">{}</a></li>".format(day,mod.blog.slug(title),title) - a = a + "</ul></li>" - a = a + "</ul></li>" -returns = a + "</div>" -:} -</div> diff --git a/includes/header.html b/includes/header.html @@ -1,15 +0,0 @@ -<div> - <h1>This is in fact not a blog. %page%</h1> - {: -for i,x in sorted(pagedata.items(),reverse=True): - l = i - if page == "":page = "index" - if str(i) == page: c = "current" - else: c = "" - - if i == "index": - i = "" - i = "/"+i - returns = "<a class=\"{}\" href=\"{}\">{}</a>&nbsp;".format(c, i, l) + returns - :} -</div> diff --git a/mod/__init__.py b/mod/__init__.py @@ -1,2 +0,0 @@ -#Imports all mods from mod/ -import blog diff --git a/mod/blog.py b/mod/blog.py @@ -1,101 +0,0 @@ -import json, time - -def getPages(template,settings,name,page): - pages = {} - settings['postTemplate'] = settings.get("postTemplate","./templates/post.html") - settings['defaultPostCount'] = settings.get("defaultPostCount","0") - settings['description'] = settings.get("description","0") - data = json.load(file(settings['data'])) - temp = file(settings['postTemplate']).read() - - # Generates all posts on page (/all - a = "" - posts = 0 - for i in data: - a = generatePost(i,temp,page) + a - posts += 1 - - pages['all']= {} - pages['all']['default'] = template.replace("%"+name+"%",a) - - # Generates index - a = "" - for i in data: - if int(settings['defaultPostCount']) == 0 or int(i['post']) >= posts-int(settings['defaultPostCount']): - back = i['content'] - if settings['description'] != "0": - i['content'] = i['description'] - a = generatePost(i,temp,page) + a - i['content'] = back - - pages['default'] = template.replace("%"+name+"%",a) - - # Generates individual pages referenced by title (/post/<title>) - pages['post'] = {} - for i in data: - post = generatePost(i,temp,page) - pages['post'][slug(i['title'])] = template.replace("%"+name+"%",post) - - return pages - - -#Generates post out of given template, data and page name, returns string -def generatePost(data, post, page): - for name,x in data.items(): - if name == 'title': - if page == "index": - linkpage = "" - - else: - linkpage = page + "/" - - post = post.replace("%titlelink%","/"+linkpage+"post/"+slug(x)) - post = post.replace("%"+name+"%", x) - - elif name == 'date': - config = getConfig("%date:",post) - if config == "none": - post = post.replace("%date:none%",x) - elif config == "-1": - post = post.replace("%date%",x) - else: - post = post.replace( - "%date:"+config+"%", - time.strftime(config.replace("&","%"),time.strptime(x,"%Y-%m-%d"))) - elif name == 'description': - pass - - else: - post = post.replace("%"+name+"%", x) - - return post - - -# Helper functions - -# slug(string -> "hi's") -> his- removes all "unwanted" characters and creates a URL-friendly slug -def slug(string): - invalidChars = [ - "<",">","#","%","{","}", - "|","\\","^","[","]","`", - "'",";","/","?",":","@", - "&","+",",","." - ] - for x in invalidChars: - string = string.replace(x, "") - - string = string.replace(" ","_") - return string.lower() - -# getConfig(string -> index, string -> data) -> gets "config" data ex. (%blah:<config>%) -def getConfig(index,data): - retVal = "" - try: - pointer = data.index(index)+len(index) - except: - retVal = "-1" - if retVal != "-1": - while data[pointer] != "%" and retVal != "-1": - retVal = retVal + data[pointer] - pointer += 1 - return retVal diff --git a/pages.json b/pages.json @@ -1,11 +0,0 @@ -{ -"index":{"template":"templates/std.html", - "pagevar":{":header":"./includes/header.html","title":"This is a test page"}, - "pagemod":{"content":{"mod":"blog","settings":{"defaultPostCount":"0","data":"./data/index.json"}}}}, -"archive":{"template":"templates/archive.html", - "pagevar":{":header":"./includes/header.html","title":"This is a test page"}, - "pagemod":{"archive":{"mod":"page","settings":{"pagevar":{":archive":"./includes/archive.html"},"location":"","template":"templates/archive.html"}}}}, -"test":{"template":"templates/std.html", - "pagevar":{":header":"./includes/header.html","title":"This is THE test page"}, - "pagemod":{"content":{"mod":"blog","settings":{"description":1,"defaultPostCount":"1","data":"./data/test.json"}}}} -} diff --git a/src/build.py b/src/build.py @@ -0,0 +1,195 @@ +#!/usr/bin/python +''' +' pnbp - pnbp is not a blogging platform +' +' Paul Longtine - paullongtine@gmail.com +' +''' +import os, sys, shutil, module, json, time + +def main(): + site = {} + + #Loops through defined "sites" + for name,v in pagedata.items(): + try: + template = file(v['template']).read() + + except: + print("{}: Can't open file '{}'".format(name,v['template'])) + sys.exit() + + template = generateTemplate(template,v['pagevar'],name) + + site[name] = runMod(template,v,name) + + buildSite(site) + +# Adds in variables defined in pages.json +# +# t = raw template, var = "pagevar" variables in pages.json (<pagename> -> "pagevar") +def generateTemplate(t,var,page): + if page == "index": + page = "" + + t = t.replace("%page%",page) + + t = runInlineScript(t,page) + + for search,replace in var.items(): + if search[0] == ":": + try: + t.index("%"+search+"%") + exists = True + + except: + exists = False + + if exists: + inc = file(replace).read() + inc = generateTemplate(inc,var,page) + t = t.replace("%"+search+"%",inc) + + else: + t = t.replace("%"+search+"%",replace) + + return t + +# Runs modules defined in pages.json +# +# t = raw template, var = "pagemod" variables in pages.json (<pagename> -> "pagemod") +def runMod(t,var,page): + subpage = {} + for name, mdata in var['pagemod'].items(): + if mdata['mod'] != "page": + try: + #Runs module specified in settings + subpage.update(getattr(module,mdata['mod']).getPages(t,mdata['settings'],name,page)) + + except Exception,e: + print("Error occured at {} using module {}:".format(page,mdata['mod'])) + if type(e) == KeyError: + print("Missing attribute {}".format(e)) + sys.exit() + + else: + print(e) + + elif mdata['mod'] == "page": + #Built-in module page, takes configuration settings and builds a page at a location + try: + template = file(mdata['settings']['template']).read() + + except: + print("Error occured at {} using module page".format(page)) + print("Cannot open file {}".format(mdata['settings']['template'])) + sys.exit() + + pv = var['pagevar'] + pv.update(mdata['settings']['pagevar']) + template = generateTemplate(template,pv,name) + if mdata['settings']['location'] == "": + t = {'default':template} + + else: + t = {mdata['settings']['location']:{'default':template}} + + subpage.update(t) + + return subpage + +#Takes all code blocks in templates ("{:print("Hi"):}") and executes it, and replaces the block with the "returns" variable +def runInlineScript(template,page): + try: + index = template.index("{:")+2 + exists = True + + except: + exists = False + + if exists: + script = "" + while template[index:index+2] != ":}": + script = script + template[index] + index += 1 + + returns = "" + exec(script) + template = template.replace(template[template.index("{:"):template.index(":}")+2],returns) + + return template + +# Builds the site off of a filestructure dictionary. +def buildSite(site): + try: + shutil.rmtree("./site/") + + except: + print("No directory site/, ignoring") + + os.mkdir("./site/") + for page, subpages in site.items(): + if page == "index": + currentDir = "./site" + + else: + currentDir = "./site/"+page + os.mkdir(currentDir) + + subpageLoop(subpages,currentDir) + + for i in os.listdir("data/static/"): + shutil.copytree("data/static/"+i,"site/"+i) + +#Recursive loop through all subpages +#d = dict of all subpages, cd = Current directory +def subpageLoop(d,currentDir): + for k, v in d.iteritems(): + if isinstance(v, dict): + subpageLoop(v,currentDir + "/" + k) + else: + if k == "default": + k = "" + + else: + k = k + "/" + + try: + file("{}/{}index.html".format(currentDir,k), "w").write(v) + + except: + try: + os.mkdir("{}".format(currentDir)) + + except: + pass + + try: + os.mkdir("{}/{}".format(currentDir,k)) + except: + pass + + file("{}/{}index.html".format(currentDir,k), "w").write(v) + +if __name__ == "__main__": + print("Going through pages...") + start = time.time() + try: + pages = open("pages.json") + + except: + print("Can't open file 'pages.json'") + sys.exit() + + pagedata = json.load(pages) + pages.close() + try: + main() + except Exception,e: + if type(e) == KeyError: + print("Missing or mistyped value: {}".format(e)) + else: + print("Something went wrong...") + print(e) + sys.exit() + print("Finished in {} ms.".format((time.time()-start)*1000)) diff --git a/src/module/__init__.py b/src/module/__init__.py @@ -0,0 +1,2 @@ +#Imports all mods from mod/ +import blog diff --git a/src/module/blog.py b/src/module/blog.py @@ -0,0 +1,101 @@ +import json, time + +def getPages(template,settings,name,page): + pages = {} + settings['postTemplate'] = settings.get("postTemplate","./templates/post.html") + settings['defaultPostCount'] = settings.get("defaultPostCount","0") + settings['description'] = settings.get("description","0") + data = json.load(file(settings['data'])) + temp = file(settings['postTemplate']).read() + + # Generates all posts on page (/all + a = "" + posts = 0 + for i in data: + a = generatePost(i,temp,page) + a + posts += 1 + + pages['all']= {} + pages['all']['default'] = template.replace("%"+name+"%",a) + + # Generates index + a = "" + for i in data: + if int(settings['defaultPostCount']) == 0 or int(i['post']) >= posts-int(settings['defaultPostCount']): + back = i['content'] + if settings['description'] != "0": + i['content'] = i['description'] + a = generatePost(i,temp,page) + a + i['content'] = back + + pages['default'] = template.replace("%"+name+"%",a) + + # Generates individual pages referenced by title (/post/<title>) + pages['post'] = {} + for i in data: + post = generatePost(i,temp,page) + pages['post'][slug(i['title'])] = template.replace("%"+name+"%",post) + + return pages + + +#Generates post out of given template, data and page name, returns string +def generatePost(data, post, page): + for name,x in data.items(): + if name == 'title': + if page == "index": + linkpage = "" + + else: + linkpage = page + "/" + + post = post.replace("%titlelink%","/"+linkpage+"post/"+slug(x)) + post = post.replace("%"+name+"%", x) + + elif name == 'date': + config = getConfig("%date:",post) + if config == "none": + post = post.replace("%date:none%",x) + elif config == "-1": + post = post.replace("%date%",x) + else: + post = post.replace( + "%date:"+config+"%", + time.strftime(config.replace("&","%"),time.strptime(x,"%Y-%m-%d"))) + elif name == 'description': + pass + + else: + post = post.replace("%"+name+"%", x) + + return post + + +# Helper functions + +# slug(string -> "hi's") -> his- removes all "unwanted" characters and creates a URL-friendly slug +def slug(string): + invalidChars = [ + "<",">","#","%","{","}", + "|","\\","^","[","]","`", + "'",";","/","?",":","@", + "&","+",",","." + ] + for x in invalidChars: + string = string.replace(x, "") + + string = string.replace(" ","_") + return string.lower() + +# getConfig(string -> index, string -> data) -> gets "config" data ex. (%blah:<config>%) +def getConfig(index,data): + retVal = "" + try: + pointer = data.index(index)+len(index) + except: + retVal = "-1" + if retVal != "-1": + while data[pointer] != "%" and retVal != "-1": + retVal = retVal + data[pointer] + pointer += 1 + return retVal diff --git a/templates/archive.html b/templates/archive.html @@ -1,13 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>%title%</title> - <link rel="stylesheet" type="text/css" href="/styles/style.css" /> - </head> - <body> - %:header% - <div id="split"> - %:archive% - </div> - </body> -</html> diff --git a/templates/post.html b/templates/post.html @@ -1,5 +0,0 @@ -<div> - <a href="%titlelink%"><h1>%title%</h1></a> - <p>%date:&B, &d &Y%</p> - <p>%content%</p> -</div> diff --git a/templates/std.html b/templates/std.html @@ -1,13 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>%title%</title> - <link rel="stylesheet" type="text/css" href="/styles/style.css" /> - </head> - <body> - %:header% - <div id="split"> - %content% - </div> - </body> -</html>