import cgi, os, logging
from functools import wraps
import wsgiref.handlers
from google.appengine.ext.webapp import template, \
WSGIApplication
from google.appengine.api import users
import webapp as webapp2
from google.appengine.ext import webapp
from google.appengine.ext import db
from model import *
from demisaucepy import cache, cfg
log = logging.getLogger(__name__)
def rebuild_cache(blog):
"""
Pre-Render's and cache's html in blog object. Everything
in here doesn't change very often, so we can update it at point of change
"""
pages = Entry.all().filter("entrytype =", "page").filter("published =", True).fetch(20)
archives = Archive.all().order('-date').fetch(10)
recententries = Entry.allpublished().fetch(10)
links = Link.all().filter('linktype =','blogroll')
template_vals = {'recententries':recententries,'pages':pages,
'links':links,'archives':archives}
path = os.path.join(os.path.dirname(__file__), 'views/sidebar.html')
blog.sidebar = template.render(path, template_vals)
path = os.path.join(os.path.dirname(__file__), 'views/topmenu.html')
blog.topmenu = template.render(path, template_vals)
blog.save()
def requires_admin(method):
@wraps(method)
def wrapper(self, *args, **kwargs):
user = users.get_current_user()
if not user:
self.redirect(users.create_login_url(self.request.uri))
return
raise self.error(403)
elif not users.is_current_user_admin():
return self.error(403)
else:
return method(self, *args, **kwargs)
return wrapper
def printinfo(method):
@wraps(method)
def wrapper(self, *args, **kwargs):
print self #.__name__
print dir(self)
for x in self.__dict__:
print x
return method(self, *args, **kwargs)
return wrapper
class BaseController(webapp2.RequestHandler):
def __init__(self):
self.template = 'index.html'
self.blog = Blog.all().fetch(1)
self.demisauce_url = 'http://www.demisauce.com'
if 'demisauce.url' in cfg.CFG:
self.demisauce_url = cfg.CFG['demisauce.url']
if self.blog == []:
self.blog = Blog()
self.blog.initialsetup()
self.blog.save()
else:
self.blog = self.blog[0]
cfg.CFG['demisauce.apikey'] = self.blog.dsapikey
cfg.CFG['demisauce.appname'] = self.blog.dsappname
current_userisadmin = False
if users.get_current_user() and users.is_current_user_admin():
current_userisadmin = True
self.template_vals = {'current_userisadmin':current_userisadmin}
def __before__(self,*args):
pass
def __after__(self,*args):
pass
def error(self,errorcode,message='an error occured'):
if errorcode == 404:
message = 'Sorry, we were not able to find the requested page. We have logged this error and will look into it.'
elif errorcode == 403:
message = 'Sorry, that page is reserved for administrators. '
elif errorcode == 500:
message = "Sorry, the server encountered an error. We have logged this error and will look into it."
return self.render('views/error.html',{'message':message})
def render(self,template_file,template_vals):
"""
Helper method to render the appropriate template
"""
if self.blog == None and self.request.path != "/admin/setup":
# no blog configured
self.redirect('/admin/setup')
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = 'Logout'
else:
url = users.create_login_url(self.request.uri)
url_linktext = 'Login'
self.template_vals.update({'url':url,
'url_linktext':url_linktext,
'blog':self.blog,
'demisauce_url':self.demisauce_url
})
self.template_vals.update(template_vals)
path = os.path.join(os.path.dirname(__file__), template_file)
self.response.out.write(template.render(path, self.template_vals))
class BasePublicPage(BaseController):
"""
Do all the common public page prep such as nav pages etc
"""
def __before__(self,slug=None):
#self.template_vals.update(public_page_gets())
pass
class MainPage(BasePublicPage):
#@printinfo
def get(self,slug=None):
entries = []
showcomments = False
if slug == None:
entries = Entry.allpublished().fetch(10)
else:
entries = Entry.all().filter('slug', slug).fetch(1)
showcomments = True
if not entries or len(entries) == 0:
return self.error(404)
self.render('views/index.html',{'entries':entries,'slug':slug,'showcomments':showcomments})
class PublicPage(BasePublicPage):
def get(self,slug=None):
entries = Entry.all().filter('slug', slug).filter("published =", True)
self.render('views/page.html',{'entries':entries})
class ArchivePage(BasePublicPage):
def get(self,monthyear=None):
showcomments = False
entries = Entry.allpublished().filter('monthyear', monthyear)
if entries and entries.count(1000) == 1:
showcomments = True
self.render('views/index.html',{'entries':entries,'showcomments':showcomments})
class TagPage(BasePublicPage):
def get(self,tags=None):
showcomments = False
entries = Entry.allpublished().filter("tags =", tags)
log.info('count = %s' % entries.count(1000))
if entries and entries.count(10000) == 1:
showcomments = True
log.info('yup, should be showing comments')
self.render('views/index.html',{'entries':entries,'showcomments':showcomments})
class FeedHandler(BaseController):
def get(self,tags=None):
entries = Entry.allpublished().fetch(10)
if entries and entries[0]:
last_updated = entries[0].date
last_updated = last_updated.strftime("%Y-%m-%dT%H:%M:%SZ")
for e in entries:
e.formatted_date = e.date.strftime("%Y-%m-%dT%H:%M:%SZ")
self.response.headers['Content-Type'] = 'application/atom+xml'
self.render('views/atom.xml',{'entries':entries,'last_updated':last_updated})
class AdminConfig(BaseController):
@requires_admin
def get(self):
blogedit = Blog.all().fetch(1)
if blogedit:
blogedit = blogedit[0]
else:
blogedit = Blog()
blogedit.save()
blogedit.initialsetup()
self.render('views/setup.html',{'blog':blogedit,'blogclass':Blog})
@requires_admin
def post(self):
key = self.request.get('object_key')
if key == None or key == '': #new
blog = Blog()
else: # edit
blog = db.get(db.Key(key))
if users.get_current_user():
blog.owner = users.get_current_user()
blog.description = self.request.get('description')
blog.title = self.request.get('title')
blog.subtitle = self.request.get('subtitle')
blog.layout = self.request.get('layout')
blog.baseurl = self.request.get('baseurl')
blog.feedurl = self.request.get('feedurl')
blog.area1 = self.request.get('area1')
blog.area2 = self.request.get('area2')
blog.area3 = self.request.get('area3')
blog.analyticsjs = self.request.get('analyticsjs')
blog.commentjs = self.request.get('commentjs')
blog.dsapikey = self.request.get('dsapikey')
blog.dsappname = self.request.get('dsappname')
blog.save()
self.redirect('/admin/entry/list/post')
class AdminEntry(BaseController):
@requires_admin
def get(self,entrytype='post',key=None):
entry = None
if key == None or key == '':
entry = Entry()
entry.entrytype = entrytype
else:
entry = db.get(db.Key(key))
self.render('views/admin.html',{'entry':entry,'entries':[]})
@requires_admin
def post(self,entrytype='post',key=None):
entry = None
if key == None or key == '':
entry = Entry(blog=self.blog)
entry.entrytype = self.request.get('entrytype')
else:
entry = db.get(db.Key(key))
if users.get_current_user():
entry.author = users.get_current_user()
entry.content = self.request.get('content')
entry.published = bool(int(self.request.get('published')))
entry.title = self.request.get('title')
entry.slug = self.request.get('real_permalink')
entry.tagswcommas = self.request.get('tags')
entry.save()
rebuild_cache(self.blog)
self.redirect('/admin/entry/list/%s' % entry.entrytype )
@requires_admin
def delete(self,key=None):
entry = None
if key == None or key == '':
print 'whoops'
else:
entry = db.get(db.Key(key))
entry.delete()
rebuild_cache(self.blog)
class AdminList(BaseController):
@requires_admin
def get(self,entrytype='post',template_vals={}):
entries = Entry.all().filter('entrytype =',entrytype).order('-date')
self.render('views/admin.html',{'entries':entries})
class AdminMigrate(BaseController):
@requires_admin
def get(self,to_version='1.15'):
if to_version == '999.99':
pass
elif to_version == '1.18':
archives = Archive.all()
for a in archives:
a.delete()
entries = Entry.all().filter('entrytype =','post').filter('published',True)
for e in entries:
e.published = False
e.save()
self.blog.entrycount = 0 # reset to start migration
self.blog.put()
for e in entries:
e.published = True
e.save()
print 'update to %s' % (e.monthyear)
self.blog.blogversion = to_version
self.blog.put()
elif to_version == '1.17':
links = Link.all()
for l in links:
l.delete()
elif to_version == '1.16':
archives = Archive.all()
for a in archives:
a.delete()
entries = Entry.all().filter('entrytype =','post')
self.blog.entrycount = 0 # reset to start migration
for e in entries:
e.update_archive()
e.monthyear = e.date.strftime('%b-%Y')
self.blog.entrycount += 1
e.put()
print 'update to %s' % (e.monthyear)
archive = Archive.all()
self.blog.blogversion = to_version
self.blog.put()
class AdminLinks(BaseController):
@requires_admin
def get(self,linktype='blogroll'):
links = Link.all()#.filter('linktype =',linktype)
link = Link(href='',linktext='',linktype='blogroll')
self.render('views/linkadmin.html',{'entries':None,'links':links,
"link":link})
@requires_admin
def post(self,linktype='blogroll',key=None):
link = None
if key == None or key == '':
link = Link(blog=self.blog)
else:
link = db.get(db.Key(key))
link.linktext = self.request.get('linktext')
link.href = self.request.get('href')
link.put()
rebuild_cache(self.blog)
self.response.out.write('link %s added' % link.linktype)
def main():
application = webapp2.WSGIApplication2(
[('/', MainPage),
('/admin', AdminList),('/admin/', AdminList),
('/admin/entry/list/(.*)', AdminList),
('/admin/entry/(.*)/(.*)', AdminEntry),
('/admin/entry/(.*)', AdminEntry),
('/admin/links/(.*)', AdminLinks),
('/admin/setup', AdminConfig),
('/admin/migrate/(.*)', AdminMigrate),
('/tag/(.*)', TagPage),
('/atom', FeedHandler),
(r'/page/(.*)', PublicPage),
(r'/archive/(.*)', ArchivePage),
(r'/entry/(.*)', MainPage),
],debug=True)
wsgiref.handlers.CGIHandler().run(application)
template.register_template_library('demisaucepy.demidj.templatetags.demisaucetags')
if __name__ == "__main__":
main()