Files
dougal-software/lib/www/server/api/middleware/event/sequence/get/csv.js

86 lines
2.4 KiB
JavaScript
Raw Normal View History

2023-09-13 21:58:06 +02:00
const { stringify } = require('csv');
const { transform, prepare } = require('../../../../../lib/sse');
const json = async function (req, res, next) {
try {
const query = req.query;
query.sequence = req.params.sequence;
const {events, sequences} = await prepare(req.params.project, query);
if ("download" in query || "d" in query) {
const extension = "csv";
// Get the sequence number(s) (more than one sequence can be selected)
const seqNums = query.sequence.split(";");
// If we've only been asked for a single sequence, get its line name
const lineName = (sequences.find(i => i.sequence == seqNums[0]) || {})?.meta?.lineName;
const filename = (seqNums.length == 1 && lineName)
? `${lineName}-NavLog.${extension}`
: `${req.params.project}-${query.sequence}.${extension}`;
res.set("Content-Disposition", `attachment; filename="${filename}"`);
}
const columns = {
id: "id",
unix_epoch: (row) => Math.floor(row.tstamp/1000),
timestamp: (row) => (new Date(row.tstamp)).toISOString(),
sequence: "sequence",
point: "point",
text: "remarks",
labels: (row) => row.labels.join(";"),
latitude: (row) => {
if (row.meta.geometry?.type == "Point" && row.meta.geometry?.coordinates) {
return row.meta.geometry.coordinates[1];
}
},
longitude: (row) => {
if (row.meta.geometry?.type == "Point" && row.meta.geometry?.coordinates) {
return row.meta.geometry.coordinates[0];
}
}
};
let fields = [ "timestamp", "sequence", "point", "text", "labels", "latitude", "longitude", "id" ];
if (req.query.fields) {
fields = req.query.fields.split(/[,;:.\s+*|]+/);
}
let delimiter = req.query.delimiter || ",";
const stringifier = stringify({delimiter});
stringifier.on('error', (err) => {
console.error(err.message);
});
stringifier.on('readable', () => {
while((row = stringifier.read()) !== null) {
res.write(row);
}
});
res.status(200);
if (!req.query.header || req.query.header.toLowerCase() == "true" || req.query.header == "1") {
// Send header
stringifier.write(fields);
}
events.forEach( event => {
stringifier.write(fields.map( field => {
if (typeof columns[field] === "function") {
return columns[field](event);
} else {
return event[columns[field]];
}
}));
});
stringifier.end();
res.end();
next();
} catch (err) {
next(err);
}
};
module.exports = json;