This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
5.1 KiB
201 lines
5.1 KiB
6 years ago
|
|
||
|
/**
|
||
|
* Module dependencies.
|
||
|
*/
|
||
|
|
||
|
var deprecate = require('util-deprecate');
|
||
|
var DOMParser = require('xmldom').DOMParser;
|
||
|
|
||
|
/**
|
||
|
* Module exports.
|
||
|
*/
|
||
|
|
||
|
exports.parse = parse;
|
||
|
exports.parseString = deprecate(parseString, '`parseString()` is deprecated. ' +
|
||
|
'It\'s not actually async. Use `parse()` instead.');
|
||
|
exports.parseStringSync = deprecate(parseStringSync, '`parseStringSync()` is ' +
|
||
|
'deprecated. Use `parse()` instead.');
|
||
|
|
||
|
/**
|
||
|
* We ignore raw text (usually whitespace), <!-- xml comments -->,
|
||
|
* and raw CDATA nodes.
|
||
|
*
|
||
|
* @param {Element} node
|
||
|
* @returns {Boolean}
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function shouldIgnoreNode (node) {
|
||
|
return node.nodeType === 3 // text
|
||
|
|| node.nodeType === 8 // comment
|
||
|
|| node.nodeType === 4; // cdata
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Parses a Plist XML string. Returns an Object.
|
||
|
*
|
||
|
* @param {String} xml - the XML String to decode
|
||
|
* @returns {Mixed} the decoded value from the Plist XML
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
function parse (xml) {
|
||
|
var doc = new DOMParser().parseFromString(xml);
|
||
|
if (doc.documentElement.nodeName !== 'plist') {
|
||
|
throw new Error('malformed document. First element should be <plist>');
|
||
|
}
|
||
|
var plist = parsePlistXML(doc.documentElement);
|
||
|
|
||
|
// the root <plist> node gets interpreted as an Array,
|
||
|
// so pull out the inner data first
|
||
|
if (plist.length == 1) plist = plist[0];
|
||
|
|
||
|
return plist;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Parses a Plist XML string. Returns an Object. Takes a `callback` function.
|
||
|
*
|
||
|
* @param {String} xml - the XML String to decode
|
||
|
* @param {Function} callback - callback function
|
||
|
* @returns {Mixed} the decoded value from the Plist XML
|
||
|
* @api public
|
||
|
* @deprecated not actually async. use parse() instead
|
||
|
*/
|
||
|
|
||
|
function parseString (xml, callback) {
|
||
|
var doc, error, plist;
|
||
|
try {
|
||
|
doc = new DOMParser().parseFromString(xml);
|
||
|
plist = parsePlistXML(doc.documentElement);
|
||
|
} catch(e) {
|
||
|
error = e;
|
||
|
}
|
||
|
callback(error, plist);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Parses a Plist XML string. Returns an Object.
|
||
|
*
|
||
|
* @param {String} xml - the XML String to decode
|
||
|
* @param {Function} callback - callback function
|
||
|
* @returns {Mixed} the decoded value from the Plist XML
|
||
|
* @api public
|
||
|
* @deprecated use parse() instead
|
||
|
*/
|
||
|
|
||
|
function parseStringSync (xml) {
|
||
|
var doc = new DOMParser().parseFromString(xml);
|
||
|
var plist;
|
||
|
if (doc.documentElement.nodeName !== 'plist') {
|
||
|
throw new Error('malformed document. First element should be <plist>');
|
||
|
}
|
||
|
plist = parsePlistXML(doc.documentElement);
|
||
|
|
||
|
// if the plist is an array with 1 element, pull it out of the array
|
||
|
if (plist.length == 1) {
|
||
|
plist = plist[0];
|
||
|
}
|
||
|
return plist;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Convert an XML based plist document into a JSON representation.
|
||
|
*
|
||
|
* @param {Object} xml_node - current XML node in the plist
|
||
|
* @returns {Mixed} built up JSON object
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function parsePlistXML (node) {
|
||
|
var i, new_obj, key, val, new_arr, res, d;
|
||
|
|
||
|
if (!node)
|
||
|
return null;
|
||
|
|
||
|
if (node.nodeName === 'plist') {
|
||
|
new_arr = [];
|
||
|
for (i=0; i < node.childNodes.length; i++) {
|
||
|
// ignore comment nodes (text)
|
||
|
if (!shouldIgnoreNode(node.childNodes[i])) {
|
||
|
new_arr.push( parsePlistXML(node.childNodes[i]));
|
||
|
}
|
||
|
}
|
||
|
return new_arr;
|
||
|
|
||
|
} else if (node.nodeName === 'dict') {
|
||
|
new_obj = {};
|
||
|
key = null;
|
||
|
for (i=0; i < node.childNodes.length; i++) {
|
||
|
// ignore comment nodes (text)
|
||
|
if (!shouldIgnoreNode(node.childNodes[i])) {
|
||
|
if (key === null) {
|
||
|
key = parsePlistXML(node.childNodes[i]);
|
||
|
} else {
|
||
|
new_obj[key] = parsePlistXML(node.childNodes[i]);
|
||
|
key = null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return new_obj;
|
||
|
|
||
|
} else if (node.nodeName === 'array') {
|
||
|
new_arr = [];
|
||
|
for (i=0; i < node.childNodes.length; i++) {
|
||
|
// ignore comment nodes (text)
|
||
|
if (!shouldIgnoreNode(node.childNodes[i])) {
|
||
|
res = parsePlistXML(node.childNodes[i]);
|
||
|
if (null != res) new_arr.push(res);
|
||
|
}
|
||
|
}
|
||
|
return new_arr;
|
||
|
|
||
|
} else if (node.nodeName === '#text') {
|
||
|
// TODO: what should we do with text types? (CDATA sections)
|
||
|
|
||
|
} else if (node.nodeName === 'key') {
|
||
|
return node.childNodes[0].nodeValue;
|
||
|
|
||
|
} else if (node.nodeName === 'string') {
|
||
|
res = '';
|
||
|
for (d=0; d < node.childNodes.length; d++) {
|
||
|
res += node.childNodes[d].nodeValue;
|
||
|
}
|
||
|
return res;
|
||
|
|
||
|
} else if (node.nodeName === 'integer') {
|
||
|
// parse as base 10 integer
|
||
|
return parseInt(node.childNodes[0].nodeValue, 10);
|
||
|
|
||
|
} else if (node.nodeName === 'real') {
|
||
|
res = '';
|
||
|
for (d=0; d < node.childNodes.length; d++) {
|
||
|
if (node.childNodes[d].nodeType === 3) {
|
||
|
res += node.childNodes[d].nodeValue;
|
||
|
}
|
||
|
}
|
||
|
return parseFloat(res);
|
||
|
|
||
|
} else if (node.nodeName === 'data') {
|
||
|
res = '';
|
||
|
for (d=0; d < node.childNodes.length; d++) {
|
||
|
if (node.childNodes[d].nodeType === 3) {
|
||
|
res += node.childNodes[d].nodeValue.replace(/\s+/g, '');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// decode base64 data to a Buffer instance
|
||
|
return new Buffer(res, 'base64');
|
||
|
|
||
|
} else if (node.nodeName === 'date') {
|
||
|
return new Date(node.childNodes[0].nodeValue);
|
||
|
|
||
|
} else if (node.nodeName === 'true') {
|
||
|
return true;
|
||
|
|
||
|
} else if (node.nodeName === 'false') {
|
||
|
return false;
|
||
|
}
|
||
|
}
|