Add EMS upload for archiving.
This commit is contained in:
@@ -6,4 +6,4 @@ VITE_COMPANY=IMEX
|
|||||||
VITE_FE_URL=https://imex.online
|
VITE_FE_URL=https://imex.online
|
||||||
VITE_FE_URL_TEST=https://test.imex.online
|
VITE_FE_URL_TEST=https://test.imex.online
|
||||||
VITE_API_URL="http://localhost:4000"
|
VITE_API_URL="http://localhost:4000"
|
||||||
VITE_API_TEST_URL="http://api.test.imex.online"
|
VITE_API_TEST_URL="https://api.test.imex.online"
|
||||||
3
.vscode/launch.json
vendored
3
.vscode/launch.json
vendored
@@ -13,7 +13,8 @@
|
|||||||
"runtimeArgs": ["--sourcemap"],
|
"runtimeArgs": ["--sourcemap"],
|
||||||
"env": {
|
"env": {
|
||||||
"REMOTE_DEBUGGING_PORT": "9222"
|
"REMOTE_DEBUGGING_PORT": "9222"
|
||||||
}
|
},
|
||||||
|
"experimentalNetworking": "off"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Debug Renderer Process",
|
"name": "Debug Renderer Process",
|
||||||
|
|||||||
17
build/com.convenient-brands.bodyshop-desktop.keepalive.plist
Normal file
17
build/com.convenient-brands.bodyshop-desktop.keepalive.plist
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>Label</key>
|
||||||
|
<string>com.convenientbrands.bodyshop-desktop.keepalive</string>
|
||||||
|
<key>ProgramArguments</key>
|
||||||
|
<array>
|
||||||
|
<string>Shop Partner Keep Alive</string>
|
||||||
|
<string>imexmedia://keep-alive</string>
|
||||||
|
</array>
|
||||||
|
<key>RunAtLoad</key>
|
||||||
|
<true/>
|
||||||
|
<key>StartInterval</key>
|
||||||
|
<integer>${KEEP_ALIVE_INTERVAL_SECONDS}</integer>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
792
package-lock.json
generated
792
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "bodyshop-desktop",
|
"name": "bodyshop-desktop",
|
||||||
"version": "0.0.1-alpha.10",
|
"version": "0.0.1-alpha.11",
|
||||||
"description": "Shop Management System Partner",
|
"description": "Shop Management System Partner",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "Convenient Brands, LLC",
|
"author": "Convenient Brands, LLC",
|
||||||
@@ -55,6 +55,7 @@
|
|||||||
"@types/xml2js": "^0.4.14",
|
"@types/xml2js": "^0.4.14",
|
||||||
"@vitejs/plugin-react": "^4.3.4",
|
"@vitejs/plugin-react": "^4.3.4",
|
||||||
"antd": "^5.24.6",
|
"antd": "^5.24.6",
|
||||||
|
"archiver": "^7.0.1",
|
||||||
"chokidar": "^4.0.3",
|
"chokidar": "^4.0.3",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dbffile": "^1.12.0",
|
"dbffile": "^1.12.0",
|
||||||
@@ -72,6 +73,7 @@
|
|||||||
"graphql-request": "^7.1.2",
|
"graphql-request": "^7.1.2",
|
||||||
"i18next": "^24.2.3",
|
"i18next": "^24.2.3",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"node-cron": "^3.0.3",
|
||||||
"playwright": "^1.51.1",
|
"playwright": "^1.51.1",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
@@ -84,7 +86,6 @@
|
|||||||
"typescript": "^5.8.3",
|
"typescript": "^5.8.3",
|
||||||
"vite": "6.2.6",
|
"vite": "6.2.6",
|
||||||
"xml2js": "^0.6.2",
|
"xml2js": "^0.6.2",
|
||||||
"xmlbuilder2": "^3.1.1",
|
"xmlbuilder2": "^3.1.1"
|
||||||
"node-cron": "^3.0.3"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import { DecodedTtl } from "./decode-ttl.interface";
|
|||||||
import DecodeVeh from "./decode-veh";
|
import DecodeVeh from "./decode-veh";
|
||||||
import { DecodedVeh } from "./decode-veh.interface";
|
import { DecodedVeh } from "./decode-veh.interface";
|
||||||
import setAppProgressbar from "../util/setAppProgressBar";
|
import setAppProgressbar from "../util/setAppProgressBar";
|
||||||
|
import UploadEmsToS3 from "./emsbackup";
|
||||||
|
|
||||||
async function ImportJob(filepath: string): Promise<void> {
|
async function ImportJob(filepath: string): Promise<void> {
|
||||||
const parsedFilePath = path.parse(filepath);
|
const parsedFilePath = path.parse(filepath);
|
||||||
@@ -191,6 +192,14 @@ async function ImportJob(filepath: string): Promise<void> {
|
|||||||
uploadNotification.show();
|
uploadNotification.show();
|
||||||
|
|
||||||
log.debug("Job inserted", insertRecordResult);
|
log.debug("Job inserted", insertRecordResult);
|
||||||
|
|
||||||
|
UploadEmsToS3({
|
||||||
|
extensionlessFilePath,
|
||||||
|
bodyshopid: newAvailableJob.bodyshopid,
|
||||||
|
ciecaid: jobObject.ciecaid ?? "",
|
||||||
|
clm_no: jobObject.clm_no ?? "",
|
||||||
|
ownr_ln: jobObject.ownr_ln ?? "",
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error("Error encountered while decoding job. ", errorTypeCheck(error));
|
log.error("Error encountered while decoding job. ", errorTypeCheck(error));
|
||||||
const uploadNotificationFailure = new Notification({
|
const uploadNotificationFailure = new Notification({
|
||||||
|
|||||||
104
src/main/decoder/emsbackup.ts
Normal file
104
src/main/decoder/emsbackup.ts
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import archiver from "archiver";
|
||||||
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
import { UUID } from "crypto";
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
import stream from "stream";
|
||||||
|
import { getTokenFromRenderer } from "../graphql/graphql-client";
|
||||||
|
import store from "../store/store";
|
||||||
|
|
||||||
|
async function UploadEmsToS3({
|
||||||
|
extensionlessFilePath,
|
||||||
|
bodyshopid,
|
||||||
|
clm_no,
|
||||||
|
ciecaid,
|
||||||
|
ownr_ln,
|
||||||
|
}: {
|
||||||
|
extensionlessFilePath: string;
|
||||||
|
bodyshopid: UUID;
|
||||||
|
clm_no: string;
|
||||||
|
ciecaid: string;
|
||||||
|
ownr_ln: string;
|
||||||
|
}): Promise<boolean> {
|
||||||
|
// This function is a placeholder for the actual upload logic
|
||||||
|
try {
|
||||||
|
const directory = path.dirname(extensionlessFilePath);
|
||||||
|
const baseFilename = path.basename(extensionlessFilePath);
|
||||||
|
|
||||||
|
// Find all files in the directory that start with the base filename
|
||||||
|
const filesToZip = fs
|
||||||
|
.readdirSync(directory)
|
||||||
|
.filter((file) => file.startsWith(baseFilename))
|
||||||
|
.map((file) => path.join(directory, file));
|
||||||
|
|
||||||
|
if (filesToZip.length === 0) {
|
||||||
|
console.error("No files found to zip.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a zip archive in memory
|
||||||
|
const archive = archiver("zip", { zlib: { level: 9 } });
|
||||||
|
const zipBuffer = await new Promise<Buffer>((resolve, reject) => {
|
||||||
|
const buffers: Buffer[] = [];
|
||||||
|
const writableStream = new stream.Writable({
|
||||||
|
write(chunk, _encoding, callback) {
|
||||||
|
buffers.push(chunk);
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
writableStream.on("finish", () => resolve(Buffer.concat(buffers)));
|
||||||
|
writableStream.on("error", reject);
|
||||||
|
|
||||||
|
archive.pipe(writableStream);
|
||||||
|
|
||||||
|
// Append files to the archive
|
||||||
|
filesToZip.forEach((file) => {
|
||||||
|
archive.file(file, { name: path.basename(file) });
|
||||||
|
});
|
||||||
|
|
||||||
|
archive.finalize();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get the presigned URL from the server
|
||||||
|
const presignedUrlResponse = await axios.post(
|
||||||
|
`${
|
||||||
|
store.get("app.isTest")
|
||||||
|
? import.meta.env.VITE_API_TEST_URL
|
||||||
|
: import.meta.env.VITE_API_URL
|
||||||
|
}/emsupload`,
|
||||||
|
{
|
||||||
|
bodyshopid,
|
||||||
|
ciecaid,
|
||||||
|
clm_no,
|
||||||
|
ownr_ln,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${await getTokenFromRenderer()}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const presignedUrl = presignedUrlResponse.data?.presignedUrl;
|
||||||
|
if (!presignedUrl) {
|
||||||
|
console.error("Failed to retrieve presigned URL.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload the zip file to S3 using the presigned URL
|
||||||
|
await axios.put(presignedUrl, zipBuffer, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/zip",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error uploading EMS to S3:", errorTypeCheck(error));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // Return true if the upload is successful
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UploadEmsToS3;
|
||||||
@@ -26,11 +26,11 @@ const ipcMainHandleAuthStateChanged = async (
|
|||||||
log.debug("Received authentication state change from Renderer.", user);
|
log.debug("Received authentication state change from Renderer.", user);
|
||||||
handleShopMetaDataFetch();
|
handleShopMetaDataFetch();
|
||||||
//Check for updates
|
//Check for updates
|
||||||
const convCo = Store.get("app.bodyshop");
|
const bodyshop = Store.get("app.bodyshop");
|
||||||
if (convCo === "alpha") {
|
if (bodyshop?.convenient_company === "alpha") {
|
||||||
autoUpdater.channel = "alpha";
|
autoUpdater.channel = "alpha";
|
||||||
log.debug("Setting update channel to ALPHA channel.");
|
log.debug("Setting update channel to ALPHA channel.");
|
||||||
} else if (convCo === "beta") {
|
} else if (bodyshop?.convenient_company === "beta") {
|
||||||
autoUpdater.channel = "beta";
|
autoUpdater.channel = "beta";
|
||||||
log.debug("Setting update channel to BETA channel.");
|
log.debug("Setting update channel to BETA channel.");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user