Poodletooth-iLand/panda/direct/directutil/DistributedLargeBlobSenderAI.py
2015-03-03 17:10:12 -05:00

69 lines
2.6 KiB
Python

"""DistributedLargeBlobSenderAI module: contains the DistributedLargeBlobSenderAI class"""
from direct.distributed import DistributedObjectAI
from direct.directnotify import DirectNotifyGlobal
import LargeBlobSenderConsts
class DistributedLargeBlobSenderAI(DistributedObjectAI.DistributedObjectAI):
"""DistributedLargeBlobSenderAI: for sending large chunks of data through
the DC system to a specific avatar"""
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedLargeBlobSenderAI')
def __init__(self, air, zoneId, targetAvId, data, useDisk=0):
DistributedObjectAI.DistributedObjectAI.__init__(self, air)
self.targetAvId = targetAvId
self.mode = 0
if useDisk:
self.mode |= LargeBlobSenderConsts.USE_DISK
self.generateWithRequired(zoneId)
# send the data
s = str(data)
if useDisk:
# write the data to a file and tell the client where to get it
import os
import random
origDir = os.getcwd()
bPath = LargeBlobSenderConsts.getLargeBlobPath()
try:
os.chdir(bPath)
except OSError:
DistributedLargeBlobSenderAI.notify.error(
'could not access %s' % bPath)
# find an unused temp filename
while 1:
num = random.randrange((1 << 30)-1)
filename = LargeBlobSenderConsts.FilePattern % num
try:
os.stat(filename)
except OSError:
break
# NOTE: there's a small chance of a race condition here, if
# the file is created by another AI just after the stat fails
f = file(filename, 'wb')
f.write(s)
f.close()
os.chdir(origDir)
self.sendUpdateToAvatarId(self.targetAvId,
'setFilename', [filename])
else:
chunkSize = LargeBlobSenderConsts.ChunkSize
while len(s):
self.sendUpdateToAvatarId(self.targetAvId,
'setChunk', [s[:chunkSize]])
s = s[chunkSize:]
# send final empty string
self.sendUpdateToAvatarId(self.targetAvId, 'setChunk', [''])
def getMode(self):
return self.mode
def getTargetAvId(self):
return self.targetAvId
def setAck(self):
DistributedLargeBlobSenderAI.notify.debug('setAck')
assert self.air.getAvatarIdFromSender() == self.targetAvId
self.requestDelete()