From ee0599e263cbd3388addbbba8ab78af0cf8f1f7c Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Wed, 19 Feb 2025 17:44:48 +1100 Subject: [PATCH] Fix #6136. Allow setting of custom tmp dir, useful for packaged envs like flatpak --- src/bonsai/bonsai/bim/__init__.py | 4 +- .../bonsai/bim/module/augin/operator.py | 2 +- .../bonsai/bim/module/project/operator.py | 8 ++- .../bonsai/bim/module/tester/operator.py | 2 +- src/bonsai/bonsai/bim/operator.py | 58 +++++++------------ src/bonsai/bonsai/bim/ui.py | 12 +++- 6 files changed, 39 insertions(+), 47 deletions(-) diff --git a/src/bonsai/bonsai/bim/__init__.py b/src/bonsai/bonsai/bim/__init__.py index 3755a8d12a..5985459e2a 100644 --- a/src/bonsai/bonsai/bim/__init__.py +++ b/src/bonsai/bonsai/bim/__init__.py @@ -115,10 +115,8 @@ classes = [ operator.ReloadIfcFile, operator.RemoveIfcFile, operator.RevertClippingPlaneCut, - operator.SelectDataDir, - operator.SelectCacheDir, + operator.SelectDir, operator.SelectIfcFile, - operator.SelectSchemaDir, operator.SelectURIAttribute, operator.SetTab, operator.SwitchTab, diff --git a/src/bonsai/bonsai/bim/module/augin/operator.py b/src/bonsai/bonsai/bim/module/augin/operator.py index 965279e9b7..c4999ab08f 100644 --- a/src/bonsai/bonsai/bim/module/augin/operator.py +++ b/src/bonsai/bonsai/bim/module/augin/operator.py @@ -113,7 +113,7 @@ class AuginCreateNewModel(bpy.types.Operator): context.scene.collection.objects.link(cam_obj) context.scene.camera = cam_obj - tmpdir = tempfile.mkdtemp() + tmpdir = tempfile.mkdtemp(dir=tool.Blender.get_addon_preferences().tmp_dir or None) thumb_path = os.path.join(tmpdir, "thumb.png") context.scene.render.image_settings.file_format = "PNG" context.scene.render.filepath = thumb_path diff --git a/src/bonsai/bonsai/bim/module/project/operator.py b/src/bonsai/bonsai/bim/module/project/operator.py index aa1c8b5403..9e40f982fb 100644 --- a/src/bonsai/bonsai/bim/module/project/operator.py +++ b/src/bonsai/bonsai/bim/module/project/operator.py @@ -1057,7 +1057,9 @@ class LoadProjectElements(bpy.types.Operator): logger = logging.getLogger("ImportIFC") path_log = tool.Blender.get_data_dir_path("process.log") if not os.access(path_log.parent, os.W_OK): - path_log = os.path.join(tempfile.mkdtemp(), "process.log") + path_log = os.path.join( + tempfile.mkdtemp(dir=tool.Blender.get_addon_preferences().tmp_dir or None), "process.log" + ) logging.basicConfig( filename=path_log, filemode="a", @@ -1579,7 +1581,9 @@ class ExportIFC(bpy.types.Operator): logger = logging.getLogger("ExportIFC") path_log = tool.Blender.get_data_dir_path("process.log") if not os.access(path_log.parent, os.W_OK): - path_log = os.path.join(tempfile.mkdtemp(), "process.log") + path_log = os.path.join( + tempfile.mkdtemp(dir=tool.Blender.get_addon_preferences().tmp_dir or None), "process.log" + ) logging.basicConfig( filename=path_log, filemode="a", diff --git a/src/bonsai/bonsai/bim/module/tester/operator.py b/src/bonsai/bonsai/bim/module/tester/operator.py index 652d0ff61a..b16abd3fcd 100644 --- a/src/bonsai/bonsai/bim/module/tester/operator.py +++ b/src/bonsai/bonsai/bim/module/tester/operator.py @@ -72,7 +72,7 @@ class ExecuteIfcTester(bpy.types.Operator): # No need for if-statement, just postponing lots of diffs. if True: - dirpath = tempfile.mkdtemp() + dirpath = tempfile.mkdtemp(dir=tool.Blender.get_addon_preferences().tmp_dir or None) start = time.time() output = Path(os.path.join(dirpath, "{}_{}.html".format(Path(ifc_path).name, Path(specs_path).name))) diff --git a/src/bonsai/bonsai/bim/operator.py b/src/bonsai/bonsai/bim/operator.py index 5ba1596203..be0d07102d 100644 --- a/src/bonsai/bonsai/bim/operator.py +++ b/src/bonsai/bonsai/bim/operator.py @@ -226,47 +226,27 @@ class SelectIfcFile(bpy.types.Operator, IFCFileSelector): return {"RUNNING_MODAL"} -class SelectDataDir(bpy.types.Operator): - bl_idname = "bim.select_data_dir" - bl_label = "Select Data Directory" +class SelectDir(bpy.types.Operator): + bl_idname = "bim.select_dir" + bl_label = "Select Directory" bl_options = {"REGISTER", "UNDO"} - bl_description = "Select the directory that contains all IFC data es. PSet, styles, etc..." + bl_description = "Open a file browser to choose the directory" filepath: bpy.props.StringProperty(subtype="FILE_PATH") + data_path: bpy.props.StringProperty(name="Data Path") def execute(self, context): - context.scene.BIMProperties.data_dir = os.path.dirname(self.filepath) - return {"FINISHED"} - - def invoke(self, context, event): - context.window_manager.fileselect_add(self) - return {"RUNNING_MODAL"} - - -class SelectCacheDir(bpy.types.Operator): - bl_idname = "bim.select_cache_dir" - bl_label = "Select Cache Directory" - bl_options = {"REGISTER", "UNDO"} - bl_description = "Select the directory that contains HDF5 cache files" - filepath: bpy.props.StringProperty(subtype="FILE_PATH") - - def execute(self, context): - context.scene.BIMProperties.cache_dir = os.path.dirname(self.filepath) - return {"FINISHED"} - - def invoke(self, context, event): - context.window_manager.fileselect_add(self) - return {"RUNNING_MODAL"} - - -class SelectSchemaDir(bpy.types.Operator): - bl_idname = "bim.select_schema_dir" - bl_label = "Select Schema Directory" - bl_options = {"REGISTER", "UNDO"} - bl_description = "Select the directory containing the IFC schema specification" - filepath: bpy.props.StringProperty(subtype="FILE_PATH") - - def execute(self, context): - context.scene.BIMProperties.schema_dir = os.path.dirname(self.filepath) + crumbs = self.data_path.split(".") + if crumbs[0] == "preferences": + crumbs.pop(0) + data = tool.Blender.get_addon_preferences() + else: + data = context + while crumbs: + crumb = crumbs.pop(0) + if crumbs: + data = getattr(data, crumb) + else: + setattr(data, crumb, os.path.dirname(self.filepath)) return {"FINISHED"} def invoke(self, context, event): @@ -816,7 +796,9 @@ class ReloadIfcFile(bpy.types.Operator, tool.Ifc.Operator): logger = logging.getLogger("ImportIFC") path_log = tool.Blender.get_data_dir_path("process.log") if not os.access(path_log.parent, os.W_OK): - path_log = os.path.join(tempfile.mkdtemp(), "process.log") + path_log = os.path.join( + tempfile.mkdtemp(dir=tool.Blender.get_addon_preferences().tmp_dir or None), "process.log" + ) logging.basicConfig( filename=path_log, filemode="a", diff --git a/src/bonsai/bonsai/bim/ui.py b/src/bonsai/bonsai/bim/ui.py index a666d3fd94..fe300719af 100644 --- a/src/bonsai/bonsai/bim/ui.py +++ b/src/bonsai/bonsai/bim/ui.py @@ -245,6 +245,10 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences): description="If disabled, the toolbar will only load when an IFC model is active", ) should_play_chaching_sound: BoolProperty(name="Play A Cha-Ching Sound When Project Costs Updates", default=False) + tmp_dir: StringProperty( + name="Temporary Directory", + description='Path to create and store temporary files. If left blank, a system default will be used.', + ) spatial_elements_unselectable: BoolProperty( name="Make Spatial Elements Unselectable By Default", default=True, @@ -356,11 +360,15 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences): def draw_directories(self, layout, context): row = layout.row(align=True) row.prop(context.scene.BIMProperties, "data_dir") - row.operator("bim.select_data_dir", icon="FILE_FOLDER", text="") + row.operator("bim.select_dir", icon="FILE_FOLDER", text="").data_path = "scene.BIMProperties.data_dir" row = layout.row(align=True) row.prop(context.scene.BIMProperties, "cache_dir") - row.operator("bim.select_cache_dir", icon="FILE_FOLDER", text="") + row.operator("bim.select_dir", icon="FILE_FOLDER", text="").data_path = "scene.BIMProperties.cache_dir" + + row = layout.row(align=True) + row.prop(self, "tmp_dir") + row.operator("bim.select_dir", icon="FILE_FOLDER", text="").data_path = "preferences.tmp_dir" def draw_drawing_settings(self, layout, context): layout.prop(context.scene.BIMProperties, "pset_dir")