Esempio n. 1
0
    def handle_request(self):
        message = self._message
        if not message:
            return

        logLevel = NimbleEnvironment.getServerLogLevel()

        try:
            data = self._parseData(message, logLevel)
        except Exception as err:
            self._sendResponse(
                NimbleResponseData(kind=DataKindEnum.GENERAL,
                                   error=DataErrorEnum.PARSE_FAILURE,
                                   response=NimbleResponseData.FAILED_RESPONSE,
                                   payload={'error': str(err)}), logLevel)
            return

        if data.kind == DataKindEnum.PING:
            reply = NimbleResponseData(
                kind=DataKindEnum.PING,
                response=NimbleResponseData.SUCCESS_RESPONSE)
        else:
            reply = self._routeMessage(data)

        if not reply:
            reply = NimbleResponseData(
                kind=DataKindEnum.GENERAL,
                error=DataErrorEnum.UNRECOGNIZED_REQUEST,
                response=NimbleResponseData.FAILED_RESPONSE)

        self._sendResponse(reply, logLevel)
Esempio n. 2
0
    def _executeCommand(cls, payload):
        cmd = payload['command']
        if cmd is None or (StringUtils.isStringType(cmd)
                           and not cmd in globals()):
            return NimbleResponseData(
                kind=DataKindEnum.COMMAND,
                response=NimbleResponseData.FAILED_RESPONSE,
                error=DataErrorEnum.INVALID_COMMAND)

        if StringUtils.isStringType(cmd):
            targetObject = globals().get(cmd)
        else:
            if isinstance(cmd, dict):
                module = str(cmd['module'])
                target = str(cmd['target'])
                method = str(cmd['method']) if 'method' in cmd else None
            else:
                target = str(cmd[0])
                module = str(cmd[1]) if len(cmd) > 0 else None
                method = str(cmd[2]) if len(cmd) > 1 else None

            try:
                res = __import__(module, globals(), locals(), [target])
                Target = getattr(res, target)
                if method:
                    m = getattr(Target, method)
                    if m is None:
                        raise Exception(
                            '%s not found on %s. Unable to execute command.' % \
                            (str(method), str(target) ))
            except Exception as err:
                return NimbleResponseData(
                    kind=DataKindEnum.COMMAND,
                    response=NimbleResponseData.FAILED_RESPONSE,
                    error=cls._getDetailedError(
                        'Failed to import remote command module', err))

            if method:
                targetObject = getattr(Target, method)
                if inspect.ismethod(
                        targetObject) and targetObject.__self__ is None:
                    targetObject = getattr(cls._instantiateClass(Target, cmd),
                                           method)
            elif inspect.isclass(Target):
                targetObject = cls._instantiateClass(Target, cmd)
            else:
                targetObject = Target

        try:
            result = targetObject(*payload['args'],
                                  **DictUtils.cleanDictKeys(payload['kwargs']))
            return cls.createReply(DataKindEnum.COMMAND, result)
        except Exception as err:
            return NimbleResponseData(
                kind=DataKindEnum.COMMAND,
                response=NimbleResponseData.FAILED_RESPONSE,
                error=cls._getDetailedError('Failed to execute command', err))
Esempio n. 3
0
    def createReply(cls, kind, result, errorMessage=None):
        payload = result if isinstance(result, dict) else {'result': result}
        warnings = ArgsUtils.extract(
            NimbleEnvironment.REMOTE_RESULT_WARNING_KEY, None, payload)

        if errorMessage:
            return NimbleResponseData(
                kind=kind,
                response=NimbleResponseData.FAILED_RESPONSE,
                warnings=warnings,
                error=errorMessage,
                payload=payload)

        return NimbleResponseData(kind=kind,
                                  warnings=warnings,
                                  response=NimbleResponseData.SUCCESS_RESPONSE,
                                  payload=payload)
Esempio n. 4
0
    def _executeMayaCommand(cls, payload, createReply=True):
        cmd = getattr(mc, str(payload['command']), None)
        if cmd is None:
            return NimbleResponseData(
                kind=DataKindEnum.MAYA_COMMAND,
                error=DataErrorEnum.UNRECOGNIZED_MAYA_COMMAND,
                response=NimbleResponseData.FAILED_RESPONSE)

        args = None
        kwargs = None
        try:
            kwargs = DictUtils.cleanDictKeys(payload['kwargs'], True)
            args = payload['args']

            try:
                result = cmd(*args, **kwargs)
            except Exception:
                # Attempts to remove an empty key if one is somehow created
                if '' in kwargs:
                    del kwargs['']
                else:
                    raise
                result = cmd(*args, **kwargs)

            if createReply:
                return cls.createReply(DataKindEnum.MAYA_COMMAND, result)
            else:
                return result
        except Exception as err:
            print('ERROR:', cmd, args, kwargs)
            message = '\n'.join([
                'Failed to execute maya command with payload:',
                'CMD {}'.format(cmd),
                'PAYLOAD: {}'.format(DictUtils.prettyPrint(payload)),
                'ARGS: {}'.format(args),
                'KWARGS: {}'.format(DictUtils.prettyPrint(kwargs))
            ])

            return NimbleResponseData(
                kind=DataKindEnum.MAYA_COMMAND,
                error=cls._getDetailedError(message, err),
                response=NimbleResponseData.FAILED_RESPONSE)
Esempio n. 5
0
    def _routeMessage(self, data):
        if data.kind == DataKindEnum.ECHO:
            return NimbleResponseData(
                kind=DataKindEnum.ECHO,
                response=NimbleResponseData.SUCCESS_RESPONSE,
                payload={'echo': data.payload['echo']})
        elif data.kind == DataKindEnum.ADD_SYSTEM_PATH:
            path = data.payload['path']
            doAdd = path not in sys.path
            if doAdd:
                sys.path.append(path)
            return NimbleResponseData(
                kind=DataKindEnum.ADD_SYSTEM_PATH,
                response=NimbleResponseData.SUCCESS_RESPONSE,
                payload={'added': doAdd})
        else:
            result = self._routeMessageImpl(data)
            if result is not None:
                return result

        return NimbleResponseData(kind=DataKindEnum.GENERAL,
                                  error=DataErrorEnum.UNRECOGNIZED_REQUEST,
                                  response=NimbleResponseData.FAILED_RESPONSE)
Esempio n. 6
0
    def _runPythonFile(cls, payload):
        try:
            path = payload['path']
            if path.endswith('.py'):
                f = open(path, 'r')
            else:
                f = open(path, 'rb')
            script = f.read()
            f.close()
        except Exception as err:
            return NimbleResponseData(
                kind=DataKindEnum.PYTHON_SCRIPT_FILE,
                error=cls._getDetailedError('Failed to run python file', err),
                response=NimbleResponseData.FAILED_RESPONSE)

        if not script:
            return NimbleResponseData(
                kind=DataKindEnum.PYTHON_SCRIPT_FILE,
                error='Empty or missing script file at: ' +
                str(payload['path']),
                response=NimbleResponseData.FAILED_RESPONSE)

        return runPythonExec(script, payload['kwargs'])
Esempio n. 7
0
def runMelExec(script):
    try:
        nimble.cmds.undoInfo(openChunk=True)
    except Exception as err:
        return False

    try:
        import maya.mel as mm
        result = mm.eval(script)
    except Exception as err:
        from nimble.data.NimbleResponseData import NimbleResponseData
        from nimble.data.enum.DataKindEnum import DataKindEnum
        result = NimbleResponseData(
            kind=DataKindEnum.MEL_SCRIPT,
            response=NimbleResponseData.FAILED_RESPONSE,
            error=str(err))

    try:
        nimble.cmds.undoInfo(closeChunk=True)
    except Exception as err:
        return False

    return result
Esempio n. 8
0
    def runPythonImport(cls, payload):
        try:
            kwargs = payload.get('kwargs', {})
            targetModule = StringUtils.toStr2(payload.get('module'))
            targetMethod = StringUtils.toStr2(payload.get('method'))
            targetClass = StringUtils.toStr2(payload.get('class'))
            target = targetClass if targetClass is not None else targetMethod
            if target is None:
                parts = targetModule.rsplit('.', 1)
                targetModule = parts[0]
                target = parts[1]
        except Exception as err:
            NimbleEnvironment.logError([
                'ERROR: Failed to parse python import payload',
                'PAYLOAD: ' + DictUtils.prettyPrint(payload)
            ], err)
            return NimbleResponseData(
                kind=DataKindEnum.PYTHON_IMPORT,
                error=cls._getDetailedError(
                    '\n'.join([
                        'ERROR: Failed to parse python import payload',
                        'PAYLOAD: ' + DictUtils.prettyPrint(payload)
                    ]), err),
                response=NimbleResponseData.FAILED_RESPONSE)

        # Dynamically import the specified module and reload it to make sure any changes have
        # been updated
        try:
            module = __import__(StringUtils.toStr2(targetModule), globals(),
                                locals(),
                                [StringUtils.toStr2(target)] if target else [])
            reload(module)
            target = getattr(module, target)
        except Exception as err:
            NimbleEnvironment.logError([
                'ERROR: Failed to import python target',
                'MODULE: %s' % targetModule,
                'TARGET: %s' % target,
                'PAYLOAD: ' + DictUtils.prettyPrint(payload)
            ], err)
            return NimbleResponseData(
                kind=DataKindEnum.PYTHON_IMPORT,
                error=cls._getDetailedError('Failed to import python module',
                                            err),
                response=NimbleResponseData.FAILED_RESPONSE)

        try:
            result = dict()
            if targetClass is not None:
                tc = target()
                result = getattr(tc, targetMethod)(**kwargs) \
                    if targetMethod else \
                    tc(**kwargs)
            elif targetMethod is not None:
                result = target(**kwargs)
            else:
                # Find a NimbleScriptBase derived class definition and if it exists, run it to
                # populate the results
                for name, value in DictUtils.iter(
                        Reflection.getReflectionDict(target)):
                    if not inspect.isclass(value):
                        continue

                    if NimbleScriptBase in value.__bases__:
                        result = getattr(target, name)()(**kwargs)
                        found = True

            # If a result dictionary contains an error key format the response as a failure
            errorMessage = None
            try:
                errorMessage = ArgsUtils.extract(
                    NimbleEnvironment.REMOTE_RESULT_ERROR_KEY, None, result)
            except Exception as err:
                pass

            return cls.createReply(DataKindEnum.PYTHON_IMPORT,
                                   result,
                                   errorMessage=errorMessage)
        except Exception as err:
            msg = 'ERROR: Failed to execute remote script'
            NimbleEnvironment.logError([
                msg, 'PAYLOAD: ' + DictUtils.prettyPrint(payload),
                'TARGET: ' + str(target)
            ], err)
            return NimbleResponseData(
                kind=DataKindEnum.PYTHON_IMPORT,
                error=cls._getDetailedError(msg, err),
                response=NimbleResponseData.FAILED_RESPONSE)
Esempio n. 9
0
def runPythonExec(script, kwargs=None):
    from nimble.NimbleEnvironment import NimbleEnvironment
    from nimble.data.NimbleResponseData import NimbleResponseData
    from nimble.data.enum.DataKindEnum import DataKindEnum

    try:
        nimble.cmds.undoInfo(openChunk=True)
    except Exception as err:
        return False

    try:
        # Create a new, temporary module in which to run the script
        module = imp.new_module('runExecTempModule')

        # Initialize the script with script inputs
        setattr(module, NimbleEnvironment.REMOTE_KWARGS_KEY,
                kwargs if kwargs is not None else dict())
        setattr(module, NimbleEnvironment.REMOTE_RESULT_KEY, dict())

        # Executes the script in the new module
        exec_(script, module.__dict__)

        # Find a NimbleScriptBase derived class definition and if it exists, run it to populate the
        # results
        for name, value in Reflection.getReflectionDict(module).iteritems():
            if not inspect.isclass(value):
                continue

            if NimbleScriptBase in value.__bases__:
                getattr(module, name)().run()
                break

        # Retrieve the results object that contains all results set by the execution of the script
        result = getattr(module, NimbleEnvironment.REMOTE_RESULT_KEY)
    except Exception as err:
        logger = Logger('runPythonExec', printOut=True)
        logger.writeError('ERROR: Failed Remote Script Execution', err)
        result = NimbleResponseData(
            kind=DataKindEnum.PYTHON_SCRIPT,
            response=NimbleResponseData.FAILED_RESPONSE,
            error=str(err))

    # If a result dictionary contains an error key format the response as a failure
    try:
        errorMessage = ArgsUtils.extract(
            NimbleEnvironment.REMOTE_RESULT_ERROR_KEY, None, result)
        if errorMessage:
            return NimbleResponseData(
                kind=DataKindEnum.PYTHON_SCRIPT,
                response=NimbleResponseData.FAILED_RESPONSE,
                error=errorMessage,
                payload=result)
    except Exception as err:
        pass

    try:
        nimble.cmds.undoInfo(closeChunk=True)
    except Exception as err:
        return False

    return result