Merge branch '71-blender-addon-updater-integration' into 'develop'

Resolve "Blender Addon Updater integration"

See merge request slumber/multi-user!26
This commit is contained in:
Swann Martinez 2020-03-12 12:28:47 +00:00
commit cd00813aed
6 changed files with 3276 additions and 90 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@ __pycache__/
cache cache
config config
*.code-workspace *.code-workspace
multi_user_updater/
# sphinx build folder # sphinx build folder
_build _build

17
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,17 @@
image: python:latest
build:
script:
- git submodule init
- git submodule update
- cd multi_user/libs/replication
- rm -rf tests .git .gitignore
artifacts:
name: multi_user
paths:
- multi_user
only:
- master
- develop

View File

@ -7,6 +7,7 @@ bl_info = {
"location": "3D View > Sidebar > Multi-User tab", "location": "3D View > Sidebar > Multi-User tab",
"warning": "Unstable addon, use it at your own risks", "warning": "Unstable addon, use it at your own risks",
"category": "Collaboration", "category": "Collaboration",
"doc_url": "https://multi-user.readthedocs.io/en/develop/index.html",
"wiki_url": "https://multi-user.readthedocs.io/en/develop/index.html", "wiki_url": "https://multi-user.readthedocs.io/en/develop/index.html",
"tracker_url": "https://gitlab.com/slumber/multi-user/issues", "tracker_url": "https://gitlab.com/slumber/multi-user/issues",
"support": "COMMUNITY" "support": "COMMUNITY"
@ -133,6 +134,7 @@ def register():
from . import operators from . import operators
from . import ui from . import ui
from . import preferences from . import preferences
from . import addon_updater_ops
for cls in classes: for cls in classes:
bpy.utils.register_class(cls) bpy.utils.register_class(cls)
@ -146,6 +148,7 @@ def register():
bpy.types.WindowManager.user_index = bpy.props.IntProperty() bpy.types.WindowManager.user_index = bpy.props.IntProperty()
preferences.register() preferences.register()
addon_updater_ops.register(bl_info)
presence.register() presence.register()
operators.register() operators.register()
ui.register() ui.register()
@ -155,8 +158,10 @@ def unregister():
from . import operators from . import operators
from . import ui from . import ui
from . import preferences from . import preferences
from . import addon_updater_ops
presence.unregister() presence.unregister()
addon_updater_ops.unregister()
ui.unregister() ui.unregister()
operators.unregister() operators.unregister()
preferences.unregister() preferences.unregister()

1671
multi_user/addon_updater.py Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,11 @@
import logging import logging
import bpy import bpy
from . import utils, bl_types, environment from . import utils, bl_types, environment, addon_updater_ops
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ReplicatedDatablock(bpy.types.PropertyGroup): class ReplicatedDatablock(bpy.types.PropertyGroup):
type_name: bpy.props.StringProperty() type_name: bpy.props.StringProperty()
bl_name: bpy.props.StringProperty() bl_name: bpy.props.StringProperty()
@ -14,8 +15,9 @@ class ReplicatedDatablock(bpy.types.PropertyGroup):
auto_push: bpy.props.BoolProperty(default=True) auto_push: bpy.props.BoolProperty(default=True)
icon: bpy.props.StringProperty() icon: bpy.props.StringProperty()
class SessionPrefs(bpy.types.AddonPreferences): class SessionPrefs(bpy.types.AddonPreferences):
bl_idname = __package__ bl_idname = __package__
ip: bpy.props.StringProperty( ip: bpy.props.StringProperty(
name="ip", name="ip",
@ -33,19 +35,19 @@ class SessionPrefs(bpy.types.AddonPreferences):
name="port", name="port",
description='Distant host port', description='Distant host port',
default=5555 default=5555
) )
supported_datablocks: bpy.props.CollectionProperty( supported_datablocks: bpy.props.CollectionProperty(
type=ReplicatedDatablock, type=ReplicatedDatablock,
) )
ipc_port: bpy.props.IntProperty( ipc_port: bpy.props.IntProperty(
name="ipc_port", name="ipc_port",
description='internal ttl port(only usefull for multiple local instances)', description='internal ttl port(only usefull for multiple local instances)',
default=5561 default=5561
) )
start_empty: bpy.props.BoolProperty( start_empty: bpy.props.BoolProperty(
name="start_empty", name="start_empty",
default=False default=False
) )
right_strategy: bpy.props.EnumProperty( right_strategy: bpy.props.EnumProperty(
name='right_strategy', name='right_strategy',
description='right strategy', description='right strategy',
@ -58,16 +60,15 @@ class SessionPrefs(bpy.types.AddonPreferences):
subtype="DIR_PATH", subtype="DIR_PATH",
default=environment.DEFAULT_CACHE_DIR) default=environment.DEFAULT_CACHE_DIR)
# for UI # for UI
# category: bpy.props.EnumProperty( category: bpy.props.EnumProperty(
# name="Category", name="Category",
# description="Preferences Category", description="Preferences Category",
# items=[ items=[
# ('INFO', "Information", "Information about this add-on"), ('CONFIG', "Configuration", "Configuration about this add-on"),
# ('CONFIG', "Configuration", "Configuration about this add-on"), ('UPDATE', "Update", "Update this add-on"),
# ('UPDATE', "Update", "Update this add-on"), ],
# ], default='CONFIG'
# default='INFO' )
# )
conf_session_identity_expanded: bpy.props.BoolProperty( conf_session_identity_expanded: bpy.props.BoolProperty(
name="Identity", name="Identity",
description="Identity", description="Identity",
@ -94,82 +95,115 @@ class SessionPrefs(bpy.types.AddonPreferences):
default=False default=False
) )
auto_check_update: bpy.props.BoolProperty(
name="Auto-check for Update",
description="If enabled, auto-check for updates using an interval",
default=False,
)
updater_intrval_months: bpy.props.IntProperty(
name='Months',
description="Number of months between checking for updates",
default=0,
min=0
)
updater_intrval_days: bpy.props.IntProperty(
name='Days',
description="Number of days between checking for updates",
default=7,
min=0,
max=31
)
updater_intrval_hours: bpy.props.IntProperty(
name='Hours',
description="Number of hours between checking for updates",
default=0,
min=0,
max=23
)
updater_intrval_minutes: bpy.props.IntProperty(
name='Minutes',
description="Number of minutes between checking for updates",
default=0,
min=0,
max=59
)
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
# layout.row().prop(self, "category", expand=True) layout.row().prop(self, "category", expand=True)
# if self.category == 'INFO':
# layout.separator()
# layout.label(text="Enable real-time collaborative workflow inside blender")
# if self.category == 'CONFIG':
grid = layout.column()
# USER INFORMATIONS if self.category == 'CONFIG':
box = grid.box() grid = layout.column()
box.prop(
self, "conf_session_identity_expanded", text="User informations",
icon='DISCLOSURE_TRI_DOWN' if self.conf_session_identity_expanded
else 'DISCLOSURE_TRI_RIGHT', emboss=False)
if self.conf_session_identity_expanded:
box.row().prop(self, "username", text="name")
box.row().prop(self, "client_color", text="color")
# NETWORK SETTINGS
box = grid.box()
box.prop(
self, "conf_session_net_expanded", text="Netorking",
icon='DISCLOSURE_TRI_DOWN' if self.conf_session_net_expanded
else 'DISCLOSURE_TRI_RIGHT', emboss=False)
if self.conf_session_net_expanded:
box.row().prop(self, "ip", text="Address")
row = box.row()
row.label(text="Port:")
row.prop(self, "port", text="Address")
row = box.row()
row.label(text="Start with an empty scene:")
row.prop(self, "start_empty", text="")
table = box.box()
table.row().prop(
self, "conf_session_timing_expanded", text="Refresh rates",
icon='DISCLOSURE_TRI_DOWN' if self.conf_session_timing_expanded
else 'DISCLOSURE_TRI_RIGHT', emboss=False)
if self.conf_session_timing_expanded: # USER INFORMATIONS
line = table.row() box = grid.box()
line.label(text=" ") box.prop(
line.separator() self, "conf_session_identity_expanded", text="User informations",
line.label(text="refresh (sec)") icon='DISCLOSURE_TRI_DOWN' if self.conf_session_identity_expanded
line.label(text="apply (sec)") else 'DISCLOSURE_TRI_RIGHT', emboss=False)
if self.conf_session_identity_expanded:
box.row().prop(self, "username", text="name")
box.row().prop(self, "client_color", text="color")
for item in self.supported_datablocks: # NETWORK SETTINGS
line = table.row(align=True) box = grid.box()
line.label(text="", icon=item.icon) box.prop(
line.prop(item, "bl_delay_refresh", text="") self, "conf_session_net_expanded", text="Netorking",
line.prop(item, "bl_delay_apply", text="") icon='DISCLOSURE_TRI_DOWN' if self.conf_session_net_expanded
# HOST SETTINGS else 'DISCLOSURE_TRI_RIGHT', emboss=False)
box = grid.box()
box.prop( if self.conf_session_net_expanded:
self, "conf_session_hosting_expanded", text="Hosting", box.row().prop(self, "ip", text="Address")
icon='DISCLOSURE_TRI_DOWN' if self.conf_session_hosting_expanded row = box.row()
else 'DISCLOSURE_TRI_RIGHT', emboss=False) row.label(text="Port:")
if self.conf_session_hosting_expanded: row.prop(self, "port", text="Address")
box.row().prop(self, "right_strategy", text="Right model") row = box.row()
row = box.row() row.label(text="Start with an empty scene:")
row.label(text="Start with an empty scene:") row.prop(self, "start_empty", text="")
row.prop(self, "start_empty", text="")
table = box.box()
# CACHE SETTINGS table.row().prop(
box = grid.box() self, "conf_session_timing_expanded", text="Refresh rates",
box.prop( icon='DISCLOSURE_TRI_DOWN' if self.conf_session_timing_expanded
self, "conf_session_cache_expanded", text="Cache", else 'DISCLOSURE_TRI_RIGHT', emboss=False)
icon='DISCLOSURE_TRI_DOWN' if self.conf_session_cache_expanded
else 'DISCLOSURE_TRI_RIGHT', emboss=False) if self.conf_session_timing_expanded:
if self.conf_session_cache_expanded: line = table.row()
box.row().prop(self, "cache_directory", text="Cache directory") line.label(text=" ")
line.separator()
line.label(text="refresh (sec)")
line.label(text="apply (sec)")
for item in self.supported_datablocks:
line = table.row(align=True)
line.label(text="", icon=item.icon)
line.prop(item, "bl_delay_refresh", text="")
line.prop(item, "bl_delay_apply", text="")
# HOST SETTINGS
box = grid.box()
box.prop(
self, "conf_session_hosting_expanded", text="Hosting",
icon='DISCLOSURE_TRI_DOWN' if self.conf_session_hosting_expanded
else 'DISCLOSURE_TRI_RIGHT', emboss=False)
if self.conf_session_hosting_expanded:
box.row().prop(self, "right_strategy", text="Right model")
row = box.row()
row.label(text="Start with an empty scene:")
row.prop(self, "start_empty", text="")
# CACHE SETTINGS
box = grid.box()
box.prop(
self, "conf_session_cache_expanded", text="Cache",
icon='DISCLOSURE_TRI_DOWN' if self.conf_session_cache_expanded
else 'DISCLOSURE_TRI_RIGHT', emboss=False)
if self.conf_session_cache_expanded:
box.row().prop(self, "cache_directory", text="Cache directory")
if self.category == 'UPDATE':
from . import addon_updater_ops
addon_updater_ops.update_settings_ui_condensed(self, context)
def generate_supported_types(self): def generate_supported_types(self):
self.supported_datablocks.clear() self.supported_datablocks.clear()
@ -181,19 +215,22 @@ class SessionPrefs(bpy.types.AddonPreferences):
type_impl_name = "Bl{}".format(type.split('_')[1].capitalize()) type_impl_name = "Bl{}".format(type.split('_')[1].capitalize())
type_module_class = getattr(type_module, type_impl_name) type_module_class = getattr(type_module, type_impl_name)
new_db.name = type_impl_name new_db.name = type_impl_name
new_db.type_name = type_impl_name new_db.type_name = type_impl_name
new_db.bl_delay_refresh = type_module_class.bl_delay_refresh new_db.bl_delay_refresh = type_module_class.bl_delay_refresh
new_db.bl_delay_apply =type_module_class.bl_delay_apply new_db.bl_delay_apply = type_module_class.bl_delay_apply
new_db.use_as_filter = True new_db.use_as_filter = True
new_db.icon = type_module_class.bl_icon new_db.icon = type_module_class.bl_icon
new_db.auto_push =type_module_class.bl_automatic_push new_db.auto_push = type_module_class.bl_automatic_push
new_db.bl_name=type_module_class.bl_id new_db.bl_name = type_module_class.bl_id
classes = ( classes = (
ReplicatedDatablock, ReplicatedDatablock,
SessionPrefs, SessionPrefs,
) )
def register(): def register():
from bpy.utils import register_class from bpy.utils import register_class
@ -205,8 +242,9 @@ def register():
logger.info('Generating bl_types preferences') logger.info('Generating bl_types preferences')
prefs.generate_supported_types() prefs.generate_supported_types()
def unregister(): def unregister():
from bpy.utils import unregister_class from bpy.utils import unregister_class
for cls in reversed(classes): for cls in reversed(classes):
unregister_class(cls) unregister_class(cls)