def setup_file_association(force=False, silent=False): # Linux and OSX file associations are done together with desktop items if sys.platform != 'win32': return gmsh_bin = file_finder.path2bin('gmsh') extensions = ['.msh', '.geo', '.stl'] associate = dict.fromkeys(extensions) for ext in extensions: if _is_associated(ext): if force: associate[ext] = True else: associate[ext] = _get_input( f'Found other association for "{ext}" files, overwrite it?', silent) else: associate[ext] = True # If all rejected, return if not any(associate.values()): return if sys.platform == 'win32': with winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Classes', access=winreg.KEY_WRITE) as reg: winreg.CreateKey( reg, rf'SimNIBS.Gmsh.v{MINOR_VERSION}\shell\open\command') winreg.SetValue( reg, rf'SimNIBS.Gmsh.v{MINOR_VERSION}\shell\open\command', winreg.REG_SZ, f'"{gmsh_bin}" "%1"') for ext in extensions: try: value = winreg.QueryValue(reg, ext) except FileNotFoundError: register = True else: if value: register = _get_input( f'Found other association for "{ext}" files, overwrite it?', silent) else: register = True if register: winreg.CreateKey(reg, ext) winreg.SetValue(reg, ext, winreg.REG_SZ, fr'SimNIBS.Gmsh.v{MINOR_VERSION}')
def setup_file_association(force=False, silent=False): # Linux and OSX file associations are done together with desktop items if sys.platform != 'win32': return gmsh_bin = file_finder.path2bin('gmsh') extensions = ['.msh', '.geo', '.stl'] associate = dict.fromkeys(extensions) for ext in extensions: if _is_associated(ext): if force: associate[ext] = True else: associate[ext] = _get_input( f'Found other association for "{ext}" files, overwrite it?', silent) else: associate[ext] = True # If all rejected, return if not any(associate.values()): return if sys.platform == 'win32': # We need to run with admin privileges # So a write a .cmd script and run it with administrative privileges with tempfile.NamedTemporaryFile('w', delete=False, suffix='.cmd') as f: [ f.write(f'call assoc {ext}=gmsh.simnibs\n') for ext, val in associate.items() if val ] f.write(f'call ftype gmsh.simnibs="{gmsh_bin}" "%1"') temp_fn = f.name # I need to run as admin for some reason # using a very ugly trick to get "%1" through # I have to use %1 as an argument so "%1" in the script becomes literal ret = subprocess.run( 'powershell.exe -noprofile -executionpolicy bypass -Command ' f'"Start-Process -Wait -WindowStyle Hidden -Verb RunAs -FilePath {temp_fn}"' f' -ArgumentList "%1"', shell=True) try: ret.check_returncode() except subprocess.CalledProcessError: print('Could not associate files') finally: os.remove(temp_fn)
def copy_scripts(dest_dir): ''' Create scripts to call SimNIBS We need to write sh/cmd scripts due to the way python handles DLLs Additionaly, creates a 'simnibs' command in the matlab folder ''' scripts = glob.glob(os.path.join(SIMNIBSDIR, 'cli', '[!_]*.py')) if not os.path.isdir(dest_dir): os.makedirs(dest_dir) # Create scripts for s in scripts: basename = os.path.splitext(os.path.basename(s))[0] if basename == 'run_simnibs': basename = 'simnibs' if basename == 'simnibs_gui': gui = True else: gui = False # Norma things bash_name = os.path.join(dest_dir, basename) # Special treatment to meshfix and gmsh if basename in ['meshfix', 'gmsh']: if sys.platform == 'win32': with open(bash_name + '.cmd', 'w') as f: f.write("@echo off\n") f.write(f'"{file_finder.path2bin(basename)}" %*') else: if os.path.lexists(bash_name): os.remove(bash_name) os.symlink(file_finder.path2bin(basename), bash_name) # Other stuff else: if sys.platform == 'win32': _write_windows_cmd(s, bash_name, gui) else: _write_unix_sh(s, bash_name) # simnibs_python interpreter if sys.platform == 'win32': _write_windows_cmd(None, os.path.join(dest_dir, 'simnibs_python')) else: if os.path.lexists(os.path.join(dest_dir, 'simnibs_python')): os.remove(os.path.join(dest_dir, 'simnibs_python')) os.symlink(sys.executable, os.path.join(dest_dir, 'simnibs_python'))
def _create_apps(install_dir): """ Creates an apps for MacOS """ plist = dict(CFBundleDisplayName="SimNIBS GUI", CFBundleName="SimNIBS GUI", CFBundleIdentifier="org.simnibs", CFBundleShortVersionString=__version__, CFBundleGetInfoString=f'SimNIBS GUI {__version__}', CFBundleIconFile="gui_icon.icns", CFBundleExecutable="simnibs_gui", CFBundleInfoDictionaryVersion='6.0') _create_app(os.path.join(install_dir, 'SimNIBS GUI.app'), os.path.join(SIMNIBSDIR, 'cli', 'simnibs_gui.py'), os.path.join(SIMNIBSDIR, 'resources', 'gui_icon.icns'), plist) # Gmsh app setup target_dir = os.path.join(install_dir, 'Gmsh.app') if os.path.isdir(target_dir): shutil.rmtree(target_dir) print('Installing Gmsh') contents_dir = os.path.join(target_dir, 'Contents') resouces_dir = os.path.join(contents_dir, 'Resources') macos_dir = os.path.join(contents_dir, 'MacOS') os.mkdir(target_dir) os.mkdir(contents_dir) os.mkdir(resouces_dir) os.mkdir(macos_dir) _copy_and_log(os.path.join(SIMNIBSDIR, 'resources', 'gmsh', 'Info.plist'), os.path.join(contents_dir)) for icns in glob.glob( os.path.join(SIMNIBSDIR, 'resources', 'gmsh', '*.icns')): _copy_and_log(icns, resouces_dir) _copy_and_log(file_finder.path2bin('gmsh'), os.path.join(macos_dir))
def copy_scripts(dest_dir): ''' Create scripts to call SimNIBS We need to write sh/cmd scripts due to the way python handles DLLs Additionaly, creates a 'simnibs' command in the matlab folder ''' # On windows, copy the sitecustomize script # in order to be able to use the python interpreter without activating the environment if sys.platform == 'win32': simnibs_sitecustomize = os.path.join(SIMNIBSDIR, 'utils', 'sitecustomize.py') env_sitecustomize = os.path.join(os.path.dirname(sys.executable), 'Lib', 'site-packages', 'sitecustomize.py') write_sitecustomize = True with open(simnibs_sitecustomize, 'r') as f: simnibs_sitecustomize_contents = f.read() # Check if there is a sitecustomize file alread present and if it is identical ti the SimNIBS one if os.path.isfile(env_sitecustomize): with open(env_sitecustomize, 'r') as f: env_sitecustomize_contents = f.read() # If it's alteady there, will not append the PATH write_sitecustomize = not (simnibs_sitecustomize_contents in env_sitecustomize_contents) if write_sitecustomize: with open(env_sitecustomize, 'a') as f: f.write('\n') f.write(simnibs_sitecustomize_contents) scripts = glob.glob(os.path.join(SIMNIBSDIR, 'cli', '[!_]*.py')) if not os.path.isdir(dest_dir): os.makedirs(dest_dir) # Create scripts for s in scripts: basename = os.path.splitext(os.path.basename(s))[0] if basename == 'run_simnibs': basename = 'simnibs' if basename == 'simnibs_gui': gui = True else: gui = False # Norma things bash_name = os.path.join(dest_dir, basename) # Special treatment to meshfix and gmsh if basename in ['meshfix', 'gmsh']: if sys.platform == 'win32': with open(bash_name + '.cmd', 'w') as f: f.write("@echo off\n") f.write(f'"{file_finder.path2bin(basename)}" %*') else: if os.path.lexists(bash_name): os.remove(bash_name) os.symlink(file_finder.path2bin(basename), bash_name) # Other stuff else: if sys.platform == 'win32': _write_windows_cmd(s, bash_name, gui) else: _write_unix_sh(s, bash_name) # simnibs_python interpreter if sys.platform == 'win32': _write_windows_cmd(None, os.path.join(dest_dir, 'simnibs_python')) else: if os.path.lexists(os.path.join(dest_dir, 'simnibs_python')): os.remove(os.path.join(dest_dir, 'simnibs_python')) os.symlink(sys.executable, os.path.join(dest_dir, 'simnibs_python'))
def setup_shortcut_icons(scripts_dir, force=False, silent=False): ''' Creates shortcut icons for the gui_scripts ''' if sys.platform == 'darwin': _create_apps(os.path.abspath(os.path.join(scripts_dir, '..'))) return elif sys.platform == 'win32': shortcut_folder = os.path.join(os.environ['APPDATA'], "Microsoft", "Windows", "Start Menu", "Programs", f"SimNIBS {MINOR_VERSION}") gmsh_icon = None simnibs_icon = os.path.join(SIMNIBSDIR, 'resources', 'gui_icon.ico') elif sys.platform == 'linux': shortcut_folder = os.path.expanduser( f'~/.local/share/applications/SimNIBS-{MINOR_VERSION}') gmsh_icon = os.path.join(SIMNIBSDIR, 'resources', 'gmsh', 'logo.png') simnibs_icon = os.path.join(SIMNIBSDIR, 'resources', 'gui_icon.png') if os.path.isdir(shortcut_folder): if force: overwrite = True else: overwrite = _get_input( 'Found other SimNIBS menu icons, overwrite them?', silent) if not overwrite: print('Not adding shortucts to the current SimNIBS install') return else: shortcut_icons_clenup() os.makedirs(shortcut_folder, exist_ok=True) _create_shortcut( os.path.join(shortcut_folder, 'Gmsh'), file_finder.path2bin('gmsh'), 'Gmsh is a free 3D finite element mesh generator with a built-in CAD engine and' ' post-processor', mime_type='model/x.stl-binary', icon=gmsh_icon) fn_gui_script = os.path.join(scripts_dir, 'simnibs_gui') if sys.platform == 'win32': fn_gui_script += '.cmd' _create_shortcut( os.path.join(shortcut_folder, 'SimNIBS GUI'), fn_gui_script, 'SimNIBS is software for simulating electric fields caused by NIBS', icon=simnibs_icon) if sys.platform == 'win32': _create_shortcut( os.path.join(shortcut_folder, 'SimNIBS Directory'), os.path.abspath(os.path.join(scripts_dir, '..')), ) _create_shortcut( os.path.join(shortcut_folder, 'SimNIBS Documentation'), os.path.abspath( os.path.join(scripts_dir, '..', 'documentation', 'index.html')), ) _create_shortcut( os.path.join(shortcut_folder, 'SimNIBS Prompt'), r'%windir%\System32\cmd.exe', arguments=f'/K ""{_get_activate_bin()}"" {_get_conda_env()}') if sys.platform == 'linux': try: subprocess.run([ 'update-desktop-database', os.path.expanduser('~/.local/share/applications') ]) except: print('Could not update desktop database')