Skip to content

Instantly share code, notes, and snippets.

@lolipopshock
Created December 30, 2020 19:45
Show Gist options
  • Save lolipopshock/5aa5e2a87c5044e8f5edd49abed54e1a to your computer and use it in GitHub Desktop.
Save lolipopshock/5aa5e2a87c5044e8f5edd49abed54e1a to your computer and use it in GitHub Desktop.
A Python script for creating plist files in macOS systems interactively.
import os
import plistlib
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--META_NAME", type=str, default="programName")
parser.add_argument("--LOG_PATH", type=str, default="/var/log/programName")
class PlistTemplate:
META_NAME = "programName"
LOG_PATH = "/var/log/programName"
TEMPLATE = {
"Name": lambda cls, data: None,
"Label": lambda cls, data: f"{cls.META_NAME}.{data['Name']}",
"RunAtLoad": True,
"KeepAlive": True,
"WorkingDirectory": os.path.expanduser("~"),
"StandardOutPath": lambda cls, data: f"{cls.LOG_PATH}/{data['Name']}.out",
"StandardErrorPath": lambda cls, data: f"{cls.LOG_PATH}/{data['Name']}.err",
"EnvironmentVariables": os.environ["PATH"],
"ProgramArguments": lambda cls, data: None,
"SavePath": lambda cls, data: f"{data['Name']}.plist",
}
def __init__(self, data):
self._data = data
def export(self, filename):
with open(filename, "wb") as fp:
plistlib.dump(self._data, fp)
@classmethod
def from_interactive(cls):
data = {}
for key, val in cls.TEMPLATE.items():
default = val(cls, data) if callable(val) else val
while True:
user_input = input(
f"{key}" + (f"({default})" if default is not None else "") + ": "
)
if user_input == "":
if default is not None:
user_input = default
break
else:
print(
f"There's no default value for {key}. Please type a valid value."
)
elif key == "ProgramArguments":
user_input = user_input.strip().split(" ")
break
data[key] = user_input
data.pop("Name")
filename = data.pop("SavePath")
cls(data).export(filename)
if __name__ == "__main__":
args = parser.parse_args()
while True:
print("Easily creating plist files.")
PlistTemplate.META_NAME = args.META_NAME
PlistTemplate.LOG_PATH = args.LOG_PATH
PlistTemplate.from_interactive()
while True:
x = input("Continue ? [Y/N]")
x = x.lower()
if x == "y":
break
elif x == "n":
exit()
else:
print("Invalid choice")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment