adobe-ps-scripts-loreal/extract_ids.py
DJP 4a192a8c97 Initial commit: Adobe Photoshop API text management scripts
Local and cloud-based workflows for extracting and updating
text layers in PSD files via ExtendScript and Adobe PS API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 13:46:52 -05:00

166 lines
No EOL
5 KiB
Python
Executable file

#!/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()