root/websites/appspot.com/blog/trunk/blog/blog.py @ 9474

Revision 9474, 5.9 kB (checked in by mattn, 6 years ago)

websites/appspot.com/blog:

  • google app engineで動くweblogシステム(って程ではないが)を追加
  • 名前をまず決めにゃならん...(きっとディレクトリ名も変えちゃう)
Line 
1#!-*- coding:utf-8 -*-
2import os
3import cgi
4import logging
5import wsgiref.handlers
6from google.appengine.ext import db
7from google.appengine.ext import webapp
8from google.appengine.api import users
9from google.appengine.api import mail
10from google.appengine.ext.webapp import template
11
12top_path = '/blog/'
13
14blog_info = {
15  'title'       : 'Weblog',
16  'description' : 'my short stories',
17  'admin'       : 'admin',
18  'mail'        : 'admin@example.com',
19  'link'        : '',
20  'root'        : top_path,
21  'css'         : '/blog/static/blog.css',
22  'rss'         : '',
23  'flavour'     : 'html',
24  'num_entries' : 5,
25  'plugins'     : [],
26}
27
28class Entry(db.Model):
29  title = db.StringProperty(required=True)
30  link = db.StringProperty(required=True)
31  author = db.UserProperty(required=True)
32  description = db.StringProperty(required=True, multiline=True)
33  timestamp = db.DateTimeProperty(required=True, auto_now=True)
34
35def fixPath(path):
36  return path.replace("%25", "%").replace("//", "/")
37
38def authUser(path):
39  path = fixPath(path)
40  blog_info['author'] = users.get_current_user()
41  blog_info['login_url'] = users.create_login_url(path)
42  blog_info['logout_url'] = users.create_logout_url(path)
43  blog_info['is_admin'] = users.is_current_user_admin()
44
45try:
46  plugin_path = os.path.join(os.path.dirname(__file__), "plugins")
47  for f in os.listdir(plugin_path):
48    name, ext = os.path.splitext(f)
49    if ext != '.py' or name == '__init__': continue
50    path = top_path[1:-1].replace('/', '.')
51    try:
52      modname = '%s.plugins.%s' % (path, name)
53      logging.info('loading %s' % modname)
54      m = __import__(modname, globals(), locals(), [''])
55      blog_info['plugins'].append(m)
56    except Exception, e:
57      logging.error(e)
58  logging.info('loaded plugins')
59except Exception, e:
60  logging.error(e)
61
62class MainPage(webapp.RequestHandler):
63  def __init__(self):
64    self.blog_info = blog_info.copy()
65    webapp.RequestHandler.__init__(self)
66
67  def new_entry(self, **kwds):
68    return Entry(
69        title = kwds.pop('title', None),
70        link = kwds.pop('link', None),
71        author = kwds.pop('link', users.get_current_user()),
72        description = kwds.pop('description', None),
73    )
74
75  def fill_entry(self, entry):
76    entry.category = top_path[:-1]
77    entry.linkid = entry.link
78    entry.linkkey = self.blog_info['link'] + entry.linkid[1:]
79    entry.link = self.blog_info['link'] + "%s.%s" % (entry.linkid[1:], self.blog_info['flavour'])
80
81  def init_plugins(self):
82    if len(self.blog_info['link']) == 0:
83      self.blog_info['link'] = "%s://%s%s" % (self.request.scheme, self.request.host, top_path)
84    if len(self.blog_info['rss']) == 0:
85      self.blog_info['rss'] = "%s://%s%s%s" % (self.request.scheme, self.request.host, top_path, 'index.rss')
86    if self.blog_info['css'][0] == '/':
87      self.blog_info['css'] = "%s://%s%s" % (self.request.scheme, self.request.host, self.blog_info['css'])
88    for plugin in self.blog_info['plugins']:
89      try:
90        method = getattr(plugin, 'init')
91        if method:
92          if method(self): logging.info("initialized plugin: %s" % plugin.__name__)
93      except Exception, e:
94        self.blog_info['plugins'].remove(plugin)
95
96  def call_plugins(self, method, *args):
97    ret = 0
98    for plugin in self.blog_info['plugins']:
99      try:
100        func = getattr(plugin, method)
101        if func:
102          if func(self, *args): ret = ret + 1
103      except AttributeError, e:
104        pass
105    if ret: logging.info("%s: called %d functions" % (method, ret))
106    return ret
107
108  def get_template(self, method) :
109    return os.path.join(os.path.dirname(__file__),
110            "templates", "%s.%s" % (method, self.blog_info['flavour']))
111
112  def get_path_ext(self):
113    path, ext = os.path.splitext(fixPath(self.request.path)[len(top_path)-1:])
114    if ext: ext = ext[1:]
115    return path, ext
116
117  def post(self):
118    authUser(self.request.path)
119    path_info, flavour = self.get_path_ext()
120    if not flavour: flavour = self.blog_info['flavour']
121    else: self.blog_info['flavour'] = flavour
122
123    self.init_plugins()
124    entry = db.GqlQuery('SELECT * FROM Entry WHERE link = :path_info', path_info=path_info).get()
125    self.call_plugins('post', entry)
126    self.call_plugins('finish', entry)
127    self.redirect(top_path[:-1] + "%s.%s" % (path_info, flavour));
128
129  def get(self):
130    authUser(self.request.path)
131    path_info, flavour = self.get_path_ext()
132    if not flavour: flavour = self.blog_info['flavour']
133    else: self.blog_info['flavour'] = flavour
134
135    self.init_plugins()
136    template_values = {
137      'blog_info' : self.blog_info,
138      'path_info' : path_info,
139    }
140    name = os.path.basename(path_info)
141    if name == 'index':
142      path_info = path_info[:-len(name)]
143    if path_info and path_info[-1:] != '/':
144      self.blog_info['method'] = 'entry'
145      entry = db.GqlQuery('SELECT * FROM Entry WHERE link = :path_info', path_info=path_info).get()
146      if entry: self.fill_entry(entry)
147      self.call_plugins('entry', entry)
148      template_values['entry'] = entry
149    else:
150      self.blog_info['method'] = 'entries'
151      entries = []
152      if self.call_plugins('entries', entries) == 0:
153        for entry in db.GqlQuery('SELECT * FROM Entry ORDER BY timestamp DESC'):
154          if entry.link[:len(path_info)] == path_info:
155            self.fill_entry(entry)
156            entries.append(entry)
157            if len(entries) >= int(self.blog_info['num_entries']): break
158      for entry in entries:
159        self.call_plugins('entry', entry)
160      template_values['entries'] = entries
161    path = os.path.join(os.path.dirname(__file__), self.get_template(self.blog_info['method']))
162    content_type = template.render(self.get_template('content_type'), template_values).rstrip('\n')
163    self.response.headers['Content-Type'] = content_type
164    self.response.out.write(template.render(path, template_values))
165
166def main():
167  application = webapp.WSGIApplication([(top_path + '.*', MainPage)], debug=True)
168  wsgiref.handlers.CGIHandler().run(application)
169
170if __name__ == '__main__':
171  main()
Note: See TracBrowser for help on using the browser.