add demonstration of geosearch
[gae-samples.git] / paging / suggestkey.py
blobd0154fa0898695a73894379cb4413e675812097c
1 #!/usr/bin/env python
3 # Copyright 2008 Google Inc.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
18 """Suggestion Box - An example paging application.
20 A simple Suggestion Box application that demonstrates
21 paging by using the __key__ property provided for every
22 entity.
24 """
26 import base64
27 import datetime
28 import hashlib
29 import logging
30 import os
31 import pickle
32 import wsgiref.handlers
34 from google.appengine.ext import webapp
35 from google.appengine.ext.webapp import template
36 from google.appengine.ext import db
37 from google.appengine.api import users
38 from google.appengine.ext.webapp.util import login_required
39 from time import mktime
42 PAGESIZE = 5
45 class SuggestionByKey(db.Model):
46 """
47 A suggestion in the suggestion box, which we want to display
48 in the order they were created.
49 """
50 suggestion = db.StringProperty()
51 created = db.DateTimeProperty(auto_now_add=True)
54 def encodebookmark(created, key):
55 """
56 From the created timestamp and the key for an entity create
57 a base64 encoded bookmark that can be used for paging.
59 Args:
60 created: datetime when the entity was created.
61 key: db.Key() of the entity.
63 Returns:
64 A base64 encoded representation of the values.
65 """
66 timestamp = mktime(created.timetuple())+1e-6*created.microsecond
67 return base64.b64encode("%f|%s" % (timestamp, key))
70 def decodebookmark(b64bookmark):
71 """
72 Takes a string encoded by 'encodebookmark' and reverses
73 the process.
75 Args:
76 A base64 encoded representation of the values.
78 Returns:
79 (created, key) where
81 created: datetime when the entity was created.
82 key: db.Key() of the entity.
83 """
84 timestamp, key = base64.b64decode(b64bookmark).split('|')
85 created = datetime.datetime.fromtimestamp(float(timestamp))
86 return created, key
89 class SuggestionByKeyHandler(webapp.RequestHandler):
90 """
91 Handles the creation of a single Suggestion, and the display
92 of suggestions broken into PAGESIZE pages.
93 """
95 @login_required
96 def get(self):
97 bookmark = self.request.get('bookmark')
98 next = None
99 if bookmark:
100 created, key = decodebookmark(bookmark)
101 logging.info('key = %s, created = %s' % (key, created))
102 query = SuggestionByKey.gql(
103 ' WHERE created = :created AND __key__ >= :key ORDER BY __key__ ASC',
104 created = created, key = db.Key(key))
105 suggestions = query.fetch(PAGESIZE+1)
106 logging.info(type(suggestions))
107 if len(suggestions) < (PAGESIZE + 1):
108 logging.info('Going for more entities since we only got %d' % len(suggestions))
109 remainder = PAGESIZE + 1 - len(suggestions)
110 query = SuggestionByKey.gql(
111 'WHERE created < :created ORDER BY created DESC, __key__ ASC',
112 created = created)
113 moresuggestions = query.fetch(remainder)
114 logging.info('Got %d more' % len(moresuggestions))
115 suggestions += moresuggestions
116 logging.info('For a total of %d entities' % len(suggestions))
117 else:
118 query = SuggestionByKey.gql('ORDER BY created DESC, __key__ ASC')
119 suggestions = query.fetch(PAGESIZE+1)
120 if len(suggestions) == PAGESIZE+1:
121 next = encodebookmark(suggestions[-1].created, suggestions[-1].key())
122 suggestions = suggestions[:PAGESIZE]
124 template_values = {'next': next, 'suggestions': suggestions}
125 template_file = os.path.join(os.path.dirname(__file__), 'suggestion.html')
126 self.response.out.write(template.render(template_file, template_values))
128 def post(self):
129 s = SuggestionByKey(suggestion = self.request.get('suggestion'))
130 s.put()
131 self.redirect('/key/')
134 class SuggestionByKeyPopulate(webapp.RequestHandler):
136 Handles populating the datastore with some sample
137 Suggestions to see how the paging works.
139 def post(self):
140 now = datetime.datetime.now()
141 for i in range(6):
142 s = SuggestionByKey(suggestion = 'Suggestion %d' % i, created = now)
143 s.put()
144 self.redirect('/key/')
147 def main():
148 application = webapp.WSGIApplication([
149 ('/key/pop/', SuggestionByKeyPopulate),
150 ('/key/', SuggestionByKeyHandler)
151 ], debug=True)
152 wsgiref.handlers.CGIHandler().run(application)
155 if __name__ == '__main__':
156 main()