diff --git a/src/admin.js b/src/admin.js deleted file mode 100644 index e9fbbef..0000000 --- a/src/admin.js +++ /dev/null @@ -1,127 +0,0 @@ -// node src/admin.js --purge-node-id 123 -// node src/admin.js --purge-node-id '!AABBCCDD' - -const commandLineArgs = require("command-line-args"); -const commandLineUsage = require("command-line-usage"); - -// create prisma db client -const { PrismaClient } = require("@prisma/client"); -const NodeIdUtil = require("./utils/node_id_util"); -const prisma = new PrismaClient(); - -const optionsList = [ - { - name: 'help', - alias: 'h', - type: Boolean, - description: 'Display this usage guide.' - }, - { - name: "purge-node-id", - type: String, - description: "Purges all records for the provided node id.", - }, -]; - -// parse command line args -const options = commandLineArgs(optionsList); - -// show help -if(options.help){ - const usage = commandLineUsage([ - { - header: 'Meshtastic Map Admin', - content: 'Command line admin tool for the Meshtastic Map', - }, - { - header: 'Options', - optionList: optionsList, - }, - ]); - console.log(usage); - return; -} - -// get options and fallback to default values -const purgeNodeId = options["purge-node-id"] ?? null; - -async function purgeNodeById(nodeId) { - - // convert to numeric id - nodeId = NodeIdUtil.convertToNumeric(nodeId); - - // purge environment metrics - await prisma.environmentMetric.deleteMany({ - where: { - node_id: nodeId, - }, - }); - - // purge map reports - await prisma.mapReport.deleteMany({ - where: { - node_id: nodeId, - }, - }); - - // purge neighbour infos - await prisma.neighbourInfo.deleteMany({ - where: { - node_id: nodeId, - }, - }); - - // purge this node - await prisma.node.deleteMany({ - where: { - node_id: nodeId, - }, - }); - - // purge positions - await prisma.position.deleteMany({ - where: { - node_id: nodeId, - }, - }); - - // purge power metrics - await prisma.powerMetric.deleteMany({ - where: { - node_id: nodeId, - }, - }); - - // purge text messages - await prisma.textMessage.deleteMany({ - where: { - from: nodeId, - }, - }); - - // purge traceroutes - await prisma.traceRoute.deleteMany({ - where: { - from: nodeId, - }, - }); - - // purge waypoints - await prisma.waypoint.deleteMany({ - where: { - from: nodeId, - }, - }); - - console.log(`✅ Node '${nodeId}' has been purged from the database.`); - -} - -(async () => { - - // purge node by id - if(purgeNodeId){ - await purgeNodeById(purgeNodeId); - } - -})(); diff --git a/src/index.js b/src/index.js deleted file mode 100644 index 61bd055..0000000 --- a/src/index.js +++ /dev/null @@ -1,815 +0,0 @@ -const path = require('path'); -const express = require('express'); -const compression = require('compression'); -const protobufjs = require("protobufjs"); -const commandLineArgs = require("command-line-args"); -const commandLineUsage = require("command-line-usage"); - -// create prisma db client -const { PrismaClient } = require("@prisma/client"); -const prisma = new PrismaClient(); - -// return big ints as string when using JSON.stringify -BigInt.prototype.toJSON = function() { - return this.toString(); -} - -const optionsList = [ - { - name: 'help', - alias: 'h', - type: Boolean, - description: 'Display this usage guide.' - }, - { - name: "port", - type: Number, - description: "Port to serve web ui and api from.", - }, -]; - -// parse command line args -const options = commandLineArgs(optionsList); - -// show help -if(options.help){ - const usage = commandLineUsage([ - { - header: 'Meshtastic Map', - content: 'A map of all Meshtastic nodes heard via MQTT.', - }, - { - header: 'Options', - optionList: optionsList, - }, - ]); - console.log(usage); - return; -} - -// get options and fallback to default values -const port = options["port"] ?? 8080; - -// load protobufs -const root = new protobufjs.Root(); -root.resolvePath = (origin, target) => path.join(__dirname, "protos", target); -root.loadSync('meshtastic/mqtt.proto'); -const HardwareModel = root.lookupEnum("HardwareModel"); -const Role = root.lookupEnum("Config.DeviceConfig.Role"); -const RegionCode = root.lookupEnum("Config.LoRaConfig.RegionCode"); -const ModemPreset = root.lookupEnum("Config.LoRaConfig.ModemPreset"); - -// appends extra info for node objects returned from api -function formatNodeInfo(node) { - return { - ...node, - node_id_hex: "!" + node.node_id.toString(16), - hardware_model_name: HardwareModel.valuesById[node.hardware_model] ?? null, - role_name: Role.valuesById[node.role] ?? null, - region_name: RegionCode.valuesById[node.region] ?? null, - modem_preset_name: ModemPreset.valuesById[node.modem_preset] ?? null, - }; -} - -const app = express(); - -// enable compression -app.use(compression()); - -// serve files inside the public folder from / -app.use('/', express.static(path.join(__dirname, 'public'))); - -app.get('/', async (req, res) => { - res.sendFile(path.join(__dirname, 'public/index.html')); -}); - -app.get('/api', async (req, res) => { - - const links = [ - { - "path": "/api", - "description": "This page", - }, - { - "path": "/api/v1/nodes", - "description": "All meshtastic nodes", - "params": { - "role": "Filter by role", - "hardware_model": "Filter by hardware model", - }, - }, - { - "path": "/api/v1/nodes/:nodeId", - "description": "A specific meshtastic node", - }, - { - "path": "/api/v1/nodes/:nodeId/device-metrics", - "description": "Device metrics for a meshtastic node", - "params": { - "count": "How many results to return", - "time_from": "Only include metrics created after this unix timestamp (milliseconds)", - "time_to": "Only include metrics created before this unix timestamp (milliseconds)", - }, - }, - { - "path": "/api/v1/nodes/:nodeId/environment-metrics", - "description": "Environment metrics for a meshtastic node", - "params": { - "count": "How many results to return", - "time_from": "Only include metrics created after this unix timestamp (milliseconds)", - "time_to": "Only include metrics created before this unix timestamp (milliseconds)", - }, - }, - { - "path": "/api/v1/nodes/:nodeId/power-metrics", - "description": "Power metrics for a meshtastic node", - "params": { - "count": "How many results to return", - "time_from": "Only include metrics created after this unix timestamp (milliseconds)", - "time_to": "Only include metrics created before this unix timestamp (milliseconds)", - }, - }, - { - "path": "/api/v1/nodes/:nodeId/neighbours", - "description": "Neighbours for a meshtastic node", - }, - { - "path": "/api/v1/nodes/:nodeId/traceroutes", - "description": "Trace routes for a meshtastic node", - }, - { - "path": "/api/v1/nodes/:nodeId/position-history", - "description": "Position history for a meshtastic node", - "params": { - "time_from": "Only include positions created after this unix timestamp (milliseconds)", - "time_to": "Only include positions created before this unix timestamp (milliseconds)", - }, - }, - { - "path": "/api/v1/stats/hardware-models", - "description": "Database statistics about known hardware models", - }, - { - "path": "/api/v1/text-messages", - "description": "Text messages", - "params": { - "to": "Only include messages to this node id", - "from": "Only include messages from this node id", - "channel_id": "Only include messages for this channel id", - "gateway_id": "Only include messages gated to mqtt by this node id", - "last_id": "Only include messages before or after this id, based on results order", - "count": "How many results to return", - "order": "Order to return results in: asc, desc", - }, - }, - { - "path": "/api/v1/text-messages/embed", - "description": "Text messages rendered as an embeddable HTML page.", - }, - { - "path": "/api/v1/waypoints", - "description": "Waypoints", - }, - ]; - - const linksHtml = links.map((link) => { - var line = `