agmission/Development/server/helpers/file_helper.js

204 lines
6.3 KiB
JavaScript

'use strict';
const fs = require('fs-extra'),
util = require('util'),
path = require('path'),
async = require('async'),
utils = require('./utils'),
FILE = require('./file_constants'),
ci = require('case-insensitive');
// File Utils
function removeFiles(files, cb) {
const cannotDeleteOnes = [];
if (utils.isEmptyArray(files)) return cb();
async.forEach(files, (file, callback) => {
fs.remove(file, err => {
if (err)
cannotDeleteOnes.push(path.basename(file));
callback();
});
}, (err) => {
if (cannotDeleteOnes.length > 0)
return cb && cb('Can not remove files:' + cannotDeleteOnes.join(','));
else
return cb && cb();
});
};
/**
* Classify area files (kmz/kml, shape,...) into groups of job file items for the ease of futher processing
* Each job file item might contain multiple files
* @param {*} basePath the absolute path base folder of each unzipped file
* @param {*} files array of area files
* @param {*} cb
*/
function areasFromList(basePath, files, cb) {
const areaFiles = []; // { files.area/ files.dbf, files.prj, files.xcl, files. wpt}
if (!utils.isEmptyArray(files)) {
const baseFiles = files.map(item => item.replace(basePath, ''));
const processBaseFiles = baseFiles.slice(0);
let no1List = [], shapeList = [], dbfList = [], xclList = [], dspList = [], vfrList = [];
let i = processBaseFiles.length - 1, file;
while (processBaseFiles.length && i >= 0) {
file = processBaseFiles[i];
if (/\.no1$/i.test(file)) {
processBaseFiles.splice(i, 1);
no1List.push(file);
}
else if (/\.job$/i.test(file)) {
processBaseFiles.splice(i, 1);
areaFiles.push({ type: FILE.FILE_SATLOG_JOB, area: file });
}
else if (/\.kml$/i.test(file)) {
processBaseFiles.splice(i, 1);
areaFiles.push({ type: FILE.FILE_KML, area: file });
}
else if (/\.kmz$/i.test(file)) {
processBaseFiles.splice(i, 1);
areaFiles.push({ type: FILE.FILE_KMZ, area: file });
}
else if (/\.shp$/gi.test(file) && !(/(wpt|_sc)\.shp$/i.test(file))) {
processBaseFiles.splice(i, 1);
shapeList.push(file);
}
else if (/\.dbf$/i.test(file)) {
processBaseFiles.splice(i, 1);
dbfList.push(file);
}
else if (/\.dsp$/i.test(file)) {
processBaseFiles.splice(i, 1);
dspList.push(file);
}
else if (/\.xcl$/i.test(file)) {
processBaseFiles.splice(i, 1);
xclList.push(file);
}
else if (/\.vfr$/i.test(file)) {
processBaseFiles.splice(i, 1);
vfrList.push(file);
}
i--;
// The rest should be prj or junk files, take prj areas at the end of the process
}
let ciBaseFiles = ci(baseFiles), ciProcessBaseFiles = ci(processBaseFiles);
let ciIndex = -1, bareName;
if (shapeList.length) {
const beRemovedOnes = [];
shapeList.sort(); //Ensure main shape file is at beginning
for (let i = 0; i < shapeList.length; i++) {
const item = shapeList[i];
let area = { type: FILE.FILE_SHP, area: item };
bareName = item.replace(/\.[^/\\.]+$/, "");
if ((ciIndex = ciBaseFiles.indexOf(bareName + '.dbf')) >= 0)
area.dbf = baseFiles[ciIndex];
if ((ciIndex = ciBaseFiles.indexOf(bareName + '.prj')) >= 0) {
area.prj = baseFiles[ciIndex];
beRemovedOnes.push(bareName + '.prj');
}
if ((ciIndex = ciBaseFiles.indexOf(bareName + '_SC.dbf')) >= 0)
area.sitecode = baseFiles[ciIndex];
if ((ciIndex = ciBaseFiles.indexOf(bareName + 'wpt.shp')) >= 0) {
area.wpt = baseFiles[ciIndex];
beRemovedOnes.push(bareName + 'wpt.shp');
beRemovedOnes.push(bareName + 'wpt.prj');
}
if ((ciIndex = ciBaseFiles.indexOf(bareName + 'wpt.dbf')) >= 0)
area.wptDbf = baseFiles[ciIndex];
if ((ciIndex = ciBaseFiles.indexOf(bareName + '.agn')) >= 0)
area.agn = baseFiles[ciIndex];
areaFiles.push(area);
}
for (let j = 0; j < beRemovedOnes.length; j++) {
if ((ciIndex = ciProcessBaseFiles.indexOf(beRemovedOnes[j])) >= 0) {
processBaseFiles.splice(ciIndex, 1);
ciProcessBaseFiles = ci(processBaseFiles);
}
}
}
const ciXclList = ci(xclList);
const ciDspList = ci(dspList);
if (no1List.length) {
for (const item of no1List) {
let area = { type: FILE.FILE_NO1, area: item };
bareName = item.replace(/\.[^/\\.]+$/, "");
if ((ciIndex = ciDspList.indexOf(bareName + '.dsp')) >= 0)
area.dsp = dspList[ciIndex];
if ((ciIndex = ciXclList.indexOf(bareName + '.xcl')) >= 0)
area.xcl = xclList[ciIndex];
areaFiles.push(area);
}
}
// Process Agnav PRJ areas if any
if (processBaseFiles.length) {
let ciVfrList = ci(vfrList);
for (const item of processBaseFiles) {
if (/\.prj$/gi.test(item)) {
const area = { type: FILE.FILE_PRJ, area: item };
bareName = item.replace(/\.[^/\\.]+$/, "");
if ((ciIndex = ciDspList.indexOf(bareName + '.dsp')) >= 0)
area.dsp = dspList[ciIndex];
if ((ciIndex = ciXclList.indexOf(bareName + '.xcl')) >= 0)
area.xcl = xclList[ciIndex];
if ((ciIndex = ciVfrList.indexOf(bareName + '.vfr')) >= 0)
area.vfr = vfrList[ciIndex];
if (area.dsp)
areaFiles.push(area);
}
}
}
}
if (cb)
return cb(null, areaFiles);
else
return areaFiles;
}
function getAppPath(thePath) {
if (!thePath) return thePath;
return path.isAbsolute(thePath) ? thePath : path.join(process.cwd(), thePath);
}
function getRoutePath(thePath) {
if (!thePath) return thePath;
return thePath.startsWith('.') ? thePath.substring(1) : thePath;
}
function getMulterPath(thePath) {
if (!thePath) return thePath;
return thePath.startsWith('/') ? thePath.substring(1) : thePath;
}
function isSameBaseFile(path1, path2) {
if (!path1 || !path2) return false;
if (!path1 && !path2) return true;
return path.basename(path1) === path.basename(path2);
}
module.exports = {
removeFiles, removeFilesAsync: util.promisify(removeFiles), areasFromList, getAppPath, getRoutePath, getMulterPath, isSameBaseFile
};