205 lines
6.3 KiB
JavaScript
205 lines
6.3 KiB
JavaScript
const csv = require("fast-csv");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const uuid = require("uuid");
|
|
const map_conf = require("../config/map.conf");
|
|
const logger = require("./logger.util");
|
|
|
|
// Creates new map
|
|
async function addMap(filename, meta, throttle, motor) {
|
|
var total = "";
|
|
var map = [[[]]];
|
|
|
|
// Get the new map metadata
|
|
if (meta) {
|
|
if ("name" in meta) {
|
|
total += `#name:${meta["name"]}\n`;
|
|
}
|
|
if ("id" in meta) {
|
|
total += `#id:${meta["id"]}\n`;
|
|
}
|
|
if ("description" in meta) {
|
|
total += `#description:${meta["description"]}\n`;
|
|
}
|
|
}
|
|
|
|
// Check if the required data has been received
|
|
if (throttle && motor && ("0" in motor) && ("1" in motor)) {
|
|
// Creating csv and storing it
|
|
const throttle_values = Object.values(throttle);
|
|
const current_values = Object.values(motor["0"]);
|
|
const brake_values = Object.values(motor["1"]);
|
|
|
|
for (let i = 0; i <= map_conf.steps; i++) {
|
|
map[i] = [current_values[i], brake_values[i], throttle_values[i]];
|
|
}
|
|
}
|
|
|
|
try {
|
|
await csv.writeToString(map).then(data => total += data);
|
|
fs.writeFileSync(path.join(path.dirname(require.main.filename), map_conf.map_storage_path, filename), total);
|
|
} catch (error) {
|
|
throw new Error(error);
|
|
}
|
|
}
|
|
|
|
// Update current map file
|
|
async function updateMap(filename, meta, throttle, motor) {
|
|
// Get merged map comments and data
|
|
var total = await generateComments(filename, meta);
|
|
const map = await generateData(filename, throttle, motor);
|
|
|
|
// Create and store file
|
|
try {
|
|
await csv.writeToString(map).then(data => total += data);
|
|
fs.writeFileSync(path.join(path.dirname(require.main.filename), map_conf.map_storage_path, filename), total);
|
|
fs.renameSync(path.join(path.dirname(require.main.filename), map_conf.map_storage_path, filename), path.join(path.dirname(require.main.filename), map_conf.map_storage_path, `${map_conf.prefix}_${uuid.v4()}.${map_conf.extension}`));
|
|
if (fs.existsSync(path.join(path.dirname(require.main.filename), map_conf.map_storage_path, "selected"))) {
|
|
fs.unlinkSync(path.join(path.dirname(require.main.filename), map_conf.map_storage_path, "selected"));
|
|
}
|
|
} catch (error) {
|
|
throw new Error(error);
|
|
}
|
|
}
|
|
|
|
// Merges data from a stored map and a new map
|
|
async function generateData(filename, throttle, motor) {
|
|
const map = await parseMap(filename, 0);
|
|
|
|
if (throttle) {
|
|
const throttle_keys = Object.keys(throttle);
|
|
for (k of throttle_keys) {
|
|
map[k][2] = throttle[k];
|
|
}
|
|
}
|
|
|
|
if (motor && ("0" in motor) && ("1" in motor)) {
|
|
const current_keys = Object.keys(motor["0"]);
|
|
for (k of current_keys) {
|
|
map[k][0] = motor["0"][k];
|
|
}
|
|
|
|
const brake_keys = Object.keys(motor["1"]);
|
|
for (k of brake_keys) {
|
|
map[k][1] = motor["1"][k];
|
|
}
|
|
}
|
|
|
|
return map;
|
|
}
|
|
|
|
// Merges comments from stored map and new map
|
|
async function generateComments(filename, meta) {
|
|
const comments = await parseMapJson(filename, 1);
|
|
var comment_string = "";
|
|
|
|
if (meta) {
|
|
if ("name" in meta) {
|
|
comments["name"] = meta["name"];
|
|
}
|
|
|
|
if ("id" in meta) {
|
|
comments["id"] = meta["id"];
|
|
}
|
|
|
|
if ("description" in meta) {
|
|
comments["description"] = meta["description"];
|
|
}
|
|
|
|
for (k of Object.keys(comments)) {
|
|
comment_string += `#${k}:${comments[k]}\n`;
|
|
}
|
|
}
|
|
|
|
return comment_string;
|
|
}
|
|
|
|
// Check if a map exists
|
|
function mapExists(filename) {
|
|
if (path.extname(filename) != ".csv") {
|
|
return false;
|
|
}
|
|
return fs.existsSync(path.join(path.dirname(require.main.filename), map_conf.map_storage_path, filename));
|
|
}
|
|
|
|
// Parse a map and returns it as array. On 1 returns comments on 0 returns data
|
|
function parseMap(filename, mode) {
|
|
var result = [];
|
|
|
|
return new Promise((resolve, reject) => {
|
|
if (mode) {
|
|
csv.parseFile(path.join(path.dirname(require.main.filename), map_conf.map_storage_path, filename))
|
|
.on('error', error => reject(error))
|
|
.on('data', row => row[0][0] === "#" ? result.push(row[0].slice(1)) : resolve(result))
|
|
.on('end', () => resolve(result));
|
|
} else {
|
|
csv.parseFile(path.join(path.dirname(require.main.filename), map_conf.map_storage_path, filename), { comment: "#" })
|
|
.on('error', error => reject(error))
|
|
.on('data', row => result.push(row))
|
|
.on('end', () => resolve(result));
|
|
}
|
|
});
|
|
}
|
|
|
|
// Parse map data as JSON
|
|
async function parseMapJson(filename, mode) {
|
|
const map = await parseMap(filename, mode);
|
|
var json_map = {};
|
|
|
|
if (mode) {
|
|
if (map && map.length) {
|
|
for (const m of map) {
|
|
json_map[m.slice(0, m.indexOf(":")).toLowerCase()] = m.slice(m.indexOf(":") + 1)
|
|
}
|
|
}
|
|
} else {
|
|
for (let i = 0; i < map.length; i++) {
|
|
json_map[i] = map[i]
|
|
}
|
|
}
|
|
|
|
return json_map
|
|
}
|
|
|
|
// Get available map names in storage directory
|
|
async function getAvailableMaps() {
|
|
var available_maps = {};
|
|
|
|
try {
|
|
var files = fs.readdirSync(path.join(path.dirname(require.main.filename), map_conf.map_storage_path));
|
|
|
|
for (const file of files) {
|
|
if (path.extname(file) == `.${map_conf.extension}`) {
|
|
available_maps[file] = {};
|
|
|
|
try {
|
|
let meta = await parseMap(file, 1);
|
|
|
|
if (meta && meta.length) {
|
|
for (const m of meta) {
|
|
available_maps[file][m.slice(0, m.indexOf(":")).toLowerCase()] = m.slice(m.indexOf(":") + 1)
|
|
}
|
|
}
|
|
} catch (error) {
|
|
throw new Error(error);
|
|
}
|
|
}
|
|
}
|
|
} catch (error) {
|
|
if (error.code === "ENOENT") {
|
|
logger.info("No storage directory found. Creating directory.");
|
|
fs.mkdirSync(path.join(path.dirname(require.main.filename), map_conf.map_storage_path));
|
|
}
|
|
}
|
|
|
|
return available_maps;
|
|
}
|
|
|
|
module.exports = {
|
|
getAvailableMaps,
|
|
parseMap,
|
|
parseMapJson,
|
|
mapExists,
|
|
updateMap,
|
|
addMap
|
|
}; |