svgui/pyjs/jsonrpc/django/jsonrpc.py
author Andrey Skvortsov <andrej.skvortzov@gmail.com>
Wed, 07 Dec 2016 17:54:41 +0300
changeset 1591 38e5f8847a45
parent 728 e0424e96e3fd
child 1730 64d8f52bc8c8
permissions -rw-r--r--
close Pyro socket after daemon stop


without that socket port is open after daemon shutdown.
As a result if you restart daemon with new settings (service name, for example),
it can't listen on already used port and opens the next free TCP port
regardless of requested settings.
371
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
     1
# jsonrpc.py
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
     2
#   original code: http://trac.pyworks.org/pyjamas/wiki/DjangoWithPyJamas
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
     3
#   also from: http://www.pimentech.fr/technologies/outils
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
     4
from django.utils import simplejson
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
     5
from django.http import HttpResponse
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
     6
import sys
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
     7
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
     8
from pyjs.jsonrpc import JSONRPCServiceBase
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
     9
# JSONRPCService and jsonremote are used in combination to drastically
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    10
# simplify the provision of JSONRPC services.  use as follows:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    11
#
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    12
# jsonservice = JSONRPCService()
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    13
#
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    14
# @jsonremote(jsonservice)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    15
# def test(request, echo_param):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    16
#     return "echoing the param back: %s" % echo_param
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    17
#
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    18
# dump jsonservice into urlpatterns:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    19
#  (r'^service1/$', 'djangoapp.views.jsonservice'),
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    20
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    21
class JSONRPCService(JSONRPCServiceBase):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    22
    
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    23
    def __call__(self, request, extra=None):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    24
        return self.process(request.raw_post_data)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    25
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    26
def jsonremote(service):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    27
    """Make JSONRPCService a decorator so that you can write :
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    28
    
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    29
    from jsonrpc import JSONRPCService
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    30
    chatservice = JSONRPCService()
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    31
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    32
    @jsonremote(chatservice)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    33
    def login(request, user_name):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    34
        (...)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    35
    """
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    36
    def remotify(func):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    37
        if isinstance(service, JSONRPCService):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    38
            service.add_method(func.__name__, func)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    39
        else:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    40
            emsg = 'Service "%s" not found' % str(service.__name__)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    41
            raise NotImplementedError, emsg
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    42
        return func
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    43
    return remotify
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    44
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    45
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    46
# FormProcessor provides a mechanism for turning Django Forms into JSONRPC
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    47
# Services.  If you have an existing Django app which makes prevalent
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    48
# use of Django Forms it will save you rewriting the app.
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    49
# use as follows.  in djangoapp/views.py :
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    50
#
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    51
# class SimpleForm(forms.Form):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    52
#     testfield = forms.CharField(max_length=100)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    53
#
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    54
# class SimpleForm2(forms.Form):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    55
#     testfield = forms.CharField(max_length=20)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    56
#
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    57
# processor = FormProcessor({'processsimpleform': SimpleForm,
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    58
#                            'processsimpleform2': SimpleForm2})
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    59
#
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    60
# this will result in a JSONRPC service being created with two
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    61
# RPC functions.  dump "processor" into urlpatterns to make it
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    62
# part of the app:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    63
#  (r'^formsservice/$', 'djangoapp.views.processor'),
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    64
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    65
from django import forms 
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    66
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    67
def builderrors(form):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    68
    d = {}
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    69
    for error in form.errors.keys():
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    70
        if error not in d:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    71
            d[error] = []
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    72
        for errorval in form.errors[error]:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    73
            d[error].append(unicode(errorval))
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    74
    return d
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    75
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    76
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    77
# contains the list of arguments in each field
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    78
field_names = {
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    79
 'CharField': ['max_length', 'min_length'],
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    80
 'IntegerField': ['max_value', 'min_value'],
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    81
 'FloatField': ['max_value', 'min_value'],
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    82
 'DecimalField': ['max_value', 'min_value', 'max_digits', 'decimal_places'],
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    83
 'DateField': ['input_formats'],
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    84
 'DateTimeField': ['input_formats'],
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    85
 'TimeField': ['input_formats'],
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    86
 'RegexField': ['max_length', 'min_length'], # sadly we can't get the expr
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    87
 'EmailField': ['max_length', 'min_length'],
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    88
 'URLField': ['max_length', 'min_length', 'verify_exists', 'user_agent'],
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    89
 'ChoiceField': ['choices'],
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    90
 'FilePathField': ['path', 'match', 'recursive', 'choices'],
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    91
 'IPAddressField': ['max_length', 'min_length'],
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    92
 }
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    93
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    94
def describe_field_errors(field):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    95
    res = {}
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    96
    field_type = field.__class__.__name__
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    97
    msgs = {}
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    98
    for n, m in field.error_messages.items():
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
    99
        msgs[n] = unicode(m)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   100
    res['error_messages'] = msgs
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   101
    if field_type in ['ComboField', 'MultiValueField', 'SplitDateTimeField']:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   102
        res['fields'] = map(describe_field, field.fields)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   103
    return res
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   104
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   105
def describe_fields_errors(fields, field_names):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   106
    res = {}
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   107
    if not field_names:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   108
        field_names = fields.keys()
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   109
    for name in field_names:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   110
        field = fields[name]
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   111
        res[name] = describe_field_errors(field)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   112
    return res
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   113
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   114
def describe_field(field):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   115
    res = {}
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   116
    field_type = field.__class__.__name__
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   117
    for fname in field_names.get(field_type, []) + \
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   118
          ['help_text', 'label', 'initial', 'required']:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   119
        res[fname] = getattr(field, fname)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   120
    if field_type in ['ComboField', 'MultiValueField', 'SplitDateTimeField']:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   121
        res['fields'] = map(describe_field, field.fields)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   122
    return res
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   123
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   124
def describe_fields(fields, field_names):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   125
    res = {}
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   126
    if not field_names:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   127
        field_names = fields.keys()
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   128
    for name in field_names:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   129
        field = fields[name]
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   130
        res[name] = describe_field(field)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   131
    return res
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   132
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   133
class FormProcessor(JSONRPCService):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   134
    def __init__(self, forms, _formcls=None):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   135
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   136
        if _formcls is None:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   137
            JSONRPCService.__init__(self)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   138
            for k in forms.keys():
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   139
                s  = FormProcessor({}, forms[k])
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   140
                self.add_method(k, s.__process)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   141
        else:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   142
            JSONRPCService.__init__(self, forms)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   143
            self.formcls = _formcls
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   144
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   145
    def __process(self, request, params, command=None):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   146
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   147
        f = self.formcls(params)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   148
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   149
        if command is None: # just validate
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   150
            if not f.is_valid():
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   151
                return {'success':False, 'errors': builderrors(f)}
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   152
            return {'success':True}
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   153
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   154
        elif command.has_key('describe_errors'):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   155
            field_names = command['describe_errors']
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   156
            return describe_fields_errors(f.fields, field_names)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   157
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   158
        elif command.has_key('describe'):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   159
            field_names = command['describe']
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   160
            return describe_fields(f.fields, field_names)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   161
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   162
        elif command.has_key('save'):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   163
            if not f.is_valid():
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   164
                return {'success':False, 'errors': builderrors(f)}
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   165
            instance = f.save() # XXX: if you want more, over-ride save.
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   166
            return {'success': True, 'instance': json_convert(instance) }
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   167
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   168
        elif command.has_key('html'):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   169
            return {'success': True, 'html': f.as_table()}
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   170
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   171
        return "unrecognised command"
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   172
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   173
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   174
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   175
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   176
# The following is incredibly convenient for saving vast amounts of
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   177
# coding, avoiding doing silly things like this:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   178
#     jsonresult = {'field1': djangoobject.field1,
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   179
#                   'field2': djangoobject.date.strftime('%Y.%M'),
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   180
#                    ..... }
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   181
#
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   182
# The date/time flatten function is there because JSONRPC doesn't
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   183
# support date/time objects or formats, so conversion to a string
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   184
# is the most logical choice.  pyjamas, being python, can easily
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   185
# be used to parse the string result at the other end.
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   186
#
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   187
# use as follows:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   188
#
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   189
# jsonservice = JSONRPCService()
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   190
#
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   191
# @jsonremote(jsonservice)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   192
# def list_some_model(request, start=0, count=10):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   193
#     l = SomeDjangoModelClass.objects.filter()
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   194
#     res = json_convert(l[start:end])
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   195
#
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   196
# @jsonremote(jsonservice)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   197
# def list_another_model(request, start=0, count=10):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   198
#     l = AnotherDjangoModelClass.objects.filter()
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   199
#     res = json_convert(l[start:end])
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   200
#
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   201
# dump jsonservice into urlpatterns to make the two RPC functions,
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   202
# list_some_model and list_another_model part of the django app:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   203
#  (r'^service1/$', 'djangoapp.views.jsonservice'),
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   204
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   205
from django.core.serializers import serialize
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   206
import datetime
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   207
from datetime import date
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   208
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   209
def dict_datetimeflatten(item):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   210
    d = {}
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   211
    for k, v in item.items():
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   212
        k = str(k)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   213
        if isinstance(v, datetime.date):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   214
            d[k] = str(v)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   215
        elif isinstance(v, dict):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   216
            d[k] = dict_datetimeflatten(v)
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   217
        else:
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   218
            d[k] = v
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   219
    return d
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   220
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   221
def json_convert(l, fields=None):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   222
    res = []
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   223
    for item in serialize('python', l, fields=fields):
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   224
        res.append(dict_datetimeflatten(item))
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   225
    return res
b7cb57a2da08 Adding new svgui support using twisted website HMI
laurent
parents:
diff changeset
   226