├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.rst ├── django_xmlrpc ├── __init__.py ├── apps.py ├── decorators.py ├── dispatcher.py ├── locale │ └── fr │ │ └── LC_MESSAGES │ │ ├── django.mo │ │ └── django.po ├── registry.py ├── templates │ └── xmlrpc_get.html └── views.py ├── setup.cfg └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.pyc 3 | TODO.txt 4 | README.html 5 | bin 6 | lib 7 | dist 8 | eggs 9 | parts 10 | build 11 | include 12 | downloads 13 | src_eggs 14 | develop-eggs 15 | .installed.cfg 16 | django_xmlrpc.egg-info/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007-2008, Graham Binns 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of this application nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY GRAHAM BINNS ''AS IS'' AND ANY 16 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL GRAHAM BINNS BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.rst 2 | recursive-include django_xmlrpc/locale * 3 | recursive-include django_xmlrpc/templates *.html 4 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ============== 2 | Django XML-RPC 3 | ============== 4 | 5 | **Django_xmlrpc** offers a means by which a Django developer can expose their 6 | views (or indeed any other function) using XML-RPC. 7 | 8 | This is a fork of the original version made by Svetlyak40wt compatible with 9 | Django >= 1.8 and Python >= 2.5. 10 | 11 | If you want to use **django_xmlrpc** for an older version of Django or Python, 12 | please use an old release. 13 | 14 | .. contents:: 15 | 16 | Installation 17 | ============ 18 | 19 | You could retrieve the last sources from 20 | http://github.com/Fantomas42/django-xmlrpc and run the installation script 21 | :: 22 | 23 | $ python setup.py install 24 | 25 | or use pip :: 26 | 27 | $ pip install -e git://github.com/Fantomas42/django-xmlrpc.git#egg=django-xmlrpc 28 | 29 | Usage 30 | ===== 31 | 32 | Register **django_xmlrpc** in your INSTALLED_APPS section of your project' 33 | settings. 34 | 35 | There are two ways to register methods that you want to handle: 36 | 37 | In your project's settings. :: 38 | 39 | XMLRPC_METHODS = (('path.to.your.method', 'Method name'), 40 | ('path.to.your.othermethod', 'Other Method name'),) 41 | 42 | In a file called ``xmlrpc.py`` in your application directory. :: 43 | 44 | XMLRPC_METHODS = (('path.to.your.method', 'Method name'), 45 | ('path.to.your.othermethod', 'Other Method name'),) 46 | 47 | A registered method should look like this: :: 48 | 49 | from django_xmlrpc.decorators import xmlrpc_func 50 | 51 | @xmlrpc_func(returns='string', args=['string']) 52 | def test_xmlrpc(text): 53 | """Simply returns the args passed to it as a string""" 54 | return "Here's a response! %s" % str(text) 55 | 56 | Finally we need to register the url of the XML-RPC server. Insert something 57 | like this in your project's urls.py: :: 58 | 59 | from django_xmlrpc.views import handle_xmlrpc 60 | 61 | url(r'^xmlrpc/$', handle_xmlrpc, name='xmlrpc'), 62 | -------------------------------------------------------------------------------- /django_xmlrpc/__init__.py: -------------------------------------------------------------------------------- 1 | """__init__ module for the django_xmlrpc package 2 | 3 | Authors:: 4 | Graham Binns 5 | Julien Fache 6 | 7 | Credit must go to Brendan W. McAdams , who 8 | posted the original SimpleXMLRPCDispatcher to the Django wiki: 9 | http://code.djangoproject.com/wiki/XML-RPC 10 | 11 | New BSD License 12 | =============== 13 | Copyright (c) 2007, Graham Binns http://launchpad.net/~codedragon 14 | 15 | All rights reserved. 16 | 17 | Redistribution and use in source and binary forms, with or without 18 | modification, are permitted provided that the following conditions are met: 19 | 20 | * Redistributions of source code must retain the above copyright notice, 21 | this list of conditions and the following disclaimer. 22 | * Redistributions in binary form must reproduce the above copyright notice, 23 | this list of conditions and the following disclaimer in the documentation 24 | and/or other materials provided with the distribution. 25 | * Neither the name of the nor the names of its contributors 26 | may be used to endorse or promote products derived from this software 27 | without specific prior written permission. 28 | 29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 33 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 34 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 35 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 37 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 38 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 39 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | """ 41 | VERSION = (0, 1, 8) 42 | __version__ = '.'.join(map(str, VERSION)) 43 | 44 | default_app_config = 'django_xmlrpc.apps.XMLRPCConfig' 45 | -------------------------------------------------------------------------------- /django_xmlrpc/apps.py: -------------------------------------------------------------------------------- 1 | """apps module for the django_xmlrpc package 2 | 3 | Authors:: 4 | Julien Fache 5 | 6 | Credit must go to Brendan W. McAdams , who 7 | posted the original SimpleXMLRPCDispatcher to the Django wiki: 8 | http://code.djangoproject.com/wiki/XML-RPC 9 | 10 | New BSD License 11 | =============== 12 | Copyright (c) 2007, Graham Binns http://launchpad.net/~codedragon 13 | 14 | All rights reserved. 15 | 16 | Redistribution and use in source and binary forms, with or without 17 | modification, are permitted provided that the following conditions are met: 18 | 19 | * Redistributions of source code must retain the above copyright notice, 20 | this list of conditions and the following disclaimer. 21 | * Redistributions in binary form must reproduce the above copyright notice, 22 | this list of conditions and the following disclaimer in the documentation 23 | and/or other materials provided with the distribution. 24 | * Neither the name of the nor the names of its contributors 25 | may be used to endorse or promote products derived from this software 26 | without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 32 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 33 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 34 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 36 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 37 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 38 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | """ 40 | from django.apps import AppConfig 41 | 42 | 43 | class XMLRPCConfig(AppConfig): 44 | name = 'django_xmlrpc' 45 | label = 'xmlrpc' 46 | verbose_name = 'XMRPC' 47 | 48 | def ready(self): 49 | from django_xmlrpc.registry import register_xmlrpc_methods 50 | register_xmlrpc_methods() 51 | -------------------------------------------------------------------------------- /django_xmlrpc/decorators.py: -------------------------------------------------------------------------------- 1 | """Offers decorators to make the use of django_xmlrpc a great deal simpler 2 | 3 | Authors:: 4 | Graham Binns, 5 | Reza Mohammadi 6 | 7 | Credit must go to Brendan W. McAdams , who 8 | posted the original SimpleXMLRPCDispatcher to the Django wiki: 9 | http://code.djangoproject.com/wiki/XML-RPC 10 | 11 | New BSD License 12 | =============== 13 | Copyright (c) 2007, Graham Binns http://launchpad.net/~codedragon 14 | 15 | All rights reserved. 16 | 17 | Redistribution and use in source and binary forms, with or without 18 | modification, are permitted provided that the following conditions are met: 19 | 20 | * Redistributions of source code must retain the above copyright notice, 21 | this list of conditions and the following disclaimer. 22 | * Redistributions in binary form must reproduce the above copyright notice, 23 | this list of conditions and the following disclaimer in the documentation 24 | and/or other materials provided with the distribution. 25 | * Neither the name of the nor the names of its contributors 26 | may be used to endorse or promote products derived from this software 27 | without specific prior written permission. 28 | 29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 33 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 34 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 35 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 37 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 38 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 39 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | """ 41 | try: 42 | from xmlrpc.client import Fault 43 | except ImportError: # Python 2 44 | from xmlrpclib import Fault 45 | from django.contrib.auth import authenticate 46 | from django.utils.translation import gettext as _ 47 | 48 | 49 | # Some constants for your pleasure 50 | # XXX: Any standardization? 51 | AUTHENTICATION_FAILED_CODE = 81 52 | PERMISSION_DENIED_CODE = 82 53 | 54 | 55 | class AuthenticationFailedException(Fault): 56 | """An XML-RPC fault to be raised when a permission_required authentication 57 | check fails 58 | 59 | Author 60 | """ 61 | def __init__(self): 62 | Fault.__init__(self, AUTHENTICATION_FAILED_CODE, 63 | _('Username and/or password is incorrect')) 64 | 65 | 66 | class PermissionDeniedException(Fault): 67 | """An XML-RPC fault to be raised when a permission_required permission 68 | check fails 69 | """ 70 | def __init__(self): 71 | Fault.__init__(self, PERMISSION_DENIED_CODE, _('Permission denied')) 72 | 73 | 74 | def xmlrpc_method(returns='string', args=None, name=None): 75 | """Adds a signature to an XML-RPC function. 76 | 77 | returns 78 | The return type of the function. This can either be a string 79 | description (e.g. 'string') or a type (e.g. str, bool) etc. 80 | 81 | args 82 | A list of the types of the arguments that the function accepts. These 83 | can be strings or types or a mixture of the two e.g. 84 | [str, bool, 'string'] 85 | """ 86 | # Args should be a list 87 | if args is None: 88 | args = [] 89 | 90 | def _xmlrpc_func(func): 91 | """Inner function for XML-RPC method decoration. Adds a signature to 92 | the method passed to it. 93 | 94 | func 95 | The function to add the signature to 96 | """ 97 | # Add a signature to the function 98 | func._xmlrpc_signature = { 99 | 'returns': returns, 100 | 'args': args 101 | } 102 | return func 103 | 104 | return _xmlrpc_func 105 | 106 | xmlrpc_func = xmlrpc_method 107 | 108 | 109 | # Don't use this decorator when your service is going to be 110 | # available in an unencrpted/untrusted network. 111 | # Configure HTTPS transport for your web server. 112 | def permission_required(perm=None): 113 | """Decorator for authentication. Uses Django's built in authentication 114 | framework to provide authenticated-only and permission-related access 115 | to XML-RPC methods 116 | 117 | perm 118 | The permission (as a string) that the user must hold to be able to 119 | call the function that is decorated with permission_required. 120 | """ 121 | def _dec(func): 122 | """An inner decorator. Adds the lookup code for the permission passed 123 | in the outer method to the function passed to it. 124 | 125 | func 126 | The function to add the permission check to 127 | """ 128 | def __authenticated_call(username, password, *args): 129 | """Inner inner decorator. Adds username and password parameters to 130 | a given XML-RPC function for authentication and permission 131 | checking purposes and modifies the method signature appropriately 132 | 133 | username 134 | The username used for authentication 135 | 136 | password 137 | The password used for authentication 138 | """ 139 | try: 140 | user = authenticate(username=username, password=password) 141 | if not user: 142 | raise AuthenticationFailedException 143 | if perm and not user.has_perm(perm): 144 | raise PermissionDeniedException 145 | except AuthenticationFailedException: 146 | raise 147 | except PermissionDeniedException: 148 | raise 149 | except: 150 | raise AuthenticationFailedException 151 | return func(user, *args) 152 | 153 | # Update the function's XML-RPC signature, if the method has one 154 | if hasattr(func, '_xmlrpc_signature'): 155 | sig = func._xmlrpc_signature 156 | 157 | # We just stick two string args on the front of sign['args'] to 158 | # represent username and password 159 | sig['args'] = (['string'] * 2) + sig['args'] 160 | __authenticated_call._xmlrpc_signature = sig 161 | 162 | # Update the function's docstring 163 | if func.__doc__: 164 | __authenticated_call.__doc__ = func.__doc__ + \ 165 | "\nNote: Authentication is required.""" 166 | if perm: 167 | __authenticated_call.__doc__ += (' this function requires ' 168 | '"%s" permission.' % perm) 169 | 170 | return __authenticated_call 171 | 172 | return _dec 173 | -------------------------------------------------------------------------------- /django_xmlrpc/dispatcher.py: -------------------------------------------------------------------------------- 1 | """Offers a simple XML-RPC dispatcher for django_xmlrpc 2 | 3 | Author:: 4 | Graham Binns 5 | 6 | Credit must go to Brendan W. McAdams , who 7 | posted the original SimpleXMLRPCDispatcher to the Django wiki: 8 | http://code.djangoproject.com/wiki/XML-RPC 9 | 10 | New BSD License 11 | =============== 12 | Copyright (c) 2007, Graham Binns http://launchpad.net/~codedragon 13 | 14 | All rights reserved. 15 | 16 | Redistribution and use in source and binary forms, with or without 17 | modification, are permitted provided that the following conditions are met: 18 | 19 | * Redistributions of source code must retain the above copyright notice, 20 | this list of conditions and the following disclaimer. 21 | * Redistributions in binary form must reproduce the above copyright notice, 22 | this list of conditions and the following disclaimer in the documentation 23 | and/or other materials provided with the distribution. 24 | * Neither the name of the nor the names of its contributors 25 | may be used to endorse or promote products derived from this software 26 | without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 32 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 33 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 34 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 36 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 37 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 38 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | """ 40 | from inspect import getargspec 41 | 42 | try: 43 | from xmlrpc.server import SimpleXMLRPCDispatcher 44 | except ImportError: # Python 2 45 | from SimpleXMLRPCServer import SimpleXMLRPCDispatcher 46 | 47 | 48 | class DjangoXMLRPCDispatcher(SimpleXMLRPCDispatcher): 49 | """A simple XML-RPC dispatcher for Django. 50 | 51 | Subclassess SimpleXMLRPCServer.SimpleXMLRPCDispatcher for the purpose of 52 | overriding certain built-in methods (it's nicer than monkey-patching them, 53 | that's for sure). 54 | """ 55 | 56 | def system_methodSignature(self, method): 57 | """Returns the signature details for a specified method 58 | 59 | method 60 | The name of the XML-RPC method to get the details for 61 | """ 62 | # See if we can find the method in our funcs dict 63 | # TODO: Handle this better: We really should return something more 64 | # formal than an AttributeError 65 | func = self.funcs[method] 66 | 67 | try: 68 | sig = func._xmlrpc_signature 69 | except: 70 | sig = { 71 | 'returns': 'string', 72 | 'args': ['string' for arg in getargspec(func)[0]], 73 | } 74 | 75 | return [sig['returns']] + sig['args'] 76 | 77 | xmlrpc_dispatcher = DjangoXMLRPCDispatcher(allow_none=False, encoding=None) 78 | -------------------------------------------------------------------------------- /django_xmlrpc/locale/fr/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fantomas42/django-xmlrpc/6cf59c555b207de7ecec75ac962751e8245cf8c9/django_xmlrpc/locale/fr/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /django_xmlrpc/locale/fr/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: django-xmlrpc\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2010-07-31 15:33+0200\n" 11 | "PO-Revision-Date: 2010-07-31 15:50+0100\n" 12 | "Last-Translator: Fantomas \n" 13 | "Language-Team: Fantomas42 \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=UTF-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "X-Poedit-Language: French\n" 18 | "X-Poedit-Country: FRANCE\n" 19 | "X-Poedit-SourceCharset: utf-8\n" 20 | 21 | #: decorators.py:60 22 | msgid "Username and/or password is incorrect" 23 | msgstr "Nom d'utilisateur et/ou mot de passe incorrect" 24 | 25 | #: decorators.py:68 26 | msgid "Permission denied" 27 | msgstr "Permission refusée" 28 | 29 | #: templates/xmlrpc_get.html:4 30 | #: templates/xmlrpc_get.html.py:7 31 | msgid "XML-RPC Service" 32 | msgstr "Service XML-RPC" 33 | 34 | #: templates/xmlrpc_get.html:9 35 | msgid "You need to invoke this service using an XML-RPC Client." 36 | msgstr "Vous devez invoquer ce service en utilisant un client XML-RPC." 37 | 38 | #: templates/xmlrpc_get.html:11 39 | msgid "The following methods are available :" 40 | msgstr "Les méthodes suivantes sont disponibles :" 41 | 42 | #: templates/xmlrpc_get.html:17 43 | msgid "Types of argument" 44 | msgstr "Types d'argument" 45 | 46 | #: templates/xmlrpc_get.html:19 47 | msgid "Type of return" 48 | msgstr "Type de retour" 49 | 50 | -------------------------------------------------------------------------------- /django_xmlrpc/registry.py: -------------------------------------------------------------------------------- 1 | """registry module for the django_xmlrpc package 2 | 3 | Authors:: 4 | Julien Fache 5 | 6 | Credit must go to Brendan W. McAdams , who 7 | posted the original SimpleXMLRPCDispatcher to the Django wiki: 8 | http://code.djangoproject.com/wiki/XML-RPC 9 | 10 | New BSD License 11 | =============== 12 | Copyright (c) 2007, Graham Binns http://launchpad.net/~codedragon 13 | 14 | All rights reserved. 15 | 16 | Redistribution and use in source and binary forms, with or without 17 | modification, are permitted provided that the following conditions are met: 18 | 19 | * Redistributions of source code must retain the above copyright notice, 20 | this list of conditions and the following disclaimer. 21 | * Redistributions in binary form must reproduce the above copyright notice, 22 | this list of conditions and the following disclaimer in the documentation 23 | and/or other materials provided with the distribution. 24 | * Neither the name of the nor the names of its contributors 25 | may be used to endorse or promote products derived from this software 26 | without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 32 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 33 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 34 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 36 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 37 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 38 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | """ 40 | from collections import Callable 41 | from logging import getLogger 42 | 43 | from django.apps import apps 44 | from django.conf import settings 45 | from django.core.exceptions import ImproperlyConfigured 46 | 47 | from django_xmlrpc.dispatcher import xmlrpc_dispatcher 48 | 49 | logger = getLogger('xmlrpc.registry') 50 | 51 | 52 | def register_xmlrpc_methods(): 53 | """ 54 | Register all xmlrpc methods in the server. 55 | """ 56 | if hasattr(settings, 'XMLRPC_METHODS'): 57 | register_xmlrpc_methods_legacy() 58 | else: 59 | register_xmlrpc_methods_autodiscover() 60 | register_xmlrpc_methods_helpers() 61 | 62 | 63 | def register_xmlrpc_method(path, name): 64 | """ 65 | Register a method into the server. 66 | """ 67 | # If 'path' is actually a function, just add it without fuss 68 | if isinstance(path, Callable): 69 | logger.info("Registering '%s:%s' => '%s'" % ( 70 | path.__module__, path.__name__, name)) 71 | xmlrpc_dispatcher.register_function(path, name) 72 | return 73 | 74 | # Otherwise we try and find something that we can call 75 | logger.debug('%s not callable, resolving path...' % path) 76 | i = path.rfind('.') 77 | module, attr = path[:i], path[i + 1:] 78 | 79 | try: 80 | mod = __import__(module, globals(), locals(), [attr]) 81 | except ImportError: 82 | raise ImproperlyConfigured( 83 | "Error registering XML-RPC method: " 84 | "module %s can't be imported" % module) 85 | 86 | try: 87 | func = getattr(mod, attr) 88 | except AttributeError: 89 | raise ImproperlyConfigured( 90 | 'Error registering XML-RPC method: ' 91 | 'module %s doesn\'t define a method "%s"' % (module, attr)) 92 | 93 | if not isinstance(func, Callable): 94 | raise ImproperlyConfigured( 95 | 'Error registering XML-RPC method: ' 96 | '"%s" is not callable in module %s' % (attr, module)) 97 | 98 | logger.info("Registering '%s:%s' => '%s'" % (module, attr, name)) 99 | xmlrpc_dispatcher.register_function(func, name) 100 | 101 | 102 | def register_xmlrpc_methods_legacy(): 103 | """ 104 | Load up any methods that have been registered 105 | with the server via settings. 106 | """ 107 | logger.info('Register XML-RPC methods from settings.XMLRPC_METHODS') 108 | for path, name in settings.XMLRPC_METHODS: 109 | register_xmlrpc_method(path, name) 110 | 111 | 112 | def register_xmlrpc_methods_autodiscover(): 113 | """ 114 | Looks in app directories for a module called 'xmlrpc' 115 | This should contain a distribution XMLRPC_METHODS declaration. 116 | """ 117 | logger.info('Register XML-RPC methods by inspecting INSTALLED_APPS') 118 | for application in apps.get_app_configs(): 119 | application_name = application.name 120 | logger.debug('Checking %s...' % application_name) 121 | try: 122 | module = __import__('%s.xmlrpc' % application_name, 123 | globals(), locals(), ['']) 124 | logger.debug('Found %s.xmlrpc' % application_name) 125 | except ImportError: 126 | logger.debug('Not found %s.xmlrpc' % application_name) 127 | continue 128 | if hasattr(module, 'XMLRPC_METHODS'): 129 | logger.info('Found XMLRPC_METHODS in %s.xmlrpc' % application_name) 130 | for path, name in module.XMLRPC_METHODS: 131 | register_xmlrpc_method(path, name) 132 | 133 | 134 | def register_xmlrpc_methods_helpers(): 135 | """Register the introspection and multicall methods 136 | with the XML-RPC namespace. 137 | """ 138 | xmlrpc_dispatcher.register_introspection_functions() 139 | xmlrpc_dispatcher.register_multicall_functions() 140 | -------------------------------------------------------------------------------- /django_xmlrpc/templates/xmlrpc_get.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | {% load i18n %} 3 | 4 | {% block title %}{% trans "XML-RPC Service" %}{% endblock %} 5 | 6 | {% block content %} 7 |

{% trans "XML-RPC Service" %}

8 | 9 |

{% trans "You need to invoke this service using an XML-RPC Client." %}

10 | 11 |

{% trans "The following methods are available :" %}

12 | 13 | {% for m in methods %} 14 |
15 |

{{ m.0 }}

16 |
17 | {% trans "Types of argument" %}{{ m.1.args|length|pluralize }} : {{ m.1.args }} 18 |
19 | {% trans "Type of return" %} : {{ m.1.returns }} 20 |
21 |
{{ m.2 }}
22 |
23 |
24 | {% endfor %} 25 | {% endblock %} 26 | 27 | -------------------------------------------------------------------------------- /django_xmlrpc/views.py: -------------------------------------------------------------------------------- 1 | """Uses SimpleXMLRPCServer's SimpleXMLRPCDispatcher to serve XML-RPC requests 2 | 3 | Authors:: 4 | Graham Binns 5 | Reza Mohammadi 6 | Julien Fache 7 | 8 | Credit must go to Brendan W. McAdams , who 9 | posted the original SimpleXMLRPCDispatcher to the Django wiki: 10 | http://code.djangoproject.com/wiki/XML-RPC 11 | 12 | New BSD License 13 | =============== 14 | Copyright (c) 2007, Graham Binns http://launchpad.net/~codedragon 15 | 16 | All rights reserved. 17 | 18 | Redistribution and use in source and binary forms, with or without 19 | modification, are permitted provided that the following conditions are met: 20 | 21 | * Redistributions of source code must retain the above copyright notice, 22 | this list of conditions and the following disclaimer. 23 | * Redistributions in binary form must reproduce the above copyright notice, 24 | this list of conditions and the following disclaimer in the documentation 25 | and/or other materials provided with the distribution. 26 | * Neither the name of the nor the names of its contributors 27 | may be used to endorse or promote products derived from this software 28 | without specific prior written permission. 29 | 30 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 34 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 35 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 36 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 37 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 38 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 39 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 40 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 | """ 42 | from logging import getLogger 43 | 44 | from django.http import HttpResponse 45 | from django.http import HttpResponseServerError 46 | from django.shortcuts import render 47 | from django.views.decorators.csrf import csrf_exempt 48 | 49 | from django_xmlrpc.dispatcher import xmlrpc_dispatcher 50 | 51 | 52 | logger = getLogger('xmlrpc.views') 53 | 54 | 55 | @csrf_exempt 56 | def handle_xmlrpc(request): 57 | """Handles XML-RPC requests. All XML-RPC calls should be forwarded here 58 | 59 | request 60 | The HttpRequest object that carries the XML-RPC call. If this is a 61 | GET request, nothing will happen (we only accept POST requests) 62 | """ 63 | if request.method == 'POST': 64 | logger.info(request.body) 65 | try: 66 | response = HttpResponse(content_type='text/xml') 67 | response.write( 68 | xmlrpc_dispatcher._marshaled_dispatch(request.body)) 69 | logger.debug(response) 70 | return response 71 | except: 72 | return HttpResponseServerError() 73 | else: 74 | methods = xmlrpc_dispatcher.system_listMethods() 75 | method_list = [] 76 | 77 | for method in methods: 78 | sig_ = xmlrpc_dispatcher.system_methodSignature(method) 79 | sig = { 80 | 'returns': sig_[0], 81 | 'args': ', '.join(sig_[1:]), 82 | } 83 | 84 | # This just reads your docblock, so fill it in! 85 | method_help = xmlrpc_dispatcher.system_methodHelp(method) 86 | 87 | method_list.append((method, sig, method_help)) 88 | 89 | return render(request, 'xmlrpc_get.html', {'methods': method_list}) 90 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal = 1 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from setuptools import find_packages 4 | from setuptools import setup 5 | 6 | import django_xmlrpc 7 | 8 | 9 | setup(name='django-xmlrpc', 10 | version=django_xmlrpc.__version__, 11 | 12 | description='XML-RPC Server App for the Django framework.', 13 | long_description=open(os.path.join('README.rst')).read(), 14 | keywords='django, service, xmlrpc', 15 | 16 | author='Graham Binns', 17 | author_email='graham.binns@gmail.com', 18 | maintainer='Fantomas42', 19 | maintainer_email='fantomas42@gmail.com', 20 | url='https://github.com/Fantomas42/django-xmlrpc', 21 | 22 | packages=find_packages(), 23 | classifiers=[ 24 | 'Framework :: Django', 25 | 'Development Status :: 5 - Production/Stable', 26 | 'Environment :: Web Environment', 27 | 'Programming Language :: Python', 28 | 'Programming Language :: Python :: 3', 29 | 'Intended Audience :: Developers', 30 | 'Operating System :: OS Independent', 31 | 'Topic :: Software Development :: Libraries :: Python Modules'], 32 | 33 | license='New BSD License', 34 | include_package_data=True, 35 | zip_safe=False 36 | ) 37 | --------------------------------------------------------------------------------