migrate silently, no prompts

This commit is contained in:
David Kaufman
2025-11-14 14:37:05 -05:00
parent e2b4ea58b8
commit f22d0e2292
2 changed files with 52 additions and 61 deletions

View File

@@ -31,6 +31,7 @@ from .util import (
make_export_filters,
get_serializer_from_extension,
)
import Path
import Path.Preferences as Preferences
@@ -57,7 +58,7 @@ class AssetOpenDialog(QFileDialog):
if filters:
self.selectNameFilter(filters[0]) # Default to "All supported files"
def deserialize_file(self, file_path: pathlib.Path) -> Optional[Asset]:
def deserialize_file(self, file_path: pathlib.Path, quiet=False) -> Optional[Asset]:
"""Deserialize the selected file using the appropriate serializer."""
# Find the correct serializer for the file.
file_extension = file_path.suffix.lower()
@@ -65,11 +66,15 @@ class AssetOpenDialog(QFileDialog):
self.serializers, file_extension, for_import=True
)
if not serializer_class:
QMessageBox.critical(
self,
"Error",
f"No supported serializer found for file extension '{file_extension}'",
)
message = f"No supported serializer found for file extension '{file_extension}'"
if quiet:
Path.Log.error(message)
else:
QMessageBox.critical(
self,
"Error",
message,
)
return None
# Check whether all dependencies for importing the file exist.
@@ -102,11 +107,15 @@ class AssetOpenDialog(QFileDialog):
break
if not dependency_found:
QMessageBox.critical(
self,
"Error",
f"Failed to import {file_path}: required dependency {dependency_uri} not found in stores or in parallel Bit directory",
)
message = f"Failed to import {file_path}: required dependency {dependency_uri} not found in stores or in parallel Bit directory"
if quiet:
Path.Log.error(message)
else:
QMessageBox.critical(
self,
"Error",
message,
)
return None
# If we found external toolbits, ask user if they want to import them
@@ -114,20 +123,24 @@ class AssetOpenDialog(QFileDialog):
from PySide.QtGui import QMessageBox
toolbit_names = [uri.asset_id for uri, _ in external_toolbits]
reply = QMessageBox.question(
self,
"Import External Toolbits",
f"This library references {len(external_toolbits)} toolbit(s) that are not in your local store:\n\n"
+ "\n".join(f"{name}" for name in toolbit_names)
+ f"\n\nWould you like to import these toolbits into your local store?\n"
+ "This will make them permanently available for use in other libraries.",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.Yes,
)
if quiet:
Path.Log.info("Importing tool bits for the library")
reply = QMessageBox.Yes
else:
reply = QMessageBox.question(
self,
"Import External Toolbits",
f"This library references {len(external_toolbits)} toolbit(s) that are not in your local store:\n\n"
+ "\n".join(f"{name}" for name in toolbit_names)
+ f"\n\nWould you like to import these toolbits into your local store?\n"
+ "This will make them permanently available for use in other libraries.",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.Yes,
)
if reply == QMessageBox.Yes:
# Import the external toolbits into local store
self._import_external_toolbits(external_toolbits)
self._import_external_toolbits(external_toolbits, quiet=quiet)
# After importing, use regular deserialization since toolbits are now in local store
else:
# User declined import, use context-aware deserialization for external loading
@@ -184,7 +197,7 @@ class AssetOpenDialog(QFileDialog):
# Fallback to home directory if anything goes wrong
return pathlib.Path.home()
def _import_external_toolbits(self, external_toolbits):
def _import_external_toolbits(self, external_toolbits, quiet=False):
"""Import external toolbits into the local asset store."""
from ...toolbit.serializers import all_serializers as toolbit_serializers
from .util import get_serializer_from_extension
@@ -228,12 +241,18 @@ class AssetOpenDialog(QFileDialog):
message += f"\n\nFailed to import {len(failed_imports)} toolbit(s):\n" + "\n".join(
failed_imports
)
QMessageBox.information(self, "Import Results", message)
if quiet:
Path.Log.info(message)
else:
QMessageBox.information(self, "Import Results", message)
elif failed_imports:
message = f"Failed to import all {len(failed_imports)} toolbit(s):\n" + "\n".join(
failed_imports
)
QMessageBox.warning(self, "Import Failed", message)
if quiet:
Path.Log.error(message)
else:
QMessageBox.warning(self, "Import Failed", message)
class AssetSaveDialog(QFileDialog):

View File

@@ -125,24 +125,25 @@ class CAMAssetMigrator:
workdir = Path.Preferences.preferences().GetString(workdir_str)
migrated_dir = Path.Preferences.preferences().GetString(migrated_str)
Path.Log.debug(f"workdir: {workdir}, migrated: {migrated_dir}")
if workdir and workdir != migrated_dir:
if workdir and not migrated_dir:
# Look for tool libraries to import
if os.path.isdir(workdir):
libraries = [f for f in glob.glob(workdir + os.path.sep + "*.fctl")]
libraries.sort()
if len(libraries):
# Offer library import
if self._offer_tool_library_import(workdir, libraries):
# Migrate libraries, automatically and silently
Path.Log.info("Migrating tool libraries into CAM assets")
for library in libraries:
Path.Log.info("Migrating " + library)
import_dialog = AssetOpenDialog(
cam_assets,
asset_class=Library,
serializers=library_serializers,
parent=None,
)
for library in libraries:
asset = import_dialog.deserialize_file(pathlib.Path(library))
if asset:
cam_assets.add(asset)
asset = import_dialog.deserialize_file(pathlib.Path(library), quiet=True)
if asset:
cam_assets.add(asset)
# Mark directory as migrated
Path.Preferences.preferences().SetString(migrated_str, workdir)
@@ -197,35 +198,6 @@ class CAMAssetMigrator:
Path.Log.info("User declined migration")
return False
def _offer_tool_library_import(self, workdir, libraries):
if not FreeCAD.GuiUp:
Path.Log.debug("GUI not available, skipping tool library import offer")
return False
library_names = "\n".join([f"{os.path.basename(library)}" for library in libraries])
msg = (
f"FreeCAD now keeps its tool libraries inside its assets directory."
f"You have {len(libraries)} libraries stored in another working "
f"directory {workdir}. They need to be copied to the assets directory "
f"to continue using them.\n\n"
f"{library_names}\n\n"
f"Would you like to import these libraries?"
)
Path.Log.debug("Showing tool library import dialog to user")
reply = QMessageBox.question(
None, "CAM Tool Library Import", msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes
)
if reply == QMessageBox.Yes:
Path.Log.debug("User requested tool library import")
return True
else:
Path.Log.debug("User declined tool library import")
return False
def _migrate_assets(self, source_path):
"""
Perform actual directory copying and preference updates.