From 6bcd05dc8a813025d31c31805784803d6f9537f9 Mon Sep 17 00:00:00 2001 From: Rob Vella Date: Thu, 30 Jul 2020 21:30:36 -0700 Subject: [PATCH] Create server-side stuff --- .gitignore | 1 + app.js | 106 +++++++++++++++++++++++++++++++++---------------- css/styles.css | 26 ++++++++++++ fetchData.php | 99 +++++++++++++++++++++++++++++++++++++++++++++ index.html | 24 ++++++----- 5 files changed, 212 insertions(+), 44 deletions(-) create mode 100644 fetchData.php diff --git a/.gitignore b/.gitignore index f3cd9a0..5617c92 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ yarn-error.log +storage/* diff --git a/app.js b/app.js index 89126e3..82d1f89 100644 --- a/app.js +++ b/app.js @@ -1,19 +1,18 @@ -Vue.component('lt-startstop', { - template: '', +Vue.component('lt-node-link', { + template: `{{ node }}`, + props: ['node', 'type'], data() { return { - buttonState: false + uri: '', + urlMap: { + 0: '#', + 1: 'http://stats.allstarlink.org/nodeinfo.cgi?node=', + 2: 'http://www.irlp.net/status/index.php?nodeid=' + } } }, mounted() { - this.toggleTail(); - }, - methods: { - toggleTail() { - this.buttonState = !this.buttonState; - this.$emit('click', this.buttonState); - } + this.uri = this.urlMap[this.type] + this.node; } }); @@ -25,9 +24,13 @@ let App = new Vue({ intervalTimer: null, fetchEvery: 2000, // uri = 'http://www3.winsystem.org/monitor/ajax-logtail.php' - uri: 'testdata.txt', + uri: 'fetchData.php', lastData: null, logs: [], + nodes: { + 1: [], + 2: [] + }, nodeTypeLabels: { 0: 'Unknown', 1: 'Allstar', @@ -39,9 +42,12 @@ let App = new Vue({ } } }, + mounted() { + this.toggleTail(); + }, methods: { - toggleTail(state) { - this.enabled = state; + toggleTail() { + this.enabled = !this.enabled; if (this.enabled) { this.start(); @@ -63,29 +69,42 @@ let App = new Vue({ }, fetchLog() { - axios.get(this.uri).then(({data}) => { + // Force re-render component so it updates callsigns & node info + this.$forceUpdate(); + + axios.get(this.uri + '?cmd=log').then(({data}) => { this.lastData = data; this.parseLogData(); }); }, + getNodeInfo(node, type) { + if (typeof this.nodes[type][node] !== "undefined") { + let info = this.nodes[type][node]; + if (typeof info.callsign === "undefined") return; + return `${info.callsign} ${info.desc} ${info.location}`; + } else { + return ''; + } + }, + parseLogData() { - this.logs = []; - let rows = this.lastData.split("\n").reverse(); + let rows = this.lastData.split("\n"); - rows.forEach((v) => { + rows.forEach(async (v) => { let match = v.match(/([A-Za-z]+ [0-9]+ [0-9]+\:[0-9]+\:[0-9]+) (rpt|stn)([A-Za-z0-9]+) .*? (?:\[(?:via) ([0-9]+))?/); if (!match) return; let type = this.getNodeType(match[2]); + this.addEntry( { node: match[3], via: match[4], type: type, typeLabel: this.getNodeTypeLabel(type), - desc: this.fetchNodeInfo(match[3], type), - dateTime: match[1], + info: this.fetchNodeInfo(match[3], type), + dateTime: moment(match[1], "MMM DD hh:mm:ss"), } ); }); @@ -100,22 +119,41 @@ let App = new Vue({ }, fetchNodeInfo(node, type) { - return type === 1 ? this.fetchNodeInfoAllstar(node) - : (type === 2 ? this.fetchNodeInfoIRLP(node) : null); - }, - - fetchNodeInfoAllstar(node) { - let info; - return info; - }, - - fetchNodeInfoIRLP(node) { - let info; - return info; + if (type === 0) return; + + // Bind it and recurse, fetch it again + // if (typeof this.nodes[type][node] === "undefined") { + // this.nodes[type][node] = null; + // return this.fetchNodeInfo(node, type); + if (this.nodes[type][node]) { + // Don't even call fetchNode** + return this.nodes[type][node]; + } + + axios.get(this.uri + '?cmd=node&type='+type+'&node='+node).then(({data}) => { + this.nodes[type][node] = data; + }); }, addEntry(log) { - this.logs.push(log); + // Generate unique ID for this entry + log.uniqId = (log.node + log.dateTime.unix()).hashCode(); + if (!_.findWhere(this.logs, { uniqId: log.uniqId })) { + this.logs.unshift(log); + } }, } -}); \ No newline at end of file +}); + +String.prototype.hashCode = function() { + let hash = 0; + if (this.length === 0) { + return hash; + } + for (var i = 0; i < this.length; i++) { + let char = this.charCodeAt(i); + hash = ((hash<<5)-hash)+char; + hash = hash & hash; // Convert to 32bit integer + } + return Math.abs(hash); +}; \ No newline at end of file diff --git a/css/styles.css b/css/styles.css index 4a6619b..67668cf 100644 --- a/css/styles.css +++ b/css/styles.css @@ -1,5 +1,6 @@ .header { padding: 1em; + width: 100%; } .text-center { @@ -16,9 +17,34 @@ } table.logs { + width: 85%; + margin: 0 auto; +} + +@media screen and (max-width: 64em) { + table.logs { + width: 100%; + } +} + +table.logs th { + background-color: #3e6eb6; + color: #fff; + width: 1%; +} + +table.logs th.desc { width: 100%; } +table.logs tbody tr:nth-child(even){ + background-color: #cbcbcb; +} + +table.logs tr td.when{ + white-space: nowrap; +} + /* We want to give the content area some more padding */ .content { padding: 1em 1em 3em; diff --git a/fetchData.php b/fetchData.php new file mode 100644 index 0000000..e80c802 --- /dev/null +++ b/fetchData.php @@ -0,0 +1,99 @@ + $node, + 'callsign' => $row[1], + 'desc' => $row[2], + 'location' => $row[3] + ]; + } + + return [ + 'node' => $node + ]; +} + +function fetchNodeInfoIRLP($node) { + $db = fetchIRLPDb(); + $db = explode("\n", $db); + + foreach ($db as $row) { + $line = str_getcsv($row, "\t"); + + if ($line[0] != $node) continue; + + return [ + 'node' => $node, + 'callsign' => $line[1], + 'desc' => $line[15], + 'location' => "{$line[2]}, {$line[3]}" + ]; + } + + return [ + 'node' => $node, + 'callsign' => $node, + 'desc' => '', + 'location' => '' + ]; +} + +function fetchAllStarDb() { + $dbFile = __DIR__.'/storage/allstar.txt'; + if (!file_exists($dbFile)) { + $db = file_get_contents("http://allmondb.allstarlink.org"); + file_put_contents($dbFile, $db); + return $db; + } + + return file_get_contents($dbFile); +} + +function fetchIRLPDb() { + $dbFile = __DIR__.'/storage/irlp.txt'; + + if (!file_exists($dbFile)) { + $db = file_get_contents("http://status.irlp.net/nohtmlstatus.txt.zip"); + file_put_contents("${dbFile}.zip", $db); + shell_exec("/usr/bin/unzip -p ${dbFile}.zip > ${dbFile}"); + } + + return file_get_contents($dbFile); +} + diff --git a/index.html b/index.html index 49aae08..25351bb 100644 --- a/index.html +++ b/index.html @@ -14,29 +14,32 @@

WIN System Log Tail

- +
-
- - + + - - + + - - + + - - + +
Node #Via NodeNode#Via TypeDescriptionDate/TimeWhenDescription
{{ row.node }}{{ row.via }} {{ row.typeLabel }}{{ fetchNodeInfo(row.node) }}{{ row.dateTime }}{{ row.dateTime.format('hh:mm:ss MM/DD/YY') }} + {{ getNodeInfo(row.node, row.type) }} +
@@ -46,6 +49,7 @@ +