How to read and parse gitconfig file with node.js? - node.js

[user]
name = Alvin J. Alexander
email = [omitted]
[merge]
tool = vimdiff
This is what ~/.gitconfig file looks like. I've never encountered such data objects before. Does this format have a name like json files? Or is this a custom format?
My goal is to extract data from this file to fill out a package.json template. I want to research this format to better understand how to parse it. Do parsing functions already exist for this?
For Reference
This is a template for how to parse it:
(requires iniparser module to be installed)
var iniparser = require('iniparser');
var fs = require('fs');
var home_dir = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
console.log (home_dir);
var config_file = home_dir+'/.gitconfig';
var exists = fs.existsSync(config_file);
if (exists) {
console.log("Getting some information from the git configuration...");
var config = iniparser.parseSync(config_file);
console.log(config);
return config;
}
else {
console.log("Git configuration file does not exist...");
return {};
};

This file is a ini file. You can try this parser, but any node-ini parser should do the job :).

Related

Read all JSON files contained in a dynamically updated folder

I've got multiple json files contained within a directory that will dynamically be updated by users. The users can add categories which will create new json files in that directory, and they can also remove categories which would delete json files in that directory. I'm looking for a method to read all json files contained in that folder directory, and push all the json files into a single object array. I imagine asynchronously would be desirable too.
I'm very new to using fs. I've management to read single json files by directory using
const fs = require('fs');
let data = fs.readFileSync('./sw_lbi/categories/category1.json');
let categories = JSON.parse(data);
console.log(categories);
But of course this will only solve the synchronous issue when using require()
As I'll have no idea what json files will be contained in the directory because the users will also name them, I'll need a way to read all the json files by simply calling the folder directory which contains them.
I'm imagining something like this (which obviously is foolish)
const fs = require('fs');
let data = fs.readFileSync('./sw_lbi/categories');
let categories = JSON.parse(data);
console.log(categories);
What would be the best approach to achieve this?
Thanks in advance.
First of all you need to scan this directory for files, next you need to filter them and select only JSONs, and at the end just read every file and do what you need to do
const fs = require('fs');
const path = require('path')
const jsonsInDir = fs.readdirSync('./sw_lbi/categories').filter(file => path.extname(file) === '.json');
jsonsInDir.forEach(file => {
const fileData = fs.readFileSync(path.join('./sw_lbi/categories', file));
const json = JSON.parse(fileData.toString());
});

Link to reading, editing and saving INI files in node js

I tried searching for an entire day. Either i am blind or there is no specific answer to my question. How do i do it? I'm developing a steam bot in node js and i want to load accounts - username, pass etc.. of couple of accounts from .ini file. After a long time searching i only found how to read from an .ini file using node-ini module.
var ini = require('node-ini');
ini.parse('./config.ini', function(err,data){
console.log( data.Admin.pass ); //working.
data.Admin.pass = '1136'; //not working how to change value in ini.
data.Admin.H = 'test'; //not working as well.
});
This library (https://github.com/npm/ini) is a good option to do what you are looking to achieve.
Checkout this example from the docs:
var fs = require('fs')
, ini = require('ini')
var config = ini.parse(fs.readFileSync('./config.ini', 'utf-8'))
config.scope = 'local'
config.database.database = 'use_another_database'
config.paths.default.tmpdir = '/tmp'
delete config.paths.default.datadir
config.paths.default.array.push('fourth value')
fs.writeFileSync('./config_modified.ini', ini.stringify(config, { section: 'section' }))

Get file name in express request stream

Im wondering if is posible to know what is the file name of an incomming binary request.
This is my situation I have this code that handles the file upload
router.route('/:filename')
.put(function(req,res){
var uuid = guid();
var fileExtension = req.params.filename.substring(req.params.filename.lastIndexOf("."));
if(!fs.existsSync('../files')){
fs.mkdirSync('../files')
}
var newFile = fs.createWriteStream('../files/'+uuid+fileExtension);
req.pipe(newFile);
req.on('end',function(end){
console.log("Finished")
res.send(uuid+fileExtension)
})
})
as you can see now ,I need the file name specified in the URL('/:filename'). My question is: If it is possible to take that attribute from the resquest stream, instead the url or a form key?
If you use multer middleware you can access the uploaded filename like so
var multer = require('multer')
var upload = multer()
router.route('/:filename')
.put(upload.single('fileField'),function(req,res){
var fileName = req.file.originalname
var uuid = guid();
var fileExtension = req.params.filename.substring(req.params.filename.lastIndexOf("."));
if(!fs.existsSync('../files')){
fs.mkdirSync('../files')
}
var newFile = fs.createWriteStream('../files/'+uuid+fileExtension);
req.pipe(newFile);
req.on('end',function(end){
console.log("Finished")
res.send(uuid+fileExtension)
})
})
You'll need to inspect the Content-Disposition header of the request and parse the file name information out if processing the HTTP request manually.
However, I'd recommend you look at some of the existing file upload middlewares, no point in reinventing the wheel
busboy
multer
formidable
multiparty
pez

Can't write/append to JSON file in Node Webkit

I want to have persistent memory (store the user's progress) in a .json file in %AppData%. I tried doing this according to this post, but it doesn't work. For testing purposes I'm only working with storing one object.
The code below doesn't work at all. If I use fs.open(filePath, "w", function(err, data) { ... instead of readFile(..., it does create a json file in %AppData%, but then it doesn't write anything to it, it's always 0 bytes.
var nw = require('nw.gui');
var fs = require('fs');
var path = require('path');
var file = "userdata.json";
var filePath = path.join(nw.App.dataPath, file);
console.log(filePath); // <- This shows correct path in Application Data.
fs.readFile(filePath ,function (err, data) {
var idVar = "1";
var json = JSON.parse(data);
json.push("id :" + idVar);
fs.writeFile(filePath, JSON.stringify(json));
});
If anyone has any idea where I'm messing this up, I'd be grateful..
EDIT:
Solved, thanks to kailniris.
I was simply trying to parse an empty file
There is no json in the file you try to read. Before parsing data check if the file is empty. If it is then create an empty json, push the new data into it then write it to the file else parse the json in the file.

nodejs web root

I was under the impression that when you run a nodejs webserver the root of the web is the folder containing the js file implementing the webserver. So if you have C:\foo\server.js and you run it, then "/" refers to C:\foo and "/index.htm" maps to C:\foo\index.htm
I have a file server.js with a sibling file default.htm, but when I try to load the contents of /default.htm the file is not found. An absolute file path works.
Where is "/" and what controls this?
Working up a repro I simplified it to this:
var fs = require('fs');
var body = fs.readFileSync('/default.htm');
and noticed it's looking for this
Error: ENOENT, no such file or directory 'C:\default.htm'
So "/" maps to C:\
Is there a way to control the mapping of the web root?
I notice that relative paths do work. So
var fs = require('fs');
var body = fs.readFileSync('default.htm');
succeeds.
I believe my confusion arose from the coincidental placement of my original experiment's project files at the root of a drive. This allowed references to /default.htm to resolve correctly; it was only when I moved things into a folder to place them under source control that this issue was revealed.
I will certainly look into express, but you haven't answered my question: is it possible to remap the web root and if so how?
As a matter of interest this is server.js as it currently stands
var http = require('http');
var fs = require('fs');
var sys = require('sys');
var formidable = require('formidable');
var util = require('util');
var URL = require('url');
var QueryString = require('querystring');
var mimeMap = { htm : "text/html", css : "text/css", json : "application/json" };
http.createServer(function (request, response) {
var body, token, value, mimeType;
var url = URL.parse(request.url);
var path = url.pathname;
var params = QueryString.parse(url.query);
console.log(request.method + " " + path);
switch (path) {
case "/getsettings":
try {
mimeType = "application/json";
body = fs.readFileSync("dummy.json"); //mock db
} catch(exception) {
console.log(exception.text);
body = exception;
}
break;
case "/setsettings":
mimeType = "application/json";
body="{}";
console.log(params);
break;
case "/":
path = "default.htm";
default:
try {
mimeType = mimeMap[path.substring(path.lastIndexOf('.') + 1)];
if (mimeType) {
body = fs.readFileSync(path);
} else {
mimeType = "text/html";
body = "<h1>Error</h1><body>Could not resolve mime type from file extension</body>";
}
} catch (exception) {
mimeType = "text/html";
body = "<h1>404 - not found</h1>" + exception.toString();
}
break;
}
response.writeHead(200, {'Content-Type': mimeType});
response.writeHead(200, {'Cache-Control': 'no-cache'});
response.writeHead(200, {'Pragma': 'no-cache'});
response.end(body);
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');
I'm not completely certain what you mean by "routes" but I suspect that setsettings and getsettings are the sort of thing you meant, correct me if I'm wrong.
Nodejs does not appear to support arbitrary mapping of the web root.
All that is required is to prepend absolute web paths with a period prior to using them in the file system:
var URL = require('url');
var url = URL.parse(request.url);
var path = url.pathname;
if (path[0] == '/')
path = '.' + path;
While you're correct that the root of the server is the current working directory Node.js won't do a direct pass-through to the files on your file system, that could be a bit of a security risk after all.
Instead you need to provide it with routes that then in turn provide content for the request being made.
A simple server like
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
Will just capture any request and respond in the same way (but doesn't read the file system).
Now if you want to serve out file contents you need to specify some way to read that file into the response stream, this can be done a few ways:
You can use the fs API to find the file on disk, read its contents into memory and then pipe them out to the response. This is a pretty tedious approach, especially when you start getting a larger number of files, but it does allow you very direct control over what's happening in your application
You can use a middleware server like express.js, which IMO is a much better approach to do what you're wanting to do. There's plenty of questions and answers on using Express here on StackOverflow, this is a good example of a static server which is what you talk about
Edit
With the clarification of the question the reason:
var body = fs.readFileSync('/default.htm');
Results in thinking the file is at C:\default.htm is because you're using an absolute path not a relative path. If you had:
var body = fs.readFileSync('./default.htm');
It would then know that you want to operate relative to the current working directory. / is from the root of the partition and ./ is from the current working directory.

Resources