diff --git a/GAE/README.md b/GAE/README.md
new file mode 100644
index 0000000..671768b
--- /dev/null
+++ b/GAE/README.md
@@ -0,0 +1,8 @@
+This is a simple Google App Engine (GAE) application written in Python.
+
+Features:
+ * UTF-8 strings
+ * SOAP client with Suds
+ * custom 3rd party library
+
+The application is deployed to: http://helloworld-ghajba.appspot.com/
diff --git a/GAE/helloworld/app.yaml b/GAE/helloworld/app.yaml
new file mode 100644
index 0000000..8f84fed
--- /dev/null
+++ b/GAE/helloworld/app.yaml
@@ -0,0 +1,15 @@
+application: helloworld-ghajba
+version: 1
+runtime: python27
+api_version: 1
+threadsafe: true
+
+libraries:
+- name: webapp2
+ version: 2.5.2
+- name: jinja2
+ version: 2.6
+
+handlers:
+- url: /.*
+ script: helloworld.application
diff --git a/GAE/helloworld/helloworld.py b/GAE/helloworld/helloworld.py
new file mode 100644
index 0000000..64c9d3e
--- /dev/null
+++ b/GAE/helloworld/helloworld.py
@@ -0,0 +1,31 @@
+# coding=utf-8
+import webapp2
+import os
+import sys
+import jinja2
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'lib'))
+import weather_endpoint
+
+JINJA_ENVIRONMENT = jinja2.Environment(
+ loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
+ extensions=['jinja2.ext.autoescape'],
+ autoescape=True)
+
+class MainPage(webapp2.RequestHandler):
+ def get(self):
+ weather_description = None
+ weather_picture = None
+ if self.request.get('zip'):
+ weather_description, weather_picture = weather_endpoint.get_city_weather(self.request.get('zip'))
+ template_values = {
+ 'weather_description': weather_description,
+ 'weather_picture': weather_picture
+ }
+ self.response.headers['Content-Type'] = 'text/html'
+ template = JINJA_ENVIRONMENT.get_template('index.html')
+ self.response.write(template.render(template_values))
+
+application = webapp2.WSGIApplication([
+ ('/', MainPage),
+ ('/weather', MainPage)
+], debug=True)
diff --git a/GAE/helloworld/index.html b/GAE/helloworld/index.html
new file mode 100644
index 0000000..5732ba1
--- /dev/null
+++ b/GAE/helloworld/index.html
@@ -0,0 +1,31 @@
+
+{% autoescape true %}
+
+
+ Simple GAE Project by GHajba
+
+
+ Welmoe to this all-in-one GAE project
+ This is a simple web application on the GAE created in Python
+
+ {% if not weather_description %}
+ Hello World in Chinese is: 你好世界
+
+ {% else %}
+
+ {% if weather_picture %}
+

+ {% endif %}
+ {{ weather_description }}
+
+ {% endif %}
+
+
+
+
+
+{% endautoescape %}
\ No newline at end of file
diff --git a/GAE/helloworld/lib/suds/__init__.py b/GAE/helloworld/lib/suds/__init__.py
new file mode 100644
index 0000000..73e64e2
--- /dev/null
+++ b/GAE/helloworld/lib/suds/__init__.py
@@ -0,0 +1,154 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the (LGPL) GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library Lesser General Public License for more details at
+# ( http://www.gnu.org/licenses/lgpl.html ).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# written by: Jeff Ortel ( jortel@redhat.com )
+
+"""
+Suds is a lightweight SOAP python client that provides a
+service proxy for Web Services.
+"""
+
+import os
+import sys
+
+#
+# Project properties
+#
+
+__version__ = '0.4.1'
+__build__="(beta) R705-20101207"
+
+#
+# Exceptions
+#
+
+class MethodNotFound(Exception):
+ def __init__(self, name):
+ Exception.__init__(self, "Method not found: '%s'" % name)
+
+class PortNotFound(Exception):
+ def __init__(self, name):
+ Exception.__init__(self, "Port not found: '%s'" % name)
+
+class ServiceNotFound(Exception):
+ def __init__(self, name):
+ Exception.__init__(self, "Service not found: '%s'" % name)
+
+class TypeNotFound(Exception):
+ def __init__(self, name):
+ Exception.__init__(self, "Type not found: '%s'" % tostr(name))
+
+class BuildError(Exception):
+ msg = \
+ """
+ An error occured while building a instance of (%s). As a result
+ the object you requested could not be constructed. It is recommended
+ that you construct the type manually using a Suds object.
+ Please open a ticket with a description of this error.
+ Reason: %s
+ """
+ def __init__(self, name, exception):
+ Exception.__init__(self, BuildError.msg % (name, exception))
+
+class SoapHeadersNotPermitted(Exception):
+ msg = \
+ """
+ Method (%s) was invoked with SOAP headers. The WSDL does not
+ define SOAP headers for this method. Retry without the soapheaders
+ keyword argument.
+ """
+ def __init__(self, name):
+ Exception.__init__(self, self.msg % name)
+
+class WebFault(Exception):
+ def __init__(self, fault, document):
+ if hasattr(fault, 'faultstring'):
+ Exception.__init__(self, "Server raised fault: '%s'" % fault.faultstring)
+ self.fault = fault
+ self.document = document
+
+#
+# Logging
+#
+
+class Repr:
+ def __init__(self, x):
+ self.x = x
+ def __str__(self):
+ return repr(self.x)
+
+#
+# Utility
+#
+
+def tostr(object, encoding=None):
+ """ get a unicode safe string representation of an object """
+ if isinstance(object, basestring):
+ if encoding is None:
+ return object
+ else:
+ return object.encode(encoding)
+ if isinstance(object, tuple):
+ s = ['(']
+ for item in object:
+ if isinstance(item, basestring):
+ s.append(item)
+ else:
+ s.append(tostr(item))
+ s.append(', ')
+ s.append(')')
+ return ''.join(s)
+ if isinstance(object, list):
+ s = ['[']
+ for item in object:
+ if isinstance(item, basestring):
+ s.append(item)
+ else:
+ s.append(tostr(item))
+ s.append(', ')
+ s.append(']')
+ return ''.join(s)
+ if isinstance(object, dict):
+ s = ['{']
+ for item in object.items():
+ if isinstance(item[0], basestring):
+ s.append(item[0])
+ else:
+ s.append(tostr(item[0]))
+ s.append(' = ')
+ if isinstance(item[1], basestring):
+ s.append(item[1])
+ else:
+ s.append(tostr(item[1]))
+ s.append(', ')
+ s.append('}')
+ return ''.join(s)
+ try:
+ return unicode(object)
+ except:
+ return str(object)
+
+class null:
+ """
+ The I{null} object.
+ Used to pass NULL for optional XML nodes.
+ """
+ pass
+
+def objid(obj):
+ return obj.__class__.__name__\
+ +':'+hex(id(obj))
+
+
+import client
diff --git a/GAE/helloworld/lib/suds/bindings/__init__.py b/GAE/helloworld/lib/suds/bindings/__init__.py
new file mode 100644
index 0000000..5471eba
--- /dev/null
+++ b/GAE/helloworld/lib/suds/bindings/__init__.py
@@ -0,0 +1,20 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the (LGPL) GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library Lesser General Public License for more details at
+# ( http://www.gnu.org/licenses/lgpl.html ).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# written by: Jeff Ortel ( jortel@redhat.com )
+
+"""
+Provides modules containing classes to support Web Services (SOAP)
+bindings.
+"""
\ No newline at end of file
diff --git a/GAE/helloworld/lib/suds/bindings/binding.py b/GAE/helloworld/lib/suds/bindings/binding.py
new file mode 100644
index 0000000..4a7a996
--- /dev/null
+++ b/GAE/helloworld/lib/suds/bindings/binding.py
@@ -0,0 +1,538 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the (LGPL) GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library Lesser General Public License for more details at
+# ( http://www.gnu.org/licenses/lgpl.html ).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# written by: Jeff Ortel ( jortel@redhat.com )
+
+"""
+Provides classes for (WS) SOAP bindings.
+"""
+
+from logging import getLogger
+from suds import *
+from suds.sax import Namespace
+from suds.sax.parser import Parser
+from suds.sax.document import Document
+from suds.sax.element import Element
+from suds.sudsobject import Factory, Object
+from suds.mx import Content
+from suds.mx.literal import Literal as MxLiteral
+from suds.umx.basic import Basic as UmxBasic
+from suds.umx.typed import Typed as UmxTyped
+from suds.bindings.multiref import MultiRef
+from suds.xsd.query import TypeQuery, ElementQuery
+from suds.xsd.sxbasic import Element as SchemaElement
+from suds.options import Options
+from suds.plugin import PluginContainer
+from copy import deepcopy
+
+log = getLogger(__name__)
+
+envns = ('SOAP-ENV', 'http://schemas.xmlsoap.org/soap/envelope/')
+
+
+class Binding:
+ """
+ The soap binding class used to process outgoing and imcoming
+ soap messages per the WSDL port binding.
+ @cvar replyfilter: The reply filter function.
+ @type replyfilter: (lambda s,r: r)
+ @ivar wsdl: The wsdl.
+ @type wsdl: L{suds.wsdl.Definitions}
+ @ivar schema: The collective schema contained within the wsdl.
+ @type schema: L{xsd.schema.Schema}
+ @ivar options: A dictionary options.
+ @type options: L{Options}
+ """
+
+ replyfilter = (lambda s,r: r)
+
+ def __init__(self, wsdl):
+ """
+ @param wsdl: A wsdl.
+ @type wsdl: L{wsdl.Definitions}
+ """
+ self.wsdl = wsdl
+ self.multiref = MultiRef()
+
+ def schema(self):
+ return self.wsdl.schema
+
+ def options(self):
+ return self.wsdl.options
+
+ def unmarshaller(self, typed=True):
+ """
+ Get the appropriate XML decoder.
+ @return: Either the (basic|typed) unmarshaller.
+ @rtype: L{UmxTyped}
+ """
+ if typed:
+ return UmxTyped(self.schema())
+ else:
+ return UmxBasic()
+
+ def marshaller(self):
+ """
+ Get the appropriate XML encoder.
+ @return: An L{MxLiteral} marshaller.
+ @rtype: L{MxLiteral}
+ """
+ return MxLiteral(self.schema(), self.options().xstq)
+
+ def param_defs(self, method):
+ """
+ Get parameter definitions.
+ Each I{pdef} is a tuple (I{name}, L{xsd.sxbase.SchemaObject})
+ @param method: A servic emethod.
+ @type method: I{service.Method}
+ @return: A collection of parameter definitions
+ @rtype: [I{pdef},..]
+ """
+ raise Exception, 'not implemented'
+
+ def get_message(self, method, args, kwargs):
+ """
+ Get the soap message for the specified method, args and soapheaders.
+ This is the entry point for creating the outbound soap message.
+ @param method: The method being invoked.
+ @type method: I{service.Method}
+ @param args: A list of args for the method invoked.
+ @type args: list
+ @param kwargs: Named (keyword) args for the method invoked.
+ @type kwargs: dict
+ @return: The soap envelope.
+ @rtype: L{Document}
+ """
+
+ content = self.headercontent(method)
+ header = self.header(content)
+ content = self.bodycontent(method, args, kwargs)
+ body = self.body(content)
+ env = self.envelope(header, body)
+ if self.options().prefixes:
+ body.normalizePrefixes()
+ env.promotePrefixes()
+ else:
+ env.refitPrefixes()
+ return Document(env)
+
+ def get_reply(self, method, reply):
+ """
+ Process the I{reply} for the specified I{method} by sax parsing the I{reply}
+ and then unmarshalling into python object(s).
+ @param method: The name of the invoked method.
+ @type method: str
+ @param reply: The reply XML received after invoking the specified method.
+ @type reply: str
+ @return: The unmarshalled reply. The returned value is an L{Object} for a
+ I{list} depending on whether the service returns a single object or a
+ collection.
+ @rtype: tuple ( L{Element}, L{Object} )
+ """
+ reply = self.replyfilter(reply)
+ sax = Parser()
+ replyroot = sax.parse(string=reply)
+ plugins = PluginContainer(self.options().plugins)
+ plugins.message.parsed(reply=replyroot)
+ soapenv = replyroot.getChild('Envelope')
+ soapenv.promotePrefixes()
+ soapbody = soapenv.getChild('Body')
+ self.detect_fault(soapbody)
+ soapbody = self.multiref.process(soapbody)
+ nodes = self.replycontent(method, soapbody)
+ rtypes = self.returned_types(method)
+ if len(rtypes) > 1:
+ result = self.replycomposite(rtypes, nodes)
+ return (replyroot, result)
+ if len(rtypes) == 1:
+ if rtypes[0].unbounded():
+ result = self.replylist(rtypes[0], nodes)
+ return (replyroot, result)
+ if len(nodes):
+ unmarshaller = self.unmarshaller()
+ resolved = rtypes[0].resolve(nobuiltin=True)
+ result = unmarshaller.process(nodes[0], resolved)
+ return (replyroot, result)
+ return (replyroot, None)
+
+ def detect_fault(self, body):
+ """
+ Detect I{hidden} soapenv:Fault element in the soap body.
+ @param body: The soap envelope body.
+ @type body: L{Element}
+ @raise WebFault: When found.
+ """
+ fault = body.getChild('Fault', envns)
+ if fault is None:
+ return
+ unmarshaller = self.unmarshaller(False)
+ p = unmarshaller.process(fault)
+ if self.options().faults:
+ raise WebFault(p, fault)
+ return self
+
+
+ def replylist(self, rt, nodes):
+ """
+ Construct a I{list} reply. This mehod is called when it has been detected
+ that the reply is a list.
+ @param rt: The return I{type}.
+ @type rt: L{suds.xsd.sxbase.SchemaObject}
+ @param nodes: A collection of XML nodes.
+ @type nodes: [L{Element},...]
+ @return: A list of I{unmarshalled} objects.
+ @rtype: [L{Object},...]
+ """
+ result = []
+ resolved = rt.resolve(nobuiltin=True)
+ unmarshaller = self.unmarshaller()
+ for node in nodes:
+ sobject = unmarshaller.process(node, resolved)
+ result.append(sobject)
+ return result
+
+ def replycomposite(self, rtypes, nodes):
+ """
+ Construct a I{composite} reply. This method is called when it has been
+ detected that the reply has multiple root nodes.
+ @param rtypes: A list of known return I{types}.
+ @type rtypes: [L{suds.xsd.sxbase.SchemaObject},...]
+ @param nodes: A collection of XML nodes.
+ @type nodes: [L{Element},...]
+ @return: The I{unmarshalled} composite object.
+ @rtype: L{Object},...
+ """
+ dictionary = {}
+ for rt in rtypes:
+ dictionary[rt.name] = rt
+ unmarshaller = self.unmarshaller()
+ composite = Factory.object('reply')
+ for node in nodes:
+ tag = node.name
+ rt = dictionary.get(tag, None)
+ if rt is None:
+ if node.get('id') is None:
+ raise Exception('<%s/> not mapped to message part' % tag)
+ else:
+ continue
+ resolved = rt.resolve(nobuiltin=True)
+ sobject = unmarshaller.process(node, resolved)
+ value = getattr(composite, tag, None)
+ if value is None:
+ if rt.unbounded():
+ value = []
+ setattr(composite, tag, value)
+ value.append(sobject)
+ else:
+ setattr(composite, tag, sobject)
+ else:
+ if not isinstance(value, list):
+ value = [value,]
+ setattr(composite, tag, value)
+ value.append(sobject)
+ return composite
+
+ def get_fault(self, reply):
+ """
+ Extract the fault from the specified soap reply. If I{faults} is True, an
+ exception is raised. Otherwise, the I{unmarshalled} fault L{Object} is
+ returned. This method is called when the server raises a I{web fault}.
+ @param reply: A soap reply message.
+ @type reply: str
+ @return: A fault object.
+ @rtype: tuple ( L{Element}, L{Object} )
+ """
+ reply = self.replyfilter(reply)
+ sax = Parser()
+ faultroot = sax.parse(string=reply)
+ soapenv = faultroot.getChild('Envelope')
+ soapbody = soapenv.getChild('Body')
+ fault = soapbody.getChild('Fault')
+ unmarshaller = self.unmarshaller(False)
+ p = unmarshaller.process(fault)
+ if self.options().faults:
+ raise WebFault(p, faultroot)
+ return (faultroot, p.detail)
+
+ def mkparam(self, method, pdef, object):
+ """
+ Builds a parameter for the specified I{method} using the parameter
+ definition (pdef) and the specified value (object).
+ @param method: A method name.
+ @type method: str
+ @param pdef: A parameter definition.
+ @type pdef: tuple: (I{name}, L{xsd.sxbase.SchemaObject})
+ @param object: The parameter value.
+ @type object: any
+ @return: The parameter fragment.
+ @rtype: L{Element}
+ """
+ marshaller = self.marshaller()
+ content = \
+ Content(tag=pdef[0],
+ value=object,
+ type=pdef[1],
+ real=pdef[1].resolve())
+ return marshaller.process(content)
+
+ def mkheader(self, method, hdef, object):
+ """
+ Builds a soapheader for the specified I{method} using the header
+ definition (hdef) and the specified value (object).
+ @param method: A method name.
+ @type method: str
+ @param hdef: A header definition.
+ @type hdef: tuple: (I{name}, L{xsd.sxbase.SchemaObject})
+ @param object: The header value.
+ @type object: any
+ @return: The parameter fragment.
+ @rtype: L{Element}
+ """
+ marshaller = self.marshaller()
+ if isinstance(object, (list, tuple)):
+ tags = []
+ for item in object:
+ tags.append(self.mkheader(method, hdef, item))
+ return tags
+ content = Content(tag=hdef[0], value=object, type=hdef[1])
+ return marshaller.process(content)
+
+ def envelope(self, header, body):
+ """
+ Build the B{} for an soap outbound message.
+ @param header: The soap message B{header}.
+ @type header: L{Element}
+ @param body: The soap message B{body}.
+ @type body: L{Element}
+ @return: The soap envelope containing the body and header.
+ @rtype: L{Element}
+ """
+ env = Element('Envelope', ns=envns)
+ env.addPrefix(Namespace.xsins[0], Namespace.xsins[1])
+ env.append(header)
+ env.append(body)
+ return env
+
+ def header(self, content):
+ """
+ Build the B{