Uploading the active file

I beg for some inisights on this. Am new to UXP design. my problem is, I want to fetch the active document eg test.psd file and upload it to a backend server either using react or node. .well, am able to view the details of the active doc and the path for it’s location in my pc disk but when I use fs.readFile(documentPath, cb) nothing happens. I’ve gone through the documentation and I couldn’t see the process of reading / fetching file from disk mentioned anywhere. I appreciate the insights

Firstly, UXP uses a token system to work with file I/O:
https://developer.adobe.com/photoshop/uxp/2022/uxp/reference-js/Modules/uxp/Persistent%20File%20Storage/FileSystemProvider/

Secondly, without any code examples it’s hard to help you out, please include your problem code.
You could also wrap your code in a try/catch block and log errors to console to see where your code is falling over.

my problem is, what’s the equivalence of this in uxp.

> readFile('/etc/passwd', (err, data) => {
>   if (err) throw err;
>   console.log(data);
> });

I used to use it in cep to read a file from the local disk using the path and upload that file to an external api. I want to do this too on uxp but the documentation is not anywhere near to close explaining.

There’s file.read(). If the file is outside of the Plugin or Data folder, the user will have to select the file via file picker.

thankyou. let me get something from this. initially this is what I have


the current document which is labelled 3 is saved anywhere in my pc as per the user preferences. I want when the user clicks on upload current file labelled 2, the current active file opened is fetched from it’s location using the path I get from

app.activeDocument.path

now in the file read as per the documentation it’s this way ,

const data = await myNovel.read({format: formats.binary});

so am confused . where do I feed the path url. ?

initially this was my code and I had used it before in CEP and it worked but on UXP it doesn’t work

const app = require(‘photoshop’).app;
const fs = require(‘fs’);

let getFile = function (filePath) {
return new Promise(function (resolve, reject) {
fs.readFileSync(path, function (err, data) {
if (err) {
return reject(err)
}
return resolve(data)
})
})
}

async function uploadFile() {
console.log('app ', app);
const currentDocument = app.activeDocument;
let paths = currentDocument.path
const docSize = await getFile(paths)
// do anything with the returned file eg break it into chunks before upload
console.log('docSize:: ', docSize);

}

document.getElementById(“btnPopulate”).addEventListener(“click”, uploadFile);

CEP code won’t work in UXP - they’re entirely different APIs.

You need to use the approaches detailed in the storage.fileSystemProvider page of the docs already linked above to “get” the file, then you can use the file.read() to get the data.

  const localFile = await fs.getFileForOpening();
  const fileData = await localFile.read();
1 Like

oh thankyou. I found my way through it. last question on this, is there a way to make any of the plugin folder /create a folder in the plugin folder as a default folder for which the user files are saved ? Point is, when the user is working on a file and wants to upload the current document then I don’t want to initiate the filepicker because it’s unneccessary in this case. I just want to fetch the current working document in photoshop and upload it without the filepicker getting involved anywhere. I’ve clearly gone and tested all functions in the documentation here “https://developer.adobe.com/photoshop/uxp/2022/uxp/reference-js/Modules/uxp/Persistent%20File%20Storage/FileSystemProvider/” and all functions involve a file picker.

Sorry, I didn’t articulate myself very well there. What I should have said is that setting the default save location without also creating a token is potentially script breaking.
I would imagine that in your use case you’ll want to be using persistent tokens for that as you’d want the save path to be remembered each time PS/plugin is loaded.
I do this by writing my persistent tokens to a JSON file in the plugin data folder.

As for your save error - I’m not really familiar with the API DOM as I pretty exclusively use batchPlay so forgive me if I send you in the wrong direction - but would you not be wanting to use saveAs() in this instance rather than save()?

I don’t see how that would break the script. Nodejs has got that capability and I used it so much in the CEP.

Anyway, I understood you and tried what you said up there but I have one major issue, the file is not getting saved in my case. it throws a “wrong file format” problem in react. here is my simple code for that issue. I would be greatful if you helped me check what’s wrong with the saving. only the "activeDoc.save() method has got the issue. it’s not saving to the file in the temporary folder. unable to figure out the issue .
React Typescript

import React from ‘react’

import PS from ‘photoshop’
import uxp from ‘uxp’

import styles from ‘./styles.module.scss’

type saveAsModalPageProps = {
dialog: uxp.entrypoints.UXPDialog
}

const SaveAsModalPage: React.VFC = () => {
const fs = uxp.storage.localFileSystem
const activeDoc = PS.app.activeDocument
const docs: PS.Document = PS.app.documents
let createFile: object

if (docs.length === 0) {
PS.app.showAlert(‘file has to be saved first’)
return null
}

const uploadHandler = async () => {
let tempFolder: any
let title: any
try {
tempFolder = await fs.getTemporaryFolder()
title = activeDoc.title
createFile = await tempFolder.createFile(title, { overwrite: true })

  console.log('createFile  ', createFile)

  // @ts-ignore: Object is possibly 'null'.
  await activeDoc.save(createFile, {})
} catch (error) {
  console.log('error is ', error)
}

let tempFile: uxp.storage.Entry | undefined
let data: any

tempFile = (await tempFolder.getEntries()).find(
  (entry: { name: any }) => entry.name === title,
)

// @ts-ignore: Object is possibly 'null'.
data = await tempFile.read({ format: uxp.storage.formats.binary })

//Do other things with the file.  convert the file to a blob for upload.

console.log('temporay file  ', tempFile)
console.log('data is ', data)

}

return (



upload file{’ '}


)
}

export default moduleName

UXP isn’t Node, CEP, or even a browser despite feeling like all those things, and not everything that works in those environments works in UXP.
Fundamentally, unlike Node and CEP, UXP does not grant universal access to the local filesystem, hence the token system. If your user were to select a folder outside of the folders that are permissioned by default and you were not to create a token, then next time they try and use the script it’ll fail as it doesn’t have a token to access said folder.

As for your save, I’m not sure I can help you much as I don’t do React, TS, or really use the PS DOM.
Could it be that the file hasn’t been saved yet and doesn’t have a format as such? Hence my suggestion to try using the saveAs method. Like I said, I pretty much exclusively use batchPlay and so am not familiar with the methods you are using.
You could try batchPlay instead?