'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 };