Best way to copy a directory from an external drive to a local folder with electronjs? - node.js

Just wondering if anyone has ever attempted to copy a directory from an external drive (connected via USB) to a local folder.
I am using ElectronJS so I can use my JavaScript, HTML/CSS skills to create a desktop application without utilising a C language. (i.e. C# or C++) With ElectronJS there's a lot less to worry about.
Here is the list of things I've tried so far:
basic fs.copyFile (using copyFile intially and will then loop round the directory to copy all files)
var fs = require('fs');
window.test = () => {
fs.moveSync("targetFile","destDir", function(err) {
if(err){
console.log(err);
}else{
console.log("copy complete")
}
});
}
fs.moveSync is not a function even though Visual Studio Code brought up moveSync as a suggestion when I entered fs. (ctrl + space)
using child_process functions to copy files using the command line.
Code is:
var process = require('child_process')
window.test = function(){
process.exec('ipconfig', function(err, stdout, stderr){
if(err){
console.log(err);
}else{
console.log(stdout)
}
})
}
Then bundled with browserify. Bundle.js is then imported into the html file and the test function is called on the click of a button. I'm aware the command is ipconfig for now, this was merely used to see if a command could be executed. It appears it could because I was getting process.exec is not defined.
use the node-hid node module to read and trasfer data from the external drive.
The exposed functions within this module were also reported as being undefined. And I thought about the use case longer I thought a simple copy process would suffice because external drive can be accessed like any other folder in the file explorer.
Unfortunately, all of the above have failed and I've spent the most part of the day looking for alternative modules and/or solutions.
Thanks in advance because any help to achieve this would be much appreciated.
Thanks
Patrick

The npm package fs-extra should solve your problem.
It has the move function, which
Moves a file or directory, even across devices

Ended up adding this to my preload.js for:
window.require = require;
It will work for now but is due to be depreciated.
I'll use this for now and make other updates when I have to.

Related

Where is my Electron App located

I have an electron app, that also operates on files in the same directory. These are not files the user selects, or files bundled inside the electron application, but I do need to reference them
for example:
/Users/test/Documents/myapp.app
/Users/test/Documents/example.zip
I need to know where that application is located, e.g.:
/Users/test/Documents
But instead when test.app is ran I get:
/Users/test/Documents/myapp.app/Contents/Resources/app/
Resulting in errors when it tries to access /Users/test/Documents/myapp.app/Contents/Resources/app/test.zip, or if I use a relative path, /test.zip.
How would I reliably access example.zip in this scenario? Note that I cannot bundle it with my app, it's being placed there by somebody else, so moving it is not an option, and it's a file I'm expecting to be there.
A friend and I looked up how Atom does it and arrived at this solution:
function getAppRoot() {
if ( process.platform === 'win32' ) {
return path.join( app.getAppPath(), '/../../../' );
} else {
return path.join( app.getAppPath(), '/../../../../' );
}
}
I think either app.getPath('exe') or process.execPath is what you are looking for. They both give you the path of the currently used executable.
Edit: Look at the docs for app.getPath() to get the paths of all the different folder (e.g. home, appdata, documents, etc.)
Where are you running the Electron App? If it is running under 'Documents' (I am assuming Windows), you can pass in the documents to app.getPath like so: app.getPath('documents').
If you are calling this from the render process, you might have to import remote and do the following if you are in a render process remote.app.getPath('documents');.
This electron doc will be better at explaining the path options you can pass in.
You can use the fs.readdir function to list all the files that are in a particular directory (could be your app's or anywhere). You can make a directory from the code to put all the new files so it would be easier for you to list them out properly to process.
const testFolder = './tests/';
const fs = require('fs');
fs.readdir(testFolder, (err, files) => {
files.forEach(file => {
console.log(file);
});
});
How do you get a list of the names of all files present in a directory in Node.js?

Using the exec method in Node.js

I have been following a series of tutorials on Node.js. To demonstrate child processes using exec, I have been given the code below under the file of exec.js When I go to the command line for node, I type in
node exec.js
then nothing happens. Why would this be?
var exec = require("child_process").exec;
exec("open http://www.linkedin.com");
Your code works for me.
To diagnose and fix this, I would try:
In your terminal (not using Node), verify that open http://www.linkedin.com works at all. You should see your default web browser open to the appropriate URL. If that doesn't happen, then Node can't magically fix it. Most likely, you'll need to set the default browser.
Wrap the URL in single quotes just for good measure. This protects you in some cases where the URL contains certain reserved characters.
exec("open 'http://www.linkedin.com'");
Add a callback so you can see the command's output and verify it completed successfully.
exec("open 'http://www.linkedin.com'", function (err, stdout, stderr) {
console.log('err:', err);
console.log('stdout:', stdout);
console.log('stderr:', stderr);
});
The ideal solution is to use opn, a high-quality module that already exists for this exact purpose.
For Windows, use the start command instead of open (which is for Mac) as below:
exec("start http://www.linkedin.com");

node.js issues with Meteor's file system

I have tried to figure out what i am missing from this puzzle between. Node.js and Meteor.js. Meteor is built on Node.js i know this. But Meteor doesn't not work properly with Node.js. Either I need to do 20 more steps to get the same result, which I don't know what they are. Or there is a serious bug between the two. Standalone Node.js runs the command below just fine. Running the same commands on Meteor cause errors or undefined results. Wish i had a why to solve this or they need to patch this so it will work the way it should work.
examples #1
var fs = require('fs');
fs.readFile('file.txt', 'utf8', function (err,data) {
if (err) {
return console.log(err);
}
console.log(data);
});
example #2
var jetpack = require('fs-jetpack');
var data = jetpack.read('file.txt');
console.log(data);
example #3
var fs = require ('fs');
var readMe = fs.readFileSync('file.txt', 'utf8');
console.log(readMe);
You shouldn't try to load files like this because you don't know what the folder structure looks like. Meteor creates builds from your project directory, both in development and production mode. This means that even though you have a file.txt in your project folder, it doesn't end up in the same place in the build (or it isn't even included in the build at all).
For example, your code tries to read the file from the development build folder .meteor/local/build/programs/server. However, this folder doesn't contain file.txt.
Solution: Store file.txt in the private folder of your project and use Assets.getText to read it. If you still want to use the functions from fs to load the file, you can retrieve the absolute path with Assets.absoluteFilePath.

How to add async callbacks in node to a function call?

Question is too broad / unclear. Anyone interested in this answer would be better served by visiting: Creating Callbacks for required modules in node.js
Basically I have included a CLI package in my node application. I need the CLI to spin up a new project (this entails creating a folder for the project). After the project folder is created, I need to create some files in the folder (using fs writeFile). The problem is right now, my writeFile function executes BEFORE the folder is created by the CLI package (This is detected by my console.log. This brings me to main main question.
Can I add an async callback function to the CLI.new without modifying the package I included?
FoundationCLI.new(null, {
framework: 'sites', // 'apps' or 'emails' also
template: 'basic', // 'advanced' also
name: projectName,
directory: $scope.settings.path.join("")
});
try{
if (!fs.existsSync(path)){
console.log("DIRECTORY NOT THERE!!!!!");
}
fs.writeFileSync(correctedPath, JSON.stringify(project) , 'utf-8');
} catch(err) {
throw err;
}
It uses foundation-cli. The new command executes the following async series. I'd love to add a callback to the package - still not quite sure how.
async.series(tasks, finish);
Anyone interested in this can probably get mileage out of:
Creating Callbacks for required modules in node.js
The code for the new command seem to be available on https://github.com/zurb/foundation-cli/blob/master/lib/commands/new.js
this code was not written to allow programmatic usage of the new command (it uses console.log everywhere) and does not call any callback when the work is finished.
so no there is no way to use this package to do what you are looking for. Either patch the package or find another way to do what you want to achieve.

Node js module mkdirp only creates half the directories

I'm trying to use mkdirp for a project, but when I feed it a var with my dir path I want created, it only creates the first half of it. I've installed the module locally with npm. I'm using Node v0.10.20 on a Raspberry Pi.
This is how it looks:
var filePath = "upload/home/pi/app/temp";
mkdirp(filePath, function(error) {
if(error) {
console.log(error);
} else {
...
}
});
I don't get an error creating the path, but it only creates "upload/home/pi", however if I run my script again, it creates the rest of the directory structure. Upload is a
directory in the current working directory which is the user home.
I emailed the author of the module who suggested that it could be because I'm using a flash drive as my medium, which in turn lies about when IO operations are complete, which I guess confuses node.js to think it has successfully written the path to disk. How should I tackle my problem? I guess I can do a check on if the directory was created, and loop that until it has, but that feels like the wrong thing to do. Any suggestions welcome.
Thanks.
Try doing this synchronously:
var filePath = "upload/home/pi/app/temp";
mkdirp(filePath)

Resources