예제 #1
0
    def _runImpl(self):
        self._server = NimbleServer(router=self._router)
        self._SERVER_THREAD = self
        self._ACTIVATING    = False

        NimbleEnvironment.log(NimbleServerThread._ACTIVE_MESSAGE)
        asyncore.loop()
예제 #2
0
    def open(self):
        if self._active:
            nowTime = TimeUtils.getNowSeconds()
            if nowTime - self._activatedTime > NimbleEnvironment.CONNECTION_LIFETIME:
                self.close()
            else:
                return False

        self._activatedTime = TimeUtils.getNowSeconds()
        try:
            target = (NimbleEnvironment.getConnectionHost(),
                      NimbleEnvironment.getConnectionPort())
            self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

            # Sets socket option to prevent connection being refused by TCP reconnecting
            # to the same socket after a recent closure.
            self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self._socket.setblocking(1)
            self._socket.connect(target)
        except Exception as err:
            NimbleEnvironment.logError(
                '[ERROR | NIMBLE COMMUNICATION] Failed to open Nimble connection',
                err)
            return False

        if self not in NimbleConnection._CONNECTION_POOL:
            NimbleConnection._CONNECTION_POOL.append(self)

        self._active = True
        return True
예제 #3
0
def startServer(logLevel=0, router=None, inMaya=None):
    """ Starts the NimbleServer properly given the current environmental conditions. The server runs
        in a separate thread and remains active until the stopServer() method.

        @@@param logLevel:int
            The integer logLevel to use when starting the server. The allowed values are:
            [#list]
                [#item]0 (default): Only log critical actions.[/#item]
                [#item]1: Additionally log warnings as well as succinct activity.[/#item]
                [#item]2: Full verbose logging of all activity.[/#item]
            [/#list]

        @@@param router:NimbleRouter
            The router to use for the server. The default value of None will use the default
            router for the given environment. The router is responsible for handling the
            communication traffic received by the server and correctly responding as a result.

        @@@param inMaya:boolean
            Whether or not the server is being run in Maya. By default this is determined
            automatically by the Nimble environment settings. However, in some cases the
            determination can be incorrect if your external or Maya Python interpreters have been
            modified to fool the environment test. In such cases this may need to be explicitly
            set. """

    NimbleEnvironment.inMaya(override=inMaya)
    NimbleEnvironment.setServerLogLevel(logLevel)
    NimbleServerThread(router=router).start()
예제 #4
0
def startServer(logLevel =0, router =None, inMaya =None):
    """ Starts the NimbleServer properly given the current environmental conditions. The server runs
        in a separate thread and remains active until the stopServer() method.

        @@@param logLevel:int
            The integer logLevel to use when starting the server. The allowed values are:
            [#list]
                [#item]0 (default): Only log critical actions.[/#item]
                [#item]1: Additionally log warnings as well as succinct activity.[/#item]
                [#item]2: Full verbose logging of all activity.[/#item]
            [/#list]

        @@@param router:NimbleRouter
            The router to use for the server. The default value of None will use the default
            router for the given environment. The router is responsible for handling the
            communication traffic received by the server and correctly responding as a result.

        @@@param inMaya:boolean
            Whether or not the server is being run in Maya. By default this is determined
            automatically by the Nimble environment settings. However, in some cases the
            determination can be incorrect if your external or Maya Python interpreters have been
            modified to fool the environment test. In such cases this may need to be explicitly
            set. """

    NimbleEnvironment.inMaya(override=inMaya)
    NimbleEnvironment.setServerLogLevel(logLevel)
    NimbleServerThread(router=router).start()
예제 #5
0
    def open(self):
        if self._active:
            nowTime = TimeUtils.getNowSeconds()
            if nowTime - self._activatedTime > NimbleEnvironment.CONNECTION_LIFETIME:
                self.close()
            else:
                return False

        self._activatedTime = TimeUtils.getNowSeconds()
        try:
            target = (
                NimbleEnvironment.getConnectionHost(),
                NimbleEnvironment.getConnectionPort()
            )
            self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

            # Sets socket option to prevent connection being refused by TCP reconnecting
            # to the same socket after a recent closure.
            self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self._socket.setblocking(1)
            self._socket.connect(target)
        except Exception as err:
            NimbleEnvironment.logError(
                '[ERROR | NIMBLE COMMUNICATION] Failed to open Nimble connection', err)
            return False

        if self not in NimbleConnection._CONNECTION_POOL:
            NimbleConnection._CONNECTION_POOL.append(self)

        self._active = True
        return True
예제 #6
0
    def _runImpl(self):
        self._server = NimbleServer(router=self._router)
        self._SERVER_THREAD = self
        self._ACTIVATING    = False

        NimbleEnvironment.log(NimbleServerThread._ACTIVE_MESSAGE)
        asyncore.loop()
예제 #7
0
    def __call__(self, *args, **kwargs):
        """Doc..."""
        if self.response is None:
            self.response = RemoteScriptResponse()
        if self.kwargs is None:
            self.kwargs = kwargs

        try:
            self.run()
        except Exception as err:
            message = "Nimble remote script run failure"
            NimbleEnvironment.logError(message, err)
            logMessage = Logger.createErrorMessage(message, err)
            self.putErrorResult(Logger.logMessageToString(logMessage=logMessage, includePrefix=False))
        result = self.response.result
        return result if result else dict()
예제 #8
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)
예제 #9
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)
예제 #10
0
    def __init__(self, connection):
        self._connection = connection
        self._commands = None

        if NimbleEnvironment.inMaya():
            import maya.cmds as mc

            self._commands = mc
예제 #11
0
    def _send(self, nimbleData):
        """Doc..."""

        if NimbleEnvironment.inMaya():
            return MayaRouter.processRequest(nimbleData)

        result = self._sendRemote(nimbleData)
        time.sleep(0.0001)
        return result
예제 #12
0
    def __call__(self, *args, **kwargs):
        """Doc..."""
        if self.response is None:
            self.response = RemoteScriptResponse()
        if self.kwargs is None:
            self.kwargs = kwargs

        try:
            self.run()
        except Exception as err:
            message = u'Nimble remote script run failure'
            NimbleEnvironment.logError(message, err)
            logMessage = Logger.createErrorMessage(message, err)
            self.putErrorResult(
                Logger.logMessageToString(logMessage=logMessage,
                                          includePrefix=False))
        result = self.response.result
        return result if result else dict()
예제 #13
0
    def _send(self, nimbleData):
        """Doc..."""

        if NimbleEnvironment.inMaya():
            return MayaRouter.processRequest(nimbleData)

        result = self._sendRemote(nimbleData)
        time.sleep(0.0001)
        return result
예제 #14
0
    def __init__(self, router =None):
        asyncore.dispatcher.__init__(self)

        try:
            self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
            self.set_reuse_addr()
            self.bind(('localhost', NimbleEnvironment.getServerPort()))
            self.listen(5)
        except Exception, err:
            print 'FAILED: Nimble server connection'
            print err
            raise
예제 #15
0
    def __init__(self, **kwargs):
        """ Creates a new instance of NimbleConnection and opens the communication socket to the
            corresponding NimbleServer instance. NimbleEnvironment is used to determine whether the
            connection should be to a Maya or external application NimbleServer instance. """

        self._active = False
        self._socket = None

        if not NimbleEnvironment.inMaya():
            self.open()

        self._mayaCommandLink = None
예제 #16
0
    def __init__(self, router =None):
        asyncore.dispatcher.__init__(self)

        try:
            self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
            self.set_reuse_addr()
            self.bind(('localhost', NimbleEnvironment.getServerPort()))
            self.listen(5)
        except Exception as err:
            NimbleEnvironment.logError(
                '[ERROR | NIMBLE SERVER] Failed to establish server connection', err)
            raise

        if router is None:
            if NimbleEnvironment.inMaya():
                from nimble.connection.router.MayaRouter import MayaRouter
                self._router = MayaRouter
            else:
                self._router = NimbleRouter
        else:
            self._router = router
예제 #17
0
def getConnection(inMaya=None, forceCreate=False):
    """ Retrieves a communication connection object from the connection pool, which is used for
        sending commands to the remote nimble server.

        :param inMaya | boolean
            Whether or not the server is being run in Maya. By default this is determined
            automatically by the Nimble environment settings. However, in some cases the
            determination can be incorrect if your external or Maya Python interpreters have been
            modified to fool the environment test. In such cases this may need to be explicitly
            set.

        :param forceCreate | boolean
            If True a new connection will be created even if one already exists and is available.
            This should rarely be used but can be useful in multi-threaded situations where sharing
            a single connection could be harmful.

        :return NimbleConnection
            A NimbleConnection instance opened and ready for issuing commands to the remote server.
    """

    NimbleEnvironment.inMaya(override=inMaya)
    return NimbleConnection.getConnection(forceCreate=forceCreate)
예제 #18
0
def getConnection(inMaya =None, forceCreate =False):
    """ Retrieves a communication connection object from the connection pool, which is used for
        sending commands to the remote nimble server.

        :param inMaya | boolean
            Whether or not the server is being run in Maya. By default this is determined
            automatically by the Nimble environment settings. However, in some cases the
            determination can be incorrect if your external or Maya Python interpreters have been
            modified to fool the environment test. In such cases this may need to be explicitly
            set.

        :param forceCreate | boolean
            If True a new connection will be created even if one already exists and is available.
            This should rarely be used but can be useful in multi-threaded situations where sharing
            a single connection could be harmful.

        :return NimbleConnection
            A NimbleConnection instance opened and ready for issuing commands to the remote server.
    """

    NimbleEnvironment.inMaya(override=inMaya)
    return NimbleConnection.getConnection(forceCreate=forceCreate)
예제 #19
0
    def __init__(self, router=None):
        asyncore.dispatcher.__init__(self)

        try:
            self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
            self.set_reuse_addr()
            self.bind((NimbleEnvironment.getServerHost(),
                       NimbleEnvironment.getServerPort()))
            self.listen(5)
        except Exception as err:
            NimbleEnvironment.logError(
                '[ERROR | NIMBLE SERVER] Failed to establish server connection',
                err)
            raise

        if router is None:
            if NimbleEnvironment.inMaya():
                from nimble.connection.router.MayaRouter import MayaRouter
                self._router = MayaRouter
            else:
                self._router = NimbleRouter
        else:
            self._router = router
예제 #20
0
def changeServerLogLevel(logLevel=0):
    """ Changes the active servers logging level, or, if no server is active, changes the
        environment so that when a server is started it will run at the specified level. This is
        useful if, for example, you want to dynamically change the log level at a given point
        to debug.

        @@@param logLevel:int
            The integer logLevel to use when starting the server. The allowed values are:
            [#list]
                [#item]0 (default): Only log critical actions.[/#item]
                [#item]1: Additionally log warnings as well as succinct activity.[/#item]
                [#item]2: Full verbose logging of all activity.[/#item]
            [/#list] """

    return NimbleEnvironment.setServerLogLevel(logLevel)
예제 #21
0
def changeServerLogLevel(logLevel =0):
    """ Changes the active servers logging level, or, if no server is active, changes the
        environment so that when a server is started it will run at the specified level. This is
        useful if, for example, you want to dynamically change the log level at a given point
        to debug.

        @@@param logLevel:int
            The integer logLevel to use when starting the server. The allowed values are:
            [#list]
                [#item]0 (default): Only log critical actions.[/#item]
                [#item]1: Additionally log warnings as well as succinct activity.[/#item]
                [#item]2: Full verbose logging of all activity.[/#item]
            [/#list] """

    return NimbleEnvironment.setServerLogLevel(logLevel)
예제 #22
0
    def open(self):
        if self._active:
            return False

        try:
            target = ('localhost', NimbleEnvironment.getConnectionPort())
            self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

            # Sets socket option to prevent connection being refused by TCP reconnecting
            # to the same socket after a recent closure.
            self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self._socket.connect(target)
        except Exception, err:
            print 'Failed to open Nimble connection.'
            print err
            return False
예제 #23
0
    def runPythonImport(self,
                        modulePackage,
                        methodName=None,
                        className=None,
                        runInMaya=None,
                        **kwargs):
        """ Executes the specified import through Nimble in the specified run mode.

            modulePackage:  (String) An absolute (dot-syntax) formatted import to the module you
                            wish to be executed. This module will be imported by Maya and must be
                            on its sys.path.

            [methodName]:   (String) An optional function name to be executed within the module. If
                            a class name is specified this method will be called on an instance of
                            the specified class. If no class name is specified the method will be
                            called directly on the module.

            [className]:    (String) An optional class name of a class to import within the
                            specified module. The class will be imported from the module and
                            instantiated.

            [runInMaya]:    If True the import will be executed within Maya. If False the import
                            will be executed outside of Maya on the remote end of the Nimble
                            connection. The default value of None will use the current global
                            setting, which can be set by the nimble.enablePythonTestMode()
                            top-level function and defaults to runInMaya = True, i.e. test mode
                            is disabled.

            Returns a NimbleResponseData object with the results of the script execution. """

        payload = {
            'module': modulePackage,
            'method': methodName,
            'class': className,
            'kwargs': kwargs
        }

        if NimbleEnvironment.inMaya():
            return MayaRouter.runPythonImport(payload)

        if (not NimbleEnvironment.TEST_REMOTE_MODE
            ) if runInMaya is None else runInMaya:
            return self._send(
                NimbleData(kind=DataKindEnum.PYTHON_IMPORT, payload=payload))
        else:
            return MayaRouter.runPythonImport(payload)
예제 #24
0
 def echo(self, verbose =False, pretty =False):
     msg    = self._createMessage()
     header = 'RESPONSE' if hasattr(self, 'response') else 'REQUEST'
     if verbose:
         if pretty:
             s = '\n' + 100*'-' + '\n' + header + ':\n' + (len(header) + 1)*'-' + '\n'
             for n,v in msg.iteritems():
                 s += '   ' + str(n).upper() + ': ' + str(v) + '\n'
             NimbleEnvironment.log(s)
         else:
             NimbleEnvironment.log(header + ': ' + str(msg))
     else:
         NimbleEnvironment.log('<NIMBLE %s | %s>' % (header, self.kind))
예제 #25
0
    def handle_request(self):
        message = self._message
        if not message:
            return

        logLevel = NimbleEnvironment.getServerLogLevel()

        try:
            data = self._parseData(message, logLevel)
        except Exception, err:
            self._sendResponse(
                NimbleResponseData(
                    kind=DataKindEnum.GENERAL,
                    error=DataErrorEnum.PARSE_FAILURE,
                    response=NimbleResponseData.FAILED_RESPONSE,
                    payload={"error": str(err)},
                ),
                logLevel,
            )
            return
예제 #26
0
    def runPythonImport(self, modulePackage, methodName =None, className=None, runInMaya =None, **kwargs):
        """ Executes the specified import through Nimble in the specified run mode.

            modulePackage:  (String) An absolute (dot-syntax) formatted import to the module you
                            wish to be executed. This module will be imported by Maya and must be
                            on its sys.path.

            [methodName]:   (String) An optional function name to be executed within the module. If
                            a class name is specified this method will be called on an instance of
                            the specified class. If no class name is specified the method will be
                            called directly on the module.

            [className]:    (String) An optional class name of a class to import within the
                            specified module. The class will be imported from the module and
                            instantiated.

            [runInMaya]:    If True the import will be executed within Maya. If False the import
                            will be executed outside of Maya on the remote end of the Nimble
                            connection. The default value of None will use the current global
                            setting, which can be set by the nimble.enablePythonTestMode()
                            top-level function and defaults to runInMaya = True, i.e. test mode
                            is disabled.

            Returns a NimbleResponseData object with the results of the script execution. """

        payload = {
            'module':modulePackage,
            'method':methodName,
            'class':className,
            'kwargs':kwargs}

        if NimbleEnvironment.inMaya():
            return MayaRouter.runPythonImport(payload)

        if (not NimbleEnvironment.TEST_REMOTE_MODE) if runInMaya is None else runInMaya:
            return self._send(NimbleData(kind=DataKindEnum.PYTHON_IMPORT, payload=payload))
        else:
            return MayaRouter.runPythonImport(payload)
예제 #27
0
 def getNimbleConnection(cls, inMaya =None, forceCreate =None):
     NimbleEnvironment.inMaya(override=inMaya)
     try:
         return NimbleConnection.getConnection(forceCreate=forceCreate)
     except Exception:
         raise
예제 #28
0
    def run(self):
        """Doc..."""

        self.saveSelection()

        count = self.fetch('count', 1000)
        self._size = self.fetch('size', 0.1)
        self._padding = self.fetch('padding', 0.0)

        transforms = cmds.ls(selection=True, type='transform')
        if not transforms:
            self._cleanup()
            self.putErrorResult(u'ERROR: No transforms selected')
            return

        shapes = []
        totalVolume = 0.0
        shapeCount = 0
        for transform in transforms:
            shapeNames = cmds.listRelatives(transforms, shapes=True)
            if not shapeNames:
                continue

            for shape in shapeNames:
                try:
                    box = TransformUtils.getBoundingBox(shape)
                    cmds.select(shape, replace=True)
                    shapeVolume = nimble.executeMelCommand('computePolysetVolume')
                    totalVolume += shapeVolume
                    shapes.append(dict(
                        transform=transform,
                        name=shape,
                        box=box,
                        weight=float(shapeVolume)) )
                    shapeCount += 1
                except Exception as err:
                    self._cleanup()
                    NimbleEnvironment.logError(u'ERROR: Shape processing', err)

                    self.putErrorResult(
                        u'ERROR: Unable to process selection item %s -> %s' % (transform, shape) )
                    return

        if shapeCount == 0:
            self._cleanup()
            self.putErrorResult(u'ERROR: No polygon transforms found in selection')
            return

        try:
            for shape in shapes:
                if not self._createMeshPointNode(shape):
                    self._cleanup()
                    print(u'ERROR: Creation failure')
                    self.putErrorResult(u'ERROR: Unable to create point test node')

                shape['weight'] /= totalVolume
                shapeCount = int(round(float(count)*shape['weight']))
                for i in range(shapeCount):
                    self._create(shape)

                self._removeMeshPointNode()
        except Exception as err:
            self._cleanup()
            print(Logger.createErrorMessage(u'ERROR: Creation failure', err))
            self.putErrorResult(u'ERROR: Unable to create random box')
            return

        self._cleanup()
예제 #29
0
# test_externalServer.py
# (C)2012 http://www.ThreeAddOne.com
# Scott Ernst

from __future__ import print_function, absolute_import, unicode_literals, division

import time
import nimble

nimble.startServer()
nimble.echoServerStatus()

from nimble.NimbleEnvironment import NimbleEnvironment
print('IN MAYA:', NimbleEnvironment.inMaya())

time.sleep(5)

nimble.stopServer()

print('Test complete')

예제 #30
0
    def run(self):
        """Doc..."""

        self.saveSelection()

        count = self.fetch('count', 1000)
        self._size = self.fetch('size', 0.1)
        self._padding = self.fetch('padding', 0.0)

        transforms = cmds.ls(selection=True, type='transform')
        if not transforms:
            self._cleanup()
            self.putErrorResult(u'ERROR: No transforms selected')
            return

        shapes = []
        totalVolume = 0.0
        shapeCount = 0
        for transform in transforms:
            shapeNames = cmds.listRelatives(transforms, shapes=True)
            if not shapeNames:
                continue

            for shape in shapeNames:
                try:
                    box = TransformUtils.getBoundingBox(shape)
                    cmds.select(shape, replace=True)
                    shapeVolume = nimble.executeMelCommand('computePolysetVolume')
                    totalVolume += shapeVolume
                    shapes.append(dict(
                        transform=transform,
                        name=shape,
                        box=box,
                        weight=float(shapeVolume)) )
                    shapeCount += 1
                except Exception as err:
                    self._cleanup()
                    NimbleEnvironment.logError(u'ERROR: Shape processing', err)

                    self.putErrorResult(
                        u'ERROR: Unable to process selection item %s -> %s' % (transform, shape) )
                    return

        if shapeCount == 0:
            self._cleanup()
            self.putErrorResult(u'ERROR: No polygon transforms found in selection')
            return

        try:
            for shape in shapes:
                if not self._createMeshPointNode(shape):
                    self._cleanup()
                    print(u'ERROR: Creation failure')
                    self.putErrorResult(u'ERROR: Unable to create point test node')

                shape['weight'] /= totalVolume
                shapeCount = int(round(float(count)*shape['weight']))
                for i in range(shapeCount):
                    self._create(shape)

                self._removeMeshPointNode()
        except Exception as err:
            self._cleanup()
            print(Logger.createErrorMessage(u'ERROR: Creation failure', err))
            self.putErrorResult(u'ERROR: Unable to create random box')
            return

        self._cleanup()
예제 #31
0
def getIsRunningInMaya():
    return NimbleEnvironment.inMaya()
예제 #32
0
    def _sendRemote(self, nimbleData):
        responseFlags = 0
        message = u''
        retry = NimbleEnvironment.REMOTE_RETRY_COUNT

        while retry > 0:
            try:
                self.open()
            except Exception as err:
                failure = [
                    '[ERROR | NIMBLE COMMUNICATION] Unable to open connection',
                    err
                ]
                retry -= 1
                if retry == 0:
                    if not nimble.quietFailure:
                        NimbleEnvironment.logError(failure[0], failure[1])
                    return None
                continue

            try:
                serialData = nimbleData.serialize()
            except Exception as err:
                failure = [
                    '[ERROR | NIMBLE COMMUNICATION] Unable to serialize data for transmission',
                    err
                ]
                if not nimble.quietFailure:
                    NimbleEnvironment.logError(failure[0], failure[1])
                return None

            try:
                self._chunk.clear()
                self._chunk.writeUint32(NimbleEnvironment.CONNECTION_FLAGS)
                self._chunk.writeString(
                    serialData + NimbleEnvironment.TERMINATION_IDENTIFIER)
                self._socket.sendall(self._chunk.byteArray)
            except Exception as err:
                failure = [
                    '[ERROR | NIMBLE COMMUNICATION] Unable to send data', err
                ]
                self.close()
                retry -= 1
                if retry == 0:
                    if not nimble.quietFailure:
                        NimbleEnvironment.logError(failure[0], failure[1])
                    return None
                continue

            try:
                self._chunk.clear()
                b = SocketUtils.receiveInChunks(
                    self._socket,
                    chunkSize=NimbleEnvironment.SOCKET_RESPONSE_CHUNK_SIZE)
                self._chunk.writeString(b)
                self._chunk.position = 0
                responseFlags = self._chunk.readUint32()
                message = StringUtils.strToUnicode(self._chunk.read(-1))

                # Break while loop on successful reading of the result
                if message is not None:
                    break

            except Exception as err:
                if not nimble.quietFailure:
                    NimbleEnvironment.logError(
                        '[ERROR | NIMBLE COMMUNICATION] Unable to read response',
                        err)
                self.close()
                return None

        try:
            if not (responseFlags & ConnectionFlags.KEEP_ALIVE):
                self.close()
        except Exception as err:
            if not nimble.quietFailure:
                NimbleEnvironment.logError(
                    '[ERROR | NIMBLE COMMUNICATION] Unable to close connection',
                    err)

        try:
            return NimbleData.fromMessage(message)
        except Exception as err:
            if not nimble.quietFailure:
                NimbleEnvironment.logError(
                    '[ERROR | NIMBLE COMMUNICATION] Response data parsing failure',
                    err)
            return None
예제 #33
0
파일: MayaRouter.py 프로젝트: sernst/Nimble
    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)
예제 #34
0
 def getNimbleConnection(cls, inMaya =None, forceCreate =None):
     NimbleEnvironment.inMaya(override=inMaya)
     try:
         return NimbleConnection.getConnection(forceCreate=forceCreate)
     except Exception:
         raise
예제 #35
0
def getIsRunningInMaya():
    return NimbleEnvironment.inMaya()
예제 #36
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)
예제 #37
0
    def _sendRemote(self, nimbleData):
        responseFlags = 0
        message       = u''
        retry         = NimbleEnvironment.REMOTE_RETRY_COUNT

        while retry > 0:
            try:
                self.open()
            except Exception as err:
                failure = [
                    '[ERROR | NIMBLE COMMUNICATION] Unable to open connection',
                    err ]
                retry -= 1
                if retry == 0:
                    if not nimble.quietFailure:
                        NimbleEnvironment.logError(failure[0], failure[1])
                    return None
                continue

            try:
                serialData = nimbleData.serialize()
            except Exception as err:
                failure = [
                    '[ERROR | NIMBLE COMMUNICATION] Unable to serialize data for transmission',
                    err ]
                if not nimble.quietFailure:
                    NimbleEnvironment.logError(failure[0], failure[1])
                return None

            try:
                self._chunk.clear()
                self._chunk.writeUint32(NimbleEnvironment.CONNECTION_FLAGS)
                self._chunk.writeString(serialData + NimbleEnvironment.TERMINATION_IDENTIFIER)
                self._socket.sendall(self._chunk.byteArray)
            except Exception as err:
                failure = [
                    '[ERROR | NIMBLE COMMUNICATION] Unable to send data',
                    err ]
                self.close()
                retry -= 1
                if retry == 0:
                    if not nimble.quietFailure:
                        NimbleEnvironment.logError(failure[0], failure[1])
                    return None
                continue

            try:
                self._chunk.clear()
                b = SocketUtils.receiveInChunks(
                    self._socket,
                    chunkSize=NimbleEnvironment.SOCKET_RESPONSE_CHUNK_SIZE)
                self._chunk.writeString(b)
                self._chunk.position = 0
                responseFlags  = self._chunk.readUint32()
                message        = StringUtils.strToUnicode(self._chunk.read(-1))

                # Break while loop on successful reading of the result
                if message is not None:
                    break

            except Exception as err:
                if not nimble.quietFailure:
                    NimbleEnvironment.logError(
                        '[ERROR | NIMBLE COMMUNICATION] Unable to read response', err)
                self.close()
                return None

        try:
            if not (responseFlags & ConnectionFlags.KEEP_ALIVE):
                self.close()
        except Exception as err:
            if not nimble.quietFailure:
                NimbleEnvironment.logError(
                    '[ERROR | NIMBLE COMMUNICATION] Unable to close connection', err)

        try:
            return NimbleData.fromMessage(message)
        except Exception as err:
            if not nimble.quietFailure:
                NimbleEnvironment.logError(
                    '[ERROR | NIMBLE COMMUNICATION] Response data parsing failure', err)
            return None