Goolge提供很多的例程,挑选了simple-ajax-chat,不为别的就因为一看名字就知道大概要做点什么,其他的一些基本不知道做什么用。
代码位置:http://code.google.com/p/google-app-engine-samples/source/browse/trunk/simple-ajax-chat
代码不多,只有188行(如下):
1 import cgi
2 import os
3 import urllib
4 import logging
5 import pickle
6
7 from google.appengine.api import users
8 from google.appengine.ext import webapp
9 from google.appengine.ext.webapp.util import run_wsgi_app
10 from google.appengine.ext import db
11 from google.appengine.ext.webapp import template
12 from google.appengine.api import memcache
13
14 # Set the debug level
15 _DEBUG = True
16
17 class GreetingUser(db.Model):
18 greeting_user = db.UserProperty()
19 joined = db.DateTimeProperty(auto_now_add=True)
20 picture = db.StringProperty()
21 seated = db.StringProperty()
22 website = db.StringProperty()
23
24 class Greeting(db.Model):
25 author = db.UserProperty()
26 content = db.StringProperty(multiline=True)
27 date = db.DateTimeProperty(auto_now_add=True)
28
29 class BaseRequestHandler(webapp.RequestHandler):
30 """Base request handler extends webapp.Request handler
31
32 It defines the generate method, which renders a Django template
33 in response to a web request
34 """
35
36 def generate(self, template_name, template_values={}):
37 """Generate takes renders and HTML template along with values
38 passed to that template
39
40 Args:
41 template_name: A string that represents the name of the HTML template
42 template_values: A dictionary that associates objects with a string
43 assigned to that object to call in the HTML template. The defualt
44 is an empty dictionary.
45 """
46 # We check if there is a current user and generate a login or logout URL
47 user = users.get_current_user()
48
49 if user:
50 log_in_out_url = users.create_logout_url('/')
51 else:
52 log_in_out_url = users.create_login_url(self.request.path)
53
54 # We'll display the user name if available and the URL on all pages
55 values = {'user': user, 'log_in_out_url': log_in_out_url}
56 values.update(template_values)
57
58 # Construct the path to the template
59 directory = os.path.dirname(__file__)
60 path = os.path.join(directory, 'templates', template_name)
61
62 # Respond to the request by rendering the template
63 return template.render(path, values, debug=_DEBUG)
64
65 class MainRequestHandler(BaseRequestHandler):
66 def get(self):
67 if users.get_current_user():
68 url = users.create_logout_url(self.request.uri)
69 url_linktext = 'Logout'
70 else:
71 url = users.create_login_url(self.request.uri)
72 url_linktext = 'Login'
73
74 template_values = {
75 'url': url,
76 'url_linktext': url_linktext,
77 }
78
79 self.response.out.write(self.generate('index.html', template_values));
80
81 class ChatsRequestHandler(BaseRequestHandler):
82 MEMCACHE_KEY = 'greetings'
83 MEMCACHE_TEMPLATE = 'greetings_template'
84
85 def get(self):
86 template = memcache.get(self.MEMCACHE_TEMPLATE)
87 self.response.out.write(template)
88
89 def post(self):
90 greeting = Greeting()
91
92 if users.get_current_user():
93 greeting.author = users.get_current_user()
94
95 greeting.content = self.request.get('content')
96 greeting.put()
97
98 greetingsString = memcache.get(self.MEMCACHE_KEY)
99 if greetingsString is None:
100 greetingsList = []
101 else:
102 greetingsList = pickle.loads(greetingsString)
103 if len(greetingsList) >= 40:
104 greetingsList.pop(0)
105 greetingsList.append(greeting)
106
107 if not memcache.set(self.MEMCACHE_KEY, pickle.dumps(greetingsList)):
108 logging.debug("Memcache set failed:")
109
110 template_values = {
111 'greetings': greetingsList,
112 }
113 template = self.generate('chats.html', template_values)
114 if not memcache.set(self.MEMCACHE_TEMPLATE, template):
115 logging.debug("Memcache set failed:")
116
117 self.response.out.write(template)
118
119
120 class EditUserProfileHandler(BaseRequestHandler):
121 """This allows a user to edit his or her wiki profile. The user can upload
122 a picture and set a feed URL for personal data
123 """
124 def get(self, user):
125 # Get the user information
126 unescaped_user = urllib.unquote(user)
127 greeting_user_object = users.User(unescaped_user)
128 # Only that user can edit his or her profile
129 if users.get_current_user() != greeting_user_object:
130 self.redirect('/view/StartPage')
131
132 greeting_user = GreetingUser.gql('WHERE greeting_user = :1', greeting_user_object).get()
133 if not greeting_user:
134 greeting_user = GreetingUser(greeting_user=greeting_user_object)
135 greeting_user.put()
136
137 self.response.out.write(self.generate('edit_user.html', template_values={'queried_user': greeting_user}))
138
139 def post(self, user):
140 # Get the user information
141 unescaped_user = urllib.unquote(user)
142 greeting_user_object = users.User(unescaped_user)
143 # Only that user can edit his or her profile
144 if users.get_current_user() != greeting_user_object:
145 self.redirect('/')
146
147 greeting_user = GreetingUser.gql('WHERE greeting_user = :1', greeting_user_object).get()
148
149 greeting_user.picture = self.request.get('user_picture')
150 greeting_user.website = self.request.get('user_website')
151 greeting_user.seated = self.request.get('user_seated')
152 greeting_user.put()
153
154
155 self.redirect('/user/%s' % user)
156
157 class UserProfileHandler(BaseRequestHandler):
158 """Allows a user to view another user's profile. All users are able to
159 view this information by requesting http://wikiapp.appspot.com/user/*
160 """
161
162 def get(self, user):
163 """When requesting the URL, we find out that user's WikiUser information.
164 We also retrieve articles written by the user
165 """
166 # Webob over quotes the request URI, so we have to unquote twice
167 unescaped_user = urllib.unquote(urllib.unquote(user))
168
169 # Query for the user information
170 greeting_user_object = users.User(unescaped_user)
171 greeting_user = GreetingUser.gql('WHERE greeting_user = :1', greeting_user_object).get()
172
173 # Generate the user profile
174 self.response.out.write(self.generate('user.html', template_values={'queried_user': greeting_user}))
175
176
177 application = webapp.WSGIApplication(
178 [('/', MainRequestHandler),
179 ('/getchats', ChatsRequestHandler),
180 ('/user/([^/]+)', UserProfileHandler),
181 ('/edituser/([^/]+)', EditUserProfileHandler)],
182 debug=True)
183
184 def main():
185 run_wsgi_app(application)
186
187 if __name__ == "__main__":
188 main()
177行指明了程序的url地址和对应的处理;
65行,MainRequestHandler主界面