--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/iro/view/jsonresource.py Thu Sep 27 14:25:41 2012 +0200
@@ -0,0 +1,140 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2012 netzguerilla.net <iro@netzguerilla.net>
+#
+# This file is part of Iro.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+# #Software, and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+from twisted.web import resource, server, http
+from twisted.python import log, failure
+from twisted.internet import defer
+
+from ..controller.viewinterface import Interface
+from ..error import ValidateException
+
+try:
+ import json
+except ImportError:
+ import simplejson as json
+
+
+class TwistedInterface(Interface):
+ """Class that addes needed function for JSON"""
+ def __init__(self):
+ Interface.__init__(self)
+
+ def listMethods(self):
+ """Since we override lookupProcedure, its suggested to override
+ listProcedures too.
+ """
+ return self.listProcedures()
+
+
+ def listProcedures(self):
+ """returns a list of all functions that are allowed to call via XML-RPC."""
+ return ['listMethods','status','sms','fax','mail','routes','defaultRoute','bill','telnumber','email']
+
+class MethodFactory(resource.Resource):
+ def __init__(self,method,twistedInterface):
+ self.method = method
+ self.twistedInterface = twistedInterface
+
+ def render(self,request):
+ try:
+ args = []
+ if request.getHeader('Content-Type') == 'application/x-www-form-urlencoded':
+ args = {}
+ for a in request.args:
+ value = request.args[a]
+ if a != "recipients" and len(value) == 1:
+ value = value[0]
+ args[a] = value
+ elif request.getHeader('Content-Type') == 'application/json':
+ content = request.content.read()
+ if content:
+ args = json.loads(content)
+ if args is None:
+ args = []
+ else:
+ request.setResponseCode(http.NOT_ACCEPTABLE)
+ return "Only application/x-www-form-urlencoded or application/json ist allowed for Content-Type"
+ if isinstance(args,list):
+ d = defer.maybeDeferred(getattr(self.twistedInterface,self.method),*args)
+ else:
+ d = defer.maybeDeferred(getattr(self.twistedInterface,self.method), **args)
+ d.addCallback(self._cbRender, request)
+ d.addErrback(self._ebRender, request)
+ d.addBoth(lambda _: request.finish())
+ return server.NOT_DONE_YET
+ except Exception:
+ log.err(failure.Failure())
+ request.setResponseCode(http.INTERNAL_SERVER_ERROR)
+ err= {
+ "code" : 999,
+ "msg" : "Unknown error.",
+ }
+ request.setHeader('Content-Type', 'application/json')
+ return json.dumps({"status":False, "error":err})
+
+
+ def _cbRender(self,result,request):
+ request.setHeader('Content-Type', 'application/json')
+ request.write(json.dumps({"status":True, "result":result}))
+
+ def _ebRender(self, failure, request):
+ if isinstance(failure.value, ValidateException):
+ request.setResponseCode(http.BAD_REQUEST)
+ else:
+ request.setResponseCode(http.INTERNAL_SERVER_ERROR)
+
+ err= {
+ "code" : 999,
+ "msg" : "Unknown error.",
+ }
+
+ try:
+ err["code"]=failure.value.code
+ err["msg"]=failure.value.msg
+ except Exception:
+ log.err(failure)
+ pass
+ request.setHeader('Content-Type', 'application/json')
+ request.write(json.dumps({"status":False, "error":err}))
+
+class JSONFactory(resource.Resource):
+ """JSON factory"""
+ def __init__(self):
+ resource.Resource.__init__(self)
+ self.twistedInterface = TwistedInterface()
+ for method in self.twistedInterface.listProcedures():
+ self.putChild(method, MethodFactory(method, self.twistedInterface))
+
+
+def appendResource(root):
+ """adding JSON to root."""
+ root.putChild('json', JSONFactory())
+
+if __name__ == '__main__':
+ from twisted.web import resource
+ from twisted.internet import reactor
+
+ root = resource.Resource()
+ root = appendResource(root)
+ reactor.listenTCP(7080, server.Site(root))
+ reactor.run()