Skip to content

Commit

Permalink
Merge latest nviz into Luma modifications
Browse files Browse the repository at this point in the history
  • Loading branch information
Nathan Rusch committed Apr 18, 2011
2 parents d695449 + 9b4543b commit 4fdbb9d
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 14 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
*.pyc
45 changes: 39 additions & 6 deletions nukeCommandClient.py
Expand Up @@ -23,6 +23,7 @@
# any flags or arguments). # any flags or arguments).
NUKE_EXEC = 'Nuke' NUKE_EXEC = 'Nuke'


MAX_SOCKET_BYTES = 16384


class NukeConnectionError(StandardError): class NukeConnectionError(StandardError):
pass pass
Expand All @@ -33,7 +34,7 @@ class NukeManagerError(NukeConnectionError):
class NukeServerError(NukeConnectionError): class NukeServerError(NukeConnectionError):
pass pass


class NukeConnection: class NukeConnection():
''' '''
If 'port' is specified, the client will attempt to connect If 'port' is specified, the client will attempt to connect
to a command server on that port, raising an exception to a command server on that port, raising an exception
Expand All @@ -58,7 +59,7 @@ def __init__(self, port=None, host="localhost", instance=0):
if not self.test_connection(): if not self.test_connection():
raise NukeConnectionError("Could not connect to Nuke command server on port %d" % self._port) raise NukeConnectionError("Could not connect to Nuke command server on port %d" % self._port)
self.is_active = True self.is_active = True

def find_connection_port(self, start_port, end_port): def find_connection_port(self, start_port, end_port):
for port in range(start_port, end_port + 1): for port in range(start_port, end_port + 1):
self._port = port self._port = port
Expand Down Expand Up @@ -90,8 +91,32 @@ def test_connection(self):
def get(self, item_type, item_id = -1, parameters = None): def get(self, item_type, item_id = -1, parameters = None):
try: try:
data = {'action': item_type, 'id': item_id, 'parameters': parameters} data = {'action': item_type, 'id': item_id, 'parameters': parameters}
returnData = self.send(pickle.dumps(self.encode(data))) encoded = pickle.dumps(self.encode(data))

if len(encoded) > MAX_SOCKET_BYTES:
encodedBits = []
while encoded:
encodedBits.append(encoded[:MAX_SOCKET_BYTES])
encoded = encoded[MAX_SOCKET_BYTES:]

for i in range(len(encodedBits)):
result = pickle.loads(self.send(pickle.dumps({'type': "NukeTransferPartialObject", 'part': i, 'part_count': len(encodedBits), 'data': encodedBits[i]})))
if i < (len(encodedBits) - 1):
if not (isinstance(result, dict) and 'type' in result and result['type'] == "NukeTransferPartialObjectRequest" and 'part' in result and result['part'] == i+1):
raise NukeConnectionError("Unexpected response to partial object")
else:
result = pickle.loads(self.send(encoded))

if isinstance(result, dict) and 'type' in result and result['type'] == "NukeTransferPartialObject":
data = result['data']
nextPart = 1
while nextPart < result['part_count']:
returnData = self.send(pickle.dumps({'type': "NukeTransferPartialObjectRequest", 'part': nextPart}))
result = pickle.loads(returnData) result = pickle.loads(returnData)
data += result['data']
nextPart += 1

result = pickle.loads(data)
except Exception, e: except Exception, e:
raise e raise e


Expand Down Expand Up @@ -184,14 +209,22 @@ def decode(self, data):
def __getattr__(self, attrname): def __getattr__(self, attrname):
return self.get_object_item(-1, attrname) return self.get_object_item(-1, attrname)


def __getitem__(self, itemname):
return self.__getattr__(itemname)

def __repr__(self):
return object.__repr__(self).replace("instance object", "NukeConnection instance")

def __str__(self):
return self.__repr__()


class NukeObject: class NukeObject():
def __init__(self, connection, id): def __init__(self, connection, id):
self.__dict__['_id'] = id self.__dict__['_id'] = id
self.__dict__['_connection'] = connection self.__dict__['_connection'] = connection


def __getattr__(self, attrname): def __getattr__(self, attrname):
if attrname[0] in self.__dict__: if attrname[0] == "_":
return self.__dict__[attrname] return self.__dict__[attrname]
else: else:
return self._connection.get_object_attribute(self._id, attrname) return self._connection.get_object_attribute(self._id, attrname)
Expand Down Expand Up @@ -352,4 +385,4 @@ def start_managed_nuke_server(manager_port=None):
if len(sys.argv) > 1: if len(sys.argv) > 1:
manager_port = int(sys.argv[1].strip()) manager_port = int(sys.argv[1].strip())


start_managed_nuke_server(manager_port) start_managed_nuke_server(manager_port)
50 changes: 42 additions & 8 deletions nukeCommandServer.py
Expand Up @@ -8,14 +8,16 @@
listTypes = [list, tuple, set, frozenset] listTypes = [list, tuple, set, frozenset]
dictTypes = [dict] dictTypes = [dict]


MAX_SOCKET_BYTES = 16384

class NukeConnectionError(StandardError): class NukeConnectionError(StandardError):
pass pass


def nuke_command_server(): def nuke_command_server():
t = threading.Thread(None, NukeInternal) t = threading.Thread(None, NukeInternal)
t.setDaemon(True) t.setDaemon(True)
t.start() t.start()

class NukeInternal: class NukeInternal:
def __init__(self, port=None): def __init__(self, port=None):
self._objects = {} self._objects = {}
Expand Down Expand Up @@ -48,7 +50,7 @@ def __init__(self, port=None):


s.listen(backlog) s.listen(backlog)
self.start_server(s) self.start_server(s)

def start_server(self, sock): def start_server(self, sock):
''' '''
Starts the main server loop Starts the main server loop
Expand Down Expand Up @@ -106,8 +108,7 @@ def encode(self, data):
def decode(self, data): def decode(self, data):
return self.decode_data(pickle.loads(data)) return self.decode_data(pickle.loads(data))


def get(self, data_string): def get(self, data):
data = self.decode(data_string)
obj = self.get_object(data['id']) obj = self.get_object(data['id'])
params = data['parameters'] params = data['parameters']
result = None result = None
Expand Down Expand Up @@ -140,13 +141,46 @@ def get(self, data_string):
except Exception, e: except Exception, e:
result = e result = e


encoded = self.encode(result) return result

def receive(self, data_string):
data = self.decode(data_string)


if isinstance(data, dict) and 'type' in data and data['type'] == "NukeTransferPartialObjectRequest":
if data['part'] in self.partialObjects:
encoded = self.partialObjects[data['part']]
del self.partialObjects[data['part']]
return encoded return encoded


def receive(self, data): if isinstance(data, dict) and 'type' in data and data['type'] == "NukeTransferPartialObject":
return self.get(data) if data['part'] == 0:
self.partialData = ""
self.partialData += data['data']


if data['part'] == (data['part_count'] - 1):
data = pickle.loads(self.partialData)
else:
nextPart = data['part'] + 1
return pickle.dumps({'type': "NukeTransferPartialObjectRequest", 'part': nextPart})

encoded = self.encode(self.get(data))

if len(encoded) > MAX_SOCKET_BYTES:
encodedBits = []
while encoded:
encodedBits.append(encoded[:MAX_SOCKET_BYTES])
encoded = encoded[MAX_SOCKET_BYTES:]

self.partialObjects = {}
for i in range(len(encodedBits)):
self.partialObjects[i] = pickle.dumps({'type': "NukeTransferPartialObject", 'part': i, 'part_count': len(encodedBits), 'data': encodedBits[i]})

encoded = self.partialObjects[0]
del self.partialObjects[0]

return encoded


def get_object(self, id): def get_object(self, id):
if id == -1: if id == -1:
return globals() return globals()
Expand Down Expand Up @@ -195,4 +229,4 @@ def manager_callback(self, status):
manager.send(self.encode((status, self.port))) manager.send(self.encode((status, self.port)))
manager.close() manager.close()
if not status: if not status:
raise NukeConnectionError("Cannot find port to bind to") raise NukeConnectionError("Cannot find port to bind to")

0 comments on commit 4fdbb9d

Please sign in to comment.