From 957234130224806583c2e40237dd13275ad584eb Mon Sep 17 00:00:00 2001 From: Samuel Lopez <85613111+Samuelopez-ansys@users.noreply.github.com> Date: Mon, 6 May 2024 13:37:19 +0200 Subject: [PATCH] REFACTOR: Fix installer (#4634) Co-authored-by: maxcapodi78 --- _unittest/test_01_Design.py | 9 ++- .../Resources/PyAEDTInstallerFromDesktop.py | 28 ++++++-- pyaedt/workflows/customize_automation_tab.py | 45 ++++++++----- .../hfss3dlayout/toolkits_catalog.toml | 2 +- .../workflows/installer/pyaedt_installer.py | 66 +++---------------- pyaedt/workflows/installer/toolkit_manager.py | 4 +- .../workflows/project/toolkits_catalog.toml | 6 +- .../Run_PyAEDT_Toolkit_Script.py_build | 2 +- 8 files changed, 79 insertions(+), 83 deletions(-) diff --git a/_unittest/test_01_Design.py b/_unittest/test_01_Design.py index ae2150c5391..eddd0ace585 100644 --- a/_unittest/test_01_Design.py +++ b/_unittest/test_01_Design.py @@ -405,8 +405,15 @@ def test_38_toolkit(self, desktop): file = os.path.join(self.local_scratch.path, "test.py") with open(file, "w") as f: f.write("import pyaedt\n") + assert customize_automation_tab.add_script_to_menu(name="test_toolkit", script_file=file) + assert customize_automation_tab.remove_script_from_menu( + desktop_object=self.aedtapp.desktop_class, name="test_toolkit" + ) assert customize_automation_tab.add_script_to_menu( - desktop_object=self.aedtapp.desktop_class, name="test_toolkit", script_file=file + name="test_toolkit", + script_file=file, + personal_lib=self.aedtapp.desktop_class.personallib, + aedt_version=self.aedtapp.desktop_class.aedt_version_id, ) assert customize_automation_tab.remove_script_from_menu( desktop_object=self.aedtapp.desktop_class, name="test_toolkit" diff --git a/doc/source/Resources/PyAEDTInstallerFromDesktop.py b/doc/source/Resources/PyAEDTInstallerFromDesktop.py index 7d857c83b6c..38e3be78795 100644 --- a/doc/source/Resources/PyAEDTInstallerFromDesktop.py +++ b/doc/source/Resources/PyAEDTInstallerFromDesktop.py @@ -52,8 +52,28 @@ def run_pyinstaller_from_c_python(oDesktop): oDesktop.AddMessage("", "", 2, err_msg) return else: - oDesktop.AddMessage("", "", 0, "PyAEDT setup complete.") - + oDesktop.AddMessage("", "", 0, "PyAEDT virtual environment created.") + pyaedt_path = os.path.join(venv_dir, "Lib", "site-packages", "pyaedt") + if is_linux: + for dirpath, dirnames, _ in os.walk(venv_dir): + if "site-packages" in dirnames: + pyaedt_path = os.path.normpath( + os.path.join(dirpath, "site-packages", "pyaedt") + ) + if os.path.isdir(pyaedt_path): + break + personal_lib_dir = oDesktop.GetPersonalLibDirectory() + pers1 = os.path.join(personal_lib_dir, "pyaedt") + if os.path.exists(pers1): + oDesktop.AddMessage("", "", 2, "PersonalLib already mapped.") + else: + if is_windows: + command = 'mklink /D "{}" "{}"'.format(pers1, pyaedt_path) + else: + command = 'ln -s "{}" "{}"'.format(pyaedt_path, pers1) + ret_code = os.system(command) + if ret_code != 0: + oDesktop.AddMessage("", "", 2, "Error configuring symbolic link to pyaedt in PersonalLib.") import tempfile python_script = os.path.join(tempfile.gettempdir(), "configure_pyaedt.py") with open(python_script, "w") as f: @@ -62,8 +82,8 @@ def run_pyinstaller_from_c_python(oDesktop): # f.write('sys.path.insert(0, r"c:\\ansysdev\\git\\repos\\pyaedt")\n') f.write("from pyaedt.workflows.installer.pyaedt_installer import add_pyaedt_to_aedt\n") f.write( - 'add_pyaedt_to_aedt(aedt_version="{}", student_version={}, new_desktop_session=False)\n'.format( - oDesktop.GetVersion()[:6], is_student_version(oDesktop))) + 'add_pyaedt_to_aedt(aedt_version="{}", personallib=r"{}")\n'.format( + oDesktop.GetVersion()[:6], oDesktop.GetPersonalLibDirectory())) command = r'"{}" "{}"'.format(python_exe, python_script) oDesktop.AddMessage("", "", 0, command) diff --git a/pyaedt/workflows/customize_automation_tab.py b/pyaedt/workflows/customize_automation_tab.py index 5f9eb6dd85e..17e850557fe 100644 --- a/pyaedt/workflows/customize_automation_tab.py +++ b/pyaedt/workflows/customize_automation_tab.py @@ -19,7 +19,7 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - +import logging import os import shutil import subprocess # nosec @@ -267,7 +267,6 @@ def available_toolkits(): def add_script_to_menu( - desktop_object, name, script_file, template_file="Run_PyAEDT_Toolkit_Script", @@ -276,6 +275,8 @@ def add_script_to_menu( copy_to_personal_lib=True, executable_interpreter=None, panel="Panel_PyAEDT_Toolkits", + personal_lib=None, + aedt_version="", ): """Add a script to the ribbon menu. @@ -286,8 +287,6 @@ def add_script_to_menu( Parameters ---------- - desktop_object : :class:pyaedt.desktop.Desktop - Desktop object. name : str Name of the toolkit to appear in AEDT. script_file : str @@ -306,19 +305,28 @@ def add_script_to_menu( Executable python path. The default is the one current interpreter. panel : str, optional Panel name. The default is ``"Panel_PyAEDT_Toolkits"``. + personal_lib : str, optional + aedt_version : str, optional Returns ------- bool """ - + logger = logging.getLogger("Global") + if not personal_lib or not aedt_version: + from pyaedt.generic.desktop_sessions import _desktop_sessions + + if not _desktop_sessions: + logger.error("Personallib or AEDT version is not provided and there is no available desktop session.") + return False + d = list(_desktop_sessions.values())[0] + personal_lib = d.personallib + aedt_version = d.aedt_version_id if script_file and not os.path.exists(script_file): - desktop_object.logger.error("Script does not exists.") + logger.error("Script does not exists.") return False - - toolkit_dir = os.path.join(desktop_object.personallib, "Toolkits") - aedt_version = desktop_object.aedt_version_id + toolkit_dir = os.path.join(personal_lib, "Toolkits") tool_map = __tab_map(product) tool_dir = os.path.join(toolkit_dir, tool_map, name) lib_dir = os.path.join(tool_dir, "Lib") @@ -334,14 +342,15 @@ def add_script_to_menu( dest_script_path = os.path.join(lib_dir, os.path.split(script_file)[-1]) shutil.copy2(script_file, dest_script_path) - version_agnostic = False + version_agnostic = True if aedt_version[2:6].replace(".", "") in sys.executable: executable_version_agnostic = sys.executable.replace(aedt_version[2:6].replace(".", ""), "%s") - version_agnostic = True + version_agnostic = False else: executable_version_agnostic = sys.executable if executable_interpreter: + version_agnostic = True executable_version_agnostic = executable_interpreter templates_dir = os.path.dirname(pyaedt.workflows.templates.__file__) @@ -360,7 +369,7 @@ def add_script_to_menu( if dest_script_path: build_file_data = build_file_data.replace("##PYTHON_SCRIPT##", dest_script_path) - if not version_agnostic: + if version_agnostic: build_file_data = build_file_data.replace(" % version", "") out_file.write(build_file_data) @@ -368,7 +377,7 @@ def add_script_to_menu( add_automation_tab( name, toolkit_dir, icon_file=icon_file, product=product, template=file_name_dest, panel=panel ) - desktop_object.logger.info("{} installed".format(name)) + logger.info("{} installed".format(name)) return True @@ -548,15 +557,19 @@ def run_command(command): if not os.path.exists(tool_dir): # Install toolkit inside AEDT add_script_to_menu( - desktop_object=desktop_object, name=toolkit_info["name"], script_file=script_file, icon_file=script_image, product=product_name, - template_file="Run_PyAEDT_Toolkit_Script", + template_file=toolkit_info.get("template", "Run_PyAEDT_Toolkit_Script"), copy_to_personal_lib=True, executable_interpreter=python_exe, + personal_lib=desktop_object.personallib, + aedt_version=desktop_object.aedt_version_id, ) + desktop_object.logger.info("{} installed".format(toolkit_info["name"])) + if version > "232": + desktop_object.odesktop.RefreshToolkitUI() else: if os.path.exists(tool_dir): # Install toolkit inside AEDT @@ -565,6 +578,8 @@ def run_command(command): name=toolkit_info["name"], product=product_name, ) + desktop_object.logger.info("Installing dependencies") + desktop_object.logger.info("{} uninstalled".format(toolkit_info["name"])) def remove_script_from_menu(desktop_object, name, product="Project"): diff --git a/pyaedt/workflows/hfss3dlayout/toolkits_catalog.toml b/pyaedt/workflows/hfss3dlayout/toolkits_catalog.toml index 1149935ea8c..071b7ee4269 100644 --- a/pyaedt/workflows/hfss3dlayout/toolkits_catalog.toml +++ b/pyaedt/workflows/hfss3dlayout/toolkits_catalog.toml @@ -2,5 +2,5 @@ name = "Export to 3D" script = "export_to_3D.py" icon = "images/large/cad3d.png" -template = "Run_PyAEDT_Script" +template = "Run_PyAEDT_Toolkit_Script" pip = "" diff --git a/pyaedt/workflows/installer/pyaedt_installer.py b/pyaedt/workflows/installer/pyaedt_installer.py index eae13eeb397..64ca94211e5 100644 --- a/pyaedt/workflows/installer/pyaedt_installer.py +++ b/pyaedt/workflows/installer/pyaedt_installer.py @@ -24,77 +24,28 @@ import os -from pyaedt import is_windows -from pyaedt import pyaedt_path from pyaedt.generic.general_methods import read_toml from pyaedt.workflows import customize_automation_tab def add_pyaedt_to_aedt( - aedt_version="2024.1", - student_version=False, - new_desktop_session=False, - non_graphical=False, + aedt_version, + personallib, ): """Add PyAEDT tabs in AEDT. Parameters ---------- - aedt_version : str, optional + aedt_version : str AEDT release. - student_version : bool, optional - Whether to use the student version of AEDT. The default - is ``False``. - new_desktop_session : bool, optional - Whether to create a new AEDT session. The default - is ``False`` - non_graphical : bool, optional - Whether to run AEDT in non-graphical mode. The default - is ``False``. + personallib : str + AEDT Personal Lib folder. """ - from pyaedt import Desktop - from pyaedt.generic.general_methods import grpc_active_sessions - from pyaedt.generic.settings import settings + __add_pyaedt_tabs(personallib, aedt_version) - sessions = grpc_active_sessions(aedt_version, student_version) - close_on_exit = True - if not sessions: - if not new_desktop_session: - print("Launching a new AEDT desktop session.") - new_desktop_session = True - else: - close_on_exit = False - settings.use_grpc_api = True - with Desktop( - specified_version=aedt_version, - non_graphical=non_graphical, - new_desktop_session=new_desktop_session, - student_version=student_version, - close_on_exit=close_on_exit, - ) as d: - personal_lib_dir = d.odesktop.GetPersonalLibDirectory() - pers1 = os.path.join(personal_lib_dir, "pyaedt") - pid = d.odesktop.GetProcessID() - # Linking pyaedt in PersonalLib for IronPython compatibility. - if os.path.exists(pers1): - d.logger.info("PersonalLib already mapped.") - else: - if is_windows: - os.system('mklink /D "{}" "{}"'.format(pers1, pyaedt_path)) - else: - os.system('ln -s "{}" "{}"'.format(pyaedt_path, pers1)) - __add_pyaedt_tabs(d) - - if pid and new_desktop_session: - try: - os.kill(pid, 9) - except Exception: # pragma: no cover - return False - - -def __add_pyaedt_tabs(desktop_object): +def __add_pyaedt_tabs(personallib, aedt_version): """Add PyAEDT tabs in AEDT.""" pyaedt_tabs = ["Console", "Jupyter", "Run_Script", "ToolkitManager"] @@ -112,7 +63,6 @@ def __add_pyaedt_tabs(desktop_object): icon_file = os.path.join(project_workflows_dir, "images", "large", toolkit_info["icon"]) template_name = toolkit_info["template"] customize_automation_tab.add_script_to_menu( - desktop_object, toolkit_info["name"], script_path, template_name, @@ -121,4 +71,6 @@ def __add_pyaedt_tabs(desktop_object): copy_to_personal_lib=True, executable_interpreter=None, panel="Panel_PyAEDT_Installer", + personal_lib=personallib, + aedt_version=aedt_version, ) diff --git a/pyaedt/workflows/installer/toolkit_manager.py b/pyaedt/workflows/installer/toolkit_manager.py index 6ec606b8228..7134172b6f7 100644 --- a/pyaedt/workflows/installer/toolkit_manager.py +++ b/pyaedt/workflows/installer/toolkit_manager.py @@ -281,13 +281,15 @@ def button_is_clicked( if os.path.isfile(executable_interpreter): add_script_to_menu( - desktop_object=desktop, name=name, script_file=file, product=toolkit_level, icon_file=icon, executable_interpreter=executable_interpreter, + personal_lib=desktop.personallib, + aedt_version=desktop.aedt_version_id, ) + desktop.logger.info("{} installed".format(name)) else: desktop.logger.info("PyAEDT environment is not installed.") else: diff --git a/pyaedt/workflows/project/toolkits_catalog.toml b/pyaedt/workflows/project/toolkits_catalog.toml index 76270600ced..0706b1685e5 100644 --- a/pyaedt/workflows/project/toolkits_catalog.toml +++ b/pyaedt/workflows/project/toolkits_catalog.toml @@ -2,12 +2,12 @@ name = "Generate report" script = "create_report.py" icon = "images/large/pdf.png" -template = "Run_PyAEDT_Script" +template = "Run_PyAEDT_Toolkit_Script" pip = "" -[GenerateReport] +[ImportNastran] name = "Import Nastran" script = "import_nastran.py" icon = "images/large/cad3d.png" -template = "Run_PyAEDT_Script" +template = "Run_PyAEDT_Toolkit_Script" pip = "" diff --git a/pyaedt/workflows/templates/Run_PyAEDT_Toolkit_Script.py_build b/pyaedt/workflows/templates/Run_PyAEDT_Toolkit_Script.py_build index f25b98dd282..782db7609ab 100644 --- a/pyaedt/workflows/templates/Run_PyAEDT_Toolkit_Script.py_build +++ b/pyaedt/workflows/templates/Run_PyAEDT_Toolkit_Script.py_build @@ -32,7 +32,7 @@ def main(): try: oDesktop.AddMessage("", "", 0, "Toolkit launched. Please wait.") # launch file - python_exe = r"##PYTHON_EXE##" % version + python_exe = r"##PYTHON_EXE##" pyaedt_script = r"##PYTHON_SCRIPT##" check_file(python_exe) check_file(pyaedt_script)