Create initial scaffolding for client-side map interface.

This commit is contained in:
Starbeamrainbowlabs 2019-07-19 15:36:21 +01:00
parent 7469d4c1bf
commit dd9d39ba52
11 changed files with 3081 additions and 4 deletions

1
.gitignore vendored
View file

@ -7,6 +7,7 @@ example-message.json
config.custom.h config.custom.h
settings.custom.cpp settings.custom.cpp
settings.toml settings.toml
app/
Reports/*.pdf Reports/*.pdf

57
build
View file

@ -44,6 +44,13 @@ fi
############################################################################### ###############################################################################
# ██████ ██████ ███ ███ ███ ███ ███████ ███ ██ ████████
# ██ ██ ██ ████ ████ ████ ████ ██ ████ ██ ██
# ██ ██ ██ ██ ████ ██ ██ ████ ██ █████ ██ ██ ██ ██
# ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
# ██████ ██████ ██ ██ ██ ██ ███████ ██ ████ ██
# Toggles commenting and uncommenting lines in a file that contain a specific # Toggles commenting and uncommenting lines in a file that contain a specific
# substring. Checks for word boundaries either side of the substring. # substring. Checks for word boundaries either side of the substring.
# From https://stackoverflow.com/a/24901636/1460422 # From https://stackoverflow.com/a/24901636/1460422
@ -69,6 +76,8 @@ task_setup() {
task_begin "Checking Environment"; task_begin "Checking Environment";
check_command git true; check_command git true;
check_command awk true; check_command awk true;
check_command inotifywait true optional;
if [[ "$?" -ne "0" ]]; then echo "${HC}inotifywait${RS} is required to auto-rebuild on when the client-side code changes."; fi
check_command pdflatex true optional; check_command pdflatex true optional;
if [[ "$?" -ne "0" ]]; then echo "${HC}pdflatex${RS} is required to render the reports."; fi if [[ "$?" -ne "0" ]]; then echo "${HC}pdflatex${RS} is required to render the reports."; fi
check_command bibtex true optional; check_command bibtex true optional;
@ -107,12 +116,60 @@ task_setup() {
stage_end 0; stage_end 0;
} }
# ██ ██ ███████ ████████ ███████ ███ ██ ███████ ██████
# ██ ██ ██ ██ ██ ████ ██ ██ ██ ██
# ██ ██ ███████ ██ █████ ██ ██ ██ █████ ██████
# ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
# ███████ ██ ███████ ██ ███████ ██ ████ ███████ ██ ██
task_server-ttn() { task_server-ttn() {
execute node --experimental-modules ./server/index.mjs ttn-app-server; execute node --experimental-modules ./server/index.mjs ttn-app-server;
} }
# ██████ ██ ██ ███████ ███ ██ ████████
# ██ ██ ██ ██ ████ ██ ██
# ██ ██ ██ █████ ██ ██ ██ ██
# ██ ██ ██ ██ ██ ██ ██ ██
# ██████ ███████ ██ ███████ ██ ████ ██
task_client() {
task_begin "Packaging Javascript";
execute node_modules/rollup/bin/rollup --sourcemap --config rollup.config.js;
task_end $? "Error: rollup packing failed!";
task_begin "Copying html";
execute cp client_src/index.html "app/";
task_end $?;
}
task_client-watch() {
set_title "Client Watcher";
echo -e "Watching for changes.";
while :; do # : = infinite loop
# Wait for an update
# inotifywait's non-0 exit code forces an exit for some reason :-/
inotifywait -qr --event modify --format '%:e %f' client_src;
# Rebuild the client code - spawn a sub-process to avoid the hard exit
# This still doesn't work though, which is *really* annoying
stage_begin "Rebuilding client code";
./build client;
stage_end $?;
done
}
############################################################################### ###############################################################################
# ██████ ███████ ██████ ██████ ██████ ████████ ███████
# ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
# ██████ █████ ██████ ██ ██ ██████ ██ ███████
# ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
# ██ ██ ███████ ██ ██████ ██ ██ ██ ███████
task_render() { task_render() {
_render-latex-pdf "Reports/Initial-Report/Initial-Report.tex"; _render-latex-pdf "Reports/Initial-Report/Initial-Report.tex";
} }

0
client_src/css/index.css Normal file
View file

24
client_src/index.html Normal file
View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- <link rel="icon" href="resources/logo-small.png" sizes="16x16" type="image/png" />
<link rel="icon" href="resources/logo.png" sizes="256x256" type="image/png" />
<link rel="icon" href="resources/logo.svg" sizes="any" type="image/svg+xml" /> -->
<title>LoRaWAN Signal Map</title>
</head>
<body>
<h1>LoRaWAN Signal Map</h1>
<!-- Leaflet needs an id to attach to -->
<main id="map" class="working-visual">
</main>
<!---------------->
<link rel="stylesheet" href="app.css" />
<script src="app.js" charset="utf-8"></script>
</body>
</html>

View file

@ -0,0 +1,5 @@
"use strict";
export default {
ai_index_file: "ais/index.json"
};

View file

@ -0,0 +1,24 @@
"use strict";
/**
* Fetches content from the given URL and returns it via a Promise.
* Original source: https://gist.github.com/0b2aee73f8d168e36a353901193e7ff5#file-getfromurl-js
* Proof that I wrote this is, of course, available upon request.
*
* @param {string} url The url to fetch the content from.
* @returns {Promise<string>} The content at the specified url.
*/
export default function GetFromUrl(url) {
return new Promise(function(resolve, reject) {
let request = new XMLHttpRequest();
request.addEventListener("load", function() {
if (request.status > 199 && request.status < 300)
resolve(request.response);
else
reject(request.response);
});
request.open("GET", url, true);
request.send(null);
})
}

View file

@ -0,0 +1,17 @@
"use strict";
import Config from './ClientConfig.mjs';
import GetFromUrl from './Helpers/GetFromUrl.mjs';
class MapManager {
constructor() {
}
async setup() {
let index = JSON.parse(await GetFromUrl(Config.ai_index_file));
console.log(index);
}
}
export default MapManager;

9
client_src/js/index.mjs Normal file
View file

@ -0,0 +1,9 @@
import "../css/index.css";
import MapManager from './MapManager.mjs';
window.addEventListener("load", (_event) => {
const map_manager = new MapManager();
map_manager.setup();
});

2842
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -20,15 +20,25 @@
"license": "MPL-2.0", "license": "MPL-2.0",
"dependencies": { "dependencies": {
"@iarna/toml": "^2.2.3", "@iarna/toml": "^2.2.3",
"@tensorflow/tfjs": "^1.2.3",
"@tensorflow/tfjs-node-gpu": "^1.2.3", "@tensorflow/tfjs-node-gpu": "^1.2.3",
"aes-js": "^3.1.2", "aes-js": "^3.1.2",
"async-mqtt": "^2.3.0", "async-mqtt": "^2.3.0",
"awilix": "^4.2.2", "awilix": "^4.2.2",
"better-sqlite3": "^5.4.0", "better-sqlite3": "^5.4.0",
"debug": "^4.1.1", "debug": "^4.1.1",
"leaflet": "^1.5.1",
"postcss-copy": "^7.1.0",
"postcss-import": "^12.0.1",
"rollup-plugin-terser": "^5.1.1",
"simple-mqtt-client": "^1.0.1" "simple-mqtt-client": "^1.0.1"
}, },
"devDependencies": { "devDependencies": {
"@types/better-sqlite3": "^5.4.0" "@types/better-sqlite3": "^5.4.0",
"rollup": "^1.17.0",
"rollup-plugin-commonjs": "^10.0.1",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-postcss": "^2.0.3",
"rollup-plugin-replace": "^2.2.0"
} }
} }

94
rollup.config.js Normal file
View file

@ -0,0 +1,94 @@
import os from 'os';
// import path from 'pasth';
import fs from 'fs';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import postcss from 'rollup-plugin-postcss';
import { terser } from "rollup-plugin-terser";
import replace from 'rollup-plugin-replace';
// import json from 'rollup-plugin-json';
import postcss_import from 'postcss-import';
import postcss_copy from 'postcss-copy';
let plugins = [
resolve({
mainFields: [
// use "module" field for ES6 module if possible
"module", // Check for ES6 modules
// use "jsnext:main" if possible
// see https://github.com/rollup/rollup/wiki/jsnext:main
"jsnext:main",
// use "main" field or index.js, even if it's not an ES6 module
// (needs to be converted from CommonJS to ES6
// see https://github.com/rollup/rollup-plugin-commonjs
"main" // ...otherwise use the main entry point
],
// some package.json files have a `browser` field which
// specifies alternative files to load for people bundling
// for the browser. If that's you, use this option, otherwise
// pkg.browser will be ignored
browser: true, // Default: false
// not all files you want to resolve are .js files
extensions: ['.mjs', '.js', '.jsx', '.json'], // Default: [ '.mjs', '.js', '.json', '.node' ]
}),
// json({
//
// }),
replace({
exclude: 'node_modules/**',
values: {
"__BUILD_DATE__": () => new Date().toISOString(),
"__VERSION__": JSON.parse(fs.readFileSync("package.json", "utf8")).version
}
}),
commonjs({
}),
postcss({
plugins: [
postcss_import({}),
postcss_copy({
dest: "app",
template: "resources/[name].[ext]"
})
// postcss_url(),
// postcss_url({
// url: "copy",
// basePath: path.resolve("."),
// assetPath: "resources"
// })
],
// Save it to a .css file - we'll reference it ourselves thank you
// very much
extract: true,
sourceMap: true,
//minimize: true, // Causes an error at the moment for some reason
})
];
if(process.env.NODE_ENV == "production") {
console.log("[config] In production environment - minifying JS");
plugins.push(terser({
numWorkers: os.cpus().length,
compress: {
ecma: 6
}
}));
}
export default {
input: 'client_src/js/index.mjs',
output: {
file: 'app/app.js',
format: 'esm'
},
plugins
};