Check If file exists - functionGlobalContext

Hey,
it's my first post here at the forum.

I simply want to check, if a file in my rasperry directory exist.

So I tried a few things. But don't get the right way. So I found this example. I like functions, so this one seems to be the best on for me. But I don't get working:

Example

I added these two lines to the setting.js file:

functionGlobalContext: {

        // os:require('os'),

        // -- Pass in Libraries for convenience in function nodes -- //

        path : require('path'),

        fs : require('fs'),

    },

And put the code from the example in a function node:

// Sends a msg with full file path for each file in a given folder ending with given extension
// PARAMETERS:
//   msg.payload.folder {string} Folder to look in for files
//   msg.payload.ext    {string} The file extension to look for
// ASSUMPTIONS:
//   Node.JS libraries fs and path have been required in the functionGlobal section of settings.js
//   Tested using Node.JS v4.4.5 LTS and Node-Red 0.13.4
// NOTES:
//   You would almost certainly be better off using one of the "glob" modules such as glob-fs, node-glob or glob-all

var fs = global.get('fs1')
var path = global.get('path')

// Give up if fs or path have not been assigned to global context (see assumption 1)
if ( (typeof fs !== 'undefined') || (typeof path !== 'undefined') ) {
    node.error('Either fs or path modules could not be found in global context')
    return    
}
// And make sure they are functions
if ( (typeof fs !== 'object') || (typeof path !== 'object') ) {
    node.error('Either fs or path from global context is not an object & it must be')
    return    
}

var folder = msg.payload.folder || '/home/pi'
var extension = msg.payload.ext || '.gpx'

// Make sure the parameters are strings
if ( (typeof folder !== 'string') || (typeof extension !== 'string') ) {
    node.error('Either Folder or Ext is not a string, cannot process. Folder: ' + folder + ', Ext: ' + extension, err)
    return    
}

fs.readdir(folder, callback)

// readir is ASYNC so don't return msg here as
// it would be pointless

function callback(err, files) {
    if (err) {
        node.error('Oops! Folder does not exist: ' + folder, err)
        return
    }
    
    // Any error in here will crash Node-Red!! So catch them instead
    try {
        files
            .filter( filterOnExtension ) // calls the given callback func for each file, will only pass names where fn returns true
            .forEach( sendName )
    } catch (err) {
        node.error('Ouch! Something went badly wrong processing the files list', err)
        return
    }
}

function filterOnExtension(file) {
    var len = extension.length

    // Returns TRUE only if the file name ends in the given extension
    return file.substr(0-len) === extension
}

function sendName(file) {
        msg.payload = path.join(folder, file)
        node.send( msg )
}

But when I inject I got this error.

image

Any ideas what i'm doing wrong?

Hi, welcome to the forum.

Common error. You've mixed up your "nots". (typeof fs !== 'undefined') || (typeof path !== 'undefined') is always going to be true. This should do it I think: if ( !fs || !path ) :slight_smile:

We've all done it.

1 Like

ok that was simple :smiley: Thanks for the quick response.
I think I just focused to hard to the setting file.

But the code in the function is originally from your example, maybe you can change it, that will help other :slight_smile:

But now I have another problem. In the folder where I check the files, will be only one .jpg-file.
If it is there, I got the payload with path of directory.

image

But if its not there I don't get the error message of the callback function.
But I need a "yes" or "no" to carry on.

Maybe you have an idea?

Please provide a link to that example, so that we can check it.

Ah well - the falacy of assuming I know what I'm talking about! To be fair though. That was create SIX YEARS AGO! :astonished: I'd forgotten all about it.

Link is in the first post Paul and I can see that the OP is correct. In truth, I'd almost certainly do it a different way now in any case.

In the original post, you will see a reference to using a glob module and in fact, that's almost certainly what I'd do now. Using fast-glob you can pass a request such as /home/pi/Desktop/*.jpg, what you get back would be an array of paths. If there were no jpg files, you would get an empty array which, of course, you could test for.

Also, these days, you can have a package connected directly to a function node so you don't need to change settings.js nor abuse the globals.

1 Like

I checked the github site of the 'fast-glob npm', but I didn't really get any smarter than that. Do you have an example how to use that? Or how the syntax is buildt? I think thats to deep in node.js for me.

This may help:

Hey Julian,
the example gave me some inspiration and yeah how easy and confortable it is to import the modules directly in the function node. :wink:

Now I have a solution that works for me :slight_smile:

fs.stat('/home/pi/Test/grab.jpg', function(err) {  
    if (err) {
       msg.payload = 0      // Datei existiert nicht
    } else {
        msg.payload = 1     // Datei existiert bereits
    }
});

return msg;

I need the function to grab a jpg file out of rtsp security cam stream and send via telegram.

thanks for your help :muscle:t2:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.