Saving smart objects through batchplay

Hi :slight_smile:
I’m creating a plugin that has to open, save and close a lot of smart objects, which takes a considerable amount of time when using the DOM.
As a result, I was trying to find a way to do it through batchplay, but I’m not sure how to ask the user for access to the AppData folder?
So far I managed to get the path to the temp folder, the name of each smart object, and I think I pretty much understand how to get a token to be used in batchplay. But I’m struggling with figuring out a way to get access to the temp folder.
Unless I’m doing something wrong, the domains that might be relevant aren’t supported. According to the fs.supportedDomains method, the only domains I can access are userDesktop, userDocuments and userPictures.

I also tried using the plugin’s temporary folder, but my code doesn’t seem to work. It saves the same smart object over and over again, and then closes both the smart object’s document and the document it was opened through.

async function SaveCloseDoc() {
  const doc = await batchPlay(
    [
      {
        "_obj": "get",
        "_target": [
          {
            "_ref": "document",
            "_enum": "ordinal",
            "_value": "targetEnum"
          }
        ],
        "_options": {
          "dialogOptions": "dontDisplay"
        }
      }
    ], {
    "synchronousExecution": false,
    "modalBehavior": "fail"
  });
  const fileTitle = doc[0].title;
  const docID = doc[0].documentID;

  const fileSystem = await require("uxp").storage.localFileSystem;
  const tempFolder = await fileSystem.getTemporaryFolder();
  const newFile = await tempFolder.createFile(fileTitle, { overwrite: true });
  const fileToken = await fileSystem.createSessionToken(newFile);

  await batchPlay(
    [
      {
        "_obj": "save",
        "in": {
          "_path": fileToken,
          "_kind": "local"
        },
        "saveStage": {
          "_enum": "saveStageType",
          "_value": "saveBegin"
        },
        "documentID": docID,
        "_isCommand": true,
        "_options": {
          "dialogOptions": "dontDisplay"
        }
      },
      {
        "_obj": "close",
        "documentID": docID,
        "forceNotify": true,
        "_isCommand": true,
        "_options": {
          "dialogOptions": "dontDisplay"
        }
      }
    ], {
    "synchronousExecution": false,
    "modalBehavior": "fail"
  });
}

What am I missing…? Is there a better way to go about saving a smart object?
Also, is there a way to ask the user to grant permission without opening the file picker, so they won’t be able to pick a different folder?

Thank you! :slight_smile: :slight_smile:

You can save a smart object that opens as a new document using APIs:

const app = require('photoshop').app;
const doc = app.activeDocument;
doc.save();
doc.close();

where doc is the “expanded” smart object document.

I know, that’s what I was initially doing, but I want to do it through batchplay in order to improve performance :slight_smile:

Is there a performance difference?

So far I did notice a difference between approaching tasks through the API as opposed to running them through batchplay, which was faster. So I’m hoping to accomplish the same thing by quickly saving the smart objects since the plugin might have to handle hundreds of them

Do you have some examples of bP vs. API performance?

I’ve seen better results when moving layers through batchplay instead of nudging them, although I’m not sure how significant that is. But especially when being able to avoid the process of selecting a layer and then performing some tasks on it. Instead, I use batchplay and reference the layer’s id.
I’m not 100% sure saving through batchplay would be faster, but I want to try it out in case it will