"""Convert text clippings to .txt files.""" import os import re import subprocess from pathlib import Path import plistlib DEREZ_OUTPUT_RE = re.compile(r"\t\$\"([A-F0-9 ]+)\"\s+/\* (.+?) \*/") def get_text_from_plist(path: Path) -> str: """Get the utf8 text of the plist.""" plist_dict = plistlib.loads(path.read_bytes()) return plist_dict["UTI-Data"]["public.utf8-plain-text"] def get_text_from_resourcefork(path: Path) -> str: """Get the utf8 text from the resource fork.""" cmd = ["DeRez", "-only", "utf8", str(path)] output = subprocess.run(cmd, capture_output=True) byte_str = b"" print(output.stdout) for line in output.stdout.split("\n"): if match := DEREZ_OUTPUT_RE.match(line): print("match") hex_str = match.groups()[0].replace(" ", "") byte_str += bytes.fromhex(hex_str) print(byte_str) return byte_str.decode("utf8") def convert_file(path: Path): """Convert a file.""" new_path = path.with_suffix(".txt") print(f"Converting {path} to {new_path}") if os.stat(path).st_size: # This can be handled with plistlib text = get_text_from_plist(path) else: # this needs DeRez text = get_text_from_resourcefork(path) if text: new_path.write_text(text) else: print(f"Did not get text from {path}") def main(path: Path): """Convert the clipping""" if path.is_dir(): # iterate through the dir for child in path.iterdir(): if child.is_file() and child.suffix == ".textClipping": convert_file(child) elif child.is_dir(): # main(path) pass else: print(f"Skipping file {child}") elif path.is_file() and path.suffix == ".textClipping": # process the file convert_file(path) else: print(f"No idea what to do with {path}.") if __name__ == "__main__": input_path = Path("/path/to/dir/") main(input_path)