
Instead of storing the cached manager info in the Blender preferences, store the info in a JSON file. The file is located in the user prefs folder (`~/.config/blender/{version}/config` on Linux). This also reduces the number of 'refresh' operators to a single one, which then fetches all necessary info from the Manager. This fixes an issue (reported via chat) where worker tags were sometimes not retained across file saves.
169 lines
5.2 KiB
Python
169 lines
5.2 KiB
Python
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
# <pep8 compliant>
|
|
|
|
from pathlib import Path
|
|
|
|
import bpy
|
|
|
|
from . import projects, manager_info
|
|
|
|
|
|
def discard_flamenco_client(context):
|
|
"""Discard any cached Flamenco client after the Manager URL changes."""
|
|
from . import comms
|
|
|
|
comms.discard_flamenco_data()
|
|
context.window_manager.flamenco_status_ping = ""
|
|
|
|
|
|
def _refresh_the_planet(context: bpy.types.Context) -> None:
|
|
"""Refresh all GUI areas."""
|
|
for win in context.window_manager.windows:
|
|
for area in win.screen.areas:
|
|
for region in area.regions:
|
|
region.tag_redraw()
|
|
|
|
|
|
def _manager_url_updated(prefs, context):
|
|
discard_flamenco_client(context)
|
|
|
|
from . import comms
|
|
|
|
api_client = comms.flamenco_api_client(prefs.manager_url)
|
|
|
|
# Warning, be careful what of the context to access here. Accessing /
|
|
# changing too much can cause crashes, infinite loops, etc.
|
|
comms.ping_manager(context.window_manager, context.scene, api_client)
|
|
_refresh_the_planet(context)
|
|
|
|
|
|
_project_finder_enum_items = [
|
|
(key, info.label, info.description) for key, info in projects.finders.items()
|
|
]
|
|
|
|
|
|
class WorkerTag(bpy.types.PropertyGroup):
|
|
id: bpy.props.StringProperty(name="id") # type: ignore
|
|
name: bpy.props.StringProperty(name="Name") # type: ignore
|
|
description: bpy.props.StringProperty(name="Description") # type: ignore
|
|
|
|
|
|
class FlamencoPreferences(bpy.types.AddonPreferences):
|
|
bl_idname = "flamenco"
|
|
|
|
manager_url: bpy.props.StringProperty( # type: ignore
|
|
name="Manager URL",
|
|
description="Location of the Manager",
|
|
default="http://localhost:8080/",
|
|
update=_manager_url_updated,
|
|
)
|
|
|
|
project_finder: bpy.props.EnumProperty( # type: ignore
|
|
name="Project Finder",
|
|
description="Strategy for Flamenco to find the top level directory of your project",
|
|
default=_project_finder_enum_items[0][0],
|
|
items=_project_finder_enum_items,
|
|
)
|
|
|
|
# Property that gets its value from the above _job_storage, and cannot be
|
|
# set. This makes it read-only in the GUI.
|
|
job_storage_for_gui: bpy.props.StringProperty( # type: ignore
|
|
name="Job Storage Directory",
|
|
subtype="DIR_PATH",
|
|
default="",
|
|
options={"SKIP_SAVE"},
|
|
description="Directory where blend files are stored when submitting them to Flamenco. This value is determined by Flamenco Manager",
|
|
get=lambda prefs: prefs._job_storage(),
|
|
)
|
|
|
|
def draw(self, context: bpy.types.Context) -> None:
|
|
layout = self.layout
|
|
layout.use_property_decorate = False
|
|
layout.use_property_split = True
|
|
|
|
col = layout.column()
|
|
|
|
row = col.row(align=True)
|
|
row.prop(self, "manager_url")
|
|
row.operator("flamenco.ping_manager", text="", icon="FILE_REFRESH")
|
|
|
|
def text_row(parent, label):
|
|
split = parent.split(factor=0.4)
|
|
split.label(text="")
|
|
split.label(text=label)
|
|
|
|
manager = manager_info.load_cached()
|
|
|
|
if not manager:
|
|
text_row(col, "Press the refresh button before using Flamenco")
|
|
|
|
if context.window_manager.flamenco_status_ping:
|
|
text_row(col, context.window_manager.flamenco_status_ping)
|
|
else:
|
|
aligned = col.column(align=True)
|
|
text_row(aligned, "Press the refresh button to check the connection")
|
|
text_row(aligned, "and update the job storage location")
|
|
|
|
if manager and manager.shared_storage.shaman_enabled:
|
|
text_row(col, "Shaman enabled")
|
|
col.prop(self, "job_storage_for_gui", text="Job Storage")
|
|
|
|
# Project Root
|
|
col = layout.column(align=True)
|
|
col.prop(self, "project_finder")
|
|
try:
|
|
project_root = self.project_root()
|
|
except ValueError:
|
|
pass
|
|
else:
|
|
text_row(col, str(project_root))
|
|
|
|
def project_root(self) -> Path:
|
|
"""Use the configured project finder to find the project root directory."""
|
|
|
|
if not self.project_finder:
|
|
# Just a sanity fallback for missing preferences. It should be
|
|
# covered by the 'default=...' of the property, but just to be sure.
|
|
self.project_finder = "BLENDER_PROJECT"
|
|
|
|
# It is assumed that the blendfile is saved.
|
|
blendfile = Path(bpy.data.filepath)
|
|
return projects.for_blendfile(blendfile, self.project_finder)
|
|
|
|
def _job_storage(self) -> str:
|
|
info = manager_info.load_cached()
|
|
if not info:
|
|
return "Unknown, refresh first."
|
|
return str(info.shared_storage.location)
|
|
|
|
|
|
def get(context: bpy.types.Context) -> FlamencoPreferences:
|
|
"""Return the add-on preferences."""
|
|
prefs = context.preferences.addons["flamenco"].preferences
|
|
assert isinstance(
|
|
prefs, FlamencoPreferences
|
|
), "Expected FlamencoPreferences, got %s instead" % (type(prefs))
|
|
return prefs
|
|
|
|
|
|
def manager_url(context: bpy.types.Context) -> str:
|
|
"""Returns the configured Manager URL."""
|
|
prefs = get(context)
|
|
return str(prefs.manager_url)
|
|
|
|
|
|
classes = (
|
|
WorkerTag,
|
|
FlamencoPreferences,
|
|
)
|
|
_register, _unregister = bpy.utils.register_classes_factory(classes)
|
|
|
|
|
|
def register():
|
|
_register()
|
|
bpy.context.window_manager.flamenco_status_ping = ""
|
|
|
|
|
|
def unregister():
|
|
_unregister()
|