def downloadMacroList(self): local_dir = Path(get_cache_path(), 'git', str(hashlib.sha256(self.url.encode()).hexdigest()), create_dir=True) # Try Git (gitAvailable, gitExe, gitVersion, gitPython, gitVersionOk) = install_info() if gitAvailable and gitPython and gitVersionOk: repo, path = clone_local(self.url, path=local_dir) return path # Try zip/http if zlib.is_zip_available(): zip_path = Path(tempfile.mktemp(suffix=".zip")) if http_download(self.repo.getZipUrl(), zip_path): exploded = Path(tempfile.mktemp(suffix="_zip")) zlib.unzip(zip_path, exploded) # Remove old if exists if local_dir.exists(): shutil.rmtree(local_dir, ignore_errors=True) # Move exploded dir to install dir for entry_path in exploded.iterdir(): if entry_path.is_dir(): shutil.move(entry_path, local_dir) return local_dir
def installMod(self, pkg): # Get Git info git_available, _, git_version, git_python, git_version_ok = install_info( ) # Get zip info zip_available = zlib.is_zip_available() # Initialize result result = InstallResult(gitAvailable=git_available, gitPythonAvailable=git_python is not None, zipAvailable=zip_available, gitVersionOk=git_version_ok, gitVersion=git_version) # Check valid install dir in_mods = get_mod_path() == pkg.installDir.parent in_macros = pkg.installFile and get_macro_path( ) in pkg.installFile.parents if not in_mods and not in_macros: log('Invalid install dir: {0}'.format(pkg.installDir)) result.ok = False result.invalidInstallDir = True return result # Try Git install if git_available and git_version_ok and git_python: result = self.installModFromGit(pkg, result) # Try zip/http install elif zip_available: result = self.installModFromHttpZip(pkg, result) if result.ok: try: self.linkMacrosFromMod(pkg) except: # ! TODO: Rollback everything if macro links fail? pass return result
def installMacro(self, pkg): (git_available, _, git_version, git_python, git_version_ok) = install_info() # Initialize result result = InstallResult(gitAvailable=git_available, gitPythonAvailable=git_python is not None, zipAvailable=zlib.is_zip_available(), gitVersionOk=git_version_ok, gitVersion=git_version) # Ensure last version if available locally src_dir = self.downloadMacroList() # Get path of source macro file src_file = Path(src_dir, pkg.basePath, pkg.installFile.name) # Copy Macro files = [] try: macros_dir = get_macro_path() if not macros_dir.exists(): macros_dir.mkdir(parents=True) log('Installing', pkg.installFile) shutil.copy2(src_file, pkg.installFile) files.append(pkg.installFile) # Copy files if pkg.files: for f in pkg.files: file_base_path = utils.path_relative(f) dst = Path(pkg.installDir, file_base_path).absolute() src = Path(src_dir, pkg.basePath, file_base_path).absolute() log('Installing ', dst) if pkg.installDir not in dst.parents: result.message = tr( 'Macro package attempts to install files outside of permitted path' ) raise Exception() if src_dir not in src.parents: result.message = tr( 'Macro package attempts to access files outside of permitted path' ) raise Exception() dst_dir = dst.parent if dst_dir != pkg.installDir and dst_dir not in files and not dst_dir.exists( ): dst_dir.mkdir(parents=True) files.append(dst_dir) shutil.copy2(src, dst) files.append(dst) result.ok = True except: log(traceback.format_exc()) result.ok = False if not result.message: result.message = tr( 'Macro was not installed, please contact the maintainer.') # Rollback files.sort(reverse=True) for f in files: try: log("Rollback ", f) if f.is_file(): f.unlink() elif f.is_dir(): shutil.rmtree(f, ignore_errors=True) except: log(traceback.format_exc()) return result