Initial commit

This commit is contained in:
2018-09-16 09:00:12 +08:00
commit f85cec8fd1
350 changed files with 42458 additions and 0 deletions

9
lib/cloudCert.crt Normal file
View File

@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp1C0AJ+H6KeRo77undcx
kyKDn3edWDaTNrxvg4DhlGgCEBAcStoROu+6TKMw5bc/V+U4s7vqfz9vxh4GXtUk
RwPsx2ggrhp08bUYeO9zA9EMFICD6Klva6FALqCLpwv4e8g1CzeKQqhxzAe7v/Ey
dMW4foMyugGHGEO6ZCbHyPMdrg0A4NmpSV/TsWduBbjkq03D63ovAzM+u2lAHHrt
84QShY1ZZoRCHD2F7bRQW906wiVZNfQYKSeTkfc9Ctatuz8JMIq57dlyAF/R6+jC
UodEZvqO9ZTDRGbX2MWDdedRMAt8hPQxjxugiUheMCCrTbdZ5bxeXqyaTLYuzNyV
bwIDAQAB
-----END PUBLIC KEY-----

100
lib/convert.js Normal file
View File

@@ -0,0 +1,100 @@
// this file is used by controller when build uploads
function stringify(name, data, isConvert, files) {
if (isConvert && name.match(/vis-views\.json$/)) {
var parts = name.split('/');
var project = parts.shift();
data = data.toString();
// detect: /vis/, /vis.0/, /icon-blabla/, ...
var m = data.match(/": "\/[-_0-9\w]+(\.[-_0-9\w]+)?\/.+\.(png|jpg|jpeg|gif|wav|mp3|bmp|svg)+"/g);
if (m) {
for (var mm = 0; mm < m.length; mm++) {
var fn = m[mm].substring(5); // remove ": "/
var originalFileName = fn.replace(/"/g, ''); // remove last "
var p = fn.split('/');
var adapter = p.shift(); // remove vis.0 or whatever
var _project = p.length > 1 ? p.shift() : '';
fn = p.length ? p.shift() : ''; // keep only one subdirectory
fn += p.length ? '/' + p.join('/') : '';// all other subdirectories combine again
if (adapter !== 'vis.0' || _project !== project) {
// add to files
if (files.indexOf(originalFileName) === -1) { // if "vis.0/dir/otherProject.png"
files.push(originalFileName);
}
data = data.replace(m[mm], '": "/vis.0/' + project + '/' + fn);
}
}
}
// try to replace <img src="/vis.0/main...">
m = data.match(/src=\\"\/[-_0-9\w]+(\.[-_0-9\w]+)?\/.+\.(png|jpg|jpeg|gif|wav|mp3|bmp|svg)+\\"/g);
if (m) {
for (var mm = 0; mm < m.length; mm++) {
var fn = m[mm].substring(7); // remove src=\"/
var originalFileName = fn.replace(/\\"/g, ''); // remove last "
var p = fn.split('/');
var adapter = p.shift(); // remove vis.0 or whatever
var _project = p.length > 1 ? p.shift() : '';
fn = p.length ? p.shift() : ''; // keep only one subdirectory
fn += p.length ? '/' + p.join('/') : '';// all other subdirectories combine again
if (adapter !== 'vis.0' || _project !== project) {
// add to files
if (files.indexOf(originalFileName) === -1) { // if "vis.0/dir/otherProject.png"
files.push(originalFileName);
}
data = data.replace(m[mm], 'src=\\"/vis.0/' + project + '/' + fn);
}
}
}
// try to replace <img src='/vis.0/main...'>
m = data.match(/src='\/[-_0-9\w]+(\.[-_0-9\w]+)?\/.+\.(png|jpg|jpeg|gif|wav|mp3|bmp|svg)+'/g);
if (m) {
for (var mm = 0; mm < m.length; mm++) {
var fn = m[mm].substring(6); // remove src="/
var originalFileName = fn.replace(/'/g, ''); // remove last "
var p = fn.split('/');
var adapter = p.shift(); // remove vis.0 or whatever
var _project = p.length > 1 ? p.shift() : '';
fn = p.length ? p.shift() : ''; // keep only one subdirectory
fn += p.length ? '/' + p.join('/') : '';// all other subdirectories combine again
if (adapter !== 'vis.0' || _project !== project) {
// add to files
if (files.indexOf(originalFileName) === -1) { // if "vis.0/dir/otherProject.png"
files.push(originalFileName);
}
data = data.replace(m[mm], "src='/vis.0/" + project + '/' + fn);
}
}
}
// try to replace <img src='/vis.0/main...'>
m = data.match(/\.[A-Z]{3}\d{7}\./g);
if (m) {
for (var t = 0; t < m.length; t++) {
data = data.replace(m[t], '.ABC' + Math.round(Math.random() * 1000000) + '.');
}
}
// try to replace 12.13.14.15
data = data.replace(/\/\/(?:[0-9]{1,3}\.){3}[0-9]{1,3}\//g, '//127.0.0.1/');
// try to replace http://user:pass@address/
data = data.replace(/((http|https):\/\/)?([-\w0-9_.]+?):([-\w0-9_*.]+)?@[-\w0-9.]+\//g, '//127.0.0.1/');
}
return data;
}
function parse(projectName, fileName, data, settings) {
if (fileName.match(/vis-views\.json$/)) {
// Check if all images are in the right directory
var project = projectName;
if (project[project.length - 1] === '/') project = project.substring(0, project.length - 1);
data = data.toString();
// detect: "/vis.0/project/picture.png"
data = data.replace(/"\/vis.0\/([-_0-9\w]+)\//g, '"/vis.0/' + project + '/');
data = data.replace(/'\/vis.0\/([-_0-9\w]+)\//g, "'/vis.0/" + project + '/');
}
return data;
}
module.exports.stringify = stringify;
module.exports.parse = parse;

211
lib/install.js Normal file
View File

@@ -0,0 +1,211 @@
var fs = require('fs');
var path = require('path');
function copyFileSync(source, target) {
var targetFile = target;
//if target is a directory a new file with the same name will be created
if (fs.existsSync(target)) {
if (fs.lstatSync(target).isDirectory()) {
targetFile = path.join(target, path.basename(source));
}
}
fs.writeFileSync(targetFile, fs.readFileSync(source));
}
function copyFolderRecursiveSync(source, target) {
var files = [];
//check if folder needs to be created or integrated
var targetFolder = path.join(target, path.basename(source));
if (!fs.existsSync(targetFolder)) {
fs.mkdirSync(targetFolder);
}
//copy
if (fs.lstatSync(source).isDirectory() ) {
files = fs.readdirSync( source );
files.forEach(function (file) {
var curSource = path.join(source, file);
if (fs.lstatSync(curSource).isDirectory()) {
copyFolderRecursiveSync(curSource, targetFolder);
} else {
copyFileSync(curSource, targetFolder);
}
});
}
}
function deleteFolderRecursive (path) {
var files = [];
if (fs.existsSync(path)) {
files = fs.readdirSync(path);
files.forEach(function(file, index){
var curPath = path + '/' + file;
if(fs.lstatSync(curPath).isDirectory()) { // recurse
deleteFolderRecursive(curPath);
} else { // delete file
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(path);
}
}
var generic = [
'basic',
'jqplot',
'jqui',
'tabs',
'swipe'
];
var widgetSetsDependencies = {
jqui: ['basic']
};
function syncWidgetSets(onlyLocal, isLicenseError) {
if (process.argv.indexOf('--beta') !== -1) return;
var pack = null;
var changed = false;
var found;
var name;
var path = __dirname + '/../../';
// find all installed widget sets
if (onlyLocal) {
path = __dirname + '/../node_modules/';
} else {
path = __dirname + '/../../';
}
var dirs = fs.readdirSync(path);
var sets = [];
for (var d = 0; d < dirs.length; d++) {
if (dirs[d].match(/^iobroker\./i) && fs.existsSync(path + dirs[d] + '/widgets/')) {
pack = null;
try {
pack = JSON.parse(fs.readFileSync(path + dirs[d] + '/io-package.json').toString());
} catch (e) {
console.warn('Cannot parse "' + path + dirs[d] + '/io-package.json": ' + e);
}
sets.push({path: path + dirs[d], name: dirs[d].toLowerCase(), pack: pack});
}
}
if (!onlyLocal) {
try {
dirs = fs.readdirSync(__dirname + '/../../../../');
for (d = 0; d < dirs.length; d++) {
if (dirs[d].match(/^iobroker\./i) && fs.existsSync(__dirname + '/../../../../' + dirs[d] + '/widgets/')) {
found = false;
name = dirs[d].toLowerCase();
for (var s = 0; s < sets.length; s++) {
if (sets[s].name === name) {
found = true;
break;
}
}
if (!found) {
pack = null;
try {
pack = JSON.parse(fs.readFileSync(__dirname + '/../../../../' + dirs[d] + '/io-package.json').toString());
} catch (e) {
console.warn('Cannot parse "' + __dirname + '/../../../../' + dirs[d] + '/io-package.json": ' + e);
}
sets.push({path: __dirname + '/../../../../' + dirs[d], name: dirs[d].toLowerCase()});
}
}
}
} catch (e) {
}
}
// Now we have the list of widgets => copy them all to widgets directory
for (d = 0; d < sets.length; d++) {
copyFolderRecursiveSync(sets[d].path + '/widgets/', __dirname + '/../www/');
}
var widgetSets = [];
// Read the list of installed widgets
var installed = fs.readdirSync(__dirname + '/../www/widgets/');
for (d = 0; d < installed.length; d++) {
if (installed[d].match(/\.html$/)) {
name = installed[d].replace('.html', '');
var isGeneric = generic.indexOf(name) !== -1;
found = isGeneric;
if (!found) {
for (var b = 0; b < sets.length; b++) {
var ssName = sets[b].name.toLowerCase();
if (ssName === 'iobroker.vis-' + name || ssName === 'iobroker.' + name) {
found = true;
break;
}
}
}
if (!found) {
changed = true;
//delete
fs.unlinkSync(__dirname + '/../www/widgets/' + name + '.html');
if (fs.existsSync(__dirname + '/../www/widgets/' + name)) {
deleteFolderRecursive(__dirname + '/../www/widgets/' + name);
}
}
else {
if (isGeneric) {
if (widgetSetsDependencies[name] && widgetSetsDependencies[name].length) {
widgetSets.push({name: name, depends: widgetSetsDependencies[name]});
} else {
widgetSets.push(name);
}
} else {
for (var g = 0; g < sets.length; g++) {
var sName = sets[g].name.toLowerCase();
if (sName === 'iobroker.vis-' + name || sName === 'iobroker.' + name) {
if (sets[g].pack && sets[g].pack.native && sets[g].pack.native.always) {
widgetSets.push({name: name, always: true});
} else if (sets[g].pack && sets[g].pack.native && sets[g].pack.native.dependencies) {
widgetSets.push({name: name, depends: sets[g].pack.native.dependencies});
} else {
widgetSets.push(name);
}
break;
}
}
}
}
}
}
// build config file
var visConfig = {
widgetSets: widgetSets
};
var text = 'var visConfig = ' + JSON.stringify(visConfig, null, 4) + ';\n';
if (isLicenseError) {
text = text.replace('var visConfig = {', 'var visConfig = {license: false,');
}
text += 'if (typeof exports !== \'undefined\') {\n';
text += ' exports.config = visConfig;\n';
text += '} else {\n';
text += ' visConfig.language = window.navigator.userLanguage || window.navigator.language;\n';
text += '}\n';
var oldText = fs.readFileSync(__dirname + '/../www/js/config.js').toString();
if (oldText !== text) {
fs.writeFileSync(__dirname + '/../www/js/config.js', text);
return text;
} else {
return false;
}
}
if (typeof module !== 'undefined' && module.parent) {
module.exports = syncWidgetSets;
} else {
syncWidgetSets();
}

53
lib/states.js Normal file
View File

@@ -0,0 +1,53 @@
var getUsedObjectIDs = require(__dirname + '/../www/js/visUtils').getUsedObjectIDs;
function calcProject(objects, projects, instance, result, callback) {
if (!projects || !projects.length) {
callback(null, result || []);
return;
}
result = result || [];
var project = projects.shift();
if (!project || !project.isDir) {
setImmediate(calcProject, objects, projects, instance, result, callback);
return;
}
// calculate datapoints in one project
objects.readFile('vis.' + instance, '/' + project.file + '/vis-views.json', function (err, data) {
var json;
try {
json = JSON.parse(data);
} catch (e) {
console.error('Cannot parse "/' + project.file + '/vis-views.json');
setImmediate(calcProject, objects, projects, instance, result, callback);
return;
}
var dps = getUsedObjectIDs(json, false);
if (dps && dps.IDs) {
result.push({id: 'vis.' + instance + '.datapoints.' + project.file.replace(/[.\\s]/g, '_'), val: dps.IDs.length});
}
setImmediate(calcProject, objects, projects, instance, result, callback);
});
}
function calcProjects(objects, states, instance, config, callback) {
objects.readDir('vis.' + instance, '/', function (err, projects) {
if (err || !projects || !projects.length) {
callback && callback(err || null, [{id: 'vis.' + instance + '.datapoints.total', val: 0}]);
} else {
calcProject(objects, projects, instance, [], function (err, result) {
if (result && result.length) {
var total = 0;
for (var r = 0; r < result.length; r++) {
total += result[r].val;
}
result.push({id: 'vis.' + instance + '.datapoints.total', val: total});
}
callback && callback(err, result);
});
}
});
}
module.exports = calcProjects;

83
lib/utils.js Normal file
View File

@@ -0,0 +1,83 @@
'use strict';
const fs = require('fs');
const path = require('path');
let controllerDir;
let appName;
/**
* returns application name
*
* The name of the application can be different and this function finds it out.
*
* @returns {string}
*/
function getAppName() {
const parts = __dirname.replace(/\\/g, '/').split('/');
return parts[parts.length - 2].split('.')[0];
}
/**
* looks for js-controller home folder
*
* @param {boolean} isInstall
* @returns {string}
*/
function getControllerDir(isInstall) {
// Find the js-controller location
const possibilities = [
'iobroker.js-controller',
'ioBroker.js-controller',
];
/** @type {string} */
let controllerPath;
for (const pkg of possibilities) {
try {
const possiblePath = require.resolve(pkg);
if (fs.existsSync(possiblePath)) {
controllerPath = possiblePath;
break;
}
} catch (e) { /* not found */ }
}
if (controllerPath == null) {
if (!isInstall) {
console.log('Cannot find js-controller');
process.exit(10);
} else {
process.exit();
}
}
// we found the controller
return path.dirname(controllerPath);
}
/**
* reads controller base settings
*
* @alias getConfig
* @returns {object}
*/
function getConfig() {
let configPath;
if (fs.existsSync(
configPath = path.join(controllerDir, 'conf', appName + '.json')
)) {
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
} else if (fs.existsSync(
configPath = path.join(controllerDir, 'conf', + appName.toLowerCase() + '.json')
)) {
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
} else {
throw new Error('Cannot find ' + controllerDir + '/conf/' + appName + '.json');
}
}
appName = getAppName();
controllerDir = getControllerDir(typeof process !== 'undefined' && process.argv && process.argv.indexOf('--install') !== -1);
const adapter = require(path.join(controllerDir, 'lib/adapter.js'));
exports.controllerDir = controllerDir;
exports.getConfig = getConfig;
exports.Adapter = adapter;
exports.appName = appName;