diff --git a/content.json b/content.json new file mode 100644 index 0000000..d1cad94 --- /dev/null +++ b/content.json @@ -0,0 +1,39 @@ +{ + "fork_info": "Forked by Roslund, augmented by dogvisor.", + "title": "STHLM-MESH MAP", + "home_url": "https://sthlm-mesh.se/", + "base_url": "https://map.sthlm-mesh.se/", + "announcement": { + "enabled": true, + "id": "1", + "header": "Viktigt!", + "content": "I Stockholm används LoRa preset Medium Range - Fast. För mer info klicka här." + }, + "lat": 59.3, + "lng": 378.1, + "zoom": 10, + "description": "En interaktiv karta över Meshtastic-noder i STHLM-MESH.", + "info_blocks": [ + { + "header": "Beskrivning", + "content": "Detta är en karta som enbart fokuserar på Stockholm. Den är baserad på Liam Cottle's open source projekt Meshtastic Map, men har flertalet ändringar och nya funktioner som gör att vi bättre kan analysera Meshen i Stockholm." + }, + { + "header": "Frågor och svar", + "content": [ + { + "header": "Hur får jag min nod att synas på kartan?", + "content": "Din nod behöver anting ha en GPS, ha en fast position inställd, eller att din telefon delar sin position. Utöver detta måste platsdelning vara påslåget under kanalinställningarna för MediumFast kanalen (vanligtvis kanal 0)." + }, + { + "header": "Min nod är på fel plats på kartan", + "content": "Detta är troligtvis för att din nod inte delar exakt position. Som standard är positionsprecisionen inställd på ± 3 km, vilket betyder att noden kan befinna sig inom en cirkel med radien 3 kilometer. Du kan ändra positions precisionen i kanalinställningarna. För mer info om positions precisionen, klicka här." + }, + { + "header": "Hur kan jag ansluta min nod till MQTT servern?", + "content": "Då vi enbart vill analysera Meshen i stockholm är MQTT servern inte öppen för alla. Endast ett fåtal noder är uppkopplade till MQTT för att kunna analysera trafiken som faktiskt går över LoRa. De noder som är kopplade mot MQTT servern bör: Tror du att din nod kan bidra, kontakta @Roslund på Discord." + } + ] + } + ] +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 026bb0c..8101550 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,6 +29,8 @@ services: environment: DATABASE_URL: "mysql://root:password@database:3306/meshtastic-map?connection_limit=100" MAP_OPTS: "" # add any custom index.js options here + volumes: + - content.json:/app/src/content.json:ro # publishes mqtt packets via websocket meshtastic-ws: diff --git a/package-lock.json b/package-lock.json index 1fb2318..0fc1e26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "command-line-usage": "^7.0.3", "compression": "^1.8.1", "cors": "^2.8.5", + "ejs": "^4.0.1", "express": "^5.2.1", "mqtt": "^5.14.1", "protobufjs": "^7.5.4", @@ -69,7 +70,6 @@ "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -1771,6 +1771,12 @@ "node": ">=12.17" } }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, "node_modules/babel-jest": { "version": "30.1.2", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.1.2.tgz", @@ -1873,7 +1879,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, "node_modules/base64-js": { @@ -1959,7 +1964,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -2010,7 +2014,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001737", "electron-to-chromium": "^1.5.211", @@ -2692,6 +2695,21 @@ "fast-check": "^3.23.1" } }, + "node_modules/ejs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-4.0.1.tgz", + "integrity": "sha512-krvQtxc0btwSm/nvnt1UpnaFDFVJpJ0fdckmALpCgShsr/iGYHTnJiUliZTgmzq/UxTX33TtOQVKaNigMQp/6Q==", + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.9.1" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.12.18" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.212", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.212.tgz", @@ -3062,6 +3080,27 @@ "bser": "2.1.1" } }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -3717,6 +3756,23 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jest": { "version": "30.1.3", "resolved": "https://registry.npmjs.org/jest/-/jest-30.1.3.tgz", @@ -5064,7 +5120,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -5150,7 +5205,6 @@ "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@prisma/config": "6.16.2", "@prisma/engines": "6.16.2" diff --git a/package.json b/package.json index 989093f..50c2e79 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "command-line-usage": "^7.0.3", "compression": "^1.8.1", "cors": "^2.8.5", + "ejs": "^4.0.1", "express": "^5.2.1", "mqtt": "^5.14.1", "protobufjs": "^7.5.4", diff --git a/src/index.js b/src/index.js index 48dbcc2..a547d0a 100644 --- a/src/index.js +++ b/src/index.js @@ -13,6 +13,9 @@ const statsRoutes = require('./stats.js'); const { PrismaClient } = require("@prisma/client"); const prisma = new PrismaClient(); +// Load content +const content = require('./content.json'); + // return big ints as string when using JSON.stringify BigInt.prototype.toJSON = function() { return this.toString(); @@ -77,6 +80,10 @@ function formatNodeInfo(node) { const app = express(); +// set view engine to ejs +app.set('view engine', 'ejs'); +app.set('views', path.join(__dirname, 'views')); + // enable compression app.use(compression()); @@ -87,7 +94,7 @@ app.use('/api', cors()); app.use('/', express.static(path.join(__dirname, 'public'))); app.get('/', async (req, res) => { - res.sendFile(path.join(__dirname, 'public/index.html')); + res.render('index', content); }); // stats API in separate file diff --git a/src/public/index.html b/src/views/index.ejs similarity index 97% rename from src/public/index.html rename to src/views/index.ejs index d2f1f0d..9c8e037 100644 --- a/src/public/index.html +++ b/src/views/index.ejs @@ -3,16 +3,16 @@ - STHLM-MESH MAP - - + <%= title %> + + - - - + + + @@ -173,9 +173,9 @@
-
Viktigt!
+
<%- announcement.header %>
- I Stockholm används LoRa preset Medium Range - Fast. För mer info klicka här. + <%- announcement.content %>
@@ -191,10 +191,9 @@ - +
-
@@ -213,7 +212,7 @@ @@ -356,45 +355,26 @@

Meshtastic Map

Created by Liam Cottle

-

Forked by Roslund

+

<%- fork_info %>

-
-
Beskrivning
-
-
-
Detta är en karta som enbart fokuserar på Stockholm.
-
Den är baserad på Liam Cottle's open source projekt Meshtastic Map, men har flertalet ändringar och nya funktioner som gör att vi bättre kan analysera Meshen i Stockholm.
-
+ <% info_blocks.forEach(function(info_block) { %> +
+
<%- info_block.header %>
+ <% if (typeof info_block.content == 'string') { info_block.content = [{content: info_block.content}]} %> + <% info_block.content.forEach(function(content_item) { %> +
+
+ <% if (content_item.header) { %> +
<%- content_item.header %>
+ <% } %> +
<%- content_item.content %>
+
+
+ <% }); %>
-
-
Frågor och svar
-
-
-
Hur får jag min nod att synas på kartan?
-
Din nod behöver anting ha en GPS, ha en fast position inställd, eller att din telefon delar sin position.
-
Utöver detta måste platsdelning vara påslåget under kanalinställningarna för MediumFast kanalen (vanligtvis kanal 0).
-
-
-
Min nod är på fel plats på kartan
-
Detta är troligtvis för att din nod inte delar exakt position. Som standard är positionsprecisionen inställd på ± 3 km, vilket betyder att noden kan befinna sig inom en cirkel med radien 3 kilometer.
-
Du kan ändra positions precisionen i kanalinställningarna. För mer info om positions precisionen, klicka här.
-
-
-
Hur kan jag ansluta min nod till MQTT servern?
-
Då vi enbart vill analysera Meshen i stockholm är MQTT servern inte öppen för alla. Endast ett fåtal noder är uppkopplade till MQTT för att kunna analysera trafiken som faktiskt går över LoRa.
-
De noder som är kopplade mot MQTT servern bör:
-
    -
  • Vara på en unik geografisk plats, då vi vill se hur trafiken fördelas
  • -
  • Ha en stabil fast koppling till internet (via Ethernet eller WiFi)
  • -
  • Ha hög tillgänglighet
  • -
  • Ha direktkontakt med flertalet andra noder
  • -
-
Tror du att din nod kan bidra, kontakta @Roslund på Discord.
-
-
-
+ <% }); %>
Legal
@@ -1874,11 +1854,15 @@ methods: { getAnnouncementId: function() { // change this when making a new announcement - return "1"; + return "<%= announcement.id %>"; }, shouldShowAnnouncement: function() { const lastSeenAnnouncementId = window.localStorage.getItem("last-seen-announcement-id"); - return lastSeenAnnouncementId?.toString() !== this.getAnnouncementId(); + <% if (announcement.enabled) { %> + return lastSeenAnnouncementId?.toString() !== this.getAnnouncementId(); + <% } else { %> + return false; + <% } %> }, dismissAnnouncement: function() { window.localStorage.setItem("last-seen-announcement-id", this.getAnnouncementId()); @@ -2752,13 +2736,16 @@ [100, 500], // bottom right ]; - // create map positioned over Stockholm + // create map positioned according to content.json var map = L.map('map', { maxBounds: bounds, - }).setView([ - 59.3, - 378.1, - ], 10); + }).setView( + [ + <%= lat %>, + <%= lng %>, + ], + <%= zoom %> + ); // remove leaflet link map.attributionControl.setPrefix('');