feat(rcf): clean right managment, user cannot modify others user datablocks

This commit is contained in:
Swann Martinez
2019-04-22 14:24:19 +02:00
parent 33adb26507
commit 70ff0eef54
4 changed files with 88 additions and 46 deletions

View File

@ -85,6 +85,14 @@ class RCFClient(object):
self.pipe.send_multipart( self.pipe.send_multipart(
[b"SET", umsgpack.packb(key), (umsgpack.packb(value) if value else umsgpack.packb('None'))]) [b"SET", umsgpack.packb(key), (umsgpack.packb(value) if value else umsgpack.packb('None'))])
def add(self, key, value=None):
"""Set new value in distributed hash table
Sends [SET][key][value] to the agent
"""
self.pipe.send_multipart(
[b"ADD", umsgpack.packb(key), (umsgpack.packb(value) if value else umsgpack.packb('None'))])
def get(self, key): def get(self, key):
"""Lookup value in distributed hash table """Lookup value in distributed hash table
Sends [GET][key] to the agent and waits for a value response Sends [GET][key] to the agent and waits for a value response
@ -181,11 +189,28 @@ class RCFClientAgent(object):
elif command == b"SET": elif command == b"SET":
key = umsgpack.unpackb(msg[0]) key = umsgpack.unpackb(msg[0])
value = None value = umsgpack.unpackb(msg[1])
if key in self.property_map.keys():
if self.property_map[key].id == self.id:
if value == 'None':
value = helpers.dump(key)
if value:
rcfmsg = message.RCFMessage(
key=key, id=self.id,uuid=value['uuid'], mtype="", body=value)
rcfmsg.store(self.property_map)
rcfmsg.send(self.publisher)
else:
logger.error("Fail to dump ")
elif command == b"ADD":
key = umsgpack.unpackb(msg[0])
value = umsgpack.unpackb(msg[1]) value = umsgpack.unpackb(msg[1])
if value == 'None': if value == 'None':
# try to dump from bpy
value = helpers.dump(key) value = helpers.dump(key)
if value: if value:
@ -268,27 +293,34 @@ def rcf_client_agent(ctx, pipe, queue):
client_dict = helpers.init_client(key=client_key) client_dict = helpers.init_client(key=client_key)
client_store = message.RCFMessage( client_store = message.RCFMessage(
key=client_key, id=agent.id.decode(), body=client_dict) key=client_key, id=agent.id, body=client_dict)
logger.info(client_store) logger.info(client_store)
client_store.store(agent.property_map) client_store.store(agent.property_map, True)
client_store.send(agent.publisher)
logger.info("snapshot complete") logger.info("snapshot complete")
agent.state = State.ACTIVE agent.state = State.ACTIVE
else: else:
helpers.load(rcfmsg.key, rcfmsg.body) helpers.load(rcfmsg.key, rcfmsg.body)
rcfmsg.store(agent.property_map) rcfmsg.store(agent.property_map)
logger.info("snapshot from {} stored".format(rcfmsg.id))
elif agent.state == State.ACTIVE: elif agent.state == State.ACTIVE:
if rcfmsg.id != agent.id: if rcfmsg.id != agent.id:
# update_queue.put((rcfmsg.key,rcfmsg.body)) # update_queue.put((rcfmsg.key,rcfmsg.body))
with lock: with lock:
helpers.load(rcfmsg.key, rcfmsg.body) helpers.load(rcfmsg.key, rcfmsg.body)
rcfmsg.store(agent.property_map)
# elif rcfmsg.id == agent.property_map[rcfmsg.key].id:
# with lock:
# helpers.load(rcfmsg.key, rcfmsg.body)
# logger.info("load") # logger.info("load")
# agent.serial.send_multipart([b"LOAD", umsgpack.packb(rcfmsg.key), umsgpack.packb(rcfmsg.body)]) # agent.serial.send_multipart([b"LOAD", umsgpack.packb(rcfmsg.key), umsgpack.packb(rcfmsg.body)])
# reply = agent.serial.recv_multipart() # reply = agent.serial.recv_multipart()
# if reply == b"DONE": # if reply == b"DONE":
rcfmsg.store(agent.property_map) # rcfmsg.store(agent.property_map)
# action = "update" if rcfmsg.body else "delete" # action = "update" if rcfmsg.body else "delete"
# logging.info("{}: received from {}:{},{} {}".format(rcfmsg.key, # logging.info("{}: received from {}:{},{} {}".format(rcfmsg.key,
# server.address, rcfmsg.id, server.port, action)) # server.address, rcfmsg.id, server.port, action))

View File

@ -37,9 +37,13 @@ class RCFMessage(object):
def apply(self): def apply(self):
pass pass
def store(self, dikt): def store(self, dikt, override=False):
"""Store me in a dict if I have anything to store""" """Store me in a dict if I have anything to store"""
# this currently erasing old value # this currently erasing old value
if self in dikt:
if override:
dikt[self.key] = self
else:
if self.key is not None: if self.key is not None:
dikt[self.key] = self dikt[self.key] = self
# elif self.key in dikt: # elif self.key in dikt:

View File

@ -142,7 +142,7 @@ def init_datablocks():
item.uuid = str(uuid4()) item.uuid = str(uuid4())
key = "{}/{}".format(datatype, item.name) key = "{}/{}".format(datatype, item.name)
print(key) print(key)
client_instance.set(key) client_instance.add(key)
def default_tick(): def default_tick():
@ -259,7 +259,7 @@ class session_add_property(bpy.types.Operator):
def execute(self, context): def execute(self, context):
global client_instance global client_instance
client_instance.set(self.property_path) client_instance.add(self.property_path)
return {"FINISHED"} return {"FINISHED"}
@ -474,17 +474,21 @@ def depsgraph_update(scene):
update_selected_object(bpy.context) update_selected_object(bpy.context)
selected_objects = helpers.get_selected_objects(scene) selected_objects = helpers.get_selected_objects(scene)
if len(selected_objects) > 0:
for update in updates:
update_key = "{}/{}".format(update.id.bl_rna.name, update.id.name)
remote_update = client_instance.get(update_key)
if remote_update and remote_update[0][1]["uuid"] == update.id.uuid:
print("{} sending update".format(username))
client_instance.set( # if len(selected_objects) > 0:
"{}/{}".format(update.id.bl_rna.name, update.id.name)) # for update in updates:
else: # update_key = "{}/{}".format(update.id.bl_rna.name, update.id.name)
print("{} applying update".format(username)) # remote_update = client_instance.get(update_key)
# if remote_update and remote_update[0][1]["uuid"] == update.id.uuid:
# print("{} sending update".format(username))
# client_instance.set(
# "{}/{}".format(update.id.bl_rna.name, update.id.name))
# else:
# print("{} applying update".format(username))
# if is_dirty(updates): # if is_dirty(updates):
# for update in ordered(updates): # for update in ordered(updates):
# if update[2] == "Master Collection": # if update[2] == "Master Collection":
@ -492,21 +496,20 @@ def depsgraph_update(scene):
# elif update[1] in SUPPORTED_TYPES: # elif update[1] in SUPPORTED_TYPES:
# client_instance.set("{}/{}".format(update[1], update[2])) # client_instance.set("{}/{}".format(update[1], update[2]))
# if hasattr(bpy.context, 'selected_objects'): if hasattr(bpy.context, 'selected_objects'):
# selected_objects = helpers.get_selected_objects(scene) selected_objects = helpers.get_selected_objects(scene)
# if len(selected_objects) > 0: if len(selected_objects) > 0:
# for updated_data in updates: for updated_data in updates:
# if updated_data.id.name in selected_objects: if updated_data.id.name in selected_objects:
# if updated_data.is_updated_transform or updated_data.is_updated_geometry: if updated_data.is_updated_transform or updated_data.is_updated_geometry:
# client_instance.set( client_instance.set(
# "{}/{}".format(updated_data.id.bl_rna.name, updated_data.id.name)) "{}/{}".format(updated_data.id.bl_rna.name, updated_data.id.name))
def register(): def register():
from bpy.utils import register_class from bpy.utils import register_class
for cls in classes: for cls in classes:
register_class(cls) register_class(cls)
bpy.types.ID.is_dirty = bpy.props.BoolProperty(default=False)
bpy.types.ID.uuid = bpy.props.StringProperty(default="None") bpy.types.ID.uuid = bpy.props.StringProperty(default="None")
bpy.types.Scene.session_settings = bpy.props.PointerProperty( bpy.types.Scene.session_settings = bpy.props.PointerProperty(
type=session_settings) type=session_settings)
@ -538,7 +541,6 @@ def unregister():
unregister_class(cls) unregister_class(cls)
del bpy.types.Scene.session_settings del bpy.types.Scene.session_settings
del bpy.types.ID.is_dirty
if __name__ == "__main__": if __name__ == "__main__":

4
ui.py
View File

@ -155,7 +155,11 @@ class SessionPropertiesPanel(bpy.types.Panel):
icon="UV_SYNC_SELECT") icon="UV_SYNC_SELECT")
if operators.client_keys and len(operators.client_keys) > 0: if operators.client_keys and len(operators.client_keys) > 0:
for item in operators.client_keys: for item in operators.client_keys:
owner = 'toto'
try:
owner = item[1].decode() owner = item[1].decode()
except:
pass
item_box = area_msg.box() item_box = area_msg.box()
detail_item_box = item_box.row(align = True) detail_item_box = item_box.row(align = True)