diff --git a/config.default.js b/config.default.js
new file mode 100644
index 0000000..fbd016b
--- /dev/null
+++ b/config.default.js
@@ -0,0 +1,188 @@
+module.exports = function () {
+ return {
+ 'reverseGeocodingApi': 'https://nominatim.openstreetmap.org/reverse',
+ 'maxAge': 14,
+ 'maxAgeAlert': 3,
+ 'nodeZoom': 18,
+ 'labelZoom': 13,
+ 'clientZoom': 15,
+ 'nodeAttr': [
+ // value can be a node attribute (1 depth) or a a function in utils/node with prefix show
+ {
+ 'name': 'node.status',
+ 'value': 'Status'
+ },
+ {
+ 'name': 'node.gateway',
+ 'value': 'Gateway'
+ },
+ {
+ 'name': 'node.coordinates',
+ 'value': 'GeoURI'
+ },
+ // {
+ // "name": "node.contact",
+ // "value": "owner"
+ // },
+
+ // Examples for functions
+ // {
+ // // no name will remove first column
+ // 'value': function (d) {
+ // var moment = require('moment');
+ // var V = require('snabbdom').default;
+ // return V.h('td', { props: { colSpan: 2 }, style: { background: '#49a' } },
+ // _.t('sidebar.nodeOnline') + ' translate, ' + moment(d.firstseen).get('month') +
+ // ' Month require libs like moment, access config ' + config.siteName);
+ // }
+ // },
+ // {
+ // 'name': 'Neighbour first seen',
+ // 'value': function (d, nodeDict) {
+ // return nodeDict[d.gateway_nexthop].firstseen.format() + 'access node object';
+ // }
+ // },
+ {
+ 'name': 'node.hardware',
+ 'value': 'model'
+ },
+ {
+ 'name': 'node.primaryMac',
+ 'value': 'mac'
+ },
+ {
+ 'name': 'node.firmware',
+ 'value': 'Firmware'
+ },
+ {
+ 'name': 'node.uptime',
+ 'value': 'Uptime'
+ },
+ {
+ 'name': 'node.firstSeen',
+ 'value': 'FirstSeen'
+ },
+ {
+ 'name': 'node.systemLoad',
+ 'value': 'Load'
+ },
+ {
+ 'name': 'node.ram',
+ 'value': 'RAM'
+ },
+ {
+ 'name': 'node.ipAddresses',
+ 'value': 'IPs'
+ },
+ {
+ 'name': 'node.update',
+ 'value': 'Autoupdate'
+ },
+ {
+ 'name': 'node.site',
+ 'value': 'Site'
+ },
+ {
+ 'name': 'node.clients',
+ 'value': 'Clients'
+ }
+ ],
+ 'supportedLocale': [
+ 'en',
+ 'de',
+ 'fr',
+ 'ru'
+ ],
+ // Color configs
+ 'icon': {
+ 'base': {
+ 'fillOpacity': 0.6,
+ 'opacity': 0.6,
+ 'weight': 2,
+ 'radius': 6,
+ 'className': 'stroke-first'
+ },
+ 'online': {
+ 'color': '#1566A9',
+ 'fillColor': '#1566A9'
+ },
+ 'offline': {
+ 'color': '#D43E2A',
+ 'fillColor': '#D43E2A',
+ 'radius': 3
+ },
+ 'lost': {
+ 'color': '#D43E2A',
+ 'fillColor': '#D43E2A',
+ 'radius': 4
+ },
+ 'alert': {
+ 'color': '#D43E2A',
+ 'fillColor': '#D43E2A',
+ 'radius': 5
+ },
+ 'new': {
+ 'color': '#1566A9',
+ 'fillColor': '#93E929'
+ }
+ },
+ 'client': {
+ 'wifi24': 'rgba(220, 0, 103, 0.7)',
+ 'wifi5': 'rgba(10, 156, 146, 0.7)',
+ 'other': 'rgba(227, 166, 25, 0.7)'
+ },
+ 'map': {
+ 'labelNewColor': '#459c18',
+ 'tqFrom': '#F02311',
+ 'tqTo': '#04C714',
+ 'highlightNode': {
+ 'color': '#ad2358',
+ 'weight': 8,
+ 'fillOpacity': 1,
+ 'opacity': 0.4,
+ 'className': 'stroke-first'
+ },
+ 'highlightLink': {
+ 'weight': 4,
+ 'opacity': 1,
+ 'dashArray': '5, 10'
+ }
+ },
+ 'forceGraph': {
+ 'nodeColor': '#fff',
+ 'highlightColor': 'rgba(255, 255, 255, 0.2)',
+ 'labelColor': '#fff',
+ 'tqFrom': '#770038',
+ 'tqTo': '#dc0067'
+ },
+ 'locate': {
+ 'outerCircle': {
+ 'stroke': false,
+ 'color': '#4285F4',
+ 'opacity': 1,
+ 'fillOpacity': 0.3,
+ 'clickable': false,
+ 'radius': 16
+ },
+ 'innerCircle': {
+ 'stroke:': true,
+ 'color': '#ffffff',
+ 'fillColor': '#4285F4',
+ 'weight': 1.5,
+ 'clickable': false,
+ 'opacity': 1,
+ 'fillOpacity': 1,
+ 'radius': 7
+ },
+ 'accuracyCircle': {
+ 'stroke': true,
+ 'color': '#4285F4',
+ 'weight': 1,
+ 'clickable': false,
+ 'opacity': 0.7,
+ 'fillOpacity': 0.2
+ }
+ },
+ 'cacheBreaker': ''
+ };
+};
diff --git a/config.default.json b/config.default.json
deleted file mode 100644
index 9ad9529..0000000
--- a/config.default.json
+++ /dev/null
@@ -1,169 +0,0 @@
-// Gulp will remove all comments
-{
- "reverseGeocodingApi": "https://nominatim.openstreetmap.org/reverse",
- "maxAge": 14,
- "maxAgeAlert": 3,
- "nodeZoom": 18,
- "labelZoom": 13,
- "clientZoom": 15,
- "nodeAttr": [
- // value can be a node attribute (1 depth) or a a function in utils/node with prefix show
- {
- "name": "node.status",
- "value": "Status"
- },
- {
- "name": "node.gateway",
- "value": "Gateway"
- },
- {
- "name": "node.coordinates",
- "value": "GeoURI"
- },
- // {
- // "name": "node.contact",
- // "value": "owner"
- // },
- {
- "name": "node.hardware",
- "value": "model"
- },
- {
- "name": "node.primaryMac",
- "value": "mac"
- },
- {
- "name": "node.firmware",
- "value": "Firmware"
- },
- {
- "name": "node.uptime",
- "value": "Uptime"
- },
- {
- "name": "node.firstSeen",
- "value": "FirstSeen"
- },
- {
- "name": "node.systemLoad",
- "value": "Load"
- },
- {
- "name": "node.ram",
- "value": "RAM"
- },
- {
- "name": "node.ipAddresses",
- "value": "IPs"
- },
- {
- "name": "node.update",
- "value": "Autoupdate"
- },
- {
- "name": "node.site",
- "value": "Site"
- },
- {
- "name": "node.clients",
- "value": "Clients"
- }
- ],
- "supportedLocale": [
- "en",
- "de",
- "fr",
- "ru"
- ],
- // Color configs
- "icon": {
- "base": {
- "fillOpacity": 0.6,
- "opacity": 0.6,
- "weight": 2,
- "radius": 6,
- "className": "stroke-first"
- },
- "online": {
- "color": "#1566A9",
- "fillColor": "#1566A9"
- },
- "offline": {
- "color": "#D43E2A",
- "fillColor": "#D43E2A",
- "radius": 3
- },
- "lost": {
- "color": "#D43E2A",
- "fillColor": "#D43E2A",
- "radius": 4
- },
- "alert": {
- "color": "#D43E2A",
- "fillColor": "#D43E2A",
- "radius": 5
- },
- "new": {
- "color": "#1566A9",
- "fillColor": "#93E929"
- }
- },
- "client": {
- "wifi24": "rgba(220, 0, 103, 0.7)",
- "wifi5": "rgba(10, 156, 146, 0.7)",
- "other": "rgba(227, 166, 25, 0.7)"
- },
- "map": {
- "labelNewColor": "#459c18",
- "tqFrom": "#F02311",
- "tqTo": "#04C714",
- "highlightNode": {
- "color": "#ad2358",
- "weight": 8,
- "fillOpacity": 1,
- "opacity": 0.4,
- "className": "stroke-first"
- },
- "highlightLink": {
- "weight": 4,
- "opacity": 1,
- "dashArray": "5, 10"
- }
- },
- "forceGraph": {
- "nodeColor": "#fff",
- "highlightColor": "rgba(255, 255, 255, 0.2)",
- "labelColor": "#fff",
- "tqFrom": "#770038",
- "tqTo": "#dc0067"
- },
- "locate": {
- "outerCircle": {
- "stroke": false,
- "color": "#4285F4",
- "opacity": 1,
- "fillOpacity": 0.3,
- "clickable": false,
- "radius": 16
- },
- "innerCircle": {
- "stroke:": true,
- "color": "#ffffff",
- "fillColor": "#4285F4",
- "weight": 1.5,
- "clickable": false,
- "opacity": 1,
- "fillOpacity": 1,
- "radius": 7
- },
- "accuracyCircle": {
- "stroke": true,
- "color": "#4285F4",
- "weight": 1,
- "clickable": false,
- "opacity": 0.7,
- "fillOpacity": 0.2
- }
- },
- "cacheBreaker": ""
-}
diff --git a/config.js b/config.js
new file mode 100644
index 0000000..43fe25b
--- /dev/null
+++ b/config.js
@@ -0,0 +1,119 @@
+module.exports = function () {
+ return {
+ // Variables are NODE_ID and NODE_NAME (only a-z0-9\- other chars are replaced with _)
+ 'nodeInfos': [
+ {
+ 'name': 'Clientstatistik',
+ 'href': 'https://regensburg.freifunk.net/netz/statistik/node/{NODE_ID}/',
+ 'image': 'https://grafana.regensburg.freifunk.net/render/dashboard-solo/db/ffrgb-all-nodes?panelId=1&from=now-7d&var-nodeid={NODE_ID}&var-host={NODE_NAME}&width=650&height=350&theme=light&_t={TIME}',
+ 'title': 'Knoten {NODE_ID} - weiteren Statistiken'
+ },
+ {
+ 'name': 'Trafficstatistik',
+ 'href': 'https://regensburg.freifunk.net/netz/statistik/node/{NODE_ID}/',
+ 'image': 'https://grafana.regensburg.freifunk.net/render/dashboard-solo/db/ffrgb-all-nodes?panelId=2&from=now-7d&var-nodeid={NODE_ID}&var-host={NODE_NAME}&width=650&height=350&theme=light&_t={TIME}',
+ 'title': 'Knoten {NODE_ID} - weiteren Statistiken'
+ }
+ ],
+ 'globalInfos': [
+ {
+ 'name': 'Statistik',
+ 'href': 'https://regensburg.freifunk.net/netz/statistik/',
+ 'image': 'https://grafana.regensburg.freifunk.net/render/dashboard-solo/db/ffrgb-network-wide-stats?panelId=11&from=now-1y&width=600&height=350&theme=light',
+ 'title': 'Jahresstatistik - weiteren Statistiken'
+ }
+ ],
+ // Array of data provider are supported
+ 'dataPath': [
+ 'https://regensburg.freifunk.net/data/'
+ ],
+ 'siteName': 'Freifunk Regensburg',
+ 'mapLayers': [
+ {
+ 'name': 'Freifunk Regensburg',
+ // Please ask Freifunk Regensburg before using its tile server c- example with retina tiles
+ 'url': 'https://{s}.tiles.ffrgb.net/{z}/{x}/{y}{retina}.png',
+ 'config': {
+ 'maxZoom': 20,
+ 'subdomains': '1234',
+ 'attribution': '© OpenMapTiles © OpenStreetMap contributors',
+ 'start': 6
+ }
+ },
+ {
+ 'name': 'Freifunk Regensburg Night',
+ // Please ask Freifunk Regensburg before using its tile server - example with retina and dark tiles
+ 'url': 'https://{s}.tiles.ffrgb.net/n/{z}/{x}/{y}{retina}.png',
+ 'config': {
+ 'maxZoom': 20,
+ 'subdomains': '1234',
+ 'attribution': ' © OpenMapTiles © OpenStreetMap contributors',
+ 'mode': 'night',
+ 'start': 19,
+ 'end': 7
+ }
+ },
+ {
+ 'name': 'OpenStreetMap.HOT',
+ 'url': 'https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
+ 'config': {
+ 'maxZoom': 19,
+ 'attribution': '© Openstreetmap France | © OpenStreetMap'
+ }
+ },
+ {
+ 'name': 'HERE',
+ // Please use your own API key - Free plan is on right side after the pay plans
+ 'url': 'https://{s}.base.maps.api.here.com/maptile/2.1/maptile/newest/normal.day/{z}/{x}/{y}/256/png8?app_id=YOUR_KEY&app_code=YOUR_CODE&lg=deu',
+ 'config': {
+ 'attribution': 'Map © 1987-2014 HERE',
+ 'subdomains': '1234',
+ 'maxZoom': 20
+ }
+ },
+ {
+ 'name': 'Esri.WorldImagery',
+ 'url': '//server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
+ 'config': {
+ 'maxZoom': 20,
+ 'attribution': 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
+ }
+ },
+ {
+ 'name': 'HERE.hybridDay',
+ // Please use your own API key - Free plan is on right side after the pay plans
+ 'url': 'https://{s}.aerial.maps.api.here.com/maptile/2.1/maptile/newest/{variant}/{z}/{x}/{y}/256/png8?app_id=YOUR_KEY&app_code=YOUR_CODE&lg=deu',
+ 'config': {
+ 'attribution': 'Map © 1987-2014 HERE',
+ 'subdomains': '1234',
+ 'variant': 'hybrid.day',
+ 'maxZoom': 20
+ }
+ }
+ ],
+ // Set a visible frame
+ 'fixedCenter': [
+ // Northwest
+ [
+ 49.3522,
+ 11.7752
+ ],
+ // Southeast
+ [
+ 48.7480,
+ 12.8917
+ ]
+ ],
+ 'siteNames': [
+ {
+ 'site': 'ffrgb-bat15',
+ 'name': 'Regensburg'
+ },
+ {
+ 'site': 'ffrgb',
+ 'name': 'Regensburg'
+ }
+ ]
+ };
+};
+
diff --git a/config.json b/config.json
deleted file mode 100644
index 527e2ef..0000000
--- a/config.json
+++ /dev/null
@@ -1,117 +0,0 @@
-// Gulp will remove all comments
-{
- // Variables are NODE_ID and NODE_NAME (only a-z0-9\- other chars are replaced with _)
- "nodeInfos": [
- {
- "name": "Clientstatistik",
- "href": "https://regensburg.freifunk.net/netz/statistik/node/{NODE_ID}/",
- "image": "https://grafana.regensburg.freifunk.net/render/dashboard-solo/db/ffrgb-all-nodes?panelId=1&from=now-7d&var-nodeid={NODE_ID}&var-host={NODE_NAME}&width=650&height=350&theme=light&_t={TIME}",
- "title": "Knoten {NODE_ID} - weiteren Statistiken"
- },
- {
- "name": "Trafficstatistik",
- "href": "https://regensburg.freifunk.net/netz/statistik/node/{NODE_ID}/",
- "image": "https://grafana.regensburg.freifunk.net/render/dashboard-solo/db/ffrgb-all-nodes?panelId=2&from=now-7d&var-nodeid={NODE_ID}&var-host={NODE_NAME}&width=650&height=350&theme=light&_t={TIME}",
- "title": "Knoten {NODE_ID} - weiteren Statistiken"
- }
- ],
- "globalInfos": [
- {
- "name": "Statistik",
- "href": "https://regensburg.freifunk.net/netz/statistik/",
- "image": "https://grafana.regensburg.freifunk.net/render/dashboard-solo/db/ffrgb-network-wide-stats?panelId=11&from=now-1y&width=600&height=350&theme=light",
- "title": "Jahresstatistik - weiteren Statistiken"
- }
- ],
- // Array of data provider are supported
- "dataPath": [
- "https://regensburg.freifunk.net/data/"
- ],
- "siteName": "Freifunk Regensburg",
- "mapLayers": [
- {
- "name": "Freifunk Regensburg",
- // Please ask Freifunk Regensburg before using its tile server c- example with retina tiles
- "url": "https://{s}.tiles.ffrgb.net/{z}/{x}/{y}{retina}.png",
- "config": {
- "maxZoom": 20,
- "subdomains": "1234",
- "attribution": "© OpenMapTiles © OpenStreetMap contributors",
- "start": 6
- }
- },
- {
- "name": "Freifunk Regensburg Night",
- // Please ask Freifunk Regensburg before using its tile server - example with retina and dark tiles
- "url": "https://{s}.tiles.ffrgb.net/n/{z}/{x}/{y}{retina}.png",
- "config": {
- "maxZoom": 20,
- "subdomains": "1234",
- "attribution": " © OpenMapTiles © OpenStreetMap contributors",
- "mode": "night",
- "start": 19,
- "end": 7
- }
- },
- {
- "name": "OpenStreetMap.HOT",
- "url": "https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",
- "config": {
- "maxZoom": 19,
- "attribution": "© Openstreetmap France | © OpenStreetMap"
- }
- },
- {
- "name": "HERE",
- // Please use your own API key - Free plan is on right side after the pay plans
- "url": "https://{s}.base.maps.api.here.com/maptile/2.1/maptile/newest/normal.day/{z}/{x}/{y}/256/png8?app_id=YOUR_KEY&app_code=YOUR_CODE&lg=deu",
- "config": {
- "attribution": "Map © 1987-2014 HERE",
- "subdomains": "1234",
- "maxZoom": 20
- }
- },
- {
- "name": "Esri.WorldImagery",
- "url": "//server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
- "config": {
- "maxZoom": 20,
- "attribution": "Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community"
- }
- },
- {
- "name": "HERE.hybridDay",
- // Please use your own API key - Free plan is on right side after the pay plans
- "url": "https://{s}.aerial.maps.api.here.com/maptile/2.1/maptile/newest/{variant}/{z}/{x}/{y}/256/png8?app_id=YOUR_KEY&app_code=YOUR_CODE&lg=deu",
- "config": {
- "attribution": "Map © 1987-2014 HERE",
- "subdomains": "1234",
- "variant": "hybrid.day",
- "maxZoom": 20
- }
- }
- ],
- // Set a visible frame
- "fixedCenter": [
- // Northwest
- [
- 49.3522,
- 11.7752
- ],
- // Southeast
- [
- 48.7480,
- 12.8917
- ]
- ],
- "siteNames": [
- {
- "site": "ffrgb-bat15",
- "name": "Regensburg"
- },
- {
- "site": "ffrgb",
- "name": "Regensburg"
- }
- ]
-}
diff --git a/gulp/config.js b/gulp/config.js
index 18d15e7..f6c5fa8 100644
--- a/gulp/config.js
+++ b/gulp/config.js
@@ -8,7 +8,7 @@ module.exports = function () {
sass: 'scss/**/*.scss',
javascript: ['./app.js', 'lib/**/*.js'],
json: 'locale/*.json',
- html: ['html/*.html', './config*.json']
+ html: ['html/*.html', './config*.js']
},
clean: [build + '/*.map', build + '/vendor', build + '/main.css'],
autoprefixer: ['> 1% in DE'],
diff --git a/gulp/tasks/html.js b/gulp/tasks/html.js
index 2c1aa0e..7149d5d 100644
--- a/gulp/tasks/html.js
+++ b/gulp/tasks/html.js
@@ -1,21 +1,36 @@
const fs = require('fs');
+
+// stringify functions https://gist.github.com/cowboy/3749767
+var stringify = function (obj, prop) {
+ var placeholder = '____PLACEHOLDER____';
+ var fns = [];
+ var json = JSON.stringify(obj, function (key, value) {
+ if (typeof value === 'function') {
+ fns.push(value);
+ return placeholder;
+ }
+ return value;
+ }, 2);
+ json = json.replace(new RegExp('"' + placeholder + '"', 'g'), function () {
+ return fns.shift();
+ });
+ return 'this["' + prop + '"] = ' + json + ';';
+};
+
module.exports = function (gulp, plugins, config, env) {
return function html() {
return gulp.src(env.production() ? config.build + '/*.html' : 'html/*.html')
- .pipe(plugins.inject(gulp.src(['config.json']), {
+ .pipe(plugins.inject(gulp.src(['config.js']), {
starttag: '',
- transform: function (filePath, customConfig) {
- var defaultConfig = fs.readFileSync('config.default.json', 'utf8');
- var buildConfig = Object.assign(
- JSON.parse(JSON.minify(defaultConfig)),
- JSON.parse(JSON.minify(customConfig.contents.toString('utf8')))
- );
+ transform: function () {
+ delete require.cache[require.resolve('../../config.default')];
+ delete require.cache[require.resolve('../../config')];
+ var buildConfig = Object.assign({}, require('../../config.default')(), require('../../config')());
return ''
- ;
+ ';';
}
}))
.pipe(env.production(plugins.kyhInlineSource({ compress: false })))
diff --git a/lib/infobox/node.js b/lib/infobox/node.js
index c11c50c..da0379e 100644
--- a/lib/infobox/node.js
+++ b/lib/infobox/node.js
@@ -123,7 +123,9 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper', 'utils/no
config.nodeAttr.forEach(function (row) {
var field = d[row.value];
- if (nodef['show' + row.value] !== undefined) {
+ if (typeof row.value === 'function') {
+ field = row.value(d, nodeDict);
+ } else if (nodef['show' + row.value] !== undefined) {
field = nodef['show' + row.value](d);
}
@@ -131,9 +133,8 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper', 'utils/no
if (typeof field !== 'object') {
field = V.h('td', field);
}
-
children.push(V.h('tr', [
- V.h('th', _.t(row.name)),
+ row.name !== undefined ? V.h('th', _.t(row.name)) : null,
field
]));
}