Send back only new files on upload.

This commit is contained in:
Patrick Fic
2022-05-04 17:37:32 -07:00
parent b7be304520
commit 05a8c90f03
9 changed files with 6442 additions and 78 deletions

View File

@@ -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,
};
})
);

View File

@@ -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);

View File

@@ -10,13 +10,40 @@ 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));
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(
ret = await Promise.all(
filesList.map(async (file) => {
const relativeThumbPath: string = await GenerateThumbnail(
path.join(FolderPaths.Jobs, ro_number, file.name)
@@ -28,15 +55,18 @@ export async function JobsListMedia(req: Request, res: Response) {
ro_number,
file.name,
]),
thumb: GenerateUrl([
thumbnail: GenerateUrl([
FolderPaths.StaticPath,
FolderPaths.JobsFolder,
ro_number,
relativeThumbPath,
]),
thumbnailHeight: 250,
thumbnailWidth: 250,
};
})
);
}
res.json(ret);
}

6316
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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",

View File

@@ -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"),

View 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
)}`;
}

View File

@@ -1,6 +1,10 @@
import internal from "stream";
interface MediaFile {
src: string;
thumb: string;
thumbnail: string;
thumbnailHeight: number;
thumbnailWidth: number;
}
export default MediaFile;

View File

@@ -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"