Copy files and folders from network drive folder to local folder

Hello,

Is it possible to copy the files from the network drive to local folders using UXP API?

And also want the copy operation to run in background, parallelly to open the copied file in photoshop if the event triggered in the UXP UI

import { useState, useEffect } from 'react';
import { storage } from 'uxp';
import PS from 'photoshop'
 const fs =  require('uxp').storage.localFileSystem;
 const shell = require("uxp").shell;

const useImage = ({ onImageDownloaded }) => {
  const [requests, setRequests] = useState(0);
  const copyFile = async (networkUrl) => {
    try {
      const destinationPath = 'D:\\Testing\\Test\\Output';

      if (networkUrl) {

        const folderData = await fs.getEntryWithUrl(networkUrl);
        PS.core.showAlert(folderData)
        const copiedFile = await folderData.copyTo(destinationPath, { overwrite: true });

        if (onImageDownloaded) {
          onImageDownloaded(copiedFile);
        }

        PS.core.showAlert(`File copied successfully: ${networkUrl}`);
      } else {
        PS.core.showAlert('Storage or copyTo method not available in this context.');
      }
    } catch (error) {
      console.error('Error while copying:', error);
      PS.core.showAlert(`Failed to copy: ${networkUrl}`);
    }
  };

  useEffect(() => {
    if (requests > 0) {
      const networkUrl = '\\\\192.111.0.123\\Data\\BD\\20231016\\485277\\Input';

      copyFile(networkUrl);
    }
  }, [requests]);

  const requestImage = () => setRequests(requests + 1);

  return { requests, requestImage };
};

export default useImage;

//manisfest:

  "requiredPermissions": { 
    "clipboard": "readAndWrite",
    "network": { "domains": ["all"] },
    "localFileSystem": "fullAccess",
    "allowCodeGenerationFromStrings": true
  },


Im trying to copy the files and folder from the network drive but couldn’t able to access.

A similar issue is reported here. It may provide some clues to a solution.
Can’t access certain network drive when using localFileSystem.getEntryWithUrl

Maybe copying via fs module instead of localFileSystem is something to try.

  externals: {
    uxp: 'commonjs2 uxp',
    photoshop: 'commonjs2 photoshop',
    os: 'commonjs2 os',
    fs: 'commonjs2 fs'
  },

in webpack i added and tried but

      fs.readdir(networkPath, (err, files) => {
        if (err) {
            console.error('Error reading network folder:', err);
            return;
        }
Error:
Error reading network folder: Error: no such file or directory
    at u (uxp://uxp-internal/webfs_scripts.js:2)
    at uxp://uxp-internal/webfs_scripts.js:2

but not able to read the file from the network path

const { useState, useEffect } = require('react');
import fs from "fs";
import PS from 'photoshop';
const useImage = ({ onImageDownloaded }) => {
  const [requests, setRequests] = useState(0);
  const copyFileFromNetwork = async(networkPath, localPath) => {

    try {
      fs.readdir(networkPath, (err, files) => {
        if (err) {
            console.error('Error reading network folder:', err);
            return;
        }

        files.forEach(file => {
            const sourceFile = path.join(networkPath, file);
            const destinationFile = path.join(localPath, file);

           fs.copyFile(sourceFile, destinationFile, (err) => {
                if (err) {
                    console.error(`Error copying file ${file}:`, err);
                } else {
                    console.log(`File ${file} copied successfully.`);
                }
            });
        });
    });

      if (onImageDownloaded) {
        onImageDownloaded(localPath);
      }
    } catch (error) {
      console.error('Error while copying:', error);
      throw new Error(`Failed to copy from ${networkPath} to ${localPath}`);
    }
  };

  useEffect(async() => {
    if (requests > 0) {
      const networkPathFolder = '\\\\192.111.0.123\\Data\\BD\\20231016\\485277\\Input';
      const localPathFolder = 'D:\\Testing\\Test\\Output'; // Replace with your destination path

      await copyFileFromNetwork(networkPathFolder, localPathFolder);
    }
  }, [requests]);

  const requestImage = () => setRequests(requests + 1);

  return { requests, requestImage };
};

export default useImage;

After done changes in webpack, manifest to tried with fs modules it works copy the files locally, but copy the files from network drive to local folder it doesn’t support.

@Vijay_0106 I tried fs and confirmed that copying from a network drive to local always fails on Windows; it succeeds on macOS.

For the time being, it seems that you need to manually duplicate the file locally and then run it, or take some other way to do it.

@pkrishna I think you asked for data on the plugin that fails to copy in another past topic, so I have uploaded it to Google Drive.

import * as fs from 'fs/promises';

its supports in UXP?

UXP doesn’t support fs.promises.

but as the document explained if you didn’t give callback function, it returns promise.
so in case of dealing with like fs.promises, just skipping callback function.
this is bit tricky but Node’s one and UXP’one are slightly different.

// callback function
fs.readFile("file:/Users/user/Desktop/UXPScriptRegister/index.html", { encoding: 'utf-8'},(e, v) => {
        if (e) {
            console.log(e);
        } else {
            console.log('content', v);
        }
});

// returning promise skipping callback function
const data = await fs.readFile("file:/Users/user/Desktop/folder/index.html", { encoding: 'utf-8'});
console.log(data);// html contents
const { useState, useEffect } = require('react');
import * as fs from "fs";
import * as path from "path";
import PS from 'photoshop';

const useimage= ({ onImageDownloaded }) => {
  const [requests, setRequests] = useState(0);
  const copyFileFromNetwork = async(networkPath: string, localPath: string) => {

    try {
      await fs.readdir(networkPath, (err, files) => {
        console.log("in")
        if (err) {
            console.error('Error reading network folder:', err);
            return;
        }

        files.forEach(file => {
            const sourceFile = path.join(networkPath, file);
            const destinationFile = path.join(localPath, file);
            PS.core.showAlert(destinationFile)
            fs.copyFile(sourceFile, destinationFile, (err) => {
                if (err) {
                    console.error(`Error copying file ${file}:`, err);
                } else {
                    console.log(`File ${file} copied successfully.`);
                }
            });
        });
    });

      if (onImageDownloaded) {
        onImageDownloaded(localPath);
      }
    } catch (error) {
      console.error('Error while copying:', error);
      throw new Error(`Failed to copy from ${networkPath} to ${localPath}`);
    }
  };

  useEffect(async() => {
    if (requests > 0) {
      const networkPathFolder = 'file:\\Y:\\ER\\20231016\\23444\\Test';
      const localPathFolder = 'D:\\Testing\\Test\\Output'; // Replace with your destination path

      await copyFileFromNetwork(networkPathFolder, localPathFolder);
    }
  }, [requests]);

  const requestImage = () => setRequests(requests + 1);

  return { requests, requestImage };
};

export default useimage;

The above code is working while save as .js file, if i convert this into typescript file its not working fs.readir() not working why?

Do you use webpack? Sometimes you have to explain to webpack how to handle native modules.

    externals: {
      photoshop: 'commonjs2 photoshop',
      uxp: 'commonjs2 uxp',
      os: 'commonjs2 os',
      fs: 'commonjs2 fs'

    },

I included the fs in the webpack to fs module allow to work

And you have it like this and still not working?

yes, inside the readdir callback function nothing will work @Jarda

Well, typescript generates JS file. So you can debug the JavaScript in DevTools and see what is in and where it fails.

i tried that also add the debugger inside the readdir() function, it is not debugging in the dev tool also, its weird.

can you compare the JS code you wrote and the TS-generated JS? What is different? How far can you get in DevTool before it fails?

code written in JS and ts both are similar, but webpack converted JS is quite different right?

try {
      fs.readdir(networkPath, (err, files) => {
**************** from here itself nothing works **************
        if (err) {
            console.error('Error reading network folder:', err);
            return;
        }

        files.forEach(file => {
            const sourceFile = path.join(networkPath, file);
            const destinationFile = path.join(localPath, file);

           fs.copyFile(sourceFile, destinationFile, (err) => {
                if (err) {
                    console.error(`Error copying file ${file}:`, err);
                } else {
                    console.log(`File ${file} copied successfully.`);
                }
            });
        });
    });

      if (onImageDownloaded) {
        onImageDownloaded(localPath);
      }
    } catch (error) {
      console.error('Error while copying:', error);
      throw new Error(`Failed to copy from ${networkPath} to ${localPath}`);
    }
  };

What do you see if you are right before fs.readdir and type console.log(fs.readdir) ?

its worked when I changed to

const files = fs.readdirSync(networkPath);

but why its not working asynchronously as typescript file.