Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
git-svn-id: http://micolog.googlecode.com/svn/trunk@2 fd139d67-4554-0…
…410-8437-97b8145f5b4d
- Loading branch information
coolchyni
committed
Aug 12, 2008
1 parent
1845b07
commit 9879ac3
Showing
14 changed files
with
1,506 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2008 Aaron Raddon | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
application: mlog | ||
version: 1 | ||
runtime: python | ||
api_version: 1 | ||
|
||
handlers: | ||
- url: /rpc | ||
script: metaweblog.py | ||
|
||
- url: /rpc/.* | ||
script: metaweblog.py | ||
|
||
- url: /themes/[\w\-]+/templates/.* | ||
script: blog.py | ||
|
||
- url: /themes | ||
static_dir: themes | ||
|
||
- url: /.* | ||
script: blog.py |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
#!/usr/bin/env python | ||
# | ||
# Copyright 2007 Google Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
import cgi,os | ||
import StringIO | ||
import logging | ||
import re | ||
import sys | ||
import traceback | ||
import urlparse | ||
import webob | ||
import wsgiref.headers | ||
import wsgiref.util | ||
from google.appengine.ext.webapp import * | ||
|
||
class RequestHandler(RequestHandler): | ||
def __init__(self): | ||
self.template_vals = {} | ||
|
||
def __before__(self,*args): | ||
""" | ||
Allows common code to be used for all get/post/delete methods | ||
""" | ||
pass | ||
|
||
def __after__(self,*args): | ||
""" | ||
This runs AFTER response is returned to browser. | ||
If you have follow up work that you don't want to do while | ||
browser is waiting put it here such as sending emails etc | ||
""" | ||
pass | ||
|
||
|
||
|
||
|
||
|
||
class WSGIApplication2(WSGIApplication): | ||
""" | ||
Modifyed to add new methods __before__ and __after__ | ||
before the get/post/delete/etc methods and then | ||
AFTER RESPONSE. This is important because it means you | ||
can do work after the response has been returned to the browser | ||
""" | ||
def __init__(self, url_mapping, debug=False): | ||
"""Initializes this application with the given URL mapping. | ||
Args: | ||
url_mapping: list of (URI, RequestHandler) pairs (e.g., [('/', ReqHan)]) | ||
debug: if true, we send Python stack traces to the browser on errors | ||
""" | ||
self._init_url_mappings(url_mapping) | ||
self.__debug = debug | ||
WSGIApplication.active_instance = self | ||
self.current_request_args = () | ||
|
||
def __call__(self, environ, start_response): | ||
"""Called by WSGI when a request comes in.""" | ||
request = Request(environ) | ||
response = Response() | ||
|
||
WSGIApplication.active_instance = self | ||
|
||
handler = None | ||
groups = () | ||
for regexp, handler_class in self._url_mapping: | ||
match = regexp.match(request.path) | ||
if match: | ||
handler = handler_class() | ||
handler.initialize(request, response) | ||
groups = match.groups() | ||
break | ||
|
||
self.current_request_args = groups | ||
|
||
if handler: | ||
try: | ||
handler.__before__(*groups) | ||
method = environ['REQUEST_METHOD'] | ||
if method == 'GET': | ||
handler.get(*groups) | ||
elif method == 'POST': | ||
handler.post(*groups) | ||
elif method == 'HEAD': | ||
handler.head(*groups) | ||
elif method == 'OPTIONS': | ||
handler.options(*groups) | ||
elif method == 'PUT': | ||
handler.put(*groups) | ||
elif method == 'DELETE': | ||
handler.delete(*groups) | ||
elif method == 'TRACE': | ||
handler.trace(*groups) | ||
else: | ||
handler.error(501) | ||
response.wsgi_write(start_response) | ||
handler.__after__(*groups) | ||
except Exception, e: | ||
handler.handle_exception(e, self.__debug) | ||
else: | ||
response.set_status(404) | ||
response.wsgi_write(start_response) | ||
return [''] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
import os,logging | ||
import re | ||
from functools import wraps | ||
from google.appengine.api import users | ||
from google.appengine.ext import webapp | ||
from google.appengine.ext import db | ||
from google.appengine.ext.webapp import template | ||
from google.appengine.api import memcache | ||
import app.webapp as webapp2 | ||
from model import * | ||
import wsgiref.handlers | ||
from mimetypes import types_map | ||
from datetime import datetime, timedelta | ||
|
||
logging.info('module base reloaded') | ||
|
||
def requires_admin(method): | ||
@wraps(method) | ||
def wrapper(self, *args, **kwargs): | ||
if not self.is_login: | ||
self.redirect(users.create_login_url(self.request.uri)) | ||
return | ||
elif not self.is_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 Pager(object): | ||
|
||
def __init__(self, model=None,query=None, items_per_page=10): | ||
if model: | ||
self.query = model.all() | ||
elif query: | ||
self.query=query | ||
|
||
self.items_per_page = items_per_page | ||
|
||
def fetch(self, p): | ||
max_offset = self.query.count() | ||
n = max_offset / self.items_per_page | ||
if max_offset % self.items_per_page != 0: | ||
n += 1 | ||
|
||
if p < 0 or p > n: | ||
p = 1 | ||
offset = (p - 1) * self.items_per_page | ||
results = self.query.fetch(self.items_per_page, offset) | ||
|
||
links = {'prev': p - 1, 'next': p + 1, 'last': n} | ||
if links['next'] > n: | ||
links['next'] = 0 | ||
|
||
return (results, links) | ||
|
||
|
||
class BaseRequestHandler(webapp2.RequestHandler): | ||
def __init__(self): | ||
pass | ||
|
||
def initialize(self, request, response): | ||
webapp2.RequestHandler.initialize(self, request, response) | ||
self.blog = g_blog | ||
self.login_user = users.get_current_user() | ||
self.is_login = (self.login_user != None) | ||
if self.is_login: | ||
self.loginurl=users.create_logout_url(self.request.uri) | ||
#self.user = User.all().filter('user = ', self.login_user).get() or User(user = self.login_user) | ||
else: | ||
self.loginurl=users.create_login_url(self.request.uri) | ||
#self.user = None | ||
|
||
self.is_admin = users.is_current_user_admin() | ||
if self.is_admin: | ||
self.auth = 'admin' | ||
elif self.is_login: | ||
self.auth = 'login' | ||
else: | ||
self.auth = 'guest' | ||
|
||
try: | ||
self.referer = self.request.headers['referer'] | ||
except: | ||
self.referer = None | ||
|
||
|
||
|
||
self.template_vals = {'self':self,'blog':self.blog} | ||
|
||
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." | ||
|
||
self.template_vals.update( {'errorcode':errorcode,'message':message}) | ||
if errorcode>0: | ||
self.response.set_status(errorcode) | ||
|
||
|
||
errorfile=getattr(self.blog.theme,'error'+str(errorcode)) | ||
if not errorfile: | ||
errorfile=self.blog.theme.error | ||
self.response.out.write( template.render(errorfile, self.template_vals)) | ||
|
||
|
||
def render(self,template_file,values): | ||
""" | ||
Helper method to render the appropriate template | ||
""" | ||
|
||
|
||
html = memcache.get('%s:page:%s' % (self.login_user, self.request.path_qs)) | ||
|
||
|
||
if html == None: | ||
#try: | ||
sfile=getattr(self.blog.theme, template_file) | ||
self.template_vals.update(values) | ||
html = template.render(sfile, self.template_vals) | ||
#except Exception, e: # if theme files are not found, fall back to default theme | ||
#return self.response.out.write('template file "%s" dose not exist.'%(template_file)) | ||
#return self.error(-1,'template file "%s" dose not exist.'%(sfile)) | ||
|
||
# memcache.set('%s:page:%s' % (self.login_user, self.request.path_qs), html) | ||
|
||
self.response.out.write(html) | ||
|
||
|
||
def render2(self,template_file,template_vals={}): | ||
""" | ||
Helper method to render the appropriate template | ||
""" | ||
|
||
self.template_vals.update(template_vals) | ||
path = os.path.join(self.blog.rootdir, template_file) | ||
self.response.out.write(template.render(path, self.template_vals)) | ||
|
||
|
||
def param(self, name, **kw): | ||
return self.request.get(name, **kw) | ||
|
||
def write(self, s): | ||
self.response.out.write(s) | ||
|
||
|
||
|
||
def chk_login(self, redirect_url='/'): | ||
if self.is_login: | ||
return True | ||
else: | ||
self.redirect(redirect_url) | ||
return False | ||
|
||
def chk_admin(self, redirect_url='/'): | ||
if self.is_admin: | ||
return True | ||
else: | ||
self.redirect(redirect_url) | ||
return False | ||
|
||
class BasePublicPage(BaseRequestHandler): | ||
def initialize(self, request, response): | ||
BaseRequestHandler.initialize(self,request, response) | ||
m_pages=Entry.all().filter('entrytype =','page').filter('published =',True).filter('entry_parent =',0) | ||
self.template_vals.update({ | ||
'menu_pages':m_pages, | ||
'categories':Category.all(), | ||
'recent_comments':Comment.all().order('-date').fetch(5) | ||
}) |
Oops, something went wrong.