Unable to write file using xul - javascript

Trying to write a file inside windows temp directory using XUL code:
function writeFile_launch_application(utility_name,utility_path)
{
var data ='tasklist /nh /fi "imagename eq '+utility_name+'" | find /i "'+utility_name+'">nul && (echo alerady running) || ("'+utility_path+'")';
//alert(data);
var file = Cc["#mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).
get("TmpD", Ci.nsIFile);
file.append("launch_application.bat");
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
// Then, we need an output stream to our output file.
var ostream = Cc["#mozilla.org/network/file-output-stream;1"].
createInstance(Ci.nsIFileOutputStream);
ostream.init(file, -1, -1, 0);
// Finally, we need an input stream to take data from.
const TEST_DATA = data;
let istream = Cc["#mozilla.org/io/string-input-stream;1"].
createInstance(Ci.nsIStringInputStream);
istream.setData(TEST_DATA, TEST_DATA.length);
NetUtil.asyncCopy(istream, ostream, function(aResult) {
if (!Components.isSuccessCode(aResult)) {
// an error occurred!
}
})
}
But getting error:
Timestamp: 11/29/2012 11:03:09 PM
Error: ReferenceError: Cc is not defined
Source File: chrome://myaddon/content/overlay.js
Line: 199
I also tried to add below lines at the top of my code but it didn't solve above error:
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");

Cc and Ci are aliases for Components.classes and Components.interfaces respectively.
Depending on the context they might (or might not) be already defined.
In any case
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;
(you shouldn't tag your question as firefox-addon-sdk)

When I'm developing my addon, I always try to replace Components.utils, Components.intefaces with Cu and Ci. To do that, first line in my file is:
const { Cc, Ci, Cu } = require('chrome');
Cc is Component.classes. Than you can use now
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");

Related

javascript read .ini file

I tried searching . How do i do it? I'm create html and i want to read .ini file by javascript on the client Not in the server.
I copy code from javascript parser for a string which contains .ini data
error Uncaught ReferenceError: require is not defined var fs = require('fs')
function parseINIString() {
var fs = require('fs')
var data = fs.readFileSync('C:\\test.ini', 'utf8');
var regex = {
section: /^\s*\[\s*([^\]]*)\s*\]\s*$/,
param: /^\s*([\w\.\-\_]+)\s*=\s*(.*?)\s*$/,
comment: /^\s*;.*$/
};
var value = {};
var lines = data.split(/\r\n|\r|\n/);
var section = null;
alert(lines);
for (x = 0; x < lines.length; x++) {
if (regex.comment.test(lines[x])) {
return;
} else if (regex.param.test(lines[x])) {
var match = lines[x].match(regex.param);
if (section) {
value[section][match[1]] = match[2];
} else {
value[match[1]] = match[2];
}
} else if (regex.section.test(lines[x])) {
var match = lines[x].match(regex.section);
value[match[1]] = {};
section = match[1];
} else if (lines.length == 0 && section) {//changed line to lines to fix bug.
section = null;
};
}
return value;
}
Let's say the javascript running in a browser is so called 'client script'. There are lots of limitation while writing client script, one of them is that it's not allowed to visit the user file on disk. This is to prevent any injected hacker script from reading private data. And the explicit error you see is about the new key word 'require' which is well known as 'commonjs' module which is introduced by Nodejs usually. The 'fs' is one of the internal module of Nodejs as well.
So if you still consist using client script to get the job done, you have to rewrite the script, not 'require' the 'fs' module. And use the file reader to get the content of a file object, which is generated by a file input usually.
A detailed introduction about how to read local files.

Store output of shell command in sqlite

If I execute a certain shell command in node js, the output is on the console. Is there a way I can save it in a variable so it can be POST to Sqlite database.
const shell = require('shelljs');
shell.exec('arp -a');
In this scenario, I want to store the IP address of a specific MAC/Physical address into the database. How can this be done?
Any help would be much appreciated. Thank you
You need to get the output of the command you're passing to exec. To do that, just call stdout, like this:
const shell = require('shelljs');
const stdout = shell.exec('arp -a').stdout;
Then just parse that output to get your ipaddress:
const entries = stdout.split('\r\n');
// entries sample
[ '',
'Interface: 10.17.60.53 --- 0xd',
' Internet Address Physical Address Type',
' 10.11.10.52 6c-4b-90-1d-97-b8 dynamic ',
' 10.10.11.254 xx-yy-53-2e-98-44 dynamic ']
Then you can filter your wanted address with some more manipulation.
EDIT:
To get the ip address, you could do:
let ipAddr = null;
for (let i = 0; i < entries.length; i++) {
if (entries[i].indexOf('6c-4b-90-1d-97-b8') > -1) {
ipAddr = entries[i].match(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/)[0];
break;
}
}
console.log(ipAddr); // '10.11.10.52'
I'm merely copy pasting from the docs. You should research more.
You need to add a listener to stdout
var child = exec('arp -a', {async:true});
child.stdout.on('data', function(data) {
/* ... do something with data ... */
});
Or adding the callback directly when calling exec
exec('some_long_running_process', function(code, stdout, stderr) {
console.log('Exit code:', code);
console.log('Program output:', stdout);
console.log('Program stderr:', stderr);
});
You can access the result of the command run using shell.exec with the .output property. Try the code below.
var shell = require('shelljs');
var result = shell.exec('arp -a').output;
If you don't want the result in the console, you can specify the silent option.
var result = shell.exec('arp -a', {silent: true}).output;
Now, you can use regular expressions to extract ip and mac address from the result.
I am getting the result of the command like below:
? (xxx.xxx.xxx.xxx) at xx:xx:xx:xx:xx:xx [ether] on eth0
? (yyy.yyy.yyy.yyy) at yy:yy:yy:yy:yy:yy [ether] on eth0
You can use the following code to extract ip and mac.
var res = result.split("\n").map(function(item){
return item.match(/\((\d+\.\d+\.\d+\.\d+)\) at (..:..:..:..:..:..)/);
});
console.log(res[0][1]); //IP of first interface
console.log(res[0][2]); //MAC of first interface
console.log(res[1][1]); //IP of second interface
console.log(res[1][2]); //MAC of second interface
NOTE
I was not able to find the .output property in the documentation but trying the shell.exec function in the node console revealed it.
The .stdout property or the exec function mentioned in other answers doesn't work for me. They are giving undefined errors.

Configuring mock-cli

I'm trying to use mock-cli to stub process.arv in mocha tests for a cli app. I want to test that a message is console.logged when an incorrect argument ("imit") is passed to process.argv (as defined by commands).
I'm trying to adapt the example from the documentation but i don't think i have set everything up correctly.
it passes when i comment out "stdin: require('../mocks/fakeInputStream'), // Hook up a fake input stream" though i know it's not working correctly
it fails with TypeError: sourceStream.on is not a function when run as described below
Can someone see what I'm missing?
/index.js
var commands = ['init'];
function getGitHeadArgs() {
return process.argv.slice(2, process.argv.length);
}
if (getGitHeadArgs().length) {
if (!commands.includes(getGitHeadArgs()[0])) {
console.log("Silly Githead! That's not a githead command");
}
eval(getGitHeadArgs()[0])();
} else {
console.log("You didn't tell githead to do anything!");
}
/testIndex.js
var assert = require('assert');
var index = require('../index.js');
var mockCli = require("mock-cli");
describe("incorrect argument", function() {
it("imit throws an error if an invalid command is raised", function() {
var argv = ['node', '../index.js', 'imit']; // Fake argv
var stdio = {
stdin: require('../mocks/fakeInputStream'), // Hook up a fake input stream
stdout: process.stdout, // Display the captured output in the main console
stderr: process.stderr // Display the captured error output in the main console
};
var kill = mockCli(argv, stdio, function onProcessComplete(error, result) {
var exitCode = result.code; // Process exit code
var stdout = result.stdout; // UTF-8 string contents of process.stdout
var stderr = result.stderr; // UTF-8 string contents of process.stderr
assert.equal(exitCode, 0);
assert.equal(stdout, "Silly Githead! That's not a githead command\n");
assert.equal(stderr, '');
});
// Execute the CLI task
require('../index.js');
// Kill the task if still running after one second
setTimeout(kill, 1000);
});
Is ../mocks/fakeInputStream a valid path?
Is the object at ../mocks/fakeInputStream a valid instance of ReadableStream?
The source code is avalible at GitHub.
Make sure you meet the requirements for the captureStdin(sourceStream, callback) function.
The module uses that function to capture your fakeInputStream and pipe it into a captureStream.

How to get filename and line number of where a function is called in Node?

When working in Python I always have this simple utility function which returns the file name and line number from where the function is called:
from inspect import getframeinfo, stack
def d():
""" d stands for Debug. It returns the file name and line number from where this function is called."""
caller = getframeinfo(stack()[1][0])
return "%s:%d -" % (caller.filename, caller.lineno)
So in my code I simply put a couple debug lines like this to see how far we get before some error occurs:
print d()
# Some buggy code here
print d()
# More buggy code here
print d(), 'here is the result of some var: ', someVar
This works really well for me because it really helps debugging quickly.
I'm now looking for the equivalent in a node backend script. I was searching around but I can't find anything useful (maybe I'm looking for the wrong words?).
Does anybody know how I can create a Javascript/nodejs function which outputs the file name and line number from where the function is called? All tips are welcome!
You can create an Error to get where the Error is, and its stack trace. Then you can put that into a function, to get the line where it is.
function thisLine() {
const e = new Error();
const regex = /\((.*):(\d+):(\d+)\)$/
const match = regex.exec(e.stack.split("\n")[2]);
return {
filepath: match[1],
line: match[2],
column: match[3]
};
}
console.log(thisLine());
This works for me in Google Chrome.
And also in node.
Note to #j08691's comment:
Both this and this seem to be using lineNumber, which is not present (as far as I could test) in NodeJS.
Printing line number with custom string
const moment = require('moment');
const log = console.log;
const path = require('path');
function getTime(time) { return moment().format('YYYY-MM-DD HH:mm:ss') };
function line(num = 2) {
const e = new Error();
const regex = /\((.*):(\d+):(\d+)\)$/
const match = regex.exec(e.stack.split("\n")[num]);
const filepath = match[1];
const fileName = path.basename(filepath);
const line = match[2];
const column = match[3];
return {
filepath,
fileName,
line,
column,
str: `${getTime()} - ${fileName}:${line}:${column}`
};
}
log(line().str, "mylog1");
log(line().str, "mylog2");
log(line().str, "mylog3");
OUTPUT
2021-11-22 13:07:15 - test.js:44:5 mylog1
2021-11-22 13:07:15 - test.js:45:5 mylog2
2021-11-22 13:07:15 - test.js:46:5 mylog3
You can use this gulp plugin gulp-log-line . It Logs file and line number without the extra cost of reading the stack.
you just have to install gulp and gulp-log-line using the
npm install gulp --save and npm install gulp-log-line command. after that you need to create and write the below code in gulpfile.js and run
gulp log-line to create a duplicate file in the build folder :-
var gulp = require('gulp');
var logLine = require('gulp-log-line');
gulp.task('line-log', function() {
return gulp.src("file.js", {buffer : true})
//Write here the loggers you use.
.pipe(logLine(['console.log', 'winston.info']))
.pipe(gulp.dest('./build'))
})
gulp.task('default', ['line-log'])
Example
file.js :-
console.log('First log')
var someVariable
console.log('Second log')
Becomes
console.log('file.js:1', 'First log')
var someVariable
console.log('file.js:3', 'Second log')
The only way I've found to get anything relating to line numbers is to trap the window.onerror function, and when there's an error that will get passed the error message, the file URL and the line number:
window.onerror = function(msg, url, line) {
alert(msg + "\n" + url + ":" + line);
};
This works for me on Chrome - I don't know about other browsers.
EDIT when this answer was given in Feb' 15 there was no mention of NodeJS in the question. That was only added in November '17.

How to determine the OS path separator in JavaScript?

How can I tell in JavaScript what path separator is used in the OS where the script is running?
Use path module in node.js returns the platform-specific file separator.
example
path.sep // on *nix evaluates to a string equal to "/"
Edit: As per Sebas's comment below, to use this, you need to add this at the top of your js file:
const path = require('path')
Afair you can always use / as a path separator, even on Windows.
Quote from http://bytes.com/forum/thread23123.html:
So, the situation can be summed up
rather simply:
All DOS services since DOS 2.0 and all Windows APIs accept either forward
slash or backslash. Always have.
None of the standard command shells (CMD or COMMAND) will accept forward
slashes. Even the "cd ./tmp" example
given in a previous post fails.
The Correct Answer
Yes all OS's accept CD ../ or CD ..\ or CD .. regardless of how you pass in separators. But what about reading a path back. How would you know if its say, a 'windows' path, with ' ' and \ allowed.
The Obvious 'Duh!' Question
What happens when you depend on, for example, the installation directory %PROGRAM_FILES% (x86)\Notepad++. Take the following example.
var fs = require('fs'); // file system module
var targetDir = 'C:\Program Files (x86)\Notepad++'; // target installer dir
// read all files in the directory
fs.readdir(targetDir, function(err, files) {
if(!err){
for(var i = 0; i < files.length; ++i){
var currFile = files[i];
console.log(currFile);
// ex output: 'C:\Program Files (x86)\Notepad++\notepad++.exe'
// attempt to print the parent directory of currFile
var fileDir = getDir(currFile);
console.log(fileDir);
// output is empty string, ''...what!?
}
}
});
function getDir(filePath){
if(filePath !== '' && filePath != null){
// this will fail on Windows, and work on Others
return filePath.substring(0, filePath.lastIndexOf('/') + 1);
}
}
What happened!?
targetDir is being set to a substring between the indices 0, and 0 (indexOf('/') is -1 in C:\Program Files\Notepad\Notepad++.exe), resulting in the empty string.
The Solution...
This includes code from the following post: How do I determine the current operating system with Node.js
myGlobals = { isWin: false, isOsX:false, isNix:false };
Server side detection of OS.
// this var could likely a global or available to all parts of your app
if(/^win/.test(process.platform)) { myGlobals.isWin=true; }
else if(process.platform === 'darwin'){ myGlobals.isOsX=true; }
else if(process.platform === 'linux') { myGlobals.isNix=true; }
Browser side detection of OS
var appVer = navigator.appVersion;
if (appVer.indexOf("Win")!=-1) myGlobals.isWin = true;
else if (appVer.indexOf("Mac")!=-1) myGlobals.isOsX = true;
else if (appVer.indexOf("X11")!=-1) myGlobals.isNix = true;
else if (appVer.indexOf("Linux")!=-1) myGlobals.isNix = true;
Helper Function to get the separator
function getPathSeparator(){
if(myGlobals.isWin){
return '\\';
}
else if(myGlobals.isOsx || myGlobals.isNix){
return '/';
}
// default to *nix system.
return '/';
}
// modifying our getDir method from above...
Helper function to get the parent directory (cross platform)
function getDir(filePath){
if(filePath !== '' && filePath != null){
// this will fail on Windows, and work on Others
return filePath.substring(0, filePath.lastIndexOf(getPathSeparator()) + 1);
}
}
getDir() must be intelligent enough to know which its looking for.
You can get even really slick and check for both if the user is inputting a path via command line, etc.
// in the body of getDir() ...
var sepIndex = filePath.lastIndexOf('/');
if(sepIndex == -1){
sepIndex = filePath.lastIndexOf('\\');
}
// include the trailing separator
return filePath.substring(0, sepIndex+1);
You can also use 'path' module and path.sep as stated above, if you want to load a module to do this simple of a task. Personally, i think it sufficient to just check the information from the process that is already available to you.
var path = require('path');
var fileSep = path.sep; // returns '\\' on windows, '/' on *nix
And Thats All Folks!
As already answered here, you can find the OS specific path separator with path.sep to manually construct your path. But you can also let path.join do the job, which is my preferred solution when dealing with path constructions:
Example:
const path = require('path');
const directory = 'logs';
const file = 'data.json';
const path1 = `${directory}${path.sep}${file}`;
const path2 = path.join(directory, file);
console.log(path1); // Shows "logs\data.json" on Windows
console.log(path2); // Also shows "logs\data.json" on Windows
Just use "/", it works on all OS's as far as I know.

Categories