Skip to content

Instantly share code, notes, and snippets.

@AliceDTRH
Last active February 18, 2023 20:05
Show Gist options
  • Save AliceDTRH/cc55c0ce2b6a2223375b9003771c13b4 to your computer and use it in GitHub Desktop.
Save AliceDTRH/cc55c0ce2b6a2223375b9003771c13b4 to your computer and use it in GitHub Desktop.
This script copies mods from a specified directory to the Zomboid mods directory. I personally use it in combination with steamcmd.
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
[dev-packages]
[requires]
python_version = "3.10"
python_full_version = "3.10.9"
#!/usr/bin/env python
"""
This script creates symbolic links for mods in a Project Zomboid workshop directory to the mods directory.
"""
"""
This script is provided as-is and is not fit for any particular purpose. Use it at your own risk.
Copyright for the original work belongs to AliceDTRH. Any modifications made by ChatGPT may be subject to separate ownership rights.
The user acknowledges and agrees that the use of this script, or any modifications made to it, is at their own risk, and AliceDTRH and ChatGPT shall not be liable for any damages or losses that arise from its use.
"""
import os
import sys
import logging
from pathlib import Path
# Define default paths as constants
DEFAULT_WORKSHOP_DIR = Path(os.getenv("WORKSHOP_DIR", os.path.expanduser('~/.steam/steam/steamapps/workshop/content/108600')))
DEFAULT_MODS_DIR = Path(os.getenv("MODS_DIR", os.path.expanduser('~/GOG Games/Project Zomboid/Zomboid/mods/')))
def setup_logging():
# create a logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# create a formatter
formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
# create a handler for stdout
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setLevel(logging.INFO)
stdout_handler.setFormatter(formatter)
logger.addHandler(stdout_handler)
# create a handler for stderr
stderr_handler = logging.StreamHandler(sys.stderr)
stderr_handler.setLevel(logging.ERROR)
stderr_handler.setFormatter(formatter)
logger.addHandler(stderr_handler)
return logger
def main():
# Initialize logging
logger = setup_logging()
logger.warning("This script is provided as-is and is not fit for any particular purpose. Use it at your own risk.")
logger.warning("Copyright for the original work belongs to AliceDTRH. Any modifications made by ChatGPT may be "
"subject to separate ownership rights.")
logger.warning("The user acknowledges and agrees that the use of this script, or any modifications made to it,"
"is at their own risk, and AliceDTRH and ChatGPT shall not be liable for any damages or losses "
"that arise from its use.\n")
# Prompt user for workshop and mods directories
workshop_dir = input(f"Enter the workshop directory [{DEFAULT_WORKSHOP_DIR}]: ") or DEFAULT_WORKSHOP_DIR
mods_dir = input(f"Enter the mods directory [{DEFAULT_MODS_DIR}]: ") or DEFAULT_MODS_DIR
# Convert user input to Path objects
workshop_dir = Path(workshop_dir).resolve()
mods_dir = Path(mods_dir).resolve()
# Check if workshop_dir and mods_dir exist, print an error message and exit with a non-zero code if not.
if not workshop_dir.exists():
logger.error(f'The workshop directory "{workshop_dir}" does not exist. Exiting.')
sys.exit(1)
if not mods_dir.exists():
logger.error(f'The mods directory "{mods_dir}" does not exist. Exiting.')
sys.exit(1)
logger.info("Workshop folder: %s", workshop_dir.as_uri())
logger.info("Mods folder: %s", mods_dir.as_uri())
# For each workshop folder, iterate over its subdirectory named mods,
# and create a symbolic link for each content (folder) within that directory.
for workshop_folder in workshop_dir.iterdir():
if not workshop_folder.is_dir():
continue
logger.info("Found mod: %s", workshop_folder)
mod_folder = workshop_folder / "mods"
if not mod_folder.exists():
logger.warning("The mod %s has no mods folder. Skipping.", workshop_folder.name)
continue
for content in mod_folder.iterdir():
if not content.is_dir():
continue
new_content_path = mods_dir / content.name
try:
new_content_path.symlink_to(content, True)
logger.info("Linked %s to %s", content, new_content_path)
except FileExistsError:
logger.warning("%s already exists. Skipping.", new_content_path)
except PermissionError:
logger.warning("Permission denied while trying to create symlink at %s. Skipping.", new_content_path)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment