Home | History | Annotate | Download | only in server
      1 #!/usr/bin/env python
      2 #
      3 # Copyright 2007 Google Inc.
      4 #
      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
      8 #
      9 #     http://www.apache.org/licenses/LICENSE-2.0
     10 #
     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.
     16 #
     17 
     18 import appengine_config
     19 
     20 import cgi
     21 import datetime
     22 import time
     23 import wsgiref.handlers
     24 
     25 from google.appengine.ext import db
     26 from google.appengine.api import users
     27 from google.appengine.ext import webapp
     28 
     29 from protorpc import message_types
     30 from protorpc import messages
     31 from protorpc import remote
     32 from protorpc.webapp import service_handlers
     33 
     34 
     35 class Greeting(db.Model):
     36   author = db.UserProperty()
     37   content = db.StringProperty(multiline=True)
     38   date = db.DateTimeProperty(auto_now_add=True)
     39 
     40 
     41 class MainPage(webapp.RequestHandler):
     42   def get(self):
     43     self.response.out.write('<html><body>')
     44 
     45     greetings = db.GqlQuery("SELECT * "
     46                             "FROM Greeting "
     47                             "ORDER BY date DESC LIMIT 10")
     48 
     49     for greeting in greetings:
     50       if greeting.author:
     51         self.response.out.write('<b>%s</b> wrote:' % greeting.author.nickname())
     52       else:
     53         self.response.out.write('An anonymous person wrote:')
     54       self.response.out.write('<blockquote>%s</blockquote>' %
     55                               cgi.escape(greeting.content))
     56 
     57 
     58     self.response.out.write("""
     59           <form action="/sign" method="post">
     60             <div><textarea name="content" rows="3" cols="60"></textarea></div>
     61             <div><input type="submit" value="Sign Guestbook"></div>
     62           </form>
     63         </body>
     64       </html>""")
     65 
     66 
     67 class Guestbook(webapp.RequestHandler):
     68   def post(self):
     69     greeting = Greeting()
     70 
     71     if users.get_current_user():
     72       greeting.author = users.get_current_user()
     73 
     74     greeting.content = self.request.get('content')
     75     greeting.put()
     76     self.redirect('/')
     77 
     78 
     79 class Note(messages.Message):
     80 
     81   text = messages.StringField(1, required=True)
     82   when = messages.IntegerField(2)
     83 
     84 
     85 class GetNotesRequest(messages.Message):
     86 
     87   limit = messages.IntegerField(1, default=10)
     88   on_or_before = messages.IntegerField(2)
     89 
     90   class Order(messages.Enum):
     91    WHEN = 1
     92    TEXT = 2
     93   order = messages.EnumField(Order, 3, default=Order.WHEN)
     94 
     95 
     96 class Notes(messages.Message):
     97   notes = messages.MessageField(Note, 1, repeated=True)
     98 
     99 
    100 class PostService(remote.Service):
    101 
    102   # Add the remote decorator to indicate the service methods
    103   @remote.method(Note)
    104   def post_note(self, request):
    105 
    106     # If the Note instance has a timestamp, use that timestamp
    107     if request.when is not None:
    108       when = datetime.datetime.utcfromtimestamp(request.when)
    109 
    110     # Else use the current time
    111     else:
    112       when = datetime.datetime.now()
    113     note = Greeting(content=request.text, date=when)
    114     note.put()
    115     return message_types.VoidMessage()
    116 
    117   @remote.method(GetNotesRequest, Notes)
    118   def get_notes(self, request):
    119    query = Greeting.all().order('-date')
    120 
    121    if request.on_or_before:
    122     when = datetime.datetime.utcfromtimestamp(
    123        request.on_or_before)
    124     query.filter('date <=', when)
    125 
    126    notes = []
    127    for note_model in query.fetch(request.limit):
    128     if note_model.date:
    129       when = int(time.mktime(note_model.date.utctimetuple()))
    130     else:
    131       when = None
    132     note = Note(text=note_model.content, when=when)
    133     notes.append(note)
    134 
    135    if request.order == GetNotesRequest.Order.TEXT:
    136     notes.sort(key=lambda note: note.text)
    137 
    138    return Notes(notes=notes)
    139 
    140 
    141 service_mapping = service_handlers.service_mapping(
    142     [('/postservice', PostService)])
    143 
    144 application = webapp.WSGIApplication([
    145   ('/', MainPage),
    146   ('/sign', Guestbook),
    147 ] + service_mapping,
    148 debug=True)
    149 
    150 
    151 def main():
    152   wsgiref.handlers.CGIHandler().run(application)
    153 
    154 
    155 if __name__ == '__main__':
    156   main()
    157