v1.0.0
This commit is contained in:
		
							parent
							
								
									dee3cbd7d0
								
							
						
					
					
						commit
						7acb9f196e
					
				
							
								
								
									
										62
									
								
								example.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								example.conf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
			
		||||
cert = /etc/letsencrypt/live/example.com/cert.pem
 | 
			
		||||
privkey = /etc/letsencrypt/live/example.com/privkey.pem
 | 
			
		||||
chain = /etc/letsencrypt/live/example.com/chain.pem
 | 
			
		||||
fullchain = /etc/letsencrypt/live/example.com/fullchain.pem
 | 
			
		||||
 | 
			
		||||
# Options and defaults used in the renewal process
 | 
			
		||||
[renewalparams]
 | 
			
		||||
apache_enmod = a2enmod
 | 
			
		||||
no_verify_ssl = False
 | 
			
		||||
ifaces = None
 | 
			
		||||
apache_dismod = a2dismod
 | 
			
		||||
register_unsafely_without_email = False
 | 
			
		||||
uir = None
 | 
			
		||||
installer = none
 | 
			
		||||
config_dir = /etc/letsencrypt
 | 
			
		||||
text_mode = False
 | 
			
		||||
func = <function obtain_cert at 0x30c9500>
 | 
			
		||||
prepare = False
 | 
			
		||||
work_dir = /var/lib/letsencrypt
 | 
			
		||||
tos = True
 | 
			
		||||
init = False
 | 
			
		||||
http01_port = 80
 | 
			
		||||
duplicate = False
 | 
			
		||||
key_path = None
 | 
			
		||||
nginx = False
 | 
			
		||||
fullchain_path = /home/user/letsencrypt/chain.pem
 | 
			
		||||
email = user@example.com
 | 
			
		||||
csr = None
 | 
			
		||||
agree_dev_preview = None
 | 
			
		||||
redirect = None
 | 
			
		||||
verbose_count = -3
 | 
			
		||||
config_file = None
 | 
			
		||||
renew_by_default = False
 | 
			
		||||
hsts = False
 | 
			
		||||
authenticator = webroot
 | 
			
		||||
domains = example.com,
 | 
			
		||||
rsa_key_size = 2048
 | 
			
		||||
checkpoints = 1
 | 
			
		||||
manual_test_mode = False
 | 
			
		||||
apache = False
 | 
			
		||||
cert_path = /home/user/letsencrypt/cert.pem
 | 
			
		||||
webroot_path = /srv/www/example.com/,
 | 
			
		||||
strict_permissions = False
 | 
			
		||||
apache_server_root = /etc/apache2
 | 
			
		||||
account = f4c33502df3789849f617944253b35ae
 | 
			
		||||
manual_public_ip_logging_ok = False
 | 
			
		||||
chain_path = /home/user/letsencrypt/chain.pem
 | 
			
		||||
standalone = False
 | 
			
		||||
manual = False
 | 
			
		||||
server = https://acme-v01.api.letsencrypt.org/directory
 | 
			
		||||
standalone_supported_challenges = "http-01,tls-sni-01"
 | 
			
		||||
webroot = True
 | 
			
		||||
apache_init_script = None
 | 
			
		||||
user_agent = None
 | 
			
		||||
apache_ctl = apache2ctl
 | 
			
		||||
apache_le_vhost_ext = -le-ssl.conf
 | 
			
		||||
debug = False
 | 
			
		||||
tls_sni_01_port = 443
 | 
			
		||||
logs_dir = /var/log/letsencrypt
 | 
			
		||||
configurator = None
 | 
			
		||||
[[webroot_map]]
 | 
			
		||||
example.com = /srv/www/example.com/
 | 
			
		||||
							
								
								
									
										173
									
								
								index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,173 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
var fs = require('fs');
 | 
			
		||||
var sfs = require('safe-replace').create();
 | 
			
		||||
 | 
			
		||||
function snakeCase(key) {
 | 
			
		||||
  if ('tlsSni01Port' === key) {
 | 
			
		||||
    return 'tls_sni_01_port';
 | 
			
		||||
  }
 | 
			
		||||
  /*
 | 
			
		||||
  else if ('http01Port' === key) {
 | 
			
		||||
    return 'http01-port';
 | 
			
		||||
  }
 | 
			
		||||
  */
 | 
			
		||||
  else {
 | 
			
		||||
    return key.replace(/([A-Z])/g, '_$1').toLowerCase();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function uc(match, c) {
 | 
			
		||||
  return c.toUpperCase();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function camelCase(key) {
 | 
			
		||||
  return key.replace(/_([a-z0-9])/g, uc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function parsePythonConf(str, cb) {
 | 
			
		||||
  var keys = {};
 | 
			
		||||
  var obj = {};
 | 
			
		||||
  var lines = str.split('\n');
 | 
			
		||||
 | 
			
		||||
  lines.forEach(function (line, i) {
 | 
			
		||||
    line = line.replace(/#.*/, '').trim();
 | 
			
		||||
 | 
			
		||||
    if (!line) { return; }
 | 
			
		||||
 | 
			
		||||
    var parts = line.trim().split('=');
 | 
			
		||||
    var pykey = parts.shift().trim();
 | 
			
		||||
    var key = camelCase(pykey);
 | 
			
		||||
    var val = parts.join('=').trim();
 | 
			
		||||
 | 
			
		||||
    if ('True' === val) {
 | 
			
		||||
      val = true;
 | 
			
		||||
    }
 | 
			
		||||
    else if ('False' === val) {
 | 
			
		||||
      val = false;
 | 
			
		||||
    }
 | 
			
		||||
    else if ('None' === val) {
 | 
			
		||||
      val = null;
 | 
			
		||||
    }
 | 
			
		||||
    else if (/,/.test(val) && !/^"[^"]*"$/.test(val)) {
 | 
			
		||||
      val = val.split(',');
 | 
			
		||||
    }
 | 
			
		||||
    else if (/^[0-9]+$/.test(val)) {
 | 
			
		||||
      val = parseInt(val, 10);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    obj[key] = val;
 | 
			
		||||
    if ('undefined' !== typeof keys[key]) {
 | 
			
		||||
      console.warn("unexpected duplicate key '" + key + "': '" + val + "'");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    keys[key] = i;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // we want to be able to rewrite the file with comments, etc
 | 
			
		||||
  obj.__keys = keys;
 | 
			
		||||
  obj.__lines = lines;
 | 
			
		||||
 | 
			
		||||
  cb(null, obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function toPyVal(val) {
 | 
			
		||||
  if (null === val) {
 | 
			
		||||
    return 'None';
 | 
			
		||||
  }
 | 
			
		||||
  else if (true === val) {
 | 
			
		||||
    return 'True';
 | 
			
		||||
  }
 | 
			
		||||
  else if (false === val) {
 | 
			
		||||
    return 'False';
 | 
			
		||||
  }
 | 
			
		||||
  else if ('string' === typeof val) {
 | 
			
		||||
    return val;
 | 
			
		||||
  }
 | 
			
		||||
  else if ('number' === typeof val) {
 | 
			
		||||
    return val;
 | 
			
		||||
  }
 | 
			
		||||
  else if (Array.isArray(val)) {
 | 
			
		||||
    return val.join(',');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return val && JSON.stringify(val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function stringifyPythonConf(obj, cb) {
 | 
			
		||||
  var endline;
 | 
			
		||||
 | 
			
		||||
  // nix the final newline
 | 
			
		||||
  if (!obj.__lines[obj.__lines.length - 1].trim()) {
 | 
			
		||||
    endline = obj.__lines.pop();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Object.keys(obj).forEach(function (key) {
 | 
			
		||||
    if ('__' === key.slice(0, 2)) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var pykey = snakeCase(key);
 | 
			
		||||
    var pyval = toPyVal(obj[key]);
 | 
			
		||||
    var num = obj.__keys[key];
 | 
			
		||||
    var comment = '';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if ('number' !== typeof num) {
 | 
			
		||||
      obj.__lines.push(pykey + ' = ' + pyval);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // restore comments
 | 
			
		||||
    if (-1 !== obj.__lines[num].indexOf('#')) {
 | 
			
		||||
      comment = obj.__lines[num].replace(/.*?(\s*#.*)/, '$1');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ('[' === pykey[0]) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ('undefined' === typeof pyval) {
 | 
			
		||||
      obj.__lines[num] = "___DELETE_ME___";
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  obj.__lines = obj.__lines.filter(function (line) {
 | 
			
		||||
    if ("___DELETE_ME___" !== line) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if ('string' === typeof endline) {
 | 
			
		||||
    obj.__lines.push(endline);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cb(null, obj.__lines.join('\n'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function writePythonConfFile(pathname, obj, cb) {
 | 
			
		||||
  // TODO re-read file?
 | 
			
		||||
  stringifyPythonConf(obj, function (err, text) {
 | 
			
		||||
    sfs.writeFileAsync(pathname, text, 'utf8').then(function () {
 | 
			
		||||
      cb(null, null);
 | 
			
		||||
    }, function (err) {
 | 
			
		||||
      cb(err);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function parsePythonConfFile(pathname, cb) {
 | 
			
		||||
  fs.readFile(pathname, 'utf8', function (err, text) {
 | 
			
		||||
    if (err) {
 | 
			
		||||
      cb(err);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    parsePythonConf(text, cb);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.parse = parsePythonConf;
 | 
			
		||||
module.exports.readFile = parsePythonConfFile;
 | 
			
		||||
module.exports.stringify = stringifyPythonConf;
 | 
			
		||||
module.exports.writeFile = writePythonConfFile;
 | 
			
		||||
							
								
								
									
										28
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "pyconf",
 | 
			
		||||
  "version": "1.0.0",
 | 
			
		||||
  "description": "Read and write python config files non-destructively (preserves comments)",
 | 
			
		||||
  "main": "index.js",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "test": "node test.js"
 | 
			
		||||
  },
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
    "url": "git+https://github.com/coolaj86/node-config-python.git"
 | 
			
		||||
  },
 | 
			
		||||
  "keywords": [
 | 
			
		||||
    "python",
 | 
			
		||||
    "conf",
 | 
			
		||||
    "config",
 | 
			
		||||
    "comments"
 | 
			
		||||
  ],
 | 
			
		||||
  "author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)",
 | 
			
		||||
  "license": "(MIT OR Apache-2.0)",
 | 
			
		||||
  "bugs": {
 | 
			
		||||
    "url": "https://github.com/coolaj86/node-config-python/issues"
 | 
			
		||||
  },
 | 
			
		||||
  "homepage": "https://github.com/coolaj86/node-config-python#readme",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "safe-replace": "^1.0.2"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								test.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
//var pyconf = require('pyconf');
 | 
			
		||||
var pyconf = require('./');
 | 
			
		||||
 | 
			
		||||
pyconf.readFile('example.conf', function (err, obj) {
 | 
			
		||||
  if (err) {
 | 
			
		||||
    console.error(err.stack);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pyconf.writeFile('example.conf.new', obj, function (err) {
 | 
			
		||||
    if (err) {
 | 
			
		||||
      console.error(err.stack);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    console.log("Run this command to check that the outputs are the same:");
 | 
			
		||||
    console.log("  diff example.conf example.conf.new");
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user