• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How to locate current_document property using Appscript in Python for Photoshop 2022

Community Beginner ,
Jan 17, 2022 Jan 17, 2022

Copy link to clipboard

Copied

I (foolishly) upgraded to Mac OSX Monterey, which in turn forced me to upgrade my Photoshop version to Photoshop 2022.

With Photoshop CC 2018 I used the following python code to get a specific layer by name:

 

from appscript import *

self.psApp = app('/Applications/Adobe Photoshop CC 2018/Adobe Photoshop CC 2018.app')

for layer_set in self.psApp.current_document.layer_sets():
    for group in layer_set.layers.get():
        if group.name() == "image_1":
            return group

 

Which worked great! Docs can be found here by the way.

But, when using the same code and replacing Adobe Photoshop CC 2018 with Adobe Photoshop 2022 I get an 'Unknown Property' error:

 

AttributeError: Unknown property, element or command: 'current_document'

 

And I can't get anything else to work anymore, the 'current_document' property seems to be gone or maybe renamed?

 

Any help would be greatly appreciated. The documentation for this is pretty much non-existent unfortunately.

Thanks in advance!

TOPICS
Actions and scripting , macOS

Views

350

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Community Expert ,
Jan 17, 2022 Jan 17, 2022

Copy link to clipboard

Copied

You obviously have a need to do this through Python, I can't help with that.

 

AppleScript can run JavaScript, so you maybe you could use JS:

 

var selectLayer1 = app.activeDocument.artLayers.getByName("Layer 1");
app.activeDocument.activeLayer = selectLayer1;

 

Or:

 

app.activeDocument.activeLayer = app.activeDocument.layers["Layer 1"];

 

 

As the AS wraps the JS in double quotes, any double quotes in the JS need to be escaped with a \ backslash:

 

tell application "Adobe Photoshop 2022"
	
	set js to "app.activeDocument.activeLayer = app.activeDocument.layers[\"Layer 1\"];"
	
	do javascript js
end tell

 

 

EDIT: Or you could change double quotes in the JS to use single open/close quotes so that there is no conflict with the double quotes used in the AS.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 17, 2022 Jan 17, 2022

Copy link to clipboard

Copied

Hi Stephen,

Thank you so much for your answer! I didn't know I could pass javascript to Photoshop with Applescript like that!

I am actually already able to send Applescript via python, I'll post it here for anybody else who wants to know how to do that:

from subprocess import Popen, PIPE

def run_appscript(self, script):
	p = Popen(['osascript', '-'], stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True)
		stdout, stderr = p.communicate(script)

# example
def quit_photoshop(self):
      self.run_appscript('tell application "Adobe Photoshop 2022" to quit')

 

The only thing i'd miss is a way to communicate back from Photoshop to my Python/Applescript script. For example, if I want to get the name of a layer and use that later on in my script. Would you perhaps know a way to do so? 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 17, 2022 Jan 17, 2022

Copy link to clipboard

Copied

Sorry, I'm only a beginner in using JavaScript with Adobe apps and I don't know AppleScript or Python.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 17, 2022 Jan 17, 2022

Copy link to clipboard

Copied

No problem, thank you for your help! I'll wait a bit to see if others might come up with something else but otherwise I'll mark your anwser as the correct one as it potentially could be a workaround

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 17, 2022 Jan 17, 2022

Copy link to clipboard

Copied

I obviously know how to get the layer name as a variable in JS, but I have no idea with the extra complexity that you have with adding two other scripting langauages into the mix – I find one language hard enough!

 

What are you doing in/with Python that can't be achieved using AS or JS?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 17, 2022 Jan 17, 2022

Copy link to clipboard

Copied

I think I'm going to solve it by making the js write data to a temporary js file that I can in turn read with my python application, quite the workaround but it's looking like the only option to get information back out from photoshop.

I have a bigger application that runs on Python, it does a lot of stuff and one of the things is generating a .png file that has to have a specific combination of images at specific spots. The logic for when to generate a png and what files need to be in there is determined within the python application. Data is stored and read from a remote database and the image gets processed and uploaded via an API, it can't really be done with just applescript and javascript. Not by me anyway 🙂

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 18, 2022 Jan 18, 2022

Copy link to clipboard

Copied

Thank you for the explanation.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jun 23, 2023 Jun 23, 2023

Copy link to clipboard

Copied

Hey,

(Sorry about the necromancy)

 

Seems appscript can't pick up Photoshop's scripting definition anymore, and unfortunately appscript official development ended development many moons ago, so there's likely to be no fix for this.

 

One alternative is to use the PyObjC Python module to access Apple's ScriptingBridge for Objective-C. This is clunky, since you are effectively writing Objective-C code, but "translated" into Python, but it gets the job done and this is the solution I'm currently using.

 

Some sample code to get you started, here's how you could do what you wanted above:

from ScriptingBridge import SBApplication

class YourClass:
    def some_method(self):
        self.psApp = SBApplication.applicationWithBundleIdentifier_("com.adobe.Photoshop")
        for layer_set in self.psApp.currentDocument().layerSets():
            for group in layer_set.layers().get():
                if group.name() == "image_1":
                    return group

 

Photoshop Specific Limitations:

All the AppleScript commands are wrapped, but some may not be functional due to limitations of the "rules" of ScriptingBridge. For example, the "open" command is broken, since all possible arguments must be specified, and the "open options" argument requires a reference to a class that cannot be instantiated in ScriptingBridge. Luckily you can still use the "do javascript" function to open files, or the "open -a {photoshop} {file}" shell command.

 

(Py)Objective-C "Quirks":

Translation between Objective-C and Python makes your code super verbose. For example:

AppleScript:
do javascript [script] [arguments] [open options] [show debugger]

Python:
doJavascript_withArguments_showDebugger_(script, arguments, int.from_bytes(b'Nevr'))

Some (lots) of functions will need magic enum numbers from the Photoshop sdef file (like the b'Nevr' above). You can reference those by opening Script Editor, opening the Photoshop scripting dictionary, and then File -> Save As, open the file you just saved with a text editor, and you'll be able to see the values you need for each function.

 

I won't babble on more, but for Photoshop scripting this is seems like the most usable option now that appscript is dead.

 

Here's an old Apple doc explaining most things.

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/RubyPythonCocoa/Articles/...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jun 23, 2023 Jun 23, 2023

Copy link to clipboard

Copied

LATEST

Ah just been looking around at the source for appscript and found this. Do not use ScriptingBridge lol. You can get appscript working with modern Photoshop versions by using the "terms" argument in the constructor:

from appscript import app

app(photoshop_path, terms="sdef")

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines