Understanding node `tmp` package - javascript

I'm not sure how to use the tmp package of node correctly. Maybe someone can give me an example
Filename generation
It is possible with this library to generate a unique filename in the
specified directory.
var tmp = require('tmp');
tmp.tmpName(function _tempNameGenerated(err, path) {
if (err) throw err;
console.log("Created temporary filename: ", path);
});
But what and how do I pass path. As I understand it, it makes sure, that in my desired directory are just unique filenames. So do I have to pass my for example upload directory as path? (But how syntax wise?)
Documentation

You don't.
You call tmpName, it calls its callback with an error (err, null if there isn't one) and the path.
Inside the callback you do what you want to do with the temporary filename, like write something to it.

Related

Trouble understanding the node.js walker

Im having trouble understanding how the signature/header of the node.js walker works. I understand, that a walker can iterate through a folder and you can set filters etc. But i dont really understand how the signature of the .on works.
As an example:
Walker('/etc/')
.filterDir(function(dir, stat) {
if (dir === '/etc/pam.d') {
console.warn('Skipping /etc/pam.d and children')
return false
}
return true
})
.on('entry', function(entry, stat) {
console.log('Got entry: ' + entry)
})
.on('dir', function(dir, stat) {
console.log('Got directory: ' + dir)
})
At the .on signatures,
-What do the 'dir/entry' parts do?
EDIT
I specifically mean what .on(**this part**, function(entry, stat)) {...} This part is doing
'dir', 'file', 'symlink', 'blockDevice' and so on are simply different things that act like files in the UNIX "everything is a file" design philosophy. For instance, you can list the devices connected to the system such as hard drives by running ls /dev/
The events in walker are simply filtered by "file type". 'entry' will trigger the callback function on every filesystem object, 'file' will only trigger for files, etc.
The walker, I assume, asynchronously accesses files starting from your defined folder, /etc/, and as it access files and folders as it's walking, it fires events.
Every time it accesses any element, whether its a file or a folder or whatever, I would imagine it fires the 'entry' event.
Every time it accesses a file, it fires the 'file' event.
Every time it accesses a directory, it fires the 'dir' event.
The first parameter to .on defines what events you want to register a callback to, and the second one is the callback itself, which takes as its first argument the element in question, or the path to it.
Those are function parameters. They define variable names that get values when the function is called.
const myFunction = function(dir, stat) {
console.log('Got directory: ' + dir)
};
myFunction("Foo", "Bar");
It is just that the function is called by code you did not write yourself.

problems on learnyounode exercise 5

Hi guys im trying to solve the exercises from nodeschool, i started with learnyounode, people recomende it a lot for beginners, the exercise question is this:
# LEARN YOU THE NODE.JS FOR MUCH WIN!
## FILTERED LS (Exercise 5 of 13)
Create a program that prints a list of files in a given directory,
filtered by the extension of the files. You will be provided a directory
name as the first argument to your program (e.g. '/path/to/dir/') and a
file extension to filter by as the second argument.
For example, if you get 'txt' as the second argument then you will need to
filter the list to only files that end with .txt. Note that the second
argument will not come prefixed with a '.'.
Keep in mind that the first arguments of your program are not the first
values of the process.argv array, as the first two values are reserved for
system info by Node.
The list of files should be printed to the console, one file per line. You
must use asynchronous I/O.
─────────────────────────────────────────────────────────────────────────────
## HINTS
The fs.readdir() method takes a pathname as its first argument and a
callback as its second. The callback signature is:
function callback (err, list) { /* ... */ }
where list is an array of filename strings.
Documentation on the fs module can be found by pointing your browser here:
file://C:\Users\Filipe\AppData\Roaming\npm\node_modules\learnyounode\node_
apidoc\fs.html
You may also find node's path module helpful, particularly the extname
method.
Documentation on the path module can be found by pointing your browser
here:
file://C:\Users\Filipe\AppData\Roaming\npm\node_modules\learnyounode\node_
apidoc\path.html
─────────────────────────────────────────────────────────────────────────────
» To print these instructions again, run: learnyounode print
» To execute your program in a test environment, run: learnyounode run
program.js
» To verify your program, run: learnyounode verify program.js
» For help run: learnyounode help
i tried to solve the exercise doing this:
var fs = require('fs');
fs.readdir(process.argv[2],process.argv[3],function(err,list){
for(var i = 0;i<list.length;i++)
{
var fileParts = list[i].split(".");
if(fileParts[1] == process.argv[3]){
console.log(list[i] + "\n");
}
}
});
why it doesnt work, i dont know what i am doing wrong, if someone can give me a tip to solve this i appreciate a lot, since the solutions on web are quite bit strange.
Hm, I just tested your code and it actually runs fine for me. Verify returns with solved. Not sure what you are experiencing. Btw.: put in at least some error handling. Below my solution:
const fs = require('fs');
const test = '.' + process.argv[3]
fs.readdir(process.argv[2], (err, data) => {
if (err) {
console.error(err);
} else {
data.filter(file => {
if (file.substring(file.length - test.length) === test) {
console.log(file)
}
})
}
});

In Node.js, asking for a value using Prompt, and using that value in a main js file

I'm pretty new to node.js and it seems fairly easy to use but when it comes to getting a value using the command line and returning that value to be used in another package or .js, it seems harder than I expected.
Long story short, I've used a npm package (akamai-ccu-purge), to enter a file to purge on the akamai network successfully.
I want to make it more dynamic though by prompting the user to enter the file they want purged and then using that in the akamai package.
After making a few tries using var stdin = process.openStdin(); I actually found another npm package called Prompt that seemed to be easier. Both ways seem to have the same problem though.
Node doesn't seem to want to stop for the input. It seems to want to automatically make the purge without waiting for input even though I've called that module first. It actually gets to the point where I should enter the file but it doesn't wait.
I am definitely missing something in my understanding or usage here, what am I doing wrong?
My code so far is:
var purgeUrl = require('./getUrl2');
var PurgerFactory = require('../../node_modules/akamai-ccu-purge/index'); // this is the directory where the index.js of the node module was installed
// area where I placed the authentication tokens
var config = {
clientToken: //my tokens and secrets akamai requires
};
// area where urls are placed. More than one can be listed with comma separated values
var objects = [
purgeUrl // I am trying to pull this from the getUrl2 module
];
// Go for it!
var Purger = PurgerFactory.create(config);
Purger.purgeObjects(objects, function(err, res) {
console.log('------------------------');
console.log('Purge Result:', res.body);
console.log('------------------------');
Purger.checkPurgeStatus(res.body.progressUri, function(err, res) {
console.log('Purge Status', res.body);
console.log('------------------------');
Purger.checkQueueLength(function(err, res) {
console.log('Queue Length', res.body);
console.log('------------------------');
});
});
});
The getUrl2 module looks like this:
var prompt = require('../../node_modules/prompt');
//
// Start the prompt
//
prompt.start();
//
// Get property from the user
//
prompt.get(['newUrl'], function (err, result) {
//
// Log the results.
//
console.log('Command-line input received:');
console.log(' http://example.com/custom/' + result.newUrl);
var purgeUrl = 'http://example.com/custom/' + result.newUrl;
console.log(purgeUrl);
module.exports = purgeUrl;
});
Thanks again for the help!
I would probably just allow getURL2 to expose a method that will be invoked in the main module. For example:
// getURL2
var prompt = require('../../node_modules/prompt');
module.exports = {
start: function(callback) {
prompt.start();
prompt.get(['newUrl'], function (err, result) {
// the callback is defined in your main module
return callback('http://example.com/custom/' + result.newUrl);
});
}
}
Then in your main module:
require('./getUrl2').start(function(purgeURL) {
// do stuff with the purgeURL defined in the other module
});
The implementation may differ, but conceptually, you need to make your second module, which requires some sort of input from the user, happen as a result of that input. Callbacks are a common way to do this (as are Promises). However, as prompt is not necessarily exposing a method that would necessitate a Promise, you can do it with plain old callbacks.
You might also want to search around for articles on writing command line tools (sometimes referenced as CLIs) or command line apps with Node. I found the following article to be helpful when trying to figure this out myself:
http://javascriptplayground.com/blog/2015/03/node-command-line-tool/
Also, the command-line-args module worked well for me (though there's a number of other modules out there to choose from):
https://www.npmjs.com/package/command-line-args
Good luck!

Create a file if it doesn't already exist

I would like to create a file foobar. However, if the user already has a file named foobar then I don't want to overwrite theirs. So I only want to create foobar if it doesn't exist already.
At first, I thought that I should do this:
fs.exists(filename, function(exists) {
if(exists) {
// Create file
}
else {
console.log("Refusing to overwrite existing", filename);
}
});
However, looking at the official documentation for fs.exists, it reads:
fs.exists() is an anachronism and exists only for historical reasons.
There should almost never be a reason to use it in your own code.
In particular, checking if a file exists before opening it is an
anti-pattern that leaves you vulnerable to race conditions: another
process may remove the file between the calls to fs.exists() and
fs.open(). Just open the file and handle the error when it's not
there.
fs.exists() will be deprecated.
Clearly the node developers think my method is a bad idea. Also, I don't want to use a function that will be deprecated.
How can I create a file without writing over an existing one?
I think the answer is:
Just open the file and handle the error when it's not there.
Try something like:
function createFile(filename) {
fs.open(filename,'r',function(err, fd){
if (err) {
fs.writeFile(filename, '', function(err) {
if(err) {
console.log(err);
}
console.log("The file was saved!");
});
} else {
console.log("The file exists!");
}
});
}
fs.closeSync(fs.openSync('/var/log/my.log', 'a'))
import { promises as fs } from "fs";
fs.readFile(path).catch(() =>
fs.writeFile(path, content);
);
If you would like to write data to this file later, you can use fs.appendFile('message.txt', 'data to append', 'utf8', callback);.
Asynchronously append data to a file, creating the file if it does not yet exist. Data can be a string or a buffer.
Node file system documentation.

Issue with output list for learnyounode #6 MAKE IT MODULAR

Just started coding last thursday, bear with me here:
my code for this question of the tutorial is returning a list of just the extension names from the directory and not a list of the files with the said extension, e.g. if i used a directory with 3 .js files and used js as my extension argument in the command line, then i would get
1. js
2. js
3. js
as the output, here is the question from the tutorial and my code. THANK YOU!
the question from learnyounode tutorial number 6:
LEARN YOU THE NODE.JS FOR MUCH WIN!
─────────────────────────────────────
MAKE IT MODULAR
Exercise 6 of 13
This problem is the same as the previous but introduces the concept of modules. You will need to create two files to solve this.
Create a program that prints a list of files in a given directory, filtered by the extension of the files. The first argument is the directory name and the second argument is the extension filter. Pr
int the list of files (one file per line) to the console. You must use asynchronous I/O.
You must write a module file to do most of the work. The module must export a single function that takes three arguments: the directory name, the filename extension string and a callback function, in
that order. The filename extension argument must be the same as was passed to your program. i.e. don't turn it into a RegExp or prefix with "." or do anything else but pass it to your module where y
ou can do what you need to make your filter work.
The callback function must be called using the idiomatic node(err, data) convention. This convention stipulates that unless there's an error, the first argument passed to the callback will be null, a
nd the second will be your data. In this case, the data will be your filtered list of files, as an Array. If you receive an error, e.g. from your call to fs.readdir(), the callback must be called wi
th the error, and only the error, as the first argument.
You must not print directly to the console from your module file, only from your original program.
In the case of an error bubbling up to your original program file, simply check for it and print an informative message to the console.
These four things are the contract that your module must follow.
Export a single function that takes exactly the arguments described.
Call the callback exactly once with an error or some data as described.
Don't change anything else, like global variables or stdout.
Handle all the errors that may occur and pass them to the callback.
The benefit of having a contract is that your module can be used by anyone who expects this contract. So your module could be used by anyone else who does learnyounode, or the verifier, and just work. *
and my code is:
module (p6m.js):
var fs=require('fs'), ph=require('path'), exports =module.exports={}
exports.f=function(path,ext,callbk){
fs.readdir(path,function(err,files){
if(err){
return callbk(err,null)
}
files=files.filter(
function(file){
return ph.extname(file)==="."+ext
}
)
return callbk(null,files)}
)}
and my program (p6.js):
var p6m=require('./p6m'), path=process.argv[2], ext=process.argv[3]
p6m.f(path, ext, function(err,files){
if(err){return console.log.error('Error occured:', err)};
files.forEach(function(file){
console.log(file)})})
I got the same problem with my code as of need to use a single function export . So instead of exporting a module function like this :
exports =module.exports={}
exports.f=function(path,ext,callbk){...};
try it doing this way :
module.exports = function (path, ext, callbk) {...};
because its a single function so you don't need to specify that function with a name " f " as if you are doing it in this statement :
exports.f = function(path,ext,callbk){...};
whenever you will import the module,it will automatically call this function only, since the module contains this single function.
You can try this piece of code, it works well for me.
module code: mymodule.js
var fs = require('fs');
var ph= require('path');
module.exports = function (path, ext, callbk) {
var pathio = "." + ext;
fs.readdir(path, function (err, files) {
if (err)
return callbk(err);
else {
var listf = []; //listf is the resultant list
for (var i = 0; i < files.length; i++) {
if (ph.extname(files[i]) === pathio) {
listf.push(files[i]);
}
}
callbk(null, listf);
}
});
}
program code : moduletest.js
var mod = require('./mymodule');
mod(process.argv[2], process.argv[3], function (err, listf) {
if (err) {
console.log('Error!')
} else {
for (var i = 0; i < listf.length; i++) {
console.log(listf[i]);
}
}
});
and do remember, learnyounode series is very specific about its way of coding and syntax, so even if you are doing the logic right way still you won't get pass,you need your code to be the best and optimized. I'll suggest you to refer to discussions on nodeschool itself for various issues you might get in learnyounode series.
That will work and output the right results, but what they are looking for is something like this:
module.exports = function() {};
Because they only want one function total in the exports.
You could also do something like this:
module.exports = FindFilesByExtension;
function FindFilesByExtension(path, ext, callback) {
//your code
}
Here is my solution,
Thsi is my module file filteredls.js
var fs = require('fs');
var path = require('path');
module.exports = function filterFiles(folder, extension, callback) {
fs.readdir(folder, function(err, files) {
if(err) return callback(err);
var filesArray = [];
files.forEach(function(file) {
if(path.extname(file) === "."+extension) {
filesArray.push(file);
}
});
return callback(null, filesArray);
});
}
And here is my test file for reading module modular.js
var ff = require('./filteredls.js');
ff(process.argv[2], process.argv[3], function(err, data) {
if(err)
return console.error(err);
data.forEach(function(file) {
console.log(file);
});
});
And this is my result screenshot,

Categories

Resources