iro/view/jsonresource.py
author Sandro Knauß <bugs@sandroknauss.de>
Tue, 15 Apr 2025 01:22:19 +0200
changeset 316 63c681b8e92c
parent 297 93686b0c028b
permissions -rw-r--r--
fix link to about.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
297
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
     1
# -*- coding: utf-8 -*-
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
     2
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
     3
# Copyright (c) 2012 netzguerilla.net <iro@netzguerilla.net>
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
     4
#
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
     5
# This file is part of Iro.
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
     6
#
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
     7
# Permission is hereby granted, free of charge, to any person obtaining a copy of
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
     8
# this software and associated documentation files (the "Software"), to deal in
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
     9
# the Software without restriction, including without limitation the rights to use,
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    10
# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    11
# #Software, and to permit persons to whom the Software is furnished to do so,
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    12
# subject to the following conditions:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    13
#
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    14
# The above copyright notice and this permission notice shall be included in
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    15
# all copies or substantial portions of the Software.
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    16
#
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    17
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    18
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    19
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    20
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    21
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    22
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    23
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    24
from twisted.web import resource, server, http
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    25
from twisted.python import log, failure
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    26
from twisted.internet import defer
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    27
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    28
from ..controller.viewinterface import Interface
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    29
from ..error import ValidateException
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    30
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    31
try:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    32
    import json
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    33
except ImportError:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    34
    import simplejson as json
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    35
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    36
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    37
class TwistedInterface(Interface):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    38
    """Class that addes needed function for JSON"""
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    39
    def __init__(self):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    40
        Interface.__init__(self)
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    41
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    42
    def listMethods(self):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    43
        """Since we override lookupProcedure, its suggested to override
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    44
        listProcedures too.
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    45
        """
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    46
        return self.listProcedures()
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    47
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    48
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    49
    def listProcedures(self):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    50
        """returns a list of all functions that are allowed to call via XML-RPC."""
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    51
        return ['listMethods','status','sms','fax','mail','routes','defaultRoute','bill','telnumber','email']
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    52
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    53
class MethodFactory(resource.Resource):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    54
    def __init__(self,method,twistedInterface):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    55
        self.method = method
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    56
        self.twistedInterface = twistedInterface
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    57
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    58
    def render(self,request):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    59
        try:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    60
            args = []
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    61
            if request.getHeader('Content-Type') == 'application/x-www-form-urlencoded':
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    62
                args = {}
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    63
                for a in request.args:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    64
                    value = request.args[a]
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    65
                    if a != "recipients" and len(value) == 1:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    66
                        value = value[0]
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    67
                    args[a] = value
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    68
            elif request.getHeader('Content-Type') == 'application/json':
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    69
                content = request.content.read()
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    70
                if content:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    71
                    args = json.loads(content)
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    72
                if args is None:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    73
                    args = []
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    74
            else:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    75
                request.setResponseCode(http.NOT_ACCEPTABLE)
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    76
                return "Only application/x-www-form-urlencoded or application/json ist allowed for Content-Type"
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    77
            if isinstance(args,list):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    78
                d =  defer.maybeDeferred(getattr(self.twistedInterface,self.method),*args)
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    79
            else:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    80
                d =  defer.maybeDeferred(getattr(self.twistedInterface,self.method), **args)
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    81
            d.addCallback(self._cbRender, request)
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    82
            d.addErrback(self._ebRender, request)
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    83
            d.addBoth(lambda _: request.finish())
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    84
            return server.NOT_DONE_YET
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    85
        except Exception:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    86
            log.err(failure.Failure())
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    87
            request.setResponseCode(http.INTERNAL_SERVER_ERROR)
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    88
            err= {
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    89
                    "code" : 999,
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    90
                    "msg"  : "Unknown error.",
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    91
                }
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    92
            request.setHeader('Content-Type', 'application/json')
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    93
            return json.dumps({"status":False, "error":err})
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    94
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    95
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    96
    def _cbRender(self,result,request):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    97
        request.setHeader('Content-Type', 'application/json')
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    98
        request.write(json.dumps({"status":True, "result":result}))
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    99
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   100
    def _ebRender(self, failure, request):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   101
        if isinstance(failure.value, ValidateException):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   102
            request.setResponseCode(http.BAD_REQUEST)
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   103
        else:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   104
            request.setResponseCode(http.INTERNAL_SERVER_ERROR)
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   105
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   106
        err= {
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   107
                "code" : 999,
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   108
                "msg"  : "Unknown error.",
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   109
            }
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   110
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   111
        try:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   112
            err["code"]=failure.value.code
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   113
            err["msg"]=failure.value.msg
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   114
        except Exception:
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   115
            log.err(failure)
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   116
            pass
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   117
        request.setHeader('Content-Type', 'application/json')
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   118
        request.write(json.dumps({"status":False, "error":err}))
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   119
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   120
class JSONFactory(resource.Resource):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   121
    """JSON factory"""
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   122
    def __init__(self):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   123
        resource.Resource.__init__(self)
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   124
        self.twistedInterface = TwistedInterface()
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   125
        for method in self.twistedInterface.listProcedures():
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   126
            self.putChild(method, MethodFactory(method, self.twistedInterface))
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   127
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   128
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   129
def appendResource(root):
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   130
    """adding JSON to root."""
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   131
    root.putChild('json', JSONFactory())
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   132
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   133
if __name__ == '__main__':
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   134
    from twisted.web import resource
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   135
    from twisted.internet import reactor
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   136
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   137
    root = resource.Resource()
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   138
    root = appendResource(root)
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   139
    reactor.listenTCP(7080, server.Site(root))
93686b0c028b adding json interface
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   140
    reactor.run()