public
Description: Slightly higher than low-level interface to GAE.
Clone URL: git://github.com/dustin/gae-base.git
Search Repo:
Initial version of a slightly-higher-level GAE API.
dustin (author)
Sat Apr 12 17:30:30 -0700 2008
commit  68dbb54deeb5b35afe65b601f57162f6bb2bf825
tree    245f5de21f924d13c559ab756c7ac59ee2be3731
...
 
 
 
 
...
1
2
3
4
0
@@ -0,0 +1,4 @@
0
+*.pyc
0
+db
0
+tmp
0
+log
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
0
@@ -0,0 +1,14 @@
0
+application: yourappnamehere
0
+version: 1
0
+runtime: python
0
+api_version: 1
0
+
0
+handlers:
0
+# - url: /
0
+# static_files: public/index.html
0
+# upload: public/index.html
0
+- url: /(.*\.(js|css|png|gif|jpg|ico))
0
+ static_files: public/\1
0
+ upload: public/(.*\.(js|css|png|gif|jpg))
0
+- url: .*
0
+ script: main.py
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
0
@@ -0,0 +1,16 @@
0
+#!/usr/bin/env python
0
+"""
0
+My app's controllers.
0
+
0
+Copyright (c) 2008 Dustin Sallings <dustin@spy.net>
0
+"""
0
+import logging
0
+
0
+import spy.controllers
0
+
0
+class MainHandler(spy.controllers.BaseHandler,
0
+ spy.controllers.RequestLogMixin):
0
+
0
+ def get(self):
0
+ logging.info("Look, I'm in method %s", self.currentMethod)
0
+ self.renderTemplate('index.html')
...
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
0
@@ -0,0 +1,11 @@
0
+indexes:
0
+
0
+# AUTOGENERATED
0
+
0
+# This index.yaml is automatically updated whenever the dev_appserver
0
+# detects that a new type of query is run. If you want to manage the
0
+# index.yaml file manually, remove the above marker line (the line
0
+# saying "# AUTOGENERATED"). If you want to manage some indexes
0
+# manually, move them above the marker line. The index.yaml file is
0
+# automatically uploaded to the admin console when you next deploy
0
+# your application using appcfg.py.
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
0
@@ -0,0 +1,18 @@
0
+#!/usr/bin/env python
0
+
0
+import time
0
+
0
+import wsgiref.handlers
0
+
0
+from google.appengine.ext import webapp
0
+
0
+import controllers
0
+
0
+def main():
0
+ application = webapp.WSGIApplication([
0
+ ('/', controllers.MainHandler),
0
+ ], debug=True)
0
+ wsgiref.handlers.CGIHandler().run(application)
0
+
0
+if __name__ == '__main__':
0
+ main()
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
0
@@ -0,0 +1,71 @@
0
+html {
0
+ font-family: verdana;
0
+}
0
+
0
+.info {
0
+ background: #fe0;
0
+ color: inherit;
0
+ padding: 2px;
0
+}
0
+
0
+.error {
0
+ background: #fe0;
0
+ color: red;
0
+ font-weight: bold;
0
+ padding: 2px;
0
+}
0
+
0
+.fieldWithErrors input {
0
+ border: solid red 3px;
0
+}
0
+
0
+#footer {
0
+ clear: both;
0
+ font-size: small;
0
+ border-top: solid black 1px;
0
+ margin-top: 1em;
0
+}
0
+
0
+#openid_url {
0
+ background: url(/images/login-bg.gif) no-repeat #FFF 5px;
0
+ padding-left: 25px;
0
+}
0
+
0
+#map_div_id {
0
+ margin-left: 300px;
0
+}
0
+
0
+#onmap {
0
+ float: left;
0
+ width: 300px;
0
+}
0
+
0
+#approval_map, #submission_map {
0
+ float: right;
0
+}
0
+
0
+img {
0
+ border: none;
0
+}
0
+
0
+pre code {
0
+ display: block;
0
+ background: #222;
0
+ color: green;
0
+}
0
+
0
+table {
0
+ font-size: small;
0
+ border: solid 1px;
0
+ margin-left: 1em;
0
+ border-collapse: collapse;
0
+}
0
+
0
+table th {
0
+ border: solid 1px;
0
+ background-color: #ccc;
0
+}
0
+
0
+table td {
0
+ border: solid 1px;
0
+}
...
 
 
 
 
 
 
 
 
 
0
...
1
2
3
4
5
6
7
8
9
10
0
@@ -0,0 +1,9 @@
0
+#!/usr/bin/env python
0
+"""
0
+Some controller helpers for making Google App Engine apps.
0
+
0
+Copyright (c) 2008 Dustin Sallings <dustin@spy.net>
0
+"""
0
+
0
+from base import *
0
+from log import *
0
\ No newline at end of file
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
0
@@ -0,0 +1,58 @@
0
+import os
0
+import logging
0
+
0
+from google.appengine.ext import webapp
0
+from google.appengine.ext.webapp import template
0
+
0
+import models
0
+
0
+TEMPLATES = os.path.join(os.path.dirname(__file__), '..', '..', 'templates')
0
+
0
+# Created classes
0
+_handlers = {}
0
+
0
+class BaseHandlerMeta(type):
0
+ """This metaclass generates and installs filter methods."""
0
+
0
+ def __new__(cls, name, bases, attrs):
0
+ # If this isn't a subclass of BaseHandler, don't do anything special.
0
+ if name == 'BaseHandler' or not [c for c in bases if issubclass(c, BaseHandler)]:
0
+ return super(BaseHandlerMeta, cls).__new__(
0
+ cls, name, bases, attrs)
0
+
0
+ fqn = attrs['__module__'] + "." + name
0
+ if _handlers.has_key(fqn):
0
+ return _handlers[fqn]
0
+
0
+ # Intercept all methods and add a before_x and after_x method.
0
+ for k,v in attrs.items():
0
+ if callable(v) and not (k.startswith('before_') or k.startswith('after_')):
0
+
0
+ def wrapper(s):
0
+ getattr(s, 'before_' + k, lambda *args: None)()
0
+ s.currentMethod = k
0
+ v(s)
0
+ del s.currentMethod
0
+ getattr(s, 'after_' + k, lambda *args: None)()
0
+
0
+ attrs[k] = wrapper
0
+
0
+ new_class = type.__new__(cls, name, bases, attrs)
0
+ logging.debug("Created a %s/%s/%s/%s as %s",
0
+ str(cls), str(name), str(bases), str(attrs), str(new_class))
0
+
0
+ _handlers[fqn] = new_class
0
+ return _handlers[fqn]
0
+
0
+ def __makeWrappedMethod(methodName, originalMethod):
0
+ return wrapper
0
+
0
+class BaseHandler(webapp.RequestHandler):
0
+ """Base class for all of your controllers."""
0
+
0
+ __metaclass__ = BaseHandlerMeta
0
+
0
+ def renderTemplate(self, name, args={}):
0
+ """Render the given named template under templates/"""
0
+ path = os.path.join(TEMPLATES, name)
0
+ self.response.out.write(template.render(path, args))
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
0
@@ -0,0 +1,41 @@
0
+#!/usr/bin/env python
0
+"""
0
+Tools to help with logging.
0
+
0
+Copyright (c) 2008 Dustin Sallings <dustin@spy.net>
0
+"""
0
+
0
+import time
0
+import logging
0
+
0
+class RequestLogMixin(object):
0
+ """Add this to your bases to log each http method with timings."""
0
+
0
+ __HTTP_METHODS=['get', 'post', 'put', 'head', 'delete', 'trace']
0
+ __WRAPS=(['before_' + x for x in __HTTP_METHODS] +
0
+ ['after_' + x for x in __HTTP_METHODS])
0
+
0
+ def __init__(self):
0
+ super(RequestLogMixin, self).__init__()
0
+ self.tracked = {}
0
+
0
+ def __before(self, method):
0
+ def x(*args): self.tracked[method]=time.time()
0
+ return x
0
+
0
+ def __after(self, method):
0
+ def x(*args):
0
+ logging.info("Finished %s.%s in %ss", type(self), method,
0
+ (time.time()-self.tracked[method]))
0
+ return x
0
+
0
+ def __getattr__(self, attr):
0
+ if attr in self.__WRAPS:
0
+ if attr.startswith('before_'):
0
+ rv=self.__before(attr.replace("before_", ""))
0
+ else:
0
+ rv=self.__after(attr.replace("after_", ""))
0
+ return rv
0
+ else:
0
+ raise AttributeError(attr)
0
+
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
0
@@ -0,0 +1,14 @@
0
+<?xml version="1.0" encoding="UTF-8"?>
0
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
0
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
0
+
0
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
0
+ <head>
0
+ <title>{% block fulltitle %}Your App{% endblock %}</title>
0
+ <link rel="stylesheet" type="text/css" href="/css/style.css"/>
0
+ </head>
0
+
0
+ <body>
0
+ {% block body %}{% endblock %}
0
+ </body>
0
+</html>
...
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
0
@@ -0,0 +1,8 @@
0
+{% extends "base.html" %}
0
+
0
+{% block body %}
0
+ <h1>Hello!</h1>
0
+ <p>
0
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
0
+ </p>
0
+{% endblock %}

Comments

    No one has commented yet.