diff options
Diffstat (limited to 'gstudio/xmlrpc')
-rw-r--r-- | gstudio/xmlrpc/__init__.py | 59 | ||||
-rw-r--r-- | gstudio/xmlrpc/decorators.py | 175 | ||||
-rw-r--r-- | gstudio/xmlrpc/dispatcher.py | 78 | ||||
-rw-r--r-- | gstudio/xmlrpc/metaweblog.py | 484 | ||||
-rw-r--r-- | gstudio/xmlrpc/rpc/.gitignore | 16 | ||||
-rw-r--r-- | gstudio/xmlrpc/rpc/LICENSE | 24 | ||||
-rw-r--r-- | gstudio/xmlrpc/rpc/MANIFEST.in | 3 | ||||
-rw-r--r-- | gstudio/xmlrpc/rpc/README.rst | 36 | ||||
-rw-r--r-- | gstudio/xmlrpc/rpc/__init__.py | 44 | ||||
-rw-r--r-- | gstudio/xmlrpc/rpc/decorators.py | 175 | ||||
-rw-r--r-- | gstudio/xmlrpc/rpc/dispatcher.py | 76 | ||||
-rw-r--r-- | gstudio/xmlrpc/rpc/locale/fr/LC_MESSAGES/django.mo | bin | 0 -> 1030 bytes | |||
-rw-r--r-- | gstudio/xmlrpc/rpc/locale/fr/LC_MESSAGES/django.po | 49 | ||||
-rw-r--r-- | gstudio/xmlrpc/rpc/setup.py | 31 | ||||
-rw-r--r-- | gstudio/xmlrpc/rpc/templates/xmlrpc_get.html | 26 | ||||
-rw-r--r-- | gstudio/xmlrpc/rpc/views.py | 20 | ||||
-rw-r--r-- | gstudio/xmlrpc/views.py | 193 |
17 files changed, 1363 insertions, 126 deletions
diff --git a/gstudio/xmlrpc/__init__.py b/gstudio/xmlrpc/__init__.py index afb41e6f..318e6d9f 100644 --- a/gstudio/xmlrpc/__init__.py +++ b/gstudio/xmlrpc/__init__.py @@ -54,6 +54,7 @@ GSTUDIO_XMLRPC_PINGBACK = [ ('gstudio.xmlrpc.pingback.pingback_extensions_get_pingbacks', 'pingback.extensions.getPingbacks')] +# The tuple has been modified to include entries for get and set functions GSTUDIO_XMLRPC_METAWEBLOG = [ ('gstudio.xmlrpc.metaweblog.get_users_blogs', 'blogger.getUsersBlogs'), @@ -82,35 +83,53 @@ GSTUDIO_XMLRPC_METAWEBLOG = [ ('gstudio.xmlrpc.metaweblog.new_media_object', 'metaWeblog.newMediaObject'), ('gstudio.xmlrpc.metaweblog.getNodetype', - 'metaweblog.getNodetype'), + 'metaWeblog.getNodetype'), ('gstudio.xmlrpc.metaweblog.nidExists', - 'metaweblog.nidExists'), + 'metaWeblog.nidExists'), ('gstudio.xmlrpc.metaweblog.getinfoFromSSID', - 'metaweblog.getinfoFromSSID'), - #('gstudio.xmlrpc.metaweblog.getNeighbourhood', - #'metaweblog.getNeighbourhood'), - # ('gstudio.xmlrpc.metaweblog.getallNodes', - # 'metaweblog.getallNodes'), + 'metaWeblog.getinfoFromSSID'), + ('gstudio.xmlrpc.metaweblog.getNeighbourhood', + 'metaWeblog.getNeighbourhood'), + ('gstudio.xmlrpc.metaweblog.getAll', + 'metaWeblog.getAll'), ('gstudio.xmlrpc.metaweblog.getDatatype', - 'metaweblog.getDatatype'), + 'metaWeblog.getDatatype'), ('gstudio.xmlrpc.metaweblog.getAttributevalues', - 'metaweblog.getAttributevalues'), + 'metaWeblog.getAttributevalues'), ('gstudio.xmlrpc.metaweblog.getSubjecttypes', - 'metaweblog.getSubjecttypes'), - #('gstudio.xmlrpc.metaweblog.getAttributeType', - #'metaweblog.getAttributeType'), + 'metaWeblog.getSubjecttypes'), + ('gstudio.xmlrpc.metaweblog.getAttributeType', + 'metaWeblog.getAttributeType'), ('gstudio.xmlrpc.metaweblog.getRoles', - 'metaweblog.getRoles'), + 'metaWeblog.getRoles'), ('gstudio.xmlrpc.metaweblog.getSubtypes', - 'metaweblog.getSubtypes'), - #('gstudio.xmlrpc.metaweblog.Suballtypes', - #'metaweblog.Suballtypes'), + 'metaWeblog.getSubtypes'), + ('gstudio.xmlrpc.metaweblog.getAllSubtypes', + 'metaWeblog.getAllSubtypes'), ('gstudio.xmlrpc.metaweblog.getRestrictions', - 'metaweblog.getRestrictions'), + 'metaWeblog.getRestrictions'), ('gstudio.xmlrpc.metaweblog.getlatestSSID', - 'metaweblog.getlatestSSID'), - ('gstudio.xmlrpc.metaweblog.getAllSnapshots', - 'metaweblog.getAllSnapshots') + 'metaWeblog.getlatestSSID'), + ('gstudio.xmlrpc.metaweblog.getAllSnapshots', + 'metaWeblog.getAllSnapshots'), + ('gstudio.xmlrpc.metaweblog.setAttributetype', + 'metaWeblog.setAttributetype'), + ('gstudio.xmlrpc.metaweblog.setRelationtype', + 'metaWeblog.setRelationtype'), + ('gstudio.xmlrpc.metaweblog.setObjecttype', + 'metaWeblog.setObjecttype'), + ('gstudio.xmlrpc.metaweblog.setObject', + 'metaWeblog.setObject'), + ('gstudio.xmlrpc.metaweblog.setAttribute', + 'metaWeblog.setAttribute'), + ('gstudio.xmlrpc.metaweblog.setRelation', + 'metaWeblog.setRelation'), + ('gstudio.xmlrpc.metaweblog.getGbobjectNeighbourhood', + 'metaWeblog.getGbobjectNeighbourhood') + + + + ] diff --git a/gstudio/xmlrpc/decorators.py b/gstudio/xmlrpc/decorators.py new file mode 100644 index 00000000..5d13feaa --- /dev/null +++ b/gstudio/xmlrpc/decorators.py @@ -0,0 +1,175 @@ +"""Offers decorators to make the use of django_xmlrpc a great deal simpler + +Authors:: + Graham Binns, + Reza Mohammadi + +Credit must go to Brendan W. McAdams <brendan.mcadams@thewintergrp.com>, who +posted the original SimpleXMLRPCDispatcher to the Django wiki: +http://code.djangoproject.com/wiki/XML-RPC + +New BSD License +=============== +Copyright (c) 2007, Graham Binns http://launchpad.net/~codedragon + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the <ORGANIZATION> nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" +from xmlrpclib import Fault +from django.contrib.auth import authenticate +from django.utils.translation import gettext as _ + +# This file is needed to run XMLRPC ! +# Some constants for your pleasure +#XXX: Any standardization? +AUTHENTICATION_FAILED_CODE = 81 +PERMISSION_DENIED_CODE = 82 + + +class AuthenticationFailedException(Fault): + """An XML-RPC fault to be raised when a permission_required authentication + check fails + + Author + """ + def __init__(self): + Fault.__init__(self, AUTHENTICATION_FAILED_CODE, + _('Username and/or password is incorrect')) + + +class PermissionDeniedException(Fault): + """An XML-RPC fault to be raised when a permission_required permission + check fails + """ + def __init__(self): + Fault.__init__(self, PERMISSION_DENIED_CODE, _('Permission denied')) + + +def xmlrpc_method(returns='string', args=None, name=None): + """Adds a signature to an XML-RPC function and register + it with the dispatcher. + + returns + The return type of the function. This can either be a string + description (e.g. 'string') or a type (e.g. str, bool) etc. + + args + A list of the types of the arguments that the function accepts. These + can be strings or types or a mixture of the two e.g. + [str, bool, 'string'] + """ + # Args should be a list + if args is None: + args = [] + + def _xmlrpc_func(func): + """Inner function for XML-RPC method decoration. Adds a signature to + the method passed to it. + + func + The function to add the signature to + """ + # If name is not None, register the method with the dispatcher. + from django_xmlrpc.views import xmlrpcdispatcher + if name is not None: + xmlrpcdispatcher.register_function(func, name) + + # Add a signature to the function + func._xmlrpc_signature = { + 'returns': returns, + 'args': args + } + return func + + return _xmlrpc_func + +xmlrpc_func = xmlrpc_method + + +# Don't use this decorator when your service is going to be +# available in an unencrpted/untrusted network. +# Configure HTTPS transport for your web server. +def permission_required(perm=None): + """Decorator for authentication. Uses Django's built in authentication + framework to provide authenticated-only and permission-related access + to XML-RPC methods + + perm + The permission (as a string) that the user must hold to be able to + call the function that is decorated with permission_required. + """ + def _dec(func): + """An inner decorator. Adds the lookup code for the permission passed + in the outer method to the function passed to it. + + func + The function to add the permission check to + """ + def __authenticated_call(username, password, *args): + """Inner inner decorator. Adds username and password parameters to + a given XML-RPC function for authentication and permission + checking purposes and modifies the method signature appropriately + + username + The username used for authentication + + password + The password used for authentication + """ + try: + user = authenticate(username=username, password=password) + if not user: + raise AuthenticationFailedException + if perm and not user.has_perm(perm): + raise PermissionDeniedException + except AuthenticationFailedException: + raise + except PermissionDeniedException: + raise + except: + raise AuthenticationFailedException + return func(user, *args) + + # Update the function's XML-RPC signature, if the method has one + if hasattr(func, '_xmlrpc_signature'): + sig = func._xmlrpc_signature + + # We just stick two string args on the front of sign['args'] to + # represent username and password + sig['args'] = (['string'] * 2) + sig['args'] + __authenticated_call._xmlrpc_signature = sig + + # Update the function's docstring + if func.__doc__: + __authenticated_call.__doc__ = func.__doc__ + \ + "\nNote: Authentication is required.""" + if perm: + __authenticated_call.__doc__ += ' this function requires ' \ + + '"%s" permission.' % perm + + return __authenticated_call + + return _dec diff --git a/gstudio/xmlrpc/dispatcher.py b/gstudio/xmlrpc/dispatcher.py new file mode 100644 index 00000000..28291845 --- /dev/null +++ b/gstudio/xmlrpc/dispatcher.py @@ -0,0 +1,78 @@ +"""Offers a simple XML-RPC dispatcher for django_xmlrpc + +Author:: + Graham Binns + +Credit must go to Brendan W. McAdams <brendan.mcadams@thewintergrp.com>, who +posted the original SimpleXMLRPCDispatcher to the Django wiki: +http://code.djangoproject.com/wiki/XML-RPC + +New BSD License +=============== +Copyright (c) 2007, Graham Binns http://launchpad.net/~codedragon + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the <ORGANIZATION> nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" +# This file is needed to run XMLRPC + +from inspect import getargspec +from SimpleXMLRPCServer import SimpleXMLRPCDispatcher +from django.conf import settings + + +# If we need to debug, now we know +DEBUG = hasattr(settings, 'XMLRPC_DEBUG') and settings.XMLRPC_DEBUG + + +class DjangoXMLRPCDispatcher(SimpleXMLRPCDispatcher): + """A simple XML-RPC dispatcher for Django. + + Subclassess SimpleXMLRPCServer.SimpleXMLRPCDispatcher for the purpose of + overriding certain built-in methods (it's nicer than monkey-patching them, + that's for sure). + """ + + def system_methodSignature(self, method): + """Returns the signature details for a specified method + + method + The name of the XML-RPC method to get the details for + """ + # See if we can find the method in our funcs dict + # TODO: Handle this better: We really should return something more + # formal than an AttributeError + func = self.funcs[method] + + try: + sig = func._xmlrpc_signature + except: + sig = { + 'returns': 'string', + 'args': ['string' for arg in getargspec(func)[0]], + } + + return [sig['returns']] + sig['args'] diff --git a/gstudio/xmlrpc/metaweblog.py b/gstudio/xmlrpc/metaweblog.py index 5b273ea3..4dd1fe1a 100644 --- a/gstudio/xmlrpc/metaweblog.py +++ b/gstudio/xmlrpc/metaweblog.py @@ -72,6 +72,9 @@ from gstudio.managers import DRAFT, PUBLISHED from django_xmlrpc.decorators import xmlrpc_func from django.utils.datastructures import SortedDict from gstudio.models import * +from django.contrib.auth.models import User + + # http://docs.nucleuscms.org/blog/12#errorcodes LOGIN_ERROR = 801 @@ -377,15 +380,15 @@ def new_media_object(blog_id, username, password, media): ContentFile(media['bits'].data)) return {'url': default_storage.url(path)} - +# Get functions start from here @xmlrpc_func(returns='string', args='int') def getNodetype(ssid): - """Returns the nodetype of given ssid """ + """Returns the nodetype of given nid """ try : g = Nodetype.objects.get(id=ssid) return (g.ref._meta.module_name) except Nodetype.DoesNotExist : - return "Node with the given ssid does not exist" + return "Node with the given nid does not exist" @xmlrpc_func(returns='int', args='string') def nidExists(nid): @@ -396,156 +399,439 @@ def nidExists(nid): except Nodetype.DoesNotExist: return 0 - -@xmlrpc_func(returns=['struct'],args=['string']) +@xmlrpc_func(returns='struct',args=['string']) def getinfoFromSSID(ssid_list) : """Given a list of ssids, it returns entire information of each ssid inside a dictionary with all the dictionaries contained within a list """ lst = [] for ssid in ssid_list : + try : + t = NID.objects.get(id = ssid) try : - p = Objecttype.objects.get(id = ssid) + p = Nodetype.objects.get(id = ssid) nbh = p.ref.get_nbh lst.append(str(nbh)) - except Objecttype.DoesNotExist : - return "ssid",ssid,"Does not exist" - - + except Nodetype.DoesNotExist : + lst.append("Not of type Nodetype") + except NID.DoesNotExist : + lst.append("Node Does Not Exist") return lst +@xmlrpc_func(returns='struct', args=['string','string']) +def getNeighbourhood(ssid_list, get_what): + d = {} + for ssid in ssid_list: + try: + p = NID.objects.get(id = ssid) + try : + t = Nodetype.objects.get(id = ssid) + if get_what=='rendered_nbh' : + nbh = p.ref.get_rendered_nbh + d[str(p.id)]= str(nbh) + elif get_what=='nbh': + nbh = p.ref.get_nbh + d[str(p.id)]= str(nbh) + except Nodetype.DoesNotExist : + d[str(ssid)] = "Not of type Nodetype" + except NID.DoesNotExist : + d[str(ssid)] = "Node Does Not Exist" + return d +@xmlrpc_func(returns='struct', args=['string','string']) +def getGbobjectNeighbourhood(ssid_list, get_what): + d = {} + for ssid in ssid_list: + try: + p = NID.objects.get(id = ssid) + try : + t = Gbobject.objects.get(id = ssid) + if get_what=='rendered_nbh' : + nbh = p.ref.get_rendered_nbh + d[str(p.id)]= str(nbh) + elif get_what=='nbh': + nbh = p.ref.get_nbh + d[str(p.id)]= str(nbh) + except Gbobject.DoesNotExist : + d[str(ssid)] = "Not of type Gboject" + except NID.DoesNotExist : + d[str(ssid)] = "Node Does Not Exist" + return d -@xmlrpc_func(returns=['struct'], args=['string']) + + +@xmlrpc_func(returns='struct', args=['string']) + +def getAttributeType(subjecttypelist): + """given the list of subjecttype inids the method returns all the attributetypes attached. """ + d = {} + for s in subjecttypelist : + try : + l = [] + p = NID.objects.get(id = s) + k = p.ref._meta.module_name + y = [] + if( k == 'objecttype' or 'metatype' ) : + y = Attributetype.objects.filter(subjecttype_id = s) + for i in y : + l.append(str(i.id)) + d[str(s)] = l + except NID.DoesNotExist : + d[str(s)] = "Node Does not Exist" + return d + +# Get all function for getting all nodetypes +@xmlrpc_func(returns='struct', args='string') + +def getAll(nodetype): + """Given a class name it returns all the nids corresponding to their class name.""" + d = {} + try : + p = eval(nodetype) + h = p.objects.all() + for i in h: + d[str(i.title)] = i.id + except NameError : + return "The class with the given name Does not exist" + return d + + +@xmlrpc_func(returns='struct', args=['string']) def getDatatype(attrtype_ssid_list) : """Given a list of attributessids, it returns its datatypes """ - d = {} - g = {} for l in attrtype_ssid_list : - p = NID.objects.get(id = l) - n = p.ref._meta.module_name - if n == 'attributetype' : - ft = FIELD_TYPE_CHOICES[int(p.ref.dataType) - 1] - d[str(p.id)] = ft[1] - else : - return " Node does not exist " - + try : + p = NID.objects.get(id = l) + n = p.ref._meta.module_name + if n == 'attributetype' : + ft = FIELD_TYPE_CHOICES[int(p.ref.dataType) - 1] + d[str(p.id)] = ft[1] + else : + d[str(p.id)]= "Not a attributetype" + except NID.DoesNotExist : + d[str(l)] = "Node Does not Exist" return d -@xmlrpc_func(returns=['struct'], args=['string']) +@xmlrpc_func(returns='struct', args=['string']) def getAttributevalues(Attrssidlist) : """Given a list of attributessid, it returns their values """ - d = {} for l in Attrssidlist : try : - p = Attribute.objects.get(id = l) - d[str(p.id)] = p.svalue - except Attribute.DoesNotExist : - return " Node does not exist" - + p = NID.objects.get(id = l) + k = p.ref._meta.module_name + if ( k == 'attribute' ) : + t = Attribute.objects.get(id = l) + d[str(t.id)] = t.svalue + else : + d[str(l)] = "Not an Attribute" + except NID.DoesNotExist : + d[str(l)] = "Node Does Not Exist" return d - -@xmlrpc_func(returns=['struct'], args=['string']) - - -def getSubjecttypes( AttributeTypeNid ) : - """Given an attributetypenid, it returns the subjecttype participating in the attributetype """ - d ={} - for l in AttributeTypeNid : - try : - p = Attributetype.objects.get(id = l) - n = p.ref.subjecttype_id - s = NID.objects.get(id = n) - d[str(s.title)]= n - d['applicable_nodetypes'] = p.applicable_nodetypes - except Attribute.DoesNotExist: - return " Node does not exist " - return d - - - - - - -@xmlrpc_func(returns=['struct'], args=['string']) +@xmlrpc_func(returns='struct', args='string') +def getSubjecttypes( AttributeTypeNid ): + """Given an attributetypenid, it returns the subjecttype participating in the attributetype """ + try : + d = {} + t = NID.objects.get(id = AttributeTypeNid) + k = t.ref._meta.module_name + if k == 'attributetype' : + p = Attributetype.objects.get(id = AttributeTypeNid) + n = p.subjecttype_id + d['stid'] = str(n) + d['applicable_nodetypes'] = p.applicable_nodetypes + else : + return "Not an Attributetype" + except NID.DoesNotExist: + return "Node does not exist" + return d + +@xmlrpc_func(returns='struct', args='string') def getRoles(relationtypenid) : """given a relationtype nid this method returns the roles participating in the relationtype """ - - d = {} - p = Relationtype.objects.get(nodetype_ptr_id = relationtypenid) - - d['cardinality1 '] = p.left_cardinality - d['cardinality2'] = p.right_cardinality - d['rtid'] = p.nodetype_ptr_id - d['applicablenodetype1'] = p.left_applicable_nodetypes - d['applicablenodetype2'] = p.right_applicable_nodetypes - d['subjecttype1'] = p.left_subjecttype_id - d['subjecttype2'] = p.right_subjecttype_id + try : + t = NID.objects.get(id = relationtypenid) + k = t.ref._meta.module_name + d = {} + if k == 'relationtype' : + p = Relationtype.objects.get(nodetype_ptr_id = relationtypenid) + d['cardinality1 '] = p.left_cardinality + d['cardinality2'] = p.right_cardinality + d['rtid'] = p.nodetype_ptr_id + d['applicablenodetype1'] = p.left_applicable_nodetypes + d['applicablenodetype2'] = p.right_applicable_nodetypes + d['subjecttype1'] = p.left_subjecttype_id + d['subjecttype2'] = p.right_subjecttype_id + else : + return "Not a Relationtype" + except NID.DoesNotExist : + return "Node Does Not Exist " return d - -@xmlrpc_func(returns=['struct'], args=['string']) - +@xmlrpc_func(returns='struct', args='string') def getSubtypes(nodeid) : """Returns only the immediate subtype of the node specified""" - i = 0 - l = [] - p = Objecttype.objects.get(id = nodeid) - n = p.get_children() - u = len(n) - while u>0 : - t = n[i].id - l.append(str(t)) - i = i+1 - u = u-1 + try : + y = NID.objects.get(id = nodeid) + try : + p = Nodetype.objects.get(id = nodeid) + n = p.get_children() + l = [] + for i in n: + l.append(str(i.id)) + except Nodetype.DoesNotExist : + return "Not of type nodetype" + except NID.DoesNotExist : + return " Node Does not exist" return l - - +@xmlrpc_func(returns='struct', args='string') + +def getAllSubtypes(nodeid) : + """Returns all the 'subtypes' of the node specified""" + try : + l = [] + p = NID.objects.get(id = nodeid) + try : + k = Nodetype.objects.get(id = nodeid) + h = k.get_descendants() + for i in h : + l.append(str(i.id)) + except Nodetype.DoesNotExist : + return "Not of type Nodetype" + except NID.DoesNotExist : + return "Node Does not Exist" + return l @xmlrpc_func(returns=['struct'], args=['string']) def getRestrictions(ATlist) : """Given a list of attributetype ssids, this method returns all the restrictions that the attributetypes have """ - u = {} d = {} - ft = [] + ft = [] for a in ATlist : - p = Attributetype.objects.get(id = a) - ft = FIELD_TYPE_CHOICES[int(p.dataType)-1] - u['datatype'] = ft[1] - u['length'] = p.max_digits - u['precision'] = p.decimal_places - d[str(p.id)] = u - + try : + k = NID.objects.get(id = a) + t = k.ref._meta.module_name + u = {} + if t == 'attributetype' : + p = Attributetype.objects.get(id = a) + ft = FIELD_TYPE_CHOICES[int(p.dataType)-1] + u['datatype'] = ft[1] + u['length'] = p.max_digits + u['precision'] = p.decimal_places + d[str(p.id)] = u + else : + d[str(a)] = "Not a Attributetype" + except NID.DoesNotExist : + d[str(a)] = "Node Does Not Exist" return d -@xmlrpc_func(returns='int', args='int') +@xmlrpc_func(returns='int', args='string') def getlatestSSID(nid) : """Given the id, this method will return the latest ssid of the given id """ + try : + p = NID.objects.get(id = nid) + n = p.get_ssid + u = len(n) + if u == 0 : + return "No Snapshots created" + else : + r = n[u-1] + return r + except NID.DoesNotExist: + return "Node Does Not exist" + +@xmlrpc_func(returns='struct', args='int') +def getAllSnapshots(nid) : + """Given the id, this method will return all the ssids of the given id """ + try : + p = NID.objects.get(id = nid) + n = p.get_ssid + except NID.DoesNotExist : + return "Node Does Not Exist" + return n + +# Set functions begin from here +@xmlrpc_func(returns='string', args=['struct','string']) +def setAttributetype(d,objid) : + + try : + p = NID.objects.get(id = objid) + t = p.ref._meta.module_name + w = [] + if t == 'objecttype' or t == 'metatype' : + u = Attributetype.objects.filter(subjecttype_id = objid) + y = len(u) + r = 0 + for i in u : + if str(i.title) == d['title'] : + return "Attributetype:",d['title']," already exists" + else : + r = r + 1 + if r == y : + w = Attributetype(title = d['title'],applicable_nodetypes = d['nodetype'],subjecttype_id = objid,slug = d['slug']) + w.save() + return w.id + else : + return "Not a objecttype" + except NID.DoesNotExist : + return "Node Does Not Exist" + + + +@xmlrpc_func(returns='int', args=['struct','string']) + +def setRelationtype(d,uid) : + + try : + k = NID.objects.get(id = uid) + f = k.ref._meta.module_name + r = 0 + t = [] + if ( f == 'objecttype' or f == 'metatype') : + p = Relationtype.objects.filter(left_subjecttype_id = uid) + u = len(p) + for n in p : + if (str(n.title) == d['title']) : + return "Relationtype :",d['title'],"already exists for",n.title + else : + r = r + 1 + if r == u : + t = Relationtype(title = d['title'],left_subjecttype_id = uid,right_subjecttype_id = d['right_subjecttype_id'], + slug = d['slug'],inverse = d['inverse']) + t.save() + return t.id + else : + return " Not of type Objecttype or Metatype" + except NID.DoesNotExist : + return " Node does not Exist" + +@xmlrpc_func(returns='int', args=['struct','string']) + +def setObjecttype(d) : + + k = Objecttype.objects.all() + u = len(k) + r = 0 + t = [] + for n in k : + if (str(n.title) == d['title']) : + return "Objecttype",d['title'],"already exists" + else : + r = r + 1 + if r == u : + t = Objecttype(title = d['title'], slug = d['slug']) + t.save() + + return t.id + + +@xmlrpc_func(returns='int', args=['struct','string']) + +def setObject(d,o) : + + try : + k = NID.objects.get(id = o) + t = k.ref._meta.module_name + u = 0 + r = 0 + y = [] + h = [] + if (t == 'objecttype' or t =='metatype') : + p = Objecttype.objects.get(id = o) + h = p.get_members + u = len(h) + for i in h : + if(str(i.title) == d['title']) : + return "Object",d['title'],"already exists for",p.title + else : + r = r + 1 + if r == u : + y = Gbobject(title = d['title'],slug = d['slug']) + y.save() + y.objecttypes.add(p) + return y.id + else : + return "Not of type Objecttype or metatype" + except NID.DoesNotExist : + return "Node does not exist" + +@xmlrpc_func(returns='int', args=['struct','string']) + +def setAttribute(d,objid) : + try : + k = NID.objects.get(id = objid) + t = k.ref._meta.module_name + if t == 'objecttype' or t == 'metatype' : + p = Attributetype.objects.filter(subjecttype_id = objid) + s = [] + for i in p : + if (str(i.title) == d['attributetype']) : + s = Attribute(attributetype_id = i.id,subject_id = d['subject_id'],svalue = d['svalue']) + s.save() + return s.id + else : + return " The objectid entered is not a objecttype or metatype" + except NID.DoesNotExist: + return "Node does not Exist" + + + +@xmlrpc_func(returns='int', args=['struct','string','string']) + +def setRelation(d,obj1,obj2) : + try : + p = Relationtype.objects.filter(left_subjecttype_id = obj1,right_subjecttype_id = obj2) + s = [] + for i in p : + if (str(i.title) == d['relationtypename']) : + s = Relation(relationtype_id = i.id,left_subject_id = d['left_subject_id'],right_subject_id = d['right_subject_id']) + s.save() + return s.id + except Relationtype.DoesNotExist : + return "Relationtype Does Not Exist" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - p = NID.objects.get(id = nid) - n = p.get_ssid - u = len(n) - r = n[u-1] - return r -@xmlrpc_func(returns=['struct'], args='int') -def getAllSnapshots(nid) : - """Given the id, this method will return all the ssids of the given id """ - p = NID.objects.get(id = nid) - n = p.get_ssid - return n diff --git a/gstudio/xmlrpc/rpc/.gitignore b/gstudio/xmlrpc/rpc/.gitignore new file mode 100644 index 00000000..7b4dcf61 --- /dev/null +++ b/gstudio/xmlrpc/rpc/.gitignore @@ -0,0 +1,16 @@ +*~ +*.pyc +TODO.txt +README.html +bin +lib +dist +eggs +parts +build +include +downloads +src_eggs +develop-eggs +.installed.cfg +django_xmlrpc.egg-info/
\ No newline at end of file diff --git a/gstudio/xmlrpc/rpc/LICENSE b/gstudio/xmlrpc/rpc/LICENSE new file mode 100644 index 00000000..8efdc935 --- /dev/null +++ b/gstudio/xmlrpc/rpc/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2007-2008, Graham Binns +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of this application nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY GRAHAM BINNS ''AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL GRAHAM BINNS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/gstudio/xmlrpc/rpc/MANIFEST.in b/gstudio/xmlrpc/rpc/MANIFEST.in new file mode 100644 index 00000000..2f4671ba --- /dev/null +++ b/gstudio/xmlrpc/rpc/MANIFEST.in @@ -0,0 +1,3 @@ +include README.rst +recursive-include django_xmlrpc/locale * +recursive-include django_xmlrpc/templates *.html diff --git a/gstudio/xmlrpc/rpc/README.rst b/gstudio/xmlrpc/rpc/README.rst new file mode 100644 index 00000000..bcf4ac0a --- /dev/null +++ b/gstudio/xmlrpc/rpc/README.rst @@ -0,0 +1,36 @@ +============== +Django XML-RPC +============== + +django_xmlrpc offers a means by which a Django developer can expose their views (or indeed any other function) using XML-RPC. + +This is a fork of the version hosted at : https://code.launchpad.net/~aartemenko/django-xmlrpc/svetlyak40wt compatible with Django > 1.1. + +.. contents:: + +Installation +============ + +You could retrieve the last sources from http://github.com/Fantomas42/django-xmlrpc and run the installation script :: + + $> python setup.py install + +or use pip :: + + $> pip install -e git://github.com/Fantomas42/django-xmlrpc.git#egg=django-xmlrpc + +Usage +===== + +Register **django_xmlrpc** in your INSTALLED_APPS section of your project' settings. + +Then register methods you want to handle like this in your project' settings. :: + + >>> XMLRPC_METHODS = (('path.to.your.method', 'Method name'), + ... ('path.to.your.othermethod', 'Other Method name'),) + +Finally we need to register the url of the XML-RPC server. +Insert something like this in your project's urls.py: :: + + >>> url(r'^xmlrpc/$', 'django_xmlrpc.views.handle_xmlrpc', name='xmlrpc'), + diff --git a/gstudio/xmlrpc/rpc/__init__.py b/gstudio/xmlrpc/rpc/__init__.py new file mode 100644 index 00000000..1d58f713 --- /dev/null +++ b/gstudio/xmlrpc/rpc/__init__.py @@ -0,0 +1,44 @@ +"""__init__ module for the django_xmlrpc package + +Authors:: + Graham Binns + Julien Fache + +Credit must go to Brendan W. McAdams <brendan.mcadams@thewintergrp.com>, who +posted the original SimpleXMLRPCDispatcher to the Django wiki: +http://code.djangoproject.com/wiki/XML-RPC + +New BSD License +=============== +Copyright (c) 2007, Graham Binns http://launchpad.net/~codedragon + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the <ORGANIZATION> nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" +VERSION = (0, 1, 1) +__version__ = '.'.join(map(str, VERSION)) + +from views import xmlrpcdispatcher diff --git a/gstudio/xmlrpc/rpc/decorators.py b/gstudio/xmlrpc/rpc/decorators.py new file mode 100644 index 00000000..4218a4fd --- /dev/null +++ b/gstudio/xmlrpc/rpc/decorators.py @@ -0,0 +1,175 @@ +"""Offers decorators to make the use of django_xmlrpc a great deal simpler + +Authors:: + Graham Binns, + Reza Mohammadi + +Credit must go to Brendan W. McAdams <brendan.mcadams@thewintergrp.com>, who +posted the original SimpleXMLRPCDispatcher to the Django wiki: +http://code.djangoproject.com/wiki/XML-RPC + +New BSD License +=============== +Copyright (c) 2007, Graham Binns http://launchpad.net/~codedragon + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the <ORGANIZATION> nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" +from xmlrpclib import Fault +from django.contrib.auth import authenticate +from django.utils.translation import gettext as _ + + +# Some constants for your pleasure +#XXX: Any standardization? +AUTHENTICATION_FAILED_CODE = 81 +PERMISSION_DENIED_CODE = 82 + + +class AuthenticationFailedException(Fault): + """An XML-RPC fault to be raised when a permission_required authentication + check fails + + Author + """ + def __init__(self): + Fault.__init__(self, AUTHENTICATION_FAILED_CODE, + _('Username and/or password is incorrect')) + + +class PermissionDeniedException(Fault): + """An XML-RPC fault to be raised when a permission_required permission + check fails + """ + def __init__(self): + Fault.__init__(self, PERMISSION_DENIED_CODE, _('Permission denied')) + + +def xmlrpc_method(returns='string', args=None, name=None): + """Adds a signature to an XML-RPC function and register + it with the dispatcher. + + returns + The return type of the function. This can either be a string + description (e.g. 'string') or a type (e.g. str, bool) etc. + + args + A list of the types of the arguments that the function accepts. These + can be strings or types or a mixture of the two e.g. + [str, bool, 'string'] + """ + # Args should be a list + if args is None: + args = [] + + def _xmlrpc_func(func): + """Inner function for XML-RPC method decoration. Adds a signature to + the method passed to it. + + func + The function to add the signature to + """ + # If name is not None, register the method with the dispatcher. + from django_xmlrpc.views import xmlrpcdispatcher + if name is not None: + xmlrpcdispatcher.register_function(func, name) + + # Add a signature to the function + func._xmlrpc_signature = { + 'returns': returns, + 'args': args + } + return func + + return _xmlrpc_func + +xmlrpc_func = xmlrpc_method + + +# Don't use this decorator when your service is going to be +# available in an unencrpted/untrusted network. +# Configure HTTPS transport for your web server. +def permission_required(perm=None): + """Decorator for authentication. Uses Django's built in authentication + framework to provide authenticated-only and permission-related access + to XML-RPC methods + + perm + The permission (as a string) that the user must hold to be able to + call the function that is decorated with permission_required. + """ + def _dec(func): + """An inner decorator. Adds the lookup code for the permission passed + in the outer method to the function passed to it. + + func + The function to add the permission check to + """ + def __authenticated_call(username, password, *args): + """Inner inner decorator. Adds username and password parameters to + a given XML-RPC function for authentication and permission + checking purposes and modifies the method signature appropriately + + username + The username used for authentication + + password + The password used for authentication + """ + try: + user = authenticate(username=username, password=password) + if not user: + raise AuthenticationFailedException + if perm and not user.has_perm(perm): + raise PermissionDeniedException + except AuthenticationFailedException: + raise + except PermissionDeniedException: + raise + except: + raise AuthenticationFailedException + return func(user, *args) + + # Update the function's XML-RPC signature, if the method has one + if hasattr(func, '_xmlrpc_signature'): + sig = func._xmlrpc_signature + + # We just stick two string args on the front of sign['args'] to + # represent username and password + sig['args'] = (['string'] * 2) + sig['args'] + __authenticated_call._xmlrpc_signature = sig + + # Update the function's docstring + if func.__doc__: + __authenticated_call.__doc__ = func.__doc__ + \ + "\nNote: Authentication is required.""" + if perm: + __authenticated_call.__doc__ += ' this function requires ' \ + + '"%s" permission.' % perm + + return __authenticated_call + + return _dec diff --git a/gstudio/xmlrpc/rpc/dispatcher.py b/gstudio/xmlrpc/rpc/dispatcher.py new file mode 100644 index 00000000..f4014578 --- /dev/null +++ b/gstudio/xmlrpc/rpc/dispatcher.py @@ -0,0 +1,76 @@ +"""Offers a simple XML-RPC dispatcher for django_xmlrpc + +Author:: + Graham Binns + +Credit must go to Brendan W. McAdams <brendan.mcadams@thewintergrp.com>, who +posted the original SimpleXMLRPCDispatcher to the Django wiki: +http://code.djangoproject.com/wiki/XML-RPC + +New BSD License +=============== +Copyright (c) 2007, Graham Binns http://launchpad.net/~codedragon + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the <ORGANIZATION> nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" +from inspect import getargspec +from SimpleXMLRPCServer import SimpleXMLRPCDispatcher +from django.conf import settings + + +# If we need to debug, now we know +DEBUG = hasattr(settings, 'XMLRPC_DEBUG') and settings.XMLRPC_DEBUG + + +class DjangoXMLRPCDispatcher(SimpleXMLRPCDispatcher): + """A simple XML-RPC dispatcher for Django. + + Subclassess SimpleXMLRPCServer.SimpleXMLRPCDispatcher for the purpose of + overriding certain built-in methods (it's nicer than monkey-patching them, + that's for sure). + """ + + def system_methodSignature(self, method): + """Returns the signature details for a specified method + + method + The name of the XML-RPC method to get the details for + """ + # See if we can find the method in our funcs dict + # TODO: Handle this better: We really should return something more + # formal than an AttributeError + func = self.funcs[method] + + try: + sig = func._xmlrpc_signature + except: + sig = { + 'returns': 'string', + 'args': ['string' for arg in getargspec(func)[0]], + } + + return [sig['returns']] + sig['args'] diff --git a/gstudio/xmlrpc/rpc/locale/fr/LC_MESSAGES/django.mo b/gstudio/xmlrpc/rpc/locale/fr/LC_MESSAGES/django.mo Binary files differnew file mode 100644 index 00000000..06035ed2 --- /dev/null +++ b/gstudio/xmlrpc/rpc/locale/fr/LC_MESSAGES/django.mo diff --git a/gstudio/xmlrpc/rpc/locale/fr/LC_MESSAGES/django.po b/gstudio/xmlrpc/rpc/locale/fr/LC_MESSAGES/django.po new file mode 100644 index 00000000..091e086f --- /dev/null +++ b/gstudio/xmlrpc/rpc/locale/fr/LC_MESSAGES/django.po @@ -0,0 +1,49 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: django-xmlrpc\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-07-31 15:33+0200\n" +"PO-Revision-Date: 2010-07-31 15:50+0100\n" +"Last-Translator: Fantomas <Fantomas42@gmail.com>\n" +"Language-Team: Fantomas42 <fantomas42@gmail.com>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: FRANCE\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: decorators.py:60 +msgid "Username and/or password is incorrect" +msgstr "Nom d'utilisateur et/ou mot de passe incorrect" + +#: decorators.py:68 +msgid "Permission denied" +msgstr "Permission refusée" + +#: templates/xmlrpc_get.html:4 +#: templates/xmlrpc_get.html.py:7 +msgid "XML-RPC Service" +msgstr "Service XML-RPC" + +#: templates/xmlrpc_get.html:9 +msgid "You need to invoke this service using an XML-RPC Client." +msgstr "Vous devez invoquer ce service en utilisant un client XML-RPC." + +#: templates/xmlrpc_get.html:11 +msgid "The following methods are available :" +msgstr "Les méthodes suivantes sont disponibles :" + +#: templates/xmlrpc_get.html:17 +msgid "Types of argument" +msgstr "Types d'argument" + +#: templates/xmlrpc_get.html:19 +msgid "Type of return" +msgstr "Type de retour" + diff --git a/gstudio/xmlrpc/rpc/setup.py b/gstudio/xmlrpc/rpc/setup.py new file mode 100644 index 00000000..10b4b920 --- /dev/null +++ b/gstudio/xmlrpc/rpc/setup.py @@ -0,0 +1,31 @@ +import os +from setuptools import setup, find_packages + +setup(name = 'django-xmlrpc', + version = '0.1.4', + + description = 'XML-RPC Server App for the Django framework.', + long_description=open(os.path.join('README.rst')).read(), + keywords = 'django, service, xmlrpc', + + author = 'Graham Binns', + author_email = 'graham.binns@gmail.com', + maintainer = 'Fantomas42', + maintainer_email = 'fantomas42@gmail.com', + url = 'http://github.com/Fantomas42/django-xmlrpc', + + packages = find_packages(), + classifiers=[ + 'Framework :: Django', + 'Development Status :: 5 - Production/Stable', + 'Environment :: Web Environment', + 'Programming Language :: Python', + 'Intended Audience :: Developers', + 'Operating System :: OS Independent', + 'Topic :: Software Development :: Libraries :: Python Modules',], + + license = 'New BSD License', + include_package_data = True, + zip_safe=False + ) + diff --git a/gstudio/xmlrpc/rpc/templates/xmlrpc_get.html b/gstudio/xmlrpc/rpc/templates/xmlrpc_get.html new file mode 100644 index 00000000..4c9fdfc6 --- /dev/null +++ b/gstudio/xmlrpc/rpc/templates/xmlrpc_get.html @@ -0,0 +1,26 @@ +{% extends "admin/base_site.html" %} +{% load i18n %} + +{% block title %}{% trans "XML-RPC Service" %}{% endblock %} + +{% block content %} +<h2>{% trans "XML-RPC Service" %}</h2> + +<p>{% trans "You need to invoke this service using an XML-RPC Client." %}</p> + +<h3>{% trans "The following methods are available :" %}</h3> + +{% for m in methods %} +<div class="functions"> + <h4>{{ m.0 }}</h4> + <div class="function_desc"> + <strong>{% trans "Types of argument" %}{{ m.1.args|length|pluralize }} :</strong> {{ m.1.args }} + <br /> + <strong>{% trans "Type of return" %} :</strong> {{ m.1.returns }} + <br /> + <pre class="function_doc">{{ m.2 }}</pre> + </div> +</div> +{% endfor %} +{% endblock %} + diff --git a/gstudio/xmlrpc/rpc/views.py b/gstudio/xmlrpc/rpc/views.py index 8c66b384..1edfa37e 100644 --- a/gstudio/xmlrpc/rpc/views.py +++ b/gstudio/xmlrpc/rpc/views.py @@ -156,24 +156,30 @@ if hasattr(settings, 'XMLRPC_METHODS'): raise ImproperlyConfigured('Error registering XML-RPC method: ' \ + '"%s" is not callable in module %s' % (attr, module)) - xmlrpcdispatcher.register_function(func, name) + #xmlrpcdispatcher.register_function(func, name) xmlrpcdispatcher.register_function(getNodetype,'getNodetype') - xmlrpcdispatcher.register_function(nidExists,'nidExists') + xmlrpcdispatcher.register_function(nidExists,'nidExists') xmlrpcdispatcher.register_function(getinfoFromSSID,'getinfoFromSSID') - #xmlrpcdispatcher.register_function(getNeighbourhood,'getNeighbourhood') + xmlrpcdispatcher.register_function(getNeighbourhood,'getNeighbourhood') xmlrpcdispatcher.register_function(get_nbh,'get_nbh') - #xmlrpcdispatcher.register_function(getallNodes,'getallNodes') + xmlrpcdispatcher.register_function(getAll,'getAll') xmlrpcdispatcher.register_function(getDatatype,'getDatatype') xmlrpcdispatcher.register_function(getAttributevalues,'getAttributevalues') xmlrpcdispatcher.register_function(getSubjecttypes,'getSubjecttypes') - #xmlrpcdispatcher.register_function(getAttributeType,'getAttributeType') + xmlrpcdispatcher.register_function(getAttributeType,'getAttributeType') xmlrpcdispatcher.register_function(getRoles,'getRoles') xmlrpcdispatcher.register_function(getSubtypes,'getSubtypes') - #xmlrpcdispatcher.register_function(Suballtypes,'Suballtypes') + xmlrpcdispatcher.register_function(getAllSubtypes,'getAllSubtypes') xmlrpcdispatcher.register_function(getRestrictions,'getRestrictions') xmlrpcdispatcher.register_function(getlatestSSID,'getlatestSSID') xmlrpcdispatcher.register_function(getAllSnapshots,'getAllSnapshots') - + xmlrpcdispatcher.register_function(setAttributetype,'setAttributetype') + xmlrpcdispatcher.register_function(setRelationtype,'setRelationtype') + xmlrpcdispatcher.register_function(setObjecttype,'setObjecttype') + xmlrpcdispatcher.register_function(setObject,'setObject') + xmlrpcdispatcher.register_function(setAttribute,'setAttribute') + xmlrpcdispatcher.register_function(setRelation,'setRelation') + xmlrpcdispatcher.register_function(getGbobjectNeighbourhood,'getGbobjectNeighbourhood') diff --git a/gstudio/xmlrpc/views.py b/gstudio/xmlrpc/views.py new file mode 100644 index 00000000..0bcd4f09 --- /dev/null +++ b/gstudio/xmlrpc/views.py @@ -0,0 +1,193 @@ +"""Uses SimpleXMLRPCServer's SimpleXMLRPCDispatcher to serve XML-RPC requests + +Authors:: + Graham Binns + Reza Mohammadi + Julien Fache + +Credit must go to Brendan W. McAdams <brendan.mcadams@thewintergrp.com>, who +posted the original SimpleXMLRPCDispatcher to the Django wiki: +http://code.djangoproject.com/wiki/XML-RPC + +New BSD License +=============== +Copyright (c) 2007, Graham Binns http://launchpad.net/~codedragon + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the <ORGANIZATION> nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" +import sys + +import django +from django.conf import settings +from django.template import RequestContext +from django.shortcuts import render_to_response +from django.core.exceptions import ImproperlyConfigured +from django.http import HttpResponse, HttpResponseServerError +from gstudio.xmlrpc.metaweblog import * +from django.utils.datastructures import SortedDict +try: + from django.views.decorators.csrf import csrf_exempt +except ImportError: + from django.contrib.csrf.middleware import csrf_exempt + +from dispatcher import DjangoXMLRPCDispatcher +from decorators import xmlrpc_func + + +# We create a local DEBUG variable from the data in settings. +DEBUG = hasattr(settings, 'XMLRPC_DEBUG') and settings.XMLRPC_DEBUG + +# Declare xmlrpcdispatcher correctly depending on our python version +if sys.version_info[:3] >= (2, 5,): + xmlrpcdispatcher = DjangoXMLRPCDispatcher(allow_none=True, encoding=None) +else: + xmlrpcdispatcher = DjangoXMLRPCDispatcher() + + +def request_datas(request): + if django.VERSION[1] > 3: + return request.body + return request.raw_post_data + + +@xmlrpc_func(returns='string', args=['string']) +def test_xmlrpc(text): + """Simply returns the args passed to it as a string""" + return "Here's a response! %s" % str(text) + + +@csrf_exempt +def handle_xmlrpc(request): + """Handles XML-RPC requests. All XML-RPC calls should be forwarded here + + request + The HttpRequest object that carries the XML-RPC call. If this is a + GET request, nothing will happen (we only accept POST requests) + """ + if request.method == "POST": + if DEBUG: + print request_datas(request) + try: + response = HttpResponse(content_type='text/xml') + response.write( + xmlrpcdispatcher._marshaled_dispatch(request_datas(request))) + if DEBUG: + print response + return response + except: + return HttpResponseServerError() + else: + methods = xmlrpcdispatcher.system_listMethods() + method_list = [] + + for method in methods: + sig_ = xmlrpcdispatcher.system_methodSignature(method) + sig = { + 'returns': sig_[0], + 'args': ", ".join(sig_[1:]), + } + + # this just reads your docblock, so fill it in! + method_help = xmlrpcdispatcher.system_methodHelp(method) + + method_list.append((method, sig, method_help)) + + if hasattr(settings, 'XMLRPC_GET_TEMPLATE'): + # This behaviour is deprecated + if settings.DEBUG: + print "Use of settings.XMLRPC_GET_TEMPLATE is deprecated " \ + + "Please update your code to use django_xmlrpc/templates" + template = settings.XMLRPC_GET_TEMPLATE + else: + template = 'xmlrpc_get.html' + return render_to_response(template, {'methods': method_list}, + context_instance=RequestContext(request)) + + +# Load up any methods that have been registered with the server in settings +if hasattr(settings, 'XMLRPC_METHODS'): + for path, name in settings.XMLRPC_METHODS: + # if "path" is actually a function, just add it without fuss + if callable(path): + xmlrpcdispatcher.register_function(path, name) + continue + + # Otherwise we try and find something that we can call + i = path.rfind('.') + module, attr = path[:i], path[i + 1:] + + try: + mod = __import__(module, globals(), locals(), [attr]) + except ImportError, ex: + raise ImproperlyConfigured("Error registering XML-RPC method: " \ + + "module %s can't be imported" % module) + + try: + func = getattr(mod, attr) + except AttributeError: + raise ImproperlyConfigured('Error registering XML-RPC method: ' \ + + 'module %s doesn\'t define a method "%s"' % (module, attr)) + + if not callable(func): + raise ImproperlyConfigured('Error registering XML-RPC method: ' \ + + '"%s" is not callable in module %s' % (attr, module)) + + #xmlrpcdispatcher.register_function(func, name) +# Registration for Gnowsys-studio XMLRPC functions + xmlrpcdispatcher.register_function(getNodetype,'getNodetype') + xmlrpcdispatcher.register_function(nidExists,'nidExists') + xmlrpcdispatcher.register_function(getinfoFromSSID,'getinfoFromSSID') + xmlrpcdispatcher.register_function(getNeighbourhood,'getNeighbourhood') + xmlrpcdispatcher.register_function(get_nbh,'get_nbh') + xmlrpcdispatcher.register_function(getAll,'getAll') + xmlrpcdispatcher.register_function(getDatatype,'getDatatype') + xmlrpcdispatcher.register_function(getAttributevalues,'getAttributevalues') + xmlrpcdispatcher.register_function(getSubjecttypes,'getSubjecttypes') + xmlrpcdispatcher.register_function(getAttributeType,'getAttributeType') + xmlrpcdispatcher.register_function(getRoles,'getRoles') + xmlrpcdispatcher.register_function(getSubtypes,'getSubtypes') + xmlrpcdispatcher.register_function(getAllSubtypes,'getAllSubtypes') + xmlrpcdispatcher.register_function(getRestrictions,'getRestrictions') + xmlrpcdispatcher.register_function(getlatestSSID,'getlatestSSID') + xmlrpcdispatcher.register_function(getAllSnapshots,'getAllSnapshots') + xmlrpcdispatcher.register_function(setAttributetype,'setAttributetype') + xmlrpcdispatcher.register_function(setRelationtype,'setRelationtype') + xmlrpcdispatcher.register_function(setObjecttype,'setObjecttype') + xmlrpcdispatcher.register_function(setObject,'setObject') + xmlrpcdispatcher.register_function(setAttribute,'setAttribute') + xmlrpcdispatcher.register_function(setRelation,'setRelation') + xmlrpcdispatcher.register_function(getGbobjectNeighbourhood,'getGbobjectNeighbourhood') + + + + + + +# Finally, register the introspection and multicall methods with the XML-RPC +# namespace +xmlrpcdispatcher.register_introspection_functions() +xmlrpcdispatcher.register_multicall_functions() |