565 lines
18 KiB
Python
565 lines
18 KiB
Python
import bpy
|
|
|
|
from . import updater
|
|
|
|
|
|
class CheckForUpdateButton(bpy.types.Operator):
|
|
bl_idname = 'rsl_updater.check_for_update'
|
|
bl_label = 'Check now for Update'
|
|
bl_description = 'Checks if a new update is available for Rokoko Studio Live'
|
|
bl_options = {'INTERNAL'}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return not updater.is_checking_for_update
|
|
|
|
def execute(self, context):
|
|
updater.used_updater_panel = True
|
|
updater.check_for_update_background()
|
|
return {'FINISHED'}
|
|
|
|
|
|
class UpdateToLatestButton(bpy.types.Operator):
|
|
bl_idname = 'rsl_updater.update_latest'
|
|
bl_label = 'Update Now'
|
|
bl_description = 'Updates Rokoko Studio Live to the latest compatible version'
|
|
bl_options = {'INTERNAL'}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return updater.update_needed
|
|
|
|
def execute(self, context):
|
|
updater.confirm_update_to = 'latest'
|
|
updater.used_updater_panel = True
|
|
|
|
bpy.ops.rsl_updater.confirm_update_panel('INVOKE_DEFAULT')
|
|
return {'FINISHED'}
|
|
|
|
|
|
class UpdateToSelectedButton(bpy.types.Operator):
|
|
bl_idname = 'rsl_updater.update_selected'
|
|
bl_label = 'Update to Selected version'
|
|
bl_description = 'Updates Rokoko Studio Live to the selected version'
|
|
bl_options = {'INTERNAL'}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
if updater.is_checking_for_update or not updater.version_list:
|
|
return False
|
|
return True
|
|
|
|
def execute(self, context):
|
|
updater.confirm_update_to = context.scene.rsl_updater_version_list
|
|
updater.used_updater_panel = True
|
|
|
|
bpy.ops.rsl_updater.confirm_update_panel('INVOKE_DEFAULT')
|
|
return {'FINISHED'}
|
|
|
|
|
|
class UpdateToBetaButton(bpy.types.Operator):
|
|
bl_idname = 'rsl_updater.update_beta'
|
|
bl_label = 'Update to Beta version'
|
|
bl_description = 'Updates Rokoko Studio Live to the Beta version'
|
|
bl_options = {'INTERNAL'}
|
|
|
|
def execute(self, context):
|
|
updater.confirm_update_to = 'beta'
|
|
updater.used_updater_panel = True
|
|
|
|
bpy.ops.rsl_updater.confirm_update_panel('INVOKE_DEFAULT')
|
|
return {'FINISHED'}
|
|
|
|
|
|
class RemindMeLaterButton(bpy.types.Operator):
|
|
bl_idname = 'rsl_updater.remind_me_later'
|
|
bl_label = 'Remind me later'
|
|
bl_description = 'This hides the update notification til the next Blender restart'
|
|
bl_options = {'INTERNAL'}
|
|
|
|
def execute(self, context):
|
|
updater.remind_me_later = True
|
|
self.report({'INFO'}, 'You will be reminded later')
|
|
return {'FINISHED'}
|
|
|
|
|
|
class IgnoreThisVersionButton(bpy.types.Operator):
|
|
bl_idname = 'rsl_updater.ignore_this_version'
|
|
bl_label = 'Ignore this version'
|
|
bl_description = 'Ignores this version. You will be reminded again when the next version releases'
|
|
bl_options = {'INTERNAL'}
|
|
|
|
def execute(self, context):
|
|
updater.set_ignored_version()
|
|
self.report({'INFO'}, 'Version ' + updater.latest_version_str + ' will be ignored.')
|
|
return {'FINISHED'}
|
|
|
|
|
|
class ShowPatchnotesPanel(bpy.types.Operator):
|
|
bl_idname = 'rsl_updater.show_patchnotes'
|
|
bl_label = 'Patchnotes'
|
|
bl_description = 'Shows the patchnotes of the selected version'
|
|
bl_options = {'INTERNAL'}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
if updater.is_checking_for_update or not updater.version_list:
|
|
return False
|
|
return True
|
|
|
|
def execute(self, context):
|
|
return {'FINISHED'}
|
|
|
|
def invoke(self, context, event):
|
|
updater.used_updater_panel = True
|
|
dpi_value = updater.get_user_preferences().system.dpi
|
|
return context.window_manager.invoke_props_dialog(self, width=int(dpi_value * 8.3))
|
|
|
|
def check(self, context):
|
|
# Important for changing options
|
|
return True
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
col = layout.column(align=True)
|
|
|
|
row = col.row(align=True)
|
|
row.prop(context.scene, 'rsl_updater_version_list')
|
|
|
|
if context.scene.rsl_updater_version_list:
|
|
version = updater.get_version_by_string(context.scene.rsl_updater_version_list)
|
|
|
|
col.separator()
|
|
row = col.row(align=True)
|
|
row.label(text=version.name, icon='SOLO_ON')
|
|
|
|
col.separator()
|
|
for line in version.patch_notes.replace('**', '').split('\r\n'):
|
|
if line.startswith("["):
|
|
continue
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.75
|
|
row.label(text=line)
|
|
|
|
col.separator()
|
|
row = col.row(align=True)
|
|
row.label(text='Released: ' + version.release_date)
|
|
|
|
col.separator()
|
|
|
|
|
|
class ConfirmUpdatePanel(bpy.types.Operator):
|
|
bl_idname = 'rsl_updater.confirm_update_panel'
|
|
bl_label = 'Confirm Update'
|
|
bl_description = 'This shows you a panel in which you have to confirm your update choice'
|
|
bl_options = {'INTERNAL'}
|
|
|
|
show_patchnotes = False
|
|
|
|
def execute(self, context):
|
|
print('UPDATE TO ' + updater.confirm_update_to)
|
|
if updater.confirm_update_to == 'beta':
|
|
updater.update_now(beta=True)
|
|
elif updater.confirm_update_to == 'latest':
|
|
updater.update_now(latest=True)
|
|
else:
|
|
updater.update_now(version=updater.confirm_update_to)
|
|
return {'FINISHED'}
|
|
|
|
def invoke(self, context, event):
|
|
dpi_value = updater.get_user_preferences().system.dpi
|
|
return context.window_manager.invoke_props_dialog(self, width=int(dpi_value * 4.2))
|
|
|
|
def check(self, context):
|
|
# Important for changing options
|
|
return True
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
col = layout.column(align=True)
|
|
|
|
version_str = updater.confirm_update_to
|
|
if updater.confirm_update_to == 'latest':
|
|
version_str = updater.latest_version_str
|
|
elif updater.confirm_update_to == 'beta':
|
|
version_str = 'Beta'
|
|
|
|
col.separator()
|
|
row = col.row(align=True)
|
|
row.label(text='Version: ' + version_str)
|
|
|
|
if updater.confirm_update_to == 'beta':
|
|
col.separator()
|
|
col.separator()
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.75
|
|
row.label(text='Warning:')
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.75
|
|
row.label(text=' The beta version might be unstable, some features')
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.75
|
|
row.label(text=' might not work correctly, or it might only be')
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.75
|
|
row.label(text=' compatible with the latest Blender version.')
|
|
col.separator()
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.75
|
|
row.label(text=' Check the Rokoko Github repo for more details.')
|
|
|
|
else:
|
|
row.operator(ShowPatchnotesPanel.bl_idname, text='Show Patchnotes')
|
|
|
|
col.separator()
|
|
col.separator()
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.65
|
|
row.label(text='Update now:', icon='URL')
|
|
|
|
|
|
class UpdateCompletePanel(bpy.types.Operator):
|
|
bl_idname = 'rsl_updater.update_complete_panel'
|
|
bl_label = 'Installation Report'
|
|
bl_description = 'The update if now complete'
|
|
bl_options = {'INTERNAL'}
|
|
|
|
show_patchnotes = False
|
|
|
|
def execute(self, context):
|
|
return {'FINISHED'}
|
|
|
|
def invoke(self, context, event):
|
|
dpi_value = updater.get_user_preferences().system.dpi
|
|
return context.window_manager.invoke_props_dialog(self, width=int(dpi_value * 4.2))
|
|
|
|
def check(self, context):
|
|
# Important for changing options
|
|
return True
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
col = layout.column(align=True)
|
|
|
|
if updater.update_finished:
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.9
|
|
row.label(text='Rokoko Studio Live was successfully updated.', icon='FILE_TICK')
|
|
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.9
|
|
row.label(text='Restart Blender to complete the update.', icon='BLANK1')
|
|
else:
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.9
|
|
row.label(text='Update failed.', icon='CANCEL')
|
|
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.9
|
|
row.label(text='See Updater Panel for more info.', icon='BLANK1')
|
|
|
|
|
|
class UpdateNotificationPopup(bpy.types.Operator):
|
|
bl_idname = 'rsl_updater.update_notification_popup'
|
|
bl_label = 'Update available'
|
|
bl_description = 'This shows you that an update is available'
|
|
bl_options = {'INTERNAL'}
|
|
|
|
def execute(self, context):
|
|
action = context.scene.rsl_update_action
|
|
if action == 'UPDATE':
|
|
updater.update_now(latest=True)
|
|
elif action == 'IGNORE':
|
|
updater.set_ignored_version()
|
|
else:
|
|
# Remind later aka defer
|
|
updater.remind_me_later = True
|
|
updater.ui_refresh()
|
|
return {'FINISHED'}
|
|
|
|
def invoke(self, context, event):
|
|
dpi_value = updater.get_user_preferences().system.dpi
|
|
return context.window_manager.invoke_props_dialog(self, width=int(dpi_value * 4.7))
|
|
|
|
# def invoke(self, context, event):
|
|
# return context.window_manager.invoke_props_dialog(self)
|
|
|
|
def check(self, context):
|
|
# Important for changing options
|
|
return True
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
col = layout.column(align=True)
|
|
|
|
row = col.split(factor=0.55, align=True)
|
|
row.scale_y = 1.05
|
|
row.label(text='Rokoko Studio Live v' + updater.latest_version_str + ' available!', icon='SOLO_ON')
|
|
row.operator(ShowPatchnotesPanel.bl_idname, text='Show Patchnotes')
|
|
|
|
col.separator()
|
|
col.separator()
|
|
col.separator()
|
|
row = col.row(align=True)
|
|
row.prop(context.scene, 'rsl_update_action', expand=True)
|
|
|
|
|
|
def draw_update_notification_panel(layout):
|
|
if not updater.update_needed or updater.remind_me_later or updater.is_ignored_version:
|
|
return
|
|
|
|
col = layout.column(align=True)
|
|
|
|
if updater.update_finished:
|
|
col.separator()
|
|
row = col.row(align=True)
|
|
row.label(text='Restart Blender to complete update!', icon='ERROR')
|
|
col.separator()
|
|
return
|
|
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.75
|
|
row.label(text='Update v' + updater.latest_version_str + ' available!', icon='SOLO_ON')
|
|
|
|
col.separator()
|
|
row = col.row(align=True)
|
|
row.scale_y = 1.3
|
|
row.operator(UpdateToLatestButton.bl_idname, text='Update Now')
|
|
|
|
row = col.row(align=True)
|
|
row.scale_y = 1
|
|
row.operator(RemindMeLaterButton.bl_idname, text='Defer')
|
|
row.operator(IgnoreThisVersionButton.bl_idname, text='Ignore')
|
|
|
|
col.separator()
|
|
col.separator()
|
|
col.separator()
|
|
|
|
|
|
def draw_updater_panel(context, layout, user_preferences=False):
|
|
col = layout.column(align=True)
|
|
|
|
scale_big = 2
|
|
scale_small = 1.2
|
|
|
|
if user_preferences:
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.8
|
|
row.label(text='Rokoko Studio Live Updater:', icon='URL')
|
|
col.separator()
|
|
|
|
if updater.update_finished:
|
|
col.separator()
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.75
|
|
row.label(text='Restart Blender to', icon='ERROR')
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.75
|
|
row.label(text='complete the update!', icon='BLANK1')
|
|
col.separator()
|
|
return
|
|
|
|
# If the plugin didn't load correctly, don't show the current version
|
|
if "error" in updater.current_version_str:
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.85
|
|
row.label(text="Failed to load the plugin. Try updating to latest or beta version:", icon='ERROR')
|
|
col.separator()
|
|
|
|
if updater.show_error:
|
|
errors = updater.show_error.split('\n')
|
|
for i, error in enumerate(errors):
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.85
|
|
row.label(text=error, icon='ERROR' if i == 0 else 'BLANK1')
|
|
col.separator()
|
|
|
|
if updater.is_checking_for_update:
|
|
if not updater.used_updater_panel:
|
|
row = col.row(align=True)
|
|
row.scale_y = scale_big
|
|
row.operator(CheckForUpdateButton.bl_idname, text='Checking..')
|
|
else:
|
|
split = col.row(align=True)
|
|
row = split.row(align=True)
|
|
row.scale_y = scale_big
|
|
row.operator(CheckForUpdateButton.bl_idname, text='Checking..')
|
|
row = split.row(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.scale_y = scale_big
|
|
row.operator(CheckForUpdateButton.bl_idname, text="", icon='FILE_REFRESH')
|
|
|
|
elif updater.update_needed:
|
|
split = col.row(align=True)
|
|
row = split.row(align=True)
|
|
row.scale_y = scale_big
|
|
row.operator(UpdateToLatestButton.bl_idname, text='Update now to ' + updater.latest_version_str)
|
|
row = split.row(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.scale_y = scale_big
|
|
row.operator(CheckForUpdateButton.bl_idname, text="", icon='FILE_REFRESH')
|
|
|
|
elif not updater.used_updater_panel or not updater.version_list:
|
|
row = col.row(align=True)
|
|
row.scale_y = scale_big
|
|
row.operator(CheckForUpdateButton.bl_idname, text='Check now for Update')
|
|
|
|
else:
|
|
split = col.row(align=True)
|
|
row = split.row(align=True)
|
|
row.scale_y = scale_big
|
|
row.operator(UpdateToLatestButton.bl_idname, text='Up to Date!')
|
|
row = split.row(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.scale_y = scale_big
|
|
row.operator(CheckForUpdateButton.bl_idname, text="", icon='FILE_REFRESH')
|
|
|
|
col.separator()
|
|
col.separator()
|
|
split = col.row(align=True)
|
|
row = split.split(factor=0.3, align=True)
|
|
row.scale_y = scale_small
|
|
row.active = True if not updater.is_checking_for_update and updater.version_list else False
|
|
row.label(text='Version:')
|
|
row.prop(context.scene, 'rsl_updater_version_list', text='')
|
|
row = split.row(align=True)
|
|
row.scale_y = scale_small
|
|
row.operator(ShowPatchnotesPanel.bl_idname, text="", icon='WORDWRAP_ON')
|
|
|
|
row = col.row(align=True)
|
|
row.scale_y = scale_small
|
|
row.active = True if not updater.is_checking_for_update and updater.version_list else False
|
|
selected_version_compatible = updater.is_version_compatible(context.scene.rsl_updater_version_list)
|
|
row.operator(UpdateToSelectedButton.bl_idname, text='Install Selected Version' if selected_version_compatible else 'Force Install Selected Version')
|
|
|
|
row = col.row(align=True)
|
|
row.scale_y = scale_small
|
|
row.operator(UpdateToBetaButton.bl_idname, text='Install Beta Version')
|
|
|
|
# If version is default, don't show the current version
|
|
if "error" in updater.current_version_str:
|
|
return
|
|
|
|
col.separator()
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.65
|
|
row.label(text='Add-on version: ' + updater.current_version_str)
|
|
|
|
# Show compatibility info
|
|
blender_version = ".".join(str(x) for x in bpy.app.version)
|
|
row = col.row(align=True)
|
|
row.scale_y = 0.65
|
|
row.label(text='Blender version: ' + blender_version)
|
|
|
|
|
|
# demo bare-bones preferences
|
|
class DemoPreferences(bpy.types.AddonPreferences):
|
|
bl_idname = updater.package_name
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
draw_updater_panel(context, layout, user_preferences=True)
|
|
|
|
|
|
to_register = [
|
|
CheckForUpdateButton,
|
|
UpdateToLatestButton,
|
|
UpdateToSelectedButton,
|
|
UpdateToBetaButton,
|
|
RemindMeLaterButton,
|
|
IgnoreThisVersionButton,
|
|
ShowPatchnotesPanel,
|
|
ConfirmUpdatePanel,
|
|
UpdateCompletePanel,
|
|
UpdateNotificationPopup,
|
|
DemoPreferences,
|
|
]
|
|
|
|
|
|
registered = False
|
|
|
|
|
|
def register():
|
|
global registered
|
|
if registered:
|
|
return
|
|
|
|
# Set initial version
|
|
current_version = []
|
|
for i in (1, 0, 0):
|
|
current_version.append(str(i))
|
|
updater.current_version.append(i)
|
|
|
|
# Set current version string and add beta tag and increase version number
|
|
updater.current_version_str = '.'.join(current_version)
|
|
current_version[2] = str(int(current_version[2]) + 1)
|
|
updater.current_version_str = '.'.join(current_version) + ".error"
|
|
|
|
bpy.types.Scene.rsl_updater_version_list = bpy.props.EnumProperty(
|
|
name='Version',
|
|
description='Select the version you want to install\n',
|
|
items=updater.get_version_list
|
|
)
|
|
bpy.types.Scene.rsl_update_action = bpy.props.EnumProperty(
|
|
name="Choose action",
|
|
description="Action",
|
|
items=[
|
|
("UPDATE", "Update Now", "Updates now to the latest version"),
|
|
("IGNORE", "Ignore this version", "This ignores this version. You will be reminded again when the next version releases"),
|
|
("DEFER", "Remind me later", "Hides the update notification til the next Blender restart")
|
|
]
|
|
)
|
|
|
|
# Register all Updater classes
|
|
count = 0
|
|
for cls in to_register:
|
|
try:
|
|
bpy.utils.register_class(cls)
|
|
count += 1
|
|
except ValueError:
|
|
pass
|
|
# print('Registered', count, 'Rokoko Studio Live updater classes.')
|
|
if count < len(to_register):
|
|
print('Skipped', len(to_register) - count, 'Rokoko Studio Live updater classes.')
|
|
|
|
# Delete and rename files that didn't get deleted during the update process
|
|
updater.delete_and_rename_files_on_startup()
|
|
|
|
print("LOADED UPDATER!")
|
|
registered = True
|
|
|
|
|
|
def update_info(bl_info, beta_branch):
|
|
# If not beta branch, always disable fake updates and no version checks!
|
|
if not beta_branch:
|
|
updater.fake_update = False
|
|
updater.no_ver_check = False
|
|
|
|
# Set current version
|
|
current_version = []
|
|
updater.current_version = []
|
|
for i in bl_info['version']:
|
|
current_version.append(str(i))
|
|
updater.current_version.append(i)
|
|
|
|
# Set current version string (and add beta tag and increase version number if true)
|
|
updater.current_version_str = '.'.join(current_version)
|
|
if beta_branch:
|
|
current_version[2] = str(int(current_version[2]) + 1)
|
|
updater.current_version_str = '.'.join(current_version) + ".beta"
|
|
|
|
|
|
def unregister():
|
|
global registered
|
|
registered = False
|
|
|
|
# Unregister all Updater classes
|
|
for cls in reversed(to_register):
|
|
try:
|
|
bpy.utils.unregister_class(cls)
|
|
except RuntimeError as e:
|
|
print(f"Error unregistering {cls.__name__}: {e}")
|
|
|
|
if hasattr(bpy.types.Scene, 'rsl_updater_version_list'):
|
|
del bpy.types.Scene.rsl_updater_version_list
|