Return to Snippet

Revision: 31703
at September 10, 2010 23:35 by morningcatmedia


Initial Code
# Four files
# app.yaml
# Index.html
# Base.html
# helloworld.py


# app.yaml
application: helloworld

version: 1

runtime: python

api_version: 1



handlers:
- url: /static
  static_dir: static


- url: /stylesheets

  static_dir: stylesheets



- url: /.*

  script: helloworld.py

# Index.html This is the Django template 
{% extends "base.html" %}

{% block main %}
<div><input type="submit" onclick="onAddSuccess()" value="List Guestbook"></div>

{% endblock %}


{% block form %}
  {% if logged %}
         
      <form action="/sign" enctype="multipart/form-data" method="post">
        <div><textarea id="content" name="content" rows="3" cols="60"></textarea></div>

	  {% for type_val in type %}

	    <div><input type="radio" name="type" value="{{type_val}}">{{type_val}}</div>

	  {% endfor %}
       <input type="file" name="img" id="img" >
      <div><input type="submit" value="Sign Guestbook"></div>
   </form>
  {% endif %}
    <a href="{{ url }}">{{ url_linktext }}</a>
{% endblock %}

######################################
# Below is base.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">





<html>

  <head>

    <link type="text/css" rel="stylesheet" href="/stylesheets/main.css" />

    <script type="text/javascript" src="./static/json.js"></script>

    <script type="text/javascript">



    //

    // As mentioned at http://en.wikipedia.org/wiki/XMLHttpRequest

    //

    if( !window.XMLHttpRequest ) XMLHttpRequest = function()

    {

      try{ return new ActiveXObject("Msxml2.XMLHTTP.6.0") }catch(e){}

      try{ return new ActiveXObject("Msxml2.XMLHTTP.3.0") }catch(e){}

      try{ return new ActiveXObject("Msxml2.XMLHTTP") }catch(e){}

      try{ return new ActiveXObject("Microsoft.XMLHTTP") }catch(e){}

      throw new Error("Could not find an XMLHttpRequest alternative.")

    };



    //

    // Makes an AJAX request to a local server function w/ optional arguments

    //

    // functionName: the name of the server's AJAX function to call

    // opt_argv: an Array of arguments for the AJAX function

    //



  function GetRequest(function_name, opt_argv) {

  // If optional arguments was not provided, create it as empty

  if (!opt_argv)

    opt_argv = new Array();



  // Find if the last arg is a callback function; save it

  var callback = null;

  var len = opt_argv.length;

  if (len > 0 && typeof opt_argv[len-1] == 'function') {

    callback = opt_argv[len-1];

    opt_argv.length--;

  }

  var async = (callback != null);



  // Encode the arguments in to a URI

  var query = 'action=' + encodeURIComponent(function_name);

  for (var i = 0; i < opt_argv.length; i++) {

    var key = 'arg' + i;

    var val = JSON.stringify(opt_argv[i]);

    query += '&' + key + '=' + encodeURIComponent(val);

  }

  query += '&time=' + new Date().getTime(); // IE cache workaround



  // See http://en.wikipedia.org/wiki/XMLHttpRequest to make this cross-browser compatible

  var req = new XMLHttpRequest();



  // Create a 'GET' request w/ an optional callback handler

  req.open('GET', '/list?' + query, async);

  //req.open('GET', '/list', async);



  if (async) {

    req.onreadystatechange = function() {

      if(req.readyState == 4 && req.status == 200) {

        var response = null;

        try {

         response = JSON.parse(req.responseText);

        } catch (e) {

         response = req.responseText;

        }

        callback(response);

      }

    }

  }



  // Make the actual request

  req.send(null);

}



   function PostRequest(function_name, opt_argv) {



  if (!opt_argv)

    opt_argv = new Array();



  // Find if the last arg is a callback function; save it

  var callback = null;

  var len = opt_argv.length;

  if (len > 0 && typeof opt_argv[len-1] == 'function') {

    callback = opt_argv[len-1];

    opt_argv.length--;

  }

  var async = (callback != null);



  // Build an Array of parameters, w/ function_name being the first parameter

  var params = new Array(function_name);

  for (var i = 0; i < opt_argv.length; i++) {

    params.push(opt_argv[i]);

  }

  var body = JSON.stringify(params);



  // Create an XMLHttpRequest 'POST' request w/ an optional callback handler

  var req = new XMLHttpRequest();

  

  req.open('POST', '/rpc', async);



  req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

  req.setRequestHeader("Content-length", body.length);

  req.setRequestHeader("Connection", "close");



  if (async) {

    req.onreadystatechange = function() {

      if(req.readyState == 4 && req.status == 200) {

        var response = null;

        try {

         response = JSON.parse(req.responseText);

        } catch (e) {

         response = req.responseText;

        }

        callback(response);

      }

    }

  }



  // Make the actual request

  req.send(body);



}



    // Adds a stub function that will pass the arguments to the AJAX call

    function InstallPostFunction(obj, functionName) {

      obj[functionName] = function() { PostRequest(functionName, arguments); }

    }

    

    // Adds a stub function that will pass the arguments to the AJAX call

    function InstallGetFunction(obj, functionName) {

      obj[functionName] = function() { GetRequest(functionName, arguments); }

    }





    </script>

    <script type="text/javascript">



    // Server object that will contain the callable methods

    var server = {};

    var newsrv = {};

    // Insert 'Add' as the name of a callable method

    // Add will add the record to the database

    InstallPostFunction(server, 'Add');

    InstallGetFunction(newsrv, 'list');

    

    // Handy "macro"

    function $(id){

      return document.getElementById(id);

    }



    // Client function that calls a server rpc and provides a callback

    // For this application, doAdd will Post the entry



    function doAdd() {

      server.Add($('content').value, $('img').value, onAddSuccess);

    }



    // Callback for after a successful doAdd

    function onAddSuccess() {

      newsrv.list($('content').value, $('img').value,onGetSuccess);

    }

    

    function onGetSuccess(newresponse)   {

      document.getElementById('result').innerHTML = newresponse;

   }

    </script>

  </head>

  <body onLoad="onAddSuccess()">

  

 <div>

 {% block form %}

 {% endblock %}

 </div>

 <div>

  {% block main %}

  {% endblock %}

 </div>


 <div id="result">



 </div>





  </body>

</html>

###################################### 
# Below is helloworld.py
import cgi

import os

import datetime

import logging



from google.appengine.api import users

from google.appengine.ext import webapp

from google.appengine.ext.webapp.util import run_wsgi_app

from google.appengine.ext import db

from google.appengine.ext.webapp import template

from google.appengine.api import images

from google.appengine.api import memcache

from django.utils import simplejson



class Greeting(db.Model):

    author = db.UserProperty()

    content = db.StringProperty(multiline=True)

    date = db.DateTimeProperty(auto_now_add=True)

    type = db.StringProperty(indexed=False)

    avatar = db.BlobProperty(default=None)

    usremail = db.EmailProperty()



class MainPage(webapp.RequestHandler):

   def get(self):

    self.render_form()

    stats = memcache.get_stats()

    

    #self.response.out.write("<b>Cache Hits:%s</b><br>" % stats['hits'])

    #self.response.out.write("<b>Cache Misses:%s</b><br><br>" % stats['misses'])





   def render_form(self):

        greetings_query = Greeting.all().order('-date')

        #greetings_query=db.GqlQuery("SELECT * FROM Greeting WHERE content >= :1 AND content < :2", "ccc", u"abc" + u"\ufffd")

        greetings = greetings_query.fetch(10)

        type = set(["cat", "dog", "bird"])

        logged = False



        if users.get_current_user():

            logged = True

            url = users.create_logout_url(self.request.uri)

            url_linktext = 'Logout'

        else:

            logged = False

            url = users.create_login_url(self.request.uri)

            url_linktext = 'Login to comment'



        template_values = {

          'greetings': greetings,

          'url': url,

          'url_linktext': url_linktext,

          'logged': logged,

         }



        path = os.path.join(os.path.dirname(__file__), 'index.html')

        self.response.out.write(template.render(path, template_values))





class Guestbook(webapp.RequestHandler):

  def post(self, *args):

    greeting = Greeting()



    if users.get_current_user():

      greeting.author = users.get_current_user()



    greeting.content = self.request.get('content')

    greeting.type = self.request.get('type')

    

    if self.request.get('img'):

        picture = self.request.get('img')

        avatar = images.resize(self.request.get("img"), 32, 32)

        greeting.avatar = db.Blob(avatar)

    greeting.put()

    self.redirect('/')



  def get(self):
        # Here we need to put the memcache call
        # greetings = memcache.get("greetings")
        # if greetings is not None:
        #     return greetings
        # else:

        greetings_query = Greeting.all().order('-date')

        #greetings_query=db.GqlQuery("SELECT * FROM Greeting WHERE content >= :1 AND content < :2", "ccc", u"abc" + u"\ufffd")

        greetings = greetings_query.fetch(10)

        logged = False



        if users.get_current_user():

            logged = True

            url = users.create_logout_url(self.request.uri)

            url_linktext = 'Logout'

        else:

            logged = False

            url = users.create_login_url(self.request.uri)

            url_linktext = 'Login to comment'



        for greeting in greetings:

            self.response.out.write("<p>")

            self.response.out.write(greeting.content)

            #self.response.out.write(greeting.avatar)

            self.response.out.write('<img src=http://localhost:8080/img?img_id='+str(greeting.key())+' </img>')

            self.response.out.write("</p>")



class Image (webapp.RequestHandler):

  def get(self):

    greeting = db.get(self.request.get("img_id"))

    if greeting.avatar:

      self.response.headers['Content-Type'] = "image/png"

      self.response.out.write(greeting.avatar)

    else:

      self.response.out.write("No image")





#RPC Functions



class RPCHandler(webapp.RequestHandler):

    """ Allows the functions defined in the RPCMethods class to be RPCed."""

    def __init__(self):

        webapp.RequestHandler.__init__(self)

        self.methods = RPCMethods()



    def post(self, *args):

        args = simplejson.loads(self.request.body)

        func, args = args[0], args[1:]



        if func[0] == '_':

            self.error(403) # access denied

            return



        func = getattr(self.methods, func, None)

        if not func:

            self.error(404) # file not found

            return



        result = func(*args)

        self.response.out.write(simplejson.dumps(result))



    def get(self):

        func = None



        action = self.request.get('action')

        if action:

            if action[0] == '_':

                self.error(403) # access denied

                return

            else:

                func = getattr(self.methods, action, None)



        if not func:

            self.error(404) # file not found

            return



        args = ()

        while True:

            key = 'arg%d' % len(args)

            val = self.request.get(key)

            if val:

                args += (simplejson.loads(val),)

            else:

                break

        result = func(*args)

        self.response.out.write(simplejson.dumps(result))





class RPCMethods():

    """ Defines the methods that can be RPCed.

    NOTE: Do not allow remote callers access to private/protected "_*" methods.

    """



    def Add(self, *args):

       greeting = Greeting()

       greeting.content = args[0]

       #Can't do this since I need upload the image via ajax, and that's not allowed.

       #greeting.avatar = args[1]



       greeting.put()

         

       return True



#**********





def main():

    application = webapp.WSGIApplication(

                                     [('/', MainPage),

                                      ('/img',Image),

                                      ('/rpc', RPCHandler),

                                      ('/list',Guestbook),

                                      ('/sign',Guestbook),

                                       ],

                                     debug=True)

    run_wsgi_app(application)



if __name__ == "__main__":

  main()

Initial URL


Initial Description


Initial Title
Google App Ajax Post Comment

Initial Tags
ajax, google

Initial Language
Python