def debug_install_mod(mod_src: str, mods_dir: str, mod_name: str, mod_folder_name: str) -> None: """ Compiles and installs the mod which adds a cheat code so the user can setup the debugger in-game :param mod_src: Path to the script which does this :param mods_dir: Path to the users mod folder :param mod_name: Name of the mod :param mod_folder_name: Name of mod Subfolder :return: Nothing """ print("Compiling and installing the cheatcode mod...") # Get destination file path mods_sub_dir = os.path.join(mods_dir, mod_folder_name) mod_path = os.path.join(mods_sub_dir, mod_name + '.ts4script') ensure_path_created(mods_sub_dir) # Get compiled path and compile mod mod_src_pyc = replace_extension(mod_src, "pyc") py_compile.compile(mod_src, mod_src_pyc) # Create mod at destination and add compiled file to it zf = PyZipFile(mod_path, mode='w', compression=ZIP_STORED, allowZip64=True, optimize=2) zf.write(mod_src_pyc, mod_name + ".pyc") zf.close()
def compile_full(src_dir: str, zf: PyZipFile) -> None: """ Compiles a full mod (Contains all files in source including python files which it then compiles Modified from andrew's code. https://sims4studio.com/thread/15145/started-python-scripting :param src_dir: source folder :param zf: Zip File Handle :return: Nothing """ for folder, subs, files in os.walk(src_dir): for filename in fnmatch.filter(files, '*.py'): file_path_py = folder + os.sep + filename file_path_pyc = replace_extension(file_path_py, "pyc") rel_path_pyc = get_rel_path(file_path_pyc, src_dir) py_compile.compile(file_path_py, file_path_pyc) zf.write(file_path_pyc, rel_path_pyc) remove_file(file_path_pyc) for filename in fnmatch.filter(files, '*[!p][!y][!c]'): rel_path = get_rel_path(folder + os.sep + filename, src_dir) zf.write(folder + os.sep + filename, rel_path)
def compile_slim(src_dir: str, zf: PyZipFile) -> None: """ Compiles a slim mod (Contains only the pyc files) Modified from andrew's code. https://sims4studio.com/thread/15145/started-python-scripting It is not reccomended to use this function because it's not reccomended to only have pyc files in your project as it makes your project less flexible. Going forward this will nto be called by default. :param src_dir: source folder :param zf: Zip File Handle :return: Nothing """ for folder, subs, files in os.walk(src_dir): for filename in fnmatch.filter(files, '*.py'): file_path_py = folder + os.sep + filename file_path_pyc = replace_extension(file_path_py, "pyc") rel_path_pyc = get_rel_path(file_path_pyc, src_dir) py_compile.compile(file_path_py, file_path_pyc) zf.write(file_path_pyc, rel_path_pyc) remove_file(file_path_pyc)
"curses", # Tcl/Tk GUI "tkinter", "tkinter", # Tests for the standard library "test", "tests", "idle_test", "__phello__.foo.py", # importlib frozen modules. These are already baked into CPython. "_bootstrap.py", "_bootstrap_external.py", ] if __name__ == "__main__": parser = argparse.ArgumentParser(description="Zip py source") parser.add_argument("paths", nargs="*", help="Paths to zip.") parser.add_argument("--install_dir", help="Root directory for all output files") parser.add_argument("--zip_name", help="Output zip name") args = parser.parse_args() zip_file_name = args.install_dir + '/' + args.zip_name zf = PyZipFile(zip_file_name, mode='w') for p in args.paths: path = Path(p) if path.name in DENY_LIST: continue zf.write(p)
def debug_install_egg(egg_path: str, mods_dir, dest_name: str, mod_folder_name: str) -> None: """ Copies the debug egg provided by Pycharm Pro which adds the capability to make debugging happen inside of PyCharm Pro. A bit of work goes into this so it'll be much slower. :param egg_path: Path to the debug egg :param mods_dir: Path to the mods folder :param dest_name: Name of the mod :param mod_folder_name: Name of mod Subfolder :return: """ print("Re-packaging and installing the debugging capability mod...") # Get egg filename and path filename = Path(egg_path).name mods_sub_dir = os.path.join(mods_dir, mod_folder_name) mod_path = os.path.join(mods_sub_dir, dest_name + ".ts4script") ensure_path_created(mods_sub_dir) # Get python ctypes folder sys_ctypes_folder = os.path.join(get_sys_folder(), "Lib", "ctypes") # Create temp directory tmp_dir = tempfile.TemporaryDirectory() tmp_egg = tmp_dir.name + os.sep + filename # Remove old mod in mods folder there, if it exists remove_file(mod_path) # Copy egg to temp path shutil.copyfile(egg_path, tmp_egg) # Extract egg # This step is a bit redundant but I need to copy over everything but one folder into the zip file and I don't # know how to do that in python so I copy over the zip, extract it, copy in the whole folder, delete the one # sub-folder, then re-zip everything up. It's a pain but it's what I know hwo to do now and Google's not much help zip = PyZipFile(tmp_egg) zip.extractall(tmp_dir.name) zip.close() # Remove archive remove_file(tmp_egg) # Copy ctype folder to extracted archive shutil.copytree(sys_ctypes_folder, tmp_dir.name + os.sep + "ctypes") # Remove that one folder remove_dir(tmp_dir.name + os.sep + "ctypes" + os.sep + "__pycache__") # Grab a handle on the egg zf = PyZipFile(mod_path, mode='w', compression=ZIP_STORED, allowZip64=True, optimize=2) # Add all the files in the tmp directory to the zip file for folder, subs, files in os.walk(tmp_dir.name): for file in files: archive_path = get_rel_path(folder + os.sep + file, tmp_dir.name) zf.write(folder + os.sep + file, archive_path) zf.close() # There's a temporary directory bug that causes auto-cleanup to sometimes fail # We're preventing crash messages from flooding the screen to keep things tidy try: tmp_dir.cleanup() except: pass