Merge from asset_upload 2550:2592

This commit is contained in:
kotler.linden
2009-08-10 18:46:31 +00:00
committed by Salad Dais
parent 953f4ef900
commit b3db3a8f47
10 changed files with 617 additions and 121 deletions

View File

@@ -14,7 +14,7 @@ from pyogp.lib.base.message.message import Message, Block
from pyogp.lib.base.utilities.helpers import Helpers
from pyogp.lib.base.exc import NotImplemented
from pyogp.lib.base.objects import Object
from pyogp.lib.base.params import VisualParams
from pyogp.lib.base.visualparams import VisualParams
from pyogp.lib.base.datatypes import UUID, Vector3
from pyogp.lib.base.utilities.enums import BakedIndex, TextureIndex, \
WearableMap, AssetType, WearablesIndex

View File

@@ -14,9 +14,10 @@ from pyogp.lib.base.utilities.enums import TransferChannelType, TransferSourceTy
from pyogp.lib.base.message.message_handler import MessageHandler
from pyogp.lib.base.message.message import Message, Block
from pyogp.lib.base.utilities.helpers import Helpers
from pyogp.lib.base.exc import NotImplemented
from pyogp.lib.base.exc import NotImplemented, ResourceError, ResourceNotFound
from pyogp.lib.base.objects import Object
from pyogp.lib.base.datatypes import Vector3, UUID
from pyogp.lib.base.caps import Capability
# initialize logging
@@ -35,12 +36,12 @@ class AssetManager(DataManager):
super(AssetManager, self).__init__(agent, settings)
#indexed by assetID
self.assets = {}
def enable_callbacks(self):
pass
def request_asset(self, assetID, assetType, isPriority, callback):
def request_asset(self, assetID, assetType, isPriority, callback=None, itemID=None):
"""
Sends a TransferRequest to the sim for asset assetID with type assetType,
will call back with the assetID and True with asset received or False
@@ -55,26 +56,31 @@ class AssetManager(DataManager):
def onTransferPacket(packet):
"""
TransferPacket of a successful TransferRequest
TODO wait for all all packets to arrive and assemble the data
"""
# fill in data for Asset in the requests queue and pop it off and story in assets dict
if str(transferID) == str(packet.blocks['TransferData'][0].get_variable('TransferID').data):
self.assets[str(assetID)] = AssetWearable(assetID, assetType,
packet.blocks['TransferData'][0].get_variable('Data').data)
callback(assetID, True)
if callback != None:
callback(assetID, True)
transferPacketHandler.unsubscribe(onTransferPacket)
def onTransferInfo(packet):
"""
Status of TransferRequest
Account for size and multiple packets
TODO set packet count
"""
if str(transferID) == str(packet.blocks['TransferInfo'][0].get_variable('TransferID')):
status = packet.blocks['TransferInfo'][0].get_variable("Status").data
if status != TransferStatus.OK:
log(WARNING, "Request for asset %s failed with status %s" \
% (assetID, status))
callback(assetID, False)
if callback != None:
callback(assetID, False)
transferPacketHandler.unsubscribe(onTransferPacket)
transferInfoHandler.unsubscribe(onTransferInfo)
@@ -85,8 +91,17 @@ class AssetManager(DataManager):
priority = 1.0
else:
priortity = 0.0
params = assetID.get_bytes() \
+ Helpers().int_to_bytes(assetType)
params = ''
if itemID != None:
params += self.agent.agent_id.get_bytes() + \
self.agent.session_id.get_bytes() + \
self.agent.agent_id.get_bytes() + \
UUID().get_bytes() + \
itemID.get_bytes()
params += assetID.get_bytes() + \
Helpers().int_to_bytes(assetType)
self.send_TransferRequest(transferID,
TransferChannelType.Asset,
@@ -94,11 +109,71 @@ class AssetManager(DataManager):
priority,
params)
"""
def upload_asset(self, transaction_id, type_, tempfile, store_local,
asset_data=None):
assetUploadCompleteHandler = self.agent.region.message_handler.register('AssetUploadComplete')
def onAssetUploadComplete(packet):
log(INFO, "AssetUploadComplete: %s" % packet)
assetUploadCompleteHandler.subscribe(onAssetUploadComplete)
self.send_AssetUploadRequest(transaction_id, type_, tempfile,
store_local)
"""
def upload_script_via_caps(self, item_id, script):
def upload_script_via_caps_responder(response):
if response['state'] == 'upload':
cap = Capability('UpdateScriptAgentResponse', response['uploader'])
response = cap.POST_FILE(script)
upload_script_via_caps_responder(response)
elif response['state'] == 'complete':
log(DEBUG, "Upload of script Successful")
else:
log(WARNING, "Upload failed")
cap = self.agent.region.capabilities['UpdateScriptAgent']
post_body = {'item_id' : str(item_id), 'target': 'lsl2'}
custom_headers = {'Accept' : 'application/llsd+xml'}
try:
response = cap.POST(post_body, custom_headers)
except ResourceError, error:
log(ERROR, error)
return
except ResourceNotFound, error:
log(ERROR, "404 calling: %s" % (error))
return
upload_script_via_caps_responder(response)
def upload_via_udp(self):
pass
def get_asset(self, assetID):
return self.assets[str(assetID)]
def send_AssetUploadRequest(self, TransactionID, Type, Tempfile, \
StoreLocal, AssetData=None):
"""
Sends an AssetUploadRequest packet to request that an asset be
uploaded to the to the sim
"""
packet = Message('AssetUploadRequest',
Block('AssetBlock',
TransactionID = TransactionID,
Type = Type,
Tempfile = Tempfile,
StoreLocal = StoreLocal,
AssetData = AssetData))
self.agent.region.enqueue_message(packet)
def send_TransferRequest(self, TransferID, ChannelType, SourceType,
Priority, Params):
@@ -118,8 +193,6 @@ class AssetManager(DataManager):
self.agent.region.enqueue_message(packet)
class Asset(object):
def __init__(self, assetID, assetType, data):
self.assetID = assetID

View File

@@ -2,7 +2,7 @@
import urllib2
from types import *
from logging import getLogger, CRITICAL, ERROR, WARNING, INFO, DEBUG
import re
# related
# pyogp
@@ -107,15 +107,42 @@ class Capability(object):
else:
raise ResourceError(self.public_url, e.code, e.msg, e.fp.read(), method="POST")
return self._response_handler(response)
def POST_FILE(self, file_name, custom_headers={}):
""" Opens file at file_name and posts contents to this cap. """
headers = {"Content-type" : "application/octet-stream"}
fd = open(file_name)
payload = fd.read()
fd.close
try:
response = self.restclient.POST(self.public_url,
payload, headers=headers)
except HTTPError, e:
if e.code==404:
raise ResourceNotFound(self.public_url)
else:
raise ResourceError(self.public_url, e.code, e.msg,
e.fp.read(), method="POST")
return self._response_handler(response)
def _response_handler(self, response):
# now deserialize the data again, we ask for a utility with the content type
# as the name
content_type_charset = response.headers['Content-Type']
content_type = content_type_charset.split(";")[0] # remove the charset part
pattern = re.compile('<\?xml\sversion="1.0"\s\?><llsd>.*?</llsd>')
# ToDo: write a generic serializer/deserializer
if (content_type == 'application/llsd+xml') or (content_type == 'application/xml'):
if (content_type == 'application/llsd+xml') or \
(content_type == 'application/xml') or \
(content_type == 'text/html' and \
pattern.match(response.body) != None):
deserializer = LLSDDeserializer()
else:
print response
raise DeserializerNotFound(content_type)
data = deserializer.deserialize(response.body)
@@ -125,6 +152,7 @@ class Capability(object):
return data
def __repr__(self):
return "<Capability '%s' for %s>" %(self.name, self.public_url)

View File

@@ -182,16 +182,17 @@ class InventoryManager(DataManager):
container[index[0]].inventory[inventory_index[0]] = inventory_item
if self.settings.LOG_VERBOSE:
log(DEBUG, 'Replacing a stored inventory item: %s for agent \'%s\'' % (inventory_item.ItemID, self.agent.agent_id))
log(DEBUG, 'Replacing a stored inventory item: %s' % (inventory_item.ItemID))
except:
container[index[0]].inventory.append(inventory_item)
if self.settings.LOG_VERBOSE:
log(DEBUG, 'Storing a new inventory item: %s in agent \'%s\'' % (inventory_item.ItemID, self.agent.agent_id))
log(DEBUG, 'Storing a new inventory item: %s ' % (inventory_item.ItemID))
def search_inventory(self, folder_list = [], item_id = None, name = None, match_list = []):
def search_inventory(self, folder_list = [], item_id = None, name = None,
match_list = []):
""" search through all inventory folders for an id(uuid) or Name, and
return a list of matching InventoryItems or InventoryFolders
@@ -200,60 +201,52 @@ class InventoryManager(DataManager):
This does not request inventory from the grid. It could, were we to go about enabling this...
"""
def match():
_match = lambda arg : False
if item_id != None:
def _match(arg):
if isinstance(arg, InventoryItem):
return str(arg.ItemID) == str(item_id)
else:
return str(arg.FolderID) == str(item_id)
elif name != None:
pattern = re.compile(name)
def _match(arg):
if pattern.match(arg.Name):
return True
else:
return False
return _match
is_match = match()
# search our inventory storage if we aren't told what to look in
if folder_list == []:
if folder_list == []:
search_folders = self.folders
else:
search_folders = folder_list
if item_id != None:
item_id = UUID(str(item_id))
for item in search_folders:
if isinstance(item, InventoryItem):
if str(item.ItemID) == str(item_id):
match_list.append(item)
elif isinstance(item, InventoryFolder):
matches = self.search_inventory_folder(item.FolderID, _id = item_id)
match_list.extend(matches)
return match_list
elif name != None:
for item in search_folders:
pattern = re.compile(name)
if isinstance(item, InventoryItem):
if pattern.match(item.Name):
match_list.append(item)
elif isinstance(item, InventoryFolder):
matches = self.search_inventory_folder(item.FolderID, name = name.strip())
match_list.extend(matches)
return match_list
else:
# return an empty list
return []
for item in search_folders:
if is_match(item):
match_list.append(item)
if isinstance(item, InventoryFolder):
matches = self.search_inventory_folder(item.FolderID,
_id=item_id,
name=name)
match_list.extend(matches)
return match_list
def search_inventory_folder(self, folder_id, _id = None, name = None):
""" search an inventory folder for _id or name
return a list of matches
"""
match_list = []
search_folder = [folder for folder in self.folders if str(folder.FolderID) == str(folder_id)][0]
for item in search_folder.inventory:
if _id != None:
@@ -261,9 +254,8 @@ class InventoryManager(DataManager):
if isinstance(item, InventoryItem):
if str(item.ItemID) == str(_id):
match_list.append(item)
elif isinstance(item, InventoryFolder):
if item.FolderID == _id:
if str(item.FolderID) == str(_id):
match_list.append(item)
elif name != None:
@@ -469,6 +461,81 @@ class InventoryManager(DataManager):
self.agent.send_ImprovedInstantMessage(self.agent.agent_id, self.agent.session_id, 0, FromAgentID, 0, UUID(), self.agent.Position, 0, accept_key, ID, 0, self.agent.Name(), '', '')
def create_new_item(self, folder, name, desc, asset_type, inv_type,
wearable_type, next_owner_permission, callback=None):
"""
Creates a new item in folder.
"""
transaction_id = UUID()
transaction_id.random()
updateCreateInventoryHandler = self.agent.region.message_handler.register('UpdateCreateInventoryItem')
def onUpdateCreateInventoryItem(packet):
if str(transaction_id) != \
str(packet.blocks['AgentData'][0]\
.get_variable('TransactionID').data):
inv_data = packet.blocks['InventoryData'][0]
item = InventoryItem(inv_data.get_variable('ItemID').data,
inv_data.get_variable('FolderID').data,
inv_data.get_variable('CreatorID').data,
inv_data.get_variable('OwnerID').data,
inv_data.get_variable('GroupID').data,
inv_data.get_variable('BaseMask').data,
inv_data.get_variable('OwnerMask').data,
inv_data.get_variable('GroupMask').data,
inv_data.get_variable('EveryoneMask').data,
inv_data.get_variable('NextOwnerMask').data,
inv_data.get_variable('GroupOwned').data,
inv_data.get_variable('AssetID').data,
inv_data.get_variable('Type').data,
inv_data.get_variable('InvType').data,
inv_data.get_variable('Flags').data,
inv_data.get_variable('SaleType').data,
inv_data.get_variable('SalePrice').data,
inv_data.get_variable('Name').data,
inv_data.get_variable('Description').data,
inv_data.get_variable('CreationDate').data,
inv_data.get_variable('CRC').data)
self._store_inventory_item(item)
updateCreateInventoryHandler.unsubscribe(onUpdateCreateInventoryItem)
if callback != None:
callback(item)
updateCreateInventoryHandler.subscribe(onUpdateCreateInventoryItem)
self.send_CreateInventoryItem(self.agent.agent_id,
self.agent.session_id,
0,
folder.FolderID,
transaction_id,
next_owner_permission,
asset_type,
inv_type,
wearable_type,
name,
desc)
def send_CreateInventoryItem(self, agent_id, session_id, callback_id,
folder_id, transaction_id, next_owner_mask,
type_, inv_type, wearable_type, name, desc):
""" sends a CreateInventoryItem message """
args = [Block('AgentData',
AgentID = agent_id,
SessionID = session_id)]
args += [Block('InventoryBlock',
CallbackID = callback_id,
FolderID = folder_id,
TransactionID = transaction_id,
NextOwnerMask = next_owner_mask,
Type = type_,
InvType = inv_type,
WearableType = wearable_type,
Name = name,
Description = desc)]
self.agent.region.enqueue_message(Message("CreateInventoryItem", *args))
def sendFetchInventoryDescendentsRequest(self, folder_id = None):
""" send a request to the grid for folder contents """
@@ -863,7 +930,29 @@ class InventoryItem(object):
Tests: tests/test_inventory.py
"""
def __init__(self, ItemID = None, FolderID = None, CreatorID = None, OwnerID = None, GroupID = None, BaseMask = None, OwnerMask = None, GroupMask = None, EveryoneMask = None, NextOwnerMask = 0, GroupOwned = None, AssetID = None, Type = None, InvType = None, Flags = None, SaleType = None, SalePrice = None, Name = None, Description = None, CreationDate = None, CRC = None, LastOwnerID = UUID()):
def __init__(self,
ItemID = None,
FolderID = None,
CreatorID = None,
OwnerID = None,
GroupID = None,
BaseMask = None,
OwnerMask = None,
GroupMask = None,
EveryoneMask = None,
NextOwnerMask = 0,
GroupOwned = None,
AssetID = None,
Type = None,
InvType = None,
Flags = None,
SaleType = None,
SalePrice = None,
Name = None,
Description = None,
CreationDate = None,
CRC = None,
LastOwnerID = UUID()):
""" initialize the inventory item """
self.type = 'InventoryItem'
@@ -984,47 +1073,49 @@ def sendRezObject(agent, inventory_item, RayStart, RayEnd, FromTaskID = UUID(),
packet = Message('RezObject',
Block('AgentData',
AgentID = agent.agent_id,
SessionID = agent.session_id,
GroupID = agent.ActiveGroupID),
AgentID = agent.agent_id,
SessionID = agent.session_id,
GroupID = agent.ActiveGroupID),
Block('RezData',
FromTaskID = UUID(str(FromTaskID)),
BypassRaycast = BypassRaycast,
RayStart = RayStart,
RayEnd = RayEnd,
RayTargetID = UUID(str(RayTargetID)),
RayEndIsIntersection = RayEndIsIntersection,
RezSelected = RezSelected,
RemoveItem = RemoveItem,
ItemFlags = ItemFlags,
GroupMask = GroupMask,
EveryoneMask = EveryoneMask,
NextOwnerMask = NextOwnerMask),
FromTaskID = UUID(str(FromTaskID)),
BypassRaycast = BypassRaycast,
RayStart = RayStart,
RayEnd = RayEnd,
RayTargetID = UUID(str(RayTargetID)),
RayEndIsIntersection = RayEndIsIntersection,
RezSelected = RezSelected,
RemoveItem = RemoveItem,
ItemFlags = ItemFlags,
GroupMask = GroupMask,
EveryoneMask = EveryoneMask,
NextOwnerMask = NextOwnerMask),
Block('InventoryData',
ItemID = inventory_item.ItemID,
FolderID = inventory_item.FolderID,
CreatorID = inventory_item.CreatorID,
OwnerID = inventory_item.OwnerID,
GroupID = inventory_item.GroupID,
BaseMask = inventory_item.BaseMask,
OwnerMask = inventory_item.OwnerMask,
GroupMask = inventory_item.GroupMask,
EveryoneMask = inventory_item.EveryoneMask,
GroupOwned = inventory_item.GroupOwned,
TransactionID = UUID(),
Type = inventory_item.Type,
InvType = inventory_item.InvType,
Flags = inventory_item.Flags,
SaleType = inventory_item.SaleType,
SalePrice = inventory_item.SalePrice,
Name = inventory_item.Name,
Description = inventory_item.Description,
CreationDate = inventory_item.CreationDate,
CRC = inventory_item.CRC,
NextOwnerMask = inventory_item.NextOwnerMask))
ItemID = inventory_item.ItemID,
FolderID = inventory_item.FolderID,
CreatorID = inventory_item.CreatorID,
OwnerID = inventory_item.OwnerID,
GroupID = inventory_item.GroupID,
BaseMask = inventory_item.BaseMask,
OwnerMask = inventory_item.OwnerMask,
GroupMask = inventory_item.GroupMask,
EveryoneMask = inventory_item.EveryoneMask,
GroupOwned = inventory_item.GroupOwned,
TransactionID = UUID(),
Type = inventory_item.Type,
InvType = inventory_item.InvType,
Flags = inventory_item.Flags,
SaleType = inventory_item.SaleType,
SalePrice = inventory_item.SalePrice,
Name = inventory_item.Name,
Description = inventory_item.Description,
CreationDate = inventory_item.CreationDate,
CRC = inventory_item.CRC,
NextOwnerMask = inventory_item.NextOwnerMask))
agent.region.enqueue_message(packet)
"""
Contributors can be viewed at:
http://svn.secondlife.com/svn/linden/projects/2008/pyogp/CONTRIBUTORS.txt

View File

@@ -7,11 +7,13 @@ import math
# related
# pyogp
from pyogp.lib.base import *
from pyogp.lib.base.datamanager import DataManager
from pyogp.lib.base.permissions import PermissionsTarget, PermissionsMask
from pyogp.lib.base.datatypes import UUID, Vector3, Quaternion
from pyogp.lib.base.event_system import AppEvent
# pyogp message
from pyogp.lib.base.message.message_handler import MessageHandler
@@ -20,7 +22,8 @@ from pyogp.lib.base.message.message import Message, Block
# pyogp utilities
from pyogp.lib.base.utilities.helpers import Helpers
from pyogp.lib.base.utilities.enums import PCodeEnum, CompressedUpdateFlags
from pyogp.lib.base.utilities.enums import PCodeEnum, CompressedUpdateFlags, \
Permissions, AssetType
# initialize logging
logger = getLogger('pyogp.lib.base.objects')
@@ -329,6 +332,11 @@ class ObjectManager(DataManager):
else:
#if self.settings.LOG_VERBOSE and self.settings.ENABLE_OBJECT_LOGGING: log(DEBUG, "Updating an object's attributes. LocalID = %s" % (object_properties['LocalID']))
_object._update_properties(prim_properties)
if _object.UpdateFlags & 2 != 0 and self.agent != None:
self.agent.events_handler.handle(AppEvent("ObjectSelected",
payload = {'object':_object}))
def request_object_update(self, AgentID, SessionID, ID_CacheMissType_list = None):
""" requests object updates from the simulator
@@ -360,9 +368,28 @@ class ObjectManager(DataManager):
# not sure what RayTargetID is, send as uuid of zeros
RayTargetID = UUID()
self.object_add(self.agent.agent_id, self.agent.session_id, GroupID = GroupID, PCode = PCodeEnum.Primitive, Material = 3, AddFlags = 2, PathCurve = 16, ProfileCurve = 1, PathBegin = 0, PathEnd = 0, PathScaleX = 100, PathScaleY = 100, PathShearX = 0, PathShearY = 0, PathTwist = 0, PathTwistBegin = 0, PathRadiusOffset = 0, PathTaperX = 0, PathTaperY = 0, PathRevolutions = 0, PathSkew = 0, ProfileBegin = 0, ProfileEnd = 0, ProfileHollow = 0, BypassRaycast = 1, RayStart = location_to_rez, RayEnd = location_to_rez, RayTargetID = RayTargetID, RayEndIsIntersection = 0, Scale = (0.5, 0.5, 0.5), Rotation = (0, 0, 0, 1), State = 0)
self.object_add(self.agent.agent_id, self.agent.session_id,
GroupID = GroupID, PCode = PCodeEnum.Primitive,
Material = 3, AddFlags = 2, PathCurve = 16,
ProfileCurve = 1, PathBegin = 0, PathEnd = 0,
PathScaleX = 100, PathScaleY = 100, PathShearX = 0,
PathShearY = 0, PathTwist = 0, PathTwistBegin = 0,
PathRadiusOffset = 0, PathTaperX = 0, PathTaperY = 0,
PathRevolutions = 0, PathSkew = 0, ProfileBegin = 0,
ProfileEnd = 0, ProfileHollow = 0, BypassRaycast = 1,
RayStart = location_to_rez, RayEnd = location_to_rez,
RayTargetID = RayTargetID, RayEndIsIntersection = 0,
Scale = (0.5, 0.5, 0.5), Rotation = (0, 0, 0, 1),
State = 0)
def object_add(self, AgentID, SessionID, PCode, Material, AddFlags, PathCurve, ProfileCurve, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, PathTwist, PathTwistBegin, PathRadiusOffset, PathTaperX, PathTaperY, PathRevolutions, PathSkew, ProfileBegin, ProfileEnd, ProfileHollow, BypassRaycast, RayStart, RayEnd, RayTargetID, RayEndIsIntersection, Scale, Rotation, State, GroupID = UUID()):
def object_add(self, AgentID, SessionID, PCode, Material, AddFlags,
PathCurve, ProfileCurve, PathBegin, PathEnd, PathScaleX,
PathScaleY, PathShearX, PathShearY, PathTwist,
PathTwistBegin, PathRadiusOffset, PathTaperX,
PathTaperY, PathRevolutions, PathSkew, ProfileBegin,
ProfileEnd, ProfileHollow, BypassRaycast, RayStart,
RayEnd, RayTargetID, RayEndIsIntersection, Scale,
Rotation, State, GroupID = UUID()):
'''
ObjectAdd - create new object in the world
Simulator will assign ID and send message back to signal
@@ -580,7 +607,7 @@ class ObjectManager(DataManager):
X=Helpers.packed_u8_to_float(objdata, 13, -REGION_SIZE, REGION_SIZE),
Y=Helpers.packed_u8_to_float(objdata, 14, -REGION_SIZE, REGION_SIZE),
Z=Helpers.packed_u8_to_float(objdata, 15, -REGION_SIZE, REGION_SIZE))
object_list.append(object_properties)
self.update_multiple_objects_properties(object_list)
@@ -913,6 +940,61 @@ class ObjectManager(DataManager):
self.update_multiple_objects_properties(object_list)
def send_RezScript(self, agent, prim, item_id=UUID(),
Enabled=True,
GroupID=UUID(),
BaseMask=Permissions.All,
OwnerMask=Permissions.All,
GroupMask=Permissions.None_,
EveryoneMask=Permissions.None_,
NextOwnerMask=Permissions.Transfer&Permissions.Move,
GroupOwned=False,
Type=AssetType.LSLText,
InvType=AssetType.LSLText,
Flags=0,
SaleType=0,
SalePrice=0,
Name="New Script",
Description="Created by PyOGP",
CreationDate=0,
CRC=0):
""" sends a RezScript message to the sim, not providing a item_id will
rez the default script otherwise the script with ItemID item_id will be rezzed
to prim"""
packet = Message('RezScript',
Block('AgentData',
AgentID = agent.agent_id,
SessionID = agent.session_id,
GroupID = agent.ActiveGroupID),
Block('UpdateBlock',
ObjectLocalID = prim.LocalID,
Enabled = Enabled),
Block('InventoryBlock',
ItemID = item_id,
FolderID = prim.FullID,
CreatorID = agent.agent_id,
OwnerID = agent.agent_id,
GroupID = GroupID,
BaseMask = BaseMask,
OwnerMask = OwnerMask,
GroupMask = GroupMask,
EveryoneMask = EveryoneMask,
NextOwnerMask = NextOwnerMask,
GroupOwned = GroupOwned,
TransactionID = UUID(),
Type = Type,
InvType = InvType,
Flags = Flags,
SaleType = SaleType,
SalePrice = SalePrice,
Name = Name,
Description = Description,
CreationDate = CreationDate,
CRC = CRC))
agent.region.enqueue_message(packet)
class Object(object):
""" represents an Object
@@ -1214,7 +1296,7 @@ class Object(object):
"""
self.send_ObjectSelect(agent, agent.agent_id, agent.session_id, [self.LocalID])
self.send_ObjectDeselect(agent, agent.agent_id, agent.session_id, [self.LocalID])
def send_ObjectDeselect(self, agent, AgentID, SessionID, ObjectLocalIDs):
""" send an ObjectDeselect message to the agent's host simulator
@@ -1230,13 +1312,15 @@ class Object(object):
agent.region.enqueue_message(packet)
def _update_properties(self, properties):
""" takes a dictionary of attribute:value and makes it so """
for attribute in properties:
for attribute in properties.keys():
setattr(self, attribute, properties[attribute])
"""
Contributors can be viewed at:
http://svn.secondlife.com/svn/linden/projects/2008/pyogp/CONTRIBUTORS.txt

View File

@@ -22,8 +22,6 @@ class TestAppearance(unittest.TestCase):
self.settings = Settings()
self.agent = Agent()
self.appearance = AppearanceManager(self.agent, settings = self.settings)
self.agent.agent_id = UUID("01234567-89ab-cdef-0123-456789abcdef")
self.agent.session_id = UUID("fedcba98-7654-3210-fedc-ba9876543210")
self.agent.region = DummyRegion()

File diff suppressed because one or more lines are too long

View File

@@ -8,9 +8,12 @@ from binascii import unhexlify
from pyogp.lib.base.objects import *
from pyogp.lib.base.settings import Settings
from pyogp.lib.base.region import Region
from pyogp.lib.base.agent import Agent
from pyogp.lib.base.datatypes import UUID, Vector3
# pyogp messaging
from pyogp.lib.base.message.udpdeserializer import UDPMessageDeserializer
from pyogp.lib.base.message.message import Message, Block
# pyogp tests
import pyogp.lib.base.tests.config
@@ -29,6 +32,7 @@ class TestObjects(unittest.TestCase):
self.object_store = ObjectManager(region = self.region, settings = self.settings)
self.object_store.enable_callbacks()
self.data = []
def tearDown(self):
pass
@@ -67,7 +71,59 @@ class TestObjects(unittest.TestCase):
self.assertEquals(known_objects, [(str(uuid.UUID('e2ba7ac7-db28-24e3-484d-f418b045e62d')), 159536), (str(uuid.UUID('6cbafc4a-9758-9481-cd74-c7ccc89e7440')), 171059), (str(uuid.UUID('d2b300c3-71f1-6887-2750-6d48da05e2f5')), 171036), (str(uuid.UUID('dbb7d110-3f65-0859-d494-3dc40ffb2b61')), 171037), (str(uuid.UUID('1f389eb9-8639-28ff-c37b-a3e4f39a7fed')), 171038)])
def test_onObjectUpdate_selected(self):
self.object_store.agent = Agent()
fake_uuid = UUID()
fake_uuid.random()
packet = Message('ObjectUpdate',
Block('RegionData',
RegionHandle=0,
TimeDilation=0),
Block('ObjectData',
ID=1,
State=1,
FullID=fake_uuid,
CRC=0,
PCode=0,
Material=0,
ClickAction=0,
Scale=Vector3(X=0.0, Y=0.0, Z=0.0),
ObjectData='',
ParentID=fake_uuid,
UpdateFlags=0,
ProfileCurve=0,
PathBegin=0.0,
PathEnd=0.0,
PathScaleX=0.0,
PathScaleY=0.0,
PathShearX=0.0,
PathShearY=0.0,
PathTwist=-1,
PathTwistBegin=-1,
PathRadiusOffset=-1,
PathTaperX=-1,
PathTaperY=-1,
PathRevolutions=0,
PathSkew=-1,
ProfileBegin=0,
ProfileEnd=0,
ProfileHollow=0,
TextureEntry='',
TextureAnim='',
NameValue='Test',
Data='',
Text='',
TextColor=0x0,
MedialURL=''))
def callback(payload):
self.data.append("foo")
object_handler = self.object_store.agent.events_handler.register("ObjectSelected")
object_handler.subscribe(callback)
self.object_store.region.message_handler.handle(packet)
self.assertTrue(self.data.pop, "foo")
def test_suite():
from unittest import TestSuite, makeSuite
suite = TestSuite()

View File

@@ -439,7 +439,17 @@ class TransferStatus(object):
Error = -1
UnknownSource = -2
InsufficientPermissions = -3
class Permissions(object):
Transfer = 1 << 13
Modify = 1 << 14
Copy = 1 << 15
Move = 1 << 19
None_ = 0
All = 0x7FFFFFFF
Unrestricted = Transfer | Modify | Copy
"""
Contributors can be viewed at:
http://svn.secondlife.com/svn/linden/projects/2008/pyogp/CONTRIBUTORS.txt