feat: configuration support

This commit is contained in:
Swann Martinez 2019-07-01 18:04:35 +02:00
parent 34dc4088b5
commit fa18061687
No known key found for this signature in database
GPG Key ID: 414CCAFD8DA720E1
8 changed files with 126 additions and 38 deletions

3
.gitignore vendored
View File

@ -4,4 +4,5 @@ __pycache__/
*$py.classs
*.blend1
.vscode
cache
cache
config

View File

@ -10,6 +10,7 @@ bl_info = {
import addon_utils
import logging
import random
import string
import sys
@ -24,6 +25,8 @@ DEPENDENCIES = {
"PyYAML"
}
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
# UTILITY FUNCTIONS
def client_list_callback(scene, context):
@ -59,31 +62,49 @@ def randomColor():
b = random.random()
return [r, v, b]
def save_session_config(self,context):
config = environment.load_config()
config["username"] = self.username
config["ip"] = self.ip
config["port"] = self.port
config["start_empty"] = self.start_empty
config["enable_presence"] = self.enable_presence
environment.save_config(config)
class SessionProps(bpy.types.PropertyGroup):
username: bpy.props.StringProperty(
name="Username",
default="user_{}".format(randomStringDigits())
default="user_{}".format(randomStringDigits()),
update=save_session_config
)
ip: bpy.props.StringProperty(
name="ip",
description='Distant host ip',
default="127.0.0.1")
default="127.0.0.1",
update=save_session_config
)
port: bpy.props.IntProperty(
name="port",
description='Distant host port',
default=5554)
default=5555,
update=save_session_config
)
add_property_depth: bpy.props.IntProperty(
name="add_property_depth",
default=1)
default=1
)
buffer: bpy.props.StringProperty(name="None")
is_admin: bpy.props.BoolProperty(name="is_admin", default=False)
load_data: bpy.props.BoolProperty(name="load_data", default=True)
init_scene: bpy.props.BoolProperty(name="load_data", default=True)
clear_scene: bpy.props.BoolProperty(name="clear_scene", default=False)
start_empty: bpy.props.BoolProperty(name="start_empty", default=False)
update_frequency: bpy.props.FloatProperty(
name="update_frequency", default=0.008)
name="update_frequency",
default=0.008
)
active_object: bpy.props.PointerProperty(
name="active_object", type=bpy.types.Object)
session_mode: bpy.props.EnumProperty(
@ -102,11 +123,26 @@ class SessionProps(bpy.types.PropertyGroup):
description="client enum",
items=client_list_callback
)
enable_draw: bpy.props.BoolProperty(
name="enable_draw",
enable_presence: bpy.props.BoolProperty(
name="enable_presence",
description='Enable overlay drawing module',
default=True)
default=True,
update=save_session_config
)
def load(self):
config = environment.load_config()
logger.info(config)
if config:
self.username = config["username"]
self.ip = config["ip"]
self.port = config["port"]
self.start_empty = config["start_empty"]
self.enable_presence = config["enable_presence"]
else:
logger.error("Fail to read config")
classes = {
SessionProps,
@ -114,7 +150,7 @@ classes = {
def register():
environment.setup(DEPENDENCIES)
environment.setup(DEPENDENCIES,bpy.app.binary_path_python)
from . import operators
from . import ui
@ -127,6 +163,8 @@ def register():
bpy.types.WindowManager.session = bpy.props.PointerProperty(
type=SessionProps)
bpy.context.window_manager.session.load()
operators.register()
ui.register()

View File

@ -12,7 +12,7 @@ from random import randint
import zmq
import json
from . import helpers, message
from . import environment, helpers, message
from .libs import dump_anything, umsgpack
CONNECT_TIMEOUT = 2
@ -23,7 +23,7 @@ DUMP_AGENTS_NUMBER = 1
lock = threading.Lock()
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG)
logging.basicConfig(level=environment)
instance = None
@ -202,6 +202,7 @@ class Client(object):
line = json.dumps(value.body)
fp.write(line)
class Server(object):
address = None # Server address
port = None # Server port

View File

@ -1,14 +1,32 @@
import sys
import subprocess
import os
import subprocess
import sys
from pathlib import Path
import bpy
import logging
import yaml
logger = logging.getLogger(__name__)
CONFIG_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config")
CONFIG = os.path.join(CONFIG_DIR, "app.yaml")
THIRD_PARTY = os.path.join(os.path.dirname(os.path.abspath(__file__)), "libs")
PYTHON_PATH = None
SUBPROCESS_DIR = None
def load_config():
logger.info("loading config")
with open(CONFIG, 'r') as config_file:
return yaml.safe_load(config_file)
return None
def save_config(config):
logger.info("saving config")
with open(CONFIG, 'w') as outfile:
yaml.dump(config, outfile, default_flow_style=False)
CONFIG_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)),"config")
APP_CONFIG = os.path.join(CONFIG_DIR,"config.yaml")
THIRD_PARTY = os.path.join(os.path.dirname(os.path.abspath(__file__)),"libs")
PYTHON_PATH = Path(bpy.app.binary_path_python)
SUBPROCESS_DIR = PYTHON_PATH.parent
def module_can_be_imported(name):
try:
@ -32,11 +50,17 @@ def install_pip():
def install_package(name):
target = get_package_install_directory()
subprocess.run([str(PYTHON_PATH), "-m", "pip", "install",
name, '--target', target], cwd=SUBPROCESS_DIR)
def setup(dependencies):
subprocess.run([str(PYTHON_PATH), "-m", "pip", "install",
name, '--target', target], cwd=SUBPROCESS_DIR)
def setup(dependencies, python_path):
global PYTHON_PATH, SUBPROCESS_DIR
PYTHON_PATH = Path(python_path)
SUBPROCESS_DIR = PYTHON_PATH.parent
if not module_can_be_imported("pip"):
install_pip()

View File

@ -130,7 +130,7 @@ def load_client(client=None, data=None):
net_settings = C.window_manager.session
if client and data:
if net_settings.enable_draw:
if net_settings.enable_presence:
draw.renderer.draw_client(data)
draw.renderer.draw_client_selected_objects(data)

View File

@ -88,7 +88,6 @@ def update_client_selected_object(context):
# TODO: cleanup
def init_datablocks():
for datatype in helpers.BPY_TYPES.keys():
for item in getattr(bpy.data, helpers.BPY_TYPES[datatype]):
@ -134,7 +133,7 @@ class SessionJoinOperator(bpy.types.Operator):
global execution_queue
net_settings = context.window_manager.session
# Scene setup
if net_settings.clear_scene:
if net_settings.start_empty:
clean_scene()
# Session setup
@ -157,7 +156,7 @@ class SessionJoinOperator(bpy.types.Operator):
register_ticks()
# Launch drawing module
if net_settings.enable_draw:
if net_settings.enable_presence:
draw.renderer.run()
return {"FINISHED"}
@ -394,7 +393,22 @@ class SessionDumpDatabase(bpy.types.Operator, ExportHelper):
return {"CANCELLED"}
pass
# TODO: Rename to match official blender convention
class SessionSaveConfig(bpy.types.Operator):
bl_idname = "session.save"
bl_label = "Save session configuration"
bl_description = "Save session configuration"
bl_options = {"REGISTER"}
@classmethod
def poll(cls, context):
return True
def execute(self, context):
context.window_manager.session.save()
classes = (
SessionJoinOperator,
SessionPropertyAddOperator,
@ -405,6 +419,7 @@ classes = (
SessionSnapUserOperator,
SessionPropertyRightOperator,
SessionDumpDatabase,
SessionSaveConfig,
)

View File

@ -1,5 +1,6 @@
import logging
import time
import environment
from operator import itemgetter
@ -14,7 +15,8 @@ SUPPORTED_TYPES = ['Client','Curve','Material','Texture', 'Light', 'Camera', 'Me
class ServerAgent():
def __init__(self, context=zmq.Context.instance(), id="admin"):
self.context = context
self.config = environment.load_config()
self.port = int(self.config['port'])
self.pub_sock = None
self.request_sock = None
self.collector_sock = None
@ -32,19 +34,19 @@ class ServerAgent():
# Update all clients
self.pub_sock = self.context.socket(zmq.PUB)
self.pub_sock.setsockopt(zmq.SNDHWM, 60)
self.pub_sock.bind("tcp://*:5555")
self.pub_sock.bind("tcp://*:"+str(self.port+1))
time.sleep(0.2)
# Update request
self.request_sock = self.context.socket(zmq.ROUTER)
self.request_sock.setsockopt(zmq.IDENTITY, b'SERVER')
self.request_sock.setsockopt(zmq.RCVHWM, 60)
self.request_sock.bind("tcp://*:5554")
self.request_sock.bind("tcp://*:"+str(self.port))
# Update collector
self.collector_sock = self.context.socket(zmq.PULL)
self.collector_sock.setsockopt(zmq.RCVHWM, 60)
self.collector_sock.bind("tcp://*:5556")
self.collector_sock.bind("tcp://*:"+str(self.port+2))
# poller for socket aggregation
self.poller = zmq.Poller()

15
ui.py
View File

@ -9,11 +9,15 @@ ICONS = {'Curve':'CURVE_DATA', 'Client':'SOLO_ON','Collection': 'FILE_FOLDER', '
class SESSION_PT_settings(bpy.types.Panel):
bl_idname = "MULTIUSER_SETTINGS_PT_panel"
bl_label = "Network"
bl_label = "Settings"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = "Multiuser"
def draw_header(self, context):
self.layout.label(text="", icon='TOOL_SETTINGS')
def draw(self, context):
layout = self.layout
@ -41,10 +45,10 @@ class SESSION_PT_settings(bpy.types.Panel):
row = box.row()
row.label(text="draw overlay:")
row.prop(net_settings, "enable_draw", text="")
row.prop(net_settings, "enable_presence", text="")
row = box.row()
row.label(text="clear blend:")
row.prop(net_settings, "clear_scene", text="")
row.prop(net_settings, "start_empty", text="")
row = box.row()
row = box.row()
@ -82,7 +86,7 @@ class SESSION_PT_settings(bpy.types.Panel):
# row = layout.row(align=True)
# row.operator("session.dump", icon='QUIT', text="Dump")
# row.operator("session.dump", icon='QUIT', text="Load")
# row = layout.row()
row = layout.row()
box = row.box()
row = box.row()
@ -158,6 +162,9 @@ class SESSION_PT_properties(bpy.types.Panel):
def poll(cls, context):
return client.instance and client.instance.state() == 3
def draw_header(self, context):
self.layout.label(text="", icon='OUTLINER_OB_GROUP_INSTANCE')
def draw(self, context):
layout = self.layout