#!/usr/bin/env python3 """ Extract Internal Layer IDs This script runs the ExtendScript to extract internal layer IDs from a PSD file and saves the result as a JSON file. This is critical for correctly identifying text layers when using the Adobe Photoshop API. Usage: python extract_ids.py /path/to/file.psd """ import os import sys import subprocess import json import argparse from pathlib import Path def run_extract_script(psd_path): """ Run the ExtendScript to extract internal layer IDs Args: psd_path: Path to the PSD file Returns: Path to the generated JSON file """ # Get the absolute path to the PSD file psd_path = os.path.abspath(psd_path) # Check if the file exists if not os.path.exists(psd_path): print(f"Error: PSD file not found: {psd_path}") return None # Get the path to the JSX script script_dir = os.path.dirname(os.path.abspath(__file__)) jsx_path = os.path.join(script_dir, "test", "extract_internal_ids.jsx") # Check if the script exists if not os.path.exists(jsx_path): print(f"Error: JSX script not found: {jsx_path}") return None # Create the AppleScript to run the JSX script in Photoshop applescript = f""" tell application "Adobe Photoshop" activate open POSIX file "{psd_path}" do javascript file "{jsx_path}" end tell """ # Create a temporary AppleScript file temp_as_path = os.path.join(script_dir, "temp_extract_ids.scpt") try: # Write the AppleScript to a temporary file with open(temp_as_path, "w") as f: f.write(applescript) # Run the AppleScript print(f"Opening {os.path.basename(psd_path)} in Photoshop...") print(f"Running ExtendScript to extract internal layer IDs...") result = subprocess.run( ["osascript", temp_as_path], capture_output=True, text=True ) if result.returncode != 0: print(f"Error running AppleScript: {result.stderr}") return None # Check for the output JSON file psd_dir = os.path.dirname(psd_path) psd_name = os.path.basename(psd_path).replace('.psd', '') json_path = os.path.join(psd_dir, f"{psd_name}_internal_ids.json") if os.path.exists(json_path): print(f"Successfully extracted internal layer IDs to: {json_path}") return json_path else: print(f"Warning: JSON output file not found at expected location: {json_path}") return None except Exception as e: print(f"Error: {str(e)}") return None finally: # Clean up the temporary AppleScript file if os.path.exists(temp_as_path): os.remove(temp_as_path) def analyze_layer_ids(json_path): """ Analyze the extracted layer IDs Args: json_path: Path to the JSON file with layer data Returns: None """ if not json_path or not os.path.exists(json_path): print("No JSON file to analyze") return try: # Load the JSON data with open(json_path, 'r') as f: data = json.load(f) # Extract the text layers text_layers = data.get('textLayers', []) if not text_layers: print("No text layers found in the document") return print(f"\nFound {len(text_layers)} text layers in the document:") print("=" * 70) # Print layer information print(f"{'Layer Name':<30} {'Direct ID':<10} {'Internal ID':<12} {'Text Content':<40}") print("-" * 70) for layer in text_layers: name = layer.get('name', 'Unknown') direct_id = layer.get('id', 'N/A') internal_id = layer.get('internalID', 'N/A') text = layer.get('text', 'No text') # Truncate long text for display if len(text) > 30: text = text[:27] + "..." # Replace linebreaks for display text = text.replace('\r', '\\r') print(f"{name:<30} {direct_id:<10} {internal_id:<12} {text:<40}") print("\nIMPORTANT: Use the Internal IDs when calling the Adobe Photoshop API") print(" These are the IDs that the API uses to identify text layers") except Exception as e: print(f"Error analyzing layer IDs: {str(e)}") def main(): # Parse command-line arguments parser = argparse.ArgumentParser(description="Extract internal layer IDs from a PSD file") parser.add_argument("psd_file", help="Path to the PSD file") args = parser.parse_args() # Run the extraction script json_path = run_extract_script(args.psd_file) # Analyze the results analyze_layer_ids(json_path) if __name__ == "__main__": main()