├── .gitignore ├── LICENSE ├── README.md └── standaloneRPC.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | bin/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # Installer logs 26 | pip-log.txt 27 | pip-delete-this-directory.txt 28 | 29 | # Unit test / coverage reports 30 | htmlcov/ 31 | .tox/ 32 | .coverage 33 | .cache 34 | nosetests.xml 35 | coverage.xml 36 | 37 | # Translations 38 | *.mo 39 | 40 | # Mr Developer 41 | .mr.developer.cfg 42 | .project 43 | .pydevproject 44 | 45 | # Rope 46 | .ropeproject 47 | 48 | # Django stuff: 49 | *.log 50 | *.pot 51 | 52 | # Sphinx documentation 53 | docs/_build/ 54 | 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Steve Theodore 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | standaloneRPC 2 | ============= 3 | 4 | Provides a simple RPC server for controlling a maya.standalone instance remotely. 5 | 6 | To use as a server, execute this file from the MayaPy interpeter: 7 | 8 | mayapy.exe path/to/standaloneRPC.py 9 | 10 | to connect to a server and issue commands: 11 | 12 | import standaloneRPC as srpc 13 | cmd = srpc.CMD('cmds.ls', type='transform') 14 | srpc.send_command(cmd) 15 | >>> {success:True, result:[u'persp', u'top', u'side', u'front'} 16 | 17 | See the CMD class and send_command methods for details. 18 | 19 | 20 | IMPORTANT 21 | ========= 22 | 23 | This module is NOT an attempt to provide a full-blown rpc server! It's a quick way 24 | for maya users to control a maya standalone instance without the commandPort! 25 | 26 | As such, this provides **NO security** so anyone who knew that an instance was 27 | running will have complete control over the target machine! This is **DANGEROUS** 28 | outside of controlled conditions! Do not expose a standalone running this to 29 | the internet. 30 | 31 | This also makes no effort to providing proxy services or marshalling - only basic data 32 | types can be sent and received. 33 | 34 | To drive these points home, we do not use the standard JSON-RPC protocol. That is to make sure 35 | this doesn't get confused with a real, robust, and secure RPC serrver. 36 | 37 | If you want something more robust, sophisticated and general you should check out 38 | 39 | JSON-RPC https://pypi.python.org/pypi/json-rpc 40 | or 41 | 42 | TINYRPC https://pypi.python.org/pypi/tinyrpc/0.5. 43 | 44 | or 45 | 46 | RPYC http://rpyc.readthedocs.org/en/latest/ 47 | -------------------------------------------------------------------------------- /standaloneRPC.py: -------------------------------------------------------------------------------- 1 | ''' 2 | standaloneRPC 3 | 4 | Cheapass server to control a remote instance of maya.standalone using a bare-bones RPC setup. 5 | 6 | To use as a server, execute this file from the MayaPy interpeter: 7 | 8 | mayapy.exe path/to/standaloneRPC.py 9 | 10 | to connect to a server and issue commands: 11 | 12 | import standaloneRPC as srpc 13 | cmd = srpc.CMD('cmds.ls', type='transform') 14 | srpc.send_command(cmd) 15 | >>> {success:True, result:[u'persp', u'top', u'side', u'front'} 16 | 17 | See the CMD class and send_command methods for details. 18 | 19 | 20 | IMPORTANT 21 | 22 | This is NOT an attempt at a full-blown rpc server! It's a quick way for maya users 23 | to control a maya standalone instance without the commandPort! 24 | 25 | As such, this provides NO security so anyone who knew that an instance was 26 | running will have complete control over the target machine! This is DANGEROUS. 27 | Do not expose a standlone running this directly to the internet! 28 | 29 | This also makes no effort to providing proxy services or marshalling - only basic data 30 | types can be sent and received. 31 | 32 | To drive these points home, we do not use the standard JSON-RPC protocol. That is to make sure 33 | this doesn't get confused with a real, robust, and secure RPC serrver. 34 | 35 | If you want something more robust, sophisticated and general you should check out 36 | 37 | JSON-RPC https://pypi.python.org/pypi/json-rpc 38 | or 39 | 40 | TINYRPC https://pypi.python.org/pypi/tinyrpc/0.5. 41 | 42 | or 43 | 44 | RPYC http://rpyc.readthedocs.org/en/latest/ 45 | 46 | ''' 47 | 48 | import sys 49 | import json 50 | import urlparse 51 | import socket 52 | import urllib2 53 | import traceback 54 | from wsgiref.simple_server import make_server 55 | import urllib 56 | import maya.cmds as cmds 57 | 58 | 59 | 60 | 61 | class CMD(str): 62 | ''' 63 | turn a command with arguments and keywords into a web-friendly encoded string 64 | 65 | print CMD('cmds.ls', type='transform') 66 | 'command=cmds.ls&kwargs=%7B%22type%22%3A+%22transform%22%7D' 67 | 68 | pass this to send_command so you don't have to manually create query strings 69 | ''' 70 | def __new__(cls, cmd, *args, **kwargs): 71 | result = {'command': str(cmd)} 72 | if args: 73 | result['args'] = json.dumps(args) 74 | if kwargs: 75 | result['kwargs'] = json.dumps(kwargs) 76 | return urllib.urlencode(result) 77 | 78 | 79 | def send_command(cmd, address = '127.0.0.1', port = 8000): 80 | ''' 81 | send the CMD object 'cmd' to the server at
: