import { Request, Response } from "express"; import fs from "fs-extra"; import path from "path"; import { logger } from "../server"; import ListableChecker from "../util/listableChecker"; import { PathToRoBillsFolder, PathToRoFolder } from "../util/pathGenerators"; import { FolderPaths } from "../util/serverInit"; import { JobsListMedia } from "./jobsListMedia"; export async function JobsMoveMedia(req: Request, res: Response) { const jobid: string = (req.body.jobid || "").trim(); const from_jobid: string = (req.body.from_jobid || "").trim(); const files: string[] = req.body.files; //Just file names. try { //Validate the request is valid and contains everything that it needs. if (from_jobid === "") { res.status(400).json({ error: "from_jobid must be specified. " }); return; } if (files.length === 0) { res.status(400).json({ error: "files must be specified. " }); return; } // Setup lists for both file locations const jobFileList: string[] = ( await fs.readdir(PathToRoFolder(from_jobid), { withFileTypes: true }) ) .filter((f) => f.isFile() && ListableChecker(f)) .map((dirent) => dirent.name); const billFileList: string[] = ( await fs.readdir(PathToRoBillsFolder(from_jobid), { withFileTypes: true }) ) .filter((f) => f.isFile() && ListableChecker(f)) .map((dirent) => dirent.name); //Make sure the destination RO directory exists. await fs.ensureDir(PathToRoFolder(jobid)); logger.debug("Moving job based media.", { jobid, from_jobid, files }); const movingQueue: Promise[] = []; files.forEach((file) => { if (jobFileList.includes(file)) { movingQueue.push( fs.move(path.join(FolderPaths.Jobs, from_jobid, file), path.join(FolderPaths.Jobs, jobid, file)) ); movingQueue.push( fs.move( path.join(FolderPaths.Jobs, from_jobid, FolderPaths.ThumbsSubDir, file.replace(/\.[^/.]+$/, ".png")), path.join(FolderPaths.Jobs, jobid, FolderPaths.ThumbsSubDir, file.replace(/\.[^/.]+$/, ".png")) ) ); } if (billFileList.includes(file)) { movingQueue.push( fs.move( path.join(FolderPaths.Jobs, from_jobid, FolderPaths.BillsSubDir, file), path.join(FolderPaths.Jobs, jobid, FolderPaths.BillsSubDir, file) ) ); movingQueue.push( fs.move( path.join( FolderPaths.Jobs, from_jobid, FolderPaths.BillsSubDir, FolderPaths.ThumbsSubDir, file.replace(/\.[^/.]+$/, ".png") ), path.join( FolderPaths.Jobs, jobid, FolderPaths.BillsSubDir, FolderPaths.ThumbsSubDir, file.replace(/\.[^/.]+$/, ".png") ) ) ); } }); //Use AllSettled as it allows for individual moves to fail. //e.g. if the thumbnail does not exist. await Promise.allSettled(movingQueue); JobsListMedia(req, res); } catch (err) { logger.error("Error moving job media", { from_jobid, jobid, files, err }); res.status(500).send(err); } }