mirror of
https://github.com/NohamR/pyzule-rw.git
synced 2026-10-11 02:49:40 +00:00
feat: plist operations
This commit is contained in:
@@ -35,7 +35,7 @@ then finally, to install or update cyan, just `pip install --force-reinstall git
|
|||||||
|
|
||||||
[x] refactor: dont prepare, just copy and fix as you go
|
[x] refactor: dont prepare, just copy and fix as you go
|
||||||
|
|
||||||
[2] feat: plist operations (-n, -v, -b, -m, -l, -r)
|
[x] feat: plist operations (-l and -r wont be implemented)
|
||||||
|
|
||||||
[x] feat: remove watch app
|
[x] feat: remove watch app
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,22 @@ def main() -> None:
|
|||||||
"-f", metavar="file", nargs="+",
|
"-f", metavar="file", nargs="+",
|
||||||
help="a tweak to inject/item to be added to the bundle"
|
help="a tweak to inject/item to be added to the bundle"
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-n", metavar="name",
|
||||||
|
help="modify the app's name"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-v", metavar="version",
|
||||||
|
help="modify the app's version"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-b", metavar="bundle id",
|
||||||
|
help="modify the app's bundle id"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-m", metavar="minimum",
|
||||||
|
help="modify the app's minimum OS version"
|
||||||
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-u", "--remove-supported-devices", action="store_true",
|
"-u", "--remove-supported-devices", action="store_true",
|
||||||
@@ -71,7 +87,7 @@ def main() -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-v", "--version", action="version", version="cyan v1.0"
|
"--version", action="version", version="cyan v1.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
from cyan import logic
|
from cyan import logic
|
||||||
|
|||||||
@@ -47,6 +47,14 @@ def main(parser: ArgumentParser) -> None:
|
|||||||
|
|
||||||
if args.f is not None:
|
if args.f is not None:
|
||||||
app.executable.inject(args.f, tmpdir)
|
app.executable.inject(args.f, tmpdir)
|
||||||
|
if args.n is not None:
|
||||||
|
app.plist.change_name(args.n)
|
||||||
|
if args.v is not None:
|
||||||
|
app.plist.change_version(args.v)
|
||||||
|
if args.b is not None:
|
||||||
|
app.plist.change_bundle_id(args.b)
|
||||||
|
if args.m is not None:
|
||||||
|
app.plist.change_minimum_version(args.m)
|
||||||
|
|
||||||
if args.remove_supported_devices:
|
if args.remove_supported_devices:
|
||||||
app.plist.remove_uisd()
|
app.plist.remove_uisd()
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from .plist import Plist
|
|||||||
class AppBundle:
|
class AppBundle:
|
||||||
def __init__(self, path: str):
|
def __init__(self, path: str):
|
||||||
self.path = path
|
self.path = path
|
||||||
self.plist = Plist(f"{path}/Info.plist")
|
self.plist = Plist(f"{path}/Info.plist", path)
|
||||||
|
|
||||||
self.executable = Executable(
|
self.executable = Executable(
|
||||||
f"{path}/{self.plist['CFBundleExecutable']}",
|
f"{path}/{self.plist['CFBundleExecutable']}",
|
||||||
|
|||||||
@@ -1,16 +1,23 @@
|
|||||||
import sys
|
import sys
|
||||||
import plistlib
|
import plistlib
|
||||||
from typing import Any
|
from glob import glob
|
||||||
|
from typing import Optional, Any
|
||||||
|
|
||||||
class Plist:
|
class Plist:
|
||||||
def __init__(self, path: str):
|
def __init__(
|
||||||
|
self, path: str, app_path: Optional[str] = None, throw: bool = True
|
||||||
|
):
|
||||||
try:
|
try:
|
||||||
with open(path, "rb") as f:
|
with open(path, "rb") as f:
|
||||||
self.data: dict[str, Any] = plistlib.load(f)
|
self.data: dict[str, Any] = plistlib.load(f)
|
||||||
except Exception:
|
except Exception:
|
||||||
sys.exit(f"[!] couldn't read {path}")
|
if throw:
|
||||||
|
sys.exit(f"[!] couldn't read {path}")
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
self.path = path
|
self.path = path
|
||||||
|
self.app_path = app_path
|
||||||
|
|
||||||
def __getitem__(self, key: str) -> Any:
|
def __getitem__(self, key: str) -> Any:
|
||||||
return self.data.get(key, None)
|
return self.data.get(key, None)
|
||||||
@@ -25,33 +32,89 @@ class Plist:
|
|||||||
def remove(self, key: str) -> bool:
|
def remove(self, key: str) -> bool:
|
||||||
try:
|
try:
|
||||||
del self.data[key]
|
del self.data[key]
|
||||||
|
self.save()
|
||||||
return True
|
return True
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def change(self, key: str, val: Any) -> bool:
|
def change(self, val: Any, *keys: str) -> bool:
|
||||||
try:
|
try:
|
||||||
if self[key] == val:
|
if all(self[key] == val for key in keys):
|
||||||
return False
|
return False
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self[key] = val
|
for key in keys:
|
||||||
|
self[key] = val
|
||||||
|
|
||||||
|
self.save()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def remove_uisd(self) -> None:
|
def remove_uisd(self) -> None:
|
||||||
if self.remove("UISupportedDevices"):
|
if self.remove("UISupportedDevices"):
|
||||||
self.save()
|
|
||||||
print("[*] removed UISupportedDevices")
|
print("[*] removed UISupportedDevices")
|
||||||
else:
|
else:
|
||||||
print("[?] no UISupportedDevices")
|
print("[?] no UISupportedDevices")
|
||||||
|
|
||||||
def enable_documents(self) -> None:
|
def enable_documents(self) -> None:
|
||||||
c1 = self.change("UISupportsDocumentBrowser", True)
|
c1 = self.change(True, "UISupportsDocumentBrowser")
|
||||||
c2 = self.change("UIFileSharingEnabled", True)
|
c2 = self.change(True, "UIFileSharingEnabled")
|
||||||
|
|
||||||
if c1 or c2:
|
if c1 or c2:
|
||||||
self.save()
|
|
||||||
print("[*] enabled documents support")
|
print("[*] enabled documents support")
|
||||||
else:
|
else:
|
||||||
print("[?] documents support was already enabled")
|
print("[?] documents support was already enabled")
|
||||||
|
|
||||||
|
def change_name(self, name: str) -> None:
|
||||||
|
if self.change("CFBundleName", "CFBundleDisplayName", name):
|
||||||
|
print(f"[*] changed name to \"{name}\"")
|
||||||
|
changed = 0
|
||||||
|
|
||||||
|
for lproj in glob(f"{self.app_path}/*.lproj"):
|
||||||
|
try:
|
||||||
|
pl = Plist(f"{lproj}/InfoPlist.strings", None, False)
|
||||||
|
pl["CFBundleDisplayName"] = name
|
||||||
|
pl["CFBundleName"] = name
|
||||||
|
pl.save()
|
||||||
|
changed += 1
|
||||||
|
except Exception:
|
||||||
|
pass # file might not exist
|
||||||
|
|
||||||
|
if changed != 0:
|
||||||
|
print(f"[*] changed \033[96m{changed}\033[0m localized names")
|
||||||
|
else:
|
||||||
|
print(f"[?] name was already \"{name}\"")
|
||||||
|
|
||||||
|
def change_version(self, version: str) -> None:
|
||||||
|
if self.change("CFBundleVersion", "CFBundleShortVersionString", version):
|
||||||
|
print(f"[*] changed version to \"{version}\"")
|
||||||
|
else:
|
||||||
|
print(f"[?] version was already \"{version}\"")
|
||||||
|
|
||||||
|
def change_bundle_id(self, bundle_id: str) -> None:
|
||||||
|
orig = self["CFBundleIdentifier"]
|
||||||
|
|
||||||
|
if self.change("CFBundleIdentifier", bundle_id):
|
||||||
|
print(f"[*] changed bundle id to \"{bundle_id}\"")
|
||||||
|
changed = 0
|
||||||
|
|
||||||
|
# change all other bundle ids
|
||||||
|
for ext in glob(f"{self.app_path}/*/*.appex"):
|
||||||
|
try:
|
||||||
|
pl = Plist(f"{ext}/Info.plist", None, False)
|
||||||
|
current = pl["CFBundleIdentifier"]
|
||||||
|
pl["CFBundleIdentifier"] = current.replace(orig, bundle_id)
|
||||||
|
pl.save()
|
||||||
|
changed += 1
|
||||||
|
except Exception:
|
||||||
|
pass # how tf would it not exist? idk
|
||||||
|
|
||||||
|
if changed != 0:
|
||||||
|
print(f"[*] changed \033[96m{changed}\033[0m other bundle ids")
|
||||||
|
else:
|
||||||
|
print(f"[?] bundle id was already \"{bundle_id}\"")
|
||||||
|
|
||||||
|
def change_minimum_version(self, minimum: str) -> None:
|
||||||
|
if self.change("MinimumOSVersion", minimum):
|
||||||
|
print(f"[*] changed minimum version to \"{minimum}\"")
|
||||||
|
else:
|
||||||
|
print(f"[?] minimum version was already \"{minimum}\"")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user