Created
August 6, 2025 06:06
-
-
Save error454/bacf9f5a1f8af700262b349567c32bbb to your computer and use it in GitHub Desktop.
Vibe coded logic session parser to print out a list of 3rd party and native plugins in the session
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
parseLogicSession.py | |
------------------ | |
1. Extract Logic Pro version/build from Resources/ProjectInformation.plist | |
2. Extract 3rd party and native plug-in names from Alternatives/000/ProjectData | |
Based on a pretty limited understanding and reverse engineering of a single logic session file. | |
Usage: | |
python parseLogicSession.py /path/to/LogicPro.app | |
python parseLogicSession.py /path/to/MySong.logicx | |
""" | |
from __future__ import annotations | |
import argparse | |
import re | |
import sys | |
from pathlib import Path | |
# ---------- VERSION / BUILD (ProjectInformation.plist) ------------------------ | |
_PLIST_PATTERN = re.compile(rb"Logic Pro ([^)]*\))") # captures "11.1.2 (6162)" | |
def extract_version_build(root: Path) -> tuple[str | None, str | None]: | |
"""Return (version, build) or (None, None) if not found.""" | |
plist = root / "Resources" / "ProjectInformation.plist" | |
if not plist.is_file(): | |
return None, None | |
data = plist.read_bytes() | |
m = _PLIST_PATTERN.search(data) | |
if not m: | |
return None, None | |
text = m.group(1).decode("ascii", errors="ignore") | |
m2 = re.fullmatch(r"([\d.]+)\s*\(([^)]+)\)", text) | |
return (m2.group(1), m2.group(2)) if m2 else (None, None) | |
# ---------- PLUG-IN LIST (ProjectData) ---------------------------------------- | |
_MARKER = b"46ia" | |
_OFFSET = 0x2e # bytes before marker | |
def extract_3rd_party_plugins(root: Path) -> list[str]: | |
"""Return sorted, deduplicated list of plug-in names found.""" | |
pdata = root / "Alternatives" / "000" / "ProjectData" | |
if not pdata.is_file(): | |
return [] | |
blob = pdata.read_bytes() | |
size = len(blob) | |
index = 0 | |
names = set() | |
# 3rd party plugins | |
while True: | |
idx = blob.find(_MARKER, index) | |
if idx == -1: | |
break | |
pos = idx - _OFFSET | |
end = blob.find(0, pos) | |
if end == -1: | |
break | |
raw = blob[pos:end].decode("utf-8", errors="ignore").strip() | |
if raw: | |
names.add(raw) | |
index = idx + 1 # continue searching | |
return sorted(names, key=str.lower) | |
_MARKERNATIVE = b"default.pst" | |
_OFFSETNATIVE = 0x5e # bytes before marker | |
def extract_native_plugins(root: Path) -> list[str]: | |
"""Return sorted, deduplicated list of native plug-in names found.""" | |
pdata = root / "Alternatives" / "000" / "ProjectData" | |
if not pdata.is_file(): | |
return [] | |
blob = pdata.read_bytes() | |
size = len(blob) | |
index = 0 | |
names = set() | |
# 3rd party plugins | |
while True: | |
idx = blob.find(_MARKERNATIVE, index) | |
if idx == -1: | |
break | |
pos = idx + len(_MARKERNATIVE) + _OFFSETNATIVE | |
end = blob.find(0, pos) | |
if end == -1: | |
break | |
raw = blob[pos:end].decode("utf-8", errors="ignore").strip() | |
if raw: | |
names.add(raw) | |
index = idx + 1 # continue searching | |
return sorted(names, key=str.lower) | |
# ---------- MAIN ---------------------------------------------------------------- | |
def main() -> None: | |
parser = argparse.ArgumentParser( | |
description="Print Logic Pro version/build and plug-in list." | |
) | |
parser.add_argument("folder", help="Path to .app bundle or .logicx project") | |
args = parser.parse_args() | |
root = Path(args.folder).expanduser() | |
if not root.exists(): | |
sys.exit(f"Error: {root} does not exist.") | |
# Version / build | |
version, build = extract_version_build(root) | |
if version: | |
print(f"Logic Pro version : {version}") | |
print(f"Build number : {build}\n") | |
else: | |
print("• ProjectInformation.plist not found (skipping version/build).\n") | |
# Plug-ins | |
plugins = extract_3rd_party_plugins(root) | |
if plugins: | |
print("3rd Party Plug-ins:") | |
for name in plugins: | |
print(f" {name}") | |
else: | |
print("• No 3rd party plug-in names found (check ProjectData heuristic or file path).") | |
plugins = extract_native_plugins(root) | |
if plugins: | |
print("Native Plug-ins:") | |
for name in plugins: | |
print(f" {name}") | |
else: | |
print("• No plug-in names found (check ProjectData heuristic or file path).") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment