Send back only new files on upload.
This commit is contained in:
@@ -35,13 +35,15 @@ export async function BillsListMedia(req: Request, res: Response) {
|
||||
FolderPaths.BillsSubDir,
|
||||
file.name,
|
||||
]),
|
||||
thumb: GenerateUrl([
|
||||
thumbnail: GenerateUrl([
|
||||
FolderPaths.StaticPath,
|
||||
FolderPaths.JobsFolder,
|
||||
ro_number,
|
||||
FolderPaths.BillsSubDir,
|
||||
relativeThumbPath,
|
||||
]),
|
||||
thumbnailHeight: 250,
|
||||
thumbnailWidth: 250,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
@@ -5,7 +5,9 @@ import multer from "multer";
|
||||
import path, { resolve } from "path";
|
||||
import { logger } from "../server";
|
||||
import GenerateThumbnail from "../util/generateThumbnail";
|
||||
import generateUniqueFilename from "../util/generateUniqueFilename";
|
||||
import generateUniqueFilename, {
|
||||
generateUniqueBillFilename,
|
||||
} from "../util/generateUniqueFilename";
|
||||
import {
|
||||
PathToRoBillsFolder,
|
||||
PathToVendorBillsFile,
|
||||
@@ -26,7 +28,9 @@ export const BillsMediaUploadMulter = multer({
|
||||
},
|
||||
filename: function (req, file, cb) {
|
||||
logger.info("Uploading file: ", path.basename(file.originalname));
|
||||
cb(null, generateUniqueFilename(file));
|
||||
const invoice_number: string = (req.body.invoice_number || "").trim();
|
||||
|
||||
cb(null, generateUniqueBillFilename(file, invoice_number));
|
||||
},
|
||||
}),
|
||||
});
|
||||
@@ -59,18 +63,18 @@ export async function BillsUploadMedia(req: Request, res: Response) {
|
||||
(async () => {
|
||||
const target: string = path.join(
|
||||
PathToVendorBillsFile(vendor),
|
||||
invoice_number + path.extname(file.filename)
|
||||
file.filename
|
||||
);
|
||||
|
||||
await fs.ensureDir(path.dirname(target));
|
||||
await fs.copyFile(file.path, target);
|
||||
})()
|
||||
);
|
||||
|
||||
//Copy Queue is not awaited - we don't care if it finishes before we serve up the thumbnails.
|
||||
//Copy Queue is not awaited - we don't care if it finishes before we serve up the thumbnails from the jobs directory.
|
||||
});
|
||||
}
|
||||
BillsListMedia(req, res);
|
||||
res.sendStatus(200);
|
||||
|
||||
// BillsListMedia(req, res);
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(500).send(err);
|
||||
|
||||
@@ -10,33 +10,63 @@ import { FolderPaths } from "../util/serverInit";
|
||||
export async function JobsListMedia(req: Request, res: Response) {
|
||||
const ro_number: string = (req.body.ro_number || "").trim();
|
||||
await fs.ensureDir(PathToRoFolder(ro_number));
|
||||
const filesList: fs.Dirent[] = (
|
||||
await fs.readdir(PathToRoFolder(ro_number), {
|
||||
withFileTypes: true,
|
||||
})
|
||||
).filter((f) => f.isFile() && !/(^|\/)\.[^\/\.]/g.test(f.name));
|
||||
let ret: MediaFile[];
|
||||
if (req.files) {
|
||||
//We just uploaded files, we're going to send only those back.
|
||||
ret = await Promise.all(
|
||||
(req.files as Express.Multer.File[]).map(async (file) => {
|
||||
const relativeThumbPath: string = await GenerateThumbnail(
|
||||
path.join(FolderPaths.Jobs, ro_number, file.filename)
|
||||
);
|
||||
return {
|
||||
src: GenerateUrl([
|
||||
FolderPaths.StaticPath,
|
||||
FolderPaths.JobsFolder,
|
||||
ro_number,
|
||||
file.filename,
|
||||
]),
|
||||
thumbnail: GenerateUrl([
|
||||
FolderPaths.StaticPath,
|
||||
FolderPaths.JobsFolder,
|
||||
ro_number,
|
||||
relativeThumbPath,
|
||||
]),
|
||||
thumbnailHeight: 250,
|
||||
thumbnailWidth: 250,
|
||||
};
|
||||
})
|
||||
);
|
||||
} else {
|
||||
const filesList: fs.Dirent[] = (
|
||||
await fs.readdir(PathToRoFolder(ro_number), {
|
||||
withFileTypes: true,
|
||||
})
|
||||
).filter((f) => f.isFile() && !/(^|\/)\.[^\/\.]/g.test(f.name));
|
||||
|
||||
const ret: MediaFile[] = await Promise.all(
|
||||
filesList.map(async (file) => {
|
||||
const relativeThumbPath: string = await GenerateThumbnail(
|
||||
path.join(FolderPaths.Jobs, ro_number, file.name)
|
||||
);
|
||||
return {
|
||||
src: GenerateUrl([
|
||||
FolderPaths.StaticPath,
|
||||
FolderPaths.JobsFolder,
|
||||
ro_number,
|
||||
file.name,
|
||||
]),
|
||||
thumb: GenerateUrl([
|
||||
FolderPaths.StaticPath,
|
||||
FolderPaths.JobsFolder,
|
||||
ro_number,
|
||||
relativeThumbPath,
|
||||
]),
|
||||
};
|
||||
})
|
||||
);
|
||||
ret = await Promise.all(
|
||||
filesList.map(async (file) => {
|
||||
const relativeThumbPath: string = await GenerateThumbnail(
|
||||
path.join(FolderPaths.Jobs, ro_number, file.name)
|
||||
);
|
||||
return {
|
||||
src: GenerateUrl([
|
||||
FolderPaths.StaticPath,
|
||||
FolderPaths.JobsFolder,
|
||||
ro_number,
|
||||
file.name,
|
||||
]),
|
||||
thumbnail: GenerateUrl([
|
||||
FolderPaths.StaticPath,
|
||||
FolderPaths.JobsFolder,
|
||||
ro_number,
|
||||
relativeThumbPath,
|
||||
]),
|
||||
thumbnailHeight: 250,
|
||||
thumbnailWidth: 250,
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
res.json(ret);
|
||||
}
|
||||
|
||||
6316
package-lock.json
generated
Normal file
6316
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -11,11 +11,10 @@
|
||||
"build": "tsc -p ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/multer": "^1.4.7",
|
||||
"axios": "^0.24.0",
|
||||
"bluebird": "^3.7.2",
|
||||
"body-parser": "^1.20.0",
|
||||
"cors": "2.8.5",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "10.0.0",
|
||||
"express": "^4.17.3",
|
||||
"file-type": "^16.5.3",
|
||||
@@ -28,6 +27,8 @@
|
||||
"winston-daily-rotate-file": "^4.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/cors": "^2.8.12",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/fs-extra": "^9.0.13",
|
||||
"@types/gm": "^1.18.11",
|
||||
|
||||
@@ -12,6 +12,7 @@ import DailyRotateFile from "winston-daily-rotate-file";
|
||||
import morgan from "morgan";
|
||||
import { BillsListMedia } from "./bills/billsListMedia";
|
||||
import BillRequestValidator from "./bills/billRequestValidator";
|
||||
import cors from "cors";
|
||||
import {
|
||||
BillsMediaUploadMulter,
|
||||
BillsUploadMedia,
|
||||
@@ -87,7 +88,7 @@ const port = process.env.PORT;
|
||||
app.use(bodyParser.json({ limit: "50mb" }));
|
||||
app.use(bodyParser.urlencoded({ limit: "50mb", extended: true }));
|
||||
app.use(FolderPaths.StaticPath, express.static(FolderPaths.Root));
|
||||
|
||||
app.use(cors());
|
||||
const morganMiddleware = morgan(
|
||||
"combined", //":method :url :status :res[content-length] - :response-time ms"
|
||||
{
|
||||
@@ -99,7 +100,7 @@ const morganMiddleware = morgan(
|
||||
|
||||
app.use(morganMiddleware);
|
||||
|
||||
app.get("/jobs/list", JobRequestValidator, JobsListMedia);
|
||||
app.post("/jobs/list", JobRequestValidator, JobsListMedia);
|
||||
app.post(
|
||||
"/jobs/upload",
|
||||
JobMediaUploadMulter.array("file"),
|
||||
@@ -111,7 +112,7 @@ app.post(
|
||||
JobsMoveMedia
|
||||
);
|
||||
|
||||
app.get("/bills/list", BillRequestValidator, BillsListMedia);
|
||||
app.post("/bills/list", BillRequestValidator, BillsListMedia);
|
||||
app.post(
|
||||
"/bills/upload",
|
||||
BillsMediaUploadMulter.array("file"),
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
import path from "path";
|
||||
|
||||
export default function (file: Express.Multer.File) {
|
||||
return `${file.originalname}-${Math.floor(Date.now() / 1000)}${path.extname(
|
||||
return `${path.parse(path.basename(file.originalname)).name}-${Math.floor(
|
||||
Date.now() / 1000
|
||||
)}${path.extname(file.originalname)}`;
|
||||
}
|
||||
|
||||
export function generateUniqueBillFilename(
|
||||
file: Express.Multer.File,
|
||||
invoice_number: string
|
||||
) {
|
||||
return `${invoice_number}-${Math.floor(Date.now() / 1000)}${path.extname(
|
||||
file.originalname
|
||||
)}`;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import internal from "stream";
|
||||
|
||||
interface MediaFile {
|
||||
src: string;
|
||||
thumb: string;
|
||||
thumbnail: string;
|
||||
thumbnailHeight: number;
|
||||
thumbnailWidth: number;
|
||||
}
|
||||
|
||||
export default MediaFile;
|
||||
|
||||
71
yarn.lock
71
yarn.lock
@@ -80,6 +80,11 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/cors@^2.8.12":
|
||||
"integrity" "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw=="
|
||||
"resolved" "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz"
|
||||
"version" "2.8.12"
|
||||
|
||||
"@types/express-serve-static-core@^4.17.18":
|
||||
"integrity" "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig=="
|
||||
"resolved" "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz"
|
||||
@@ -566,7 +571,7 @@
|
||||
"resolved" "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz"
|
||||
"version" "1.0.3"
|
||||
|
||||
"cors@2.8.5":
|
||||
"cors@^2.8.5":
|
||||
"integrity" "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g=="
|
||||
"resolved" "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz"
|
||||
"version" "2.8.5"
|
||||
@@ -1320,7 +1325,7 @@
|
||||
"on-finished" "~2.3.0"
|
||||
"on-headers" "~1.0.2"
|
||||
|
||||
"ms@^2.1.1":
|
||||
"ms@^2.1.1", "ms@2.1.3":
|
||||
"integrity" "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
"resolved" "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
|
||||
"version" "2.1.3"
|
||||
@@ -1330,11 +1335,6 @@
|
||||
"resolved" "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
|
||||
"ms@2.1.3":
|
||||
"integrity" "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
"resolved" "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
|
||||
"version" "2.1.3"
|
||||
|
||||
"multer@^1.4.4":
|
||||
"integrity" "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw=="
|
||||
"resolved" "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz"
|
||||
@@ -1603,7 +1603,7 @@
|
||||
"minimist" "^1.2.0"
|
||||
"strip-json-comments" "~2.0.1"
|
||||
|
||||
"readable-stream@^2.0.6", "readable-stream@^2.2.2":
|
||||
"readable-stream@^2.0.6":
|
||||
"integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
|
||||
"resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
|
||||
"version" "2.3.7"
|
||||
@@ -1616,25 +1616,20 @@
|
||||
"string_decoder" "~1.1.1"
|
||||
"util-deprecate" "~1.0.1"
|
||||
|
||||
"readable-stream@^3.1.1":
|
||||
"integrity" "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA=="
|
||||
"resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz"
|
||||
"version" "3.6.0"
|
||||
"readable-stream@^2.2.2":
|
||||
"integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
|
||||
"resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
|
||||
"version" "2.3.7"
|
||||
dependencies:
|
||||
"inherits" "^2.0.3"
|
||||
"string_decoder" "^1.1.1"
|
||||
"util-deprecate" "^1.0.1"
|
||||
"core-util-is" "~1.0.0"
|
||||
"inherits" "~2.0.3"
|
||||
"isarray" "~1.0.0"
|
||||
"process-nextick-args" "~2.0.0"
|
||||
"safe-buffer" "~5.1.1"
|
||||
"string_decoder" "~1.1.1"
|
||||
"util-deprecate" "~1.0.1"
|
||||
|
||||
"readable-stream@^3.4.0":
|
||||
"integrity" "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA=="
|
||||
"resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz"
|
||||
"version" "3.6.0"
|
||||
dependencies:
|
||||
"inherits" "^2.0.3"
|
||||
"string_decoder" "^1.1.1"
|
||||
"util-deprecate" "^1.0.1"
|
||||
|
||||
"readable-stream@^3.6.0":
|
||||
"readable-stream@^3.1.1", "readable-stream@^3.4.0", "readable-stream@^3.6.0":
|
||||
"integrity" "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA=="
|
||||
"resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz"
|
||||
"version" "3.6.0"
|
||||
@@ -1688,25 +1683,20 @@
|
||||
dependencies:
|
||||
"lowercase-keys" "^1.0.0"
|
||||
|
||||
"safe-buffer@^5.0.1", "safe-buffer@5.2.1":
|
||||
"safe-buffer@^5.0.1":
|
||||
"integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||
"resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
|
||||
"version" "5.2.1"
|
||||
|
||||
"safe-buffer@~5.1.0":
|
||||
"safe-buffer@~5.1.0", "safe-buffer@~5.1.1", "safe-buffer@5.1.2":
|
||||
"integrity" "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
"resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
|
||||
"version" "5.1.2"
|
||||
|
||||
"safe-buffer@~5.1.1":
|
||||
"integrity" "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
"resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
|
||||
"version" "5.1.2"
|
||||
|
||||
"safe-buffer@5.1.2":
|
||||
"integrity" "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
"resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
|
||||
"version" "5.1.2"
|
||||
"safe-buffer@5.2.1":
|
||||
"integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||
"resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
|
||||
"version" "5.2.1"
|
||||
|
||||
"safe-stable-stringify@^2.3.1":
|
||||
"integrity" "sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg=="
|
||||
@@ -1894,7 +1884,14 @@
|
||||
dependencies:
|
||||
"ansi-regex" "^2.0.0"
|
||||
|
||||
"strip-ansi@^6.0.0", "strip-ansi@^6.0.1":
|
||||
"strip-ansi@^6.0.0":
|
||||
"integrity" "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="
|
||||
"resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
|
||||
"version" "6.0.1"
|
||||
dependencies:
|
||||
"ansi-regex" "^5.0.1"
|
||||
|
||||
"strip-ansi@^6.0.1":
|
||||
"integrity" "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="
|
||||
"resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
|
||||
"version" "6.0.1"
|
||||
|
||||
Reference in New Issue
Block a user