From eb0d402e3b2e5d1243e4f83ed3d1d311741d1f9b Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Thu, 28 Aug 2025 18:51:46 -0700 Subject: [PATCH 01/34] save --- api/main_endpoints/routes/Printer.js | 15 ++++++++++ src/Pages/2DPrinting/2DPrinting.js | 41 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index da9c82bd1..0ca096376 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -138,4 +138,19 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => { } }); +router.post('/status', express.json, async (req, res) => { + logger.info(req); + + try { + const status = await fetch(PRINTER_URL + '/status', { + method: 'POST', + body: req.body + }); + + res.status(OK).send(status); + } catch (err) { + res.sendStatus(SERVER_ERROR); + } +}); + module.exports = router; diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index ff23d3cd0..47a871ac0 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -13,6 +13,7 @@ import ConfirmationModal from '../../Components/DecisionModal/ConfirmationModal.js'; import { useSCE } from '../../Components/context/SceContext.js'; +import { BASE_API_URL } from '../../Enums.js'; export default function Printing() { const { user, setUser } = useSCE(); @@ -41,6 +42,12 @@ export default function Printing() { setLoading(false); } + async function pollJobStatus() { + setInterval(() => { + console.log("aga"); + }, 1000); + } + async function getNumberOfPagesPrintedSoFar() { const result = await getPagesPrinted( user.email, @@ -194,6 +201,12 @@ export default function Printing() { return; } + if (window.localStorage.getItem("printId") !== null) { + setPrintStatus('You are already printing something - please wait'); + setPrintStatusColor('error'); + return; + } + // send print request with files and configuratiosn in formData const data = new FormData(); @@ -202,7 +215,35 @@ export default function Printing() { data.append('copies', copies); let status = await printPage(data, user.token); + try { + window.localStorage.setItem('printId', JSON.stringify(status?.responseData)); + } catch (err) { + // TODO: display err to client + console.log('encountered an error while trying to save print id to local storage ' + err); + } + if (!status.error) { + setPrintStatus('Printing in progress'); + + const url = new URL('/api/Printer/status', BASE_API_URL); + + console.log("h"); + + const s = await fetch(url.href, { + method: 'POST', + body: status.responseData + }); + console.log("h2"); + console.log(s); + + const promise = new Promise((resolve, reject) => { + setTimeout(() => { + resolve(); + }, 5000); + }); + + await promise; + editUser( { ...user, pagesPrinted: pagesPrinted + pagesToBeUsedInPrintRequest }, user.token, From b460d2074d58f324292db8528444f4872bac5d4f Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Thu, 28 Aug 2025 20:20:54 -0700 Subject: [PATCH 02/34] poll job status on print page; local storage first pass --- api/main_endpoints/routes/Printer.js | 10 +++---- src/APIFunctions/2DPrinting.js | 17 +++++++++++ src/Pages/2DPrinting/2DPrinting.js | 45 ++++++++++------------------ 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index 0ca096376..6428e47ff 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -138,15 +138,15 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => { } }); -router.post('/status', express.json, async (req, res) => { - logger.info(req); - +router.post('/status', express.json(), async (req, res) => { try { - const status = await fetch(PRINTER_URL + '/status', { + const response = await fetch(PRINTER_URL + '/status', { method: 'POST', - body: req.body + body: req.body.printId }); + // { status: string } + const status = await response.json(); res.status(OK).send(status); } catch (err) { res.sendStatus(SERVER_ERROR); diff --git a/src/APIFunctions/2DPrinting.js b/src/APIFunctions/2DPrinting.js index 9c1ea06a0..3488a5997 100644 --- a/src/APIFunctions/2DPrinting.js +++ b/src/APIFunctions/2DPrinting.js @@ -60,6 +60,23 @@ export function parseRange(pages, maxPages) { return result; } +export async function getPrintStatus(printId) { + const url = new URL('/api/Printer/status', BASE_API_URL); + + const response = await fetch(url.href, { + headers: { + 'Content-Type': 'application/json' + }, + method: 'POST', + body: JSON.stringify({ printId: printId }) + }); + + const json = await response.json(); + const status = json.status; + + return status; +} + /** * Print the page * @param {Object} data - PDF File and its configurations diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 47a871ac0..8074526bc 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -4,6 +4,7 @@ import { parseRange, printPage, getPagesPrinted, + getPrintStatus, } from '../../APIFunctions/2DPrinting'; import { editUser } from '../../APIFunctions/User'; @@ -13,7 +14,6 @@ import ConfirmationModal from '../../Components/DecisionModal/ConfirmationModal.js'; import { useSCE } from '../../Components/context/SceContext.js'; -import { BASE_API_URL } from '../../Enums.js'; export default function Printing() { const { user, setUser } = useSCE(); @@ -42,12 +42,6 @@ export default function Printing() { setLoading(false); } - async function pollJobStatus() { - setInterval(() => { - console.log("aga"); - }, 1000); - } - async function getNumberOfPagesPrintedSoFar() { const result = await getPagesPrinted( user.email, @@ -201,10 +195,10 @@ export default function Printing() { return; } - if (window.localStorage.getItem("printId") !== null) { + if (window.localStorage.getItem('printId') !== null) { setPrintStatus('You are already printing something - please wait'); setPrintStatusColor('error'); - return; + return; } // send print request with files and configuratiosn in formData @@ -213,35 +207,28 @@ export default function Printing() { data.append('file', PdfFile); data.append('sides', sides); data.append('copies', copies); - let status = await printPage(data, user.token); + let printReq = await printPage(data, user.token); try { - window.localStorage.setItem('printId', JSON.stringify(status?.responseData)); + window.localStorage.setItem('printId', JSON.stringify(printReq?.responseData)); } catch (err) { - // TODO: display err to client - console.log('encountered an error while trying to save print id to local storage ' + err); + setPrintStatus(':('); + setPrintStatusColor('error'); } - if (!status.error) { + if (!printReq.error) { setPrintStatus('Printing in progress'); - - const url = new URL('/api/Printer/status', BASE_API_URL); - - console.log("h"); - - const s = await fetch(url.href, { - method: 'POST', - body: status.responseData - }); - console.log("h2"); - console.log(s); + setPrintStatusColor('success'); const promise = new Promise((resolve, reject) => { - setTimeout(() => { - resolve(); - }, 5000); + const interval = setInterval(async () => { + const status = await getPrintStatus(printReq.responseData['print_id']); + if (status === 'PRINTED') { + clearInterval(interval); + resolve(); + } + }, 1000); }); - await promise; editUser( From 1c28d7b85386d16033cf5d0c230942d428776044 Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Thu, 28 Aug 2025 23:31:37 -0700 Subject: [PATCH 03/34] delete printId from local storage on complete --- src/Pages/2DPrinting/2DPrinting.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 8074526bc..f00e70963 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -231,6 +231,7 @@ export default function Printing() { }); await promise; + window.localStorage.removeItem('printId'); editUser( { ...user, pagesPrinted: pagesPrinted + pagesToBeUsedInPrintRequest }, user.token, From cffad4de315d29b2c937e086511347778e3641a5 Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Fri, 29 Aug 2025 22:17:57 -0700 Subject: [PATCH 04/34] resume polling if printId still exists --- src/Pages/2DPrinting/2DPrinting.js | 58 +++++++++++++++++++----------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index f00e70963..eddb315c4 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -35,6 +35,33 @@ export default function Printing() { const [loading, setLoading] = useState(true); const [PdfFile, setPdfFile] = useState(null); + async function tryResolvePrint(printId) { + if (printId === null) return; + + setPrintStatus('Printing in progress'); + setPrintStatusColor('success'); + + const interval = setInterval(async () => { + const status = await getPrintStatus(printId); + if (status === 'PRINTED') { + window.localStorage.removeItem('printId'); + editUser( + { ...user, pagesPrinted: pagesPrinted + pagesToBeUsedInPrintRequest }, + user.token, + ); + + setPrintStatus('Printing succeeded!'); + setPrintStatusColor('success'); + + setTimeout(() => { + setPrintStatus(null); + }, 5000); + + clearInterval(interval); + } + }, 1000); + } + async function checkPrinterHealth() { setLoading(true); const status = await healthCheck(); @@ -54,6 +81,7 @@ export default function Printing() { } useEffect(() => { + tryResolvePrint(window.localStorage.getItem('printId')); checkPrinterHealth(); getNumberOfPagesPrintedSoFar(); }, []); @@ -192,12 +220,20 @@ export default function Printing() { if (PdfFile.size > 1024 * 1024 * 150) { setPrintStatus('File exceeds 150 MB size limit'); setPrintStatusColor('error'); + setTimeout(() => { + setPrintStatus(null); + }, 5000); + return; } if (window.localStorage.getItem('printId') !== null) { setPrintStatus('You are already printing something - please wait'); setPrintStatusColor('error'); + setTimeout(() => { + setPrintStatus(null); + }, 5000); + return; } @@ -217,27 +253,7 @@ export default function Printing() { } if (!printReq.error) { - setPrintStatus('Printing in progress'); - setPrintStatusColor('success'); - - const promise = new Promise((resolve, reject) => { - const interval = setInterval(async () => { - const status = await getPrintStatus(printReq.responseData['print_id']); - if (status === 'PRINTED') { - clearInterval(interval); - resolve(); - } - }, 1000); - }); - await promise; - - window.localStorage.removeItem('printId'); - editUser( - { ...user, pagesPrinted: pagesPrinted + pagesToBeUsedInPrintRequest }, - user.token, - ); - setPrintStatus('Printing succeeded!'); - setPrintStatusColor('success'); + tryResolvePrint(printReq.responseData['print_id']); } else { setPrintStatus('Printing failed. Please try again or reach out to SCE Dev team if the issue persists.'); setPrintStatusColor('error'); From 722627af13af048170cbb504c88d1a48cb5f89ed Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Fri, 29 Aug 2025 22:33:18 -0700 Subject: [PATCH 05/34] add undefined check for localStorage in useEffect --- src/Pages/2DPrinting/2DPrinting.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index eddb315c4..19cab1e07 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -81,7 +81,7 @@ export default function Printing() { } useEffect(() => { - tryResolvePrint(window.localStorage.getItem('printId')); + tryResolvePrint(window.localStorage?.getItem('printId')); checkPrinterHealth(); getNumberOfPagesPrintedSoFar(); }, []); From dec483a150bc27ad8fc29340d2bd462ea8679abb Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Sun, 31 Aug 2025 19:38:05 -0700 Subject: [PATCH 06/34] save --- src/Pages/2DPrinting/2DPrinting.js | 46 +++++++++++++++--------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 19cab1e07..40109e0fe 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -35,6 +35,24 @@ export default function Printing() { const [loading, setLoading] = useState(true); const [PdfFile, setPdfFile] = useState(null); + async function checkPrinterHealth() { + setLoading(true); + const status = await healthCheck(); + setPrinterHealthy(status && !status.error); + setLoading(false); + } + + async function getNumberOfPagesPrintedSoFar() { + const result = await getPagesPrinted( + user.email, + user.token, + ); + setPrinterHealthy(!result.error); + if (!result.error) { + setPagesPrinted(result.pagesUsed); + } + } + async function tryResolvePrint(printId) { if (printId === null) return; @@ -52,6 +70,7 @@ export default function Printing() { setPrintStatus('Printing succeeded!'); setPrintStatusColor('success'); + getNumberOfPagesPrintedSoFar(); setTimeout(() => { setPrintStatus(null); @@ -62,24 +81,6 @@ export default function Printing() { }, 1000); } - async function checkPrinterHealth() { - setLoading(true); - const status = await healthCheck(); - setPrinterHealthy(status && !status.error); - setLoading(false); - } - - async function getNumberOfPagesPrintedSoFar() { - const result = await getPagesPrinted( - user.email, - user.token, - ); - setPrinterHealthy(!result.error); - if (!result.error) { - setPagesPrinted(result.pagesUsed); - } - } - useEffect(() => { tryResolvePrint(window.localStorage?.getItem('printId')); checkPrinterHealth(); @@ -246,7 +247,7 @@ export default function Printing() { let printReq = await printPage(data, user.token); try { - window.localStorage.setItem('printId', JSON.stringify(printReq?.responseData)); + window.localStorage.setItem('printId', JSON.stringify(printReq?.responseData['print_id'])); } catch (err) { setPrintStatus(':('); setPrintStatusColor('error'); @@ -257,11 +258,10 @@ export default function Printing() { } else { setPrintStatus('Printing failed. Please try again or reach out to SCE Dev team if the issue persists.'); setPrintStatusColor('error'); + setTimeout(() => { + setPrintStatus(null); + }, 5000); } - getNumberOfPagesPrintedSoFar(); - setTimeout(() => { - setPrintStatus(null); - }, 5000); } function handleDrop(e) { From 4913ae09bf279fd55c1931d79960bae89b009b90 Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Sun, 31 Aug 2025 20:09:37 -0700 Subject: [PATCH 07/34] save --- src/Pages/2DPrinting/2DPrinting.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 40109e0fe..6acbd09e9 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -495,4 +495,3 @@ export default function Printing() { ); } - From 9db2980b44d621461e2cd888c56e690902a0ab46 Mon Sep 17 00:00:00 2001 From: thebeninator Date: Tue, 2 Sep 2025 16:22:04 -0700 Subject: [PATCH 08/34] use promise for tryResolvePrint --- src/Pages/2DPrinting/2DPrinting.js | 60 ++++++++++++++---------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 6acbd09e9..324341025 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -59,26 +59,29 @@ export default function Printing() { setPrintStatus('Printing in progress'); setPrintStatusColor('success'); - const interval = setInterval(async () => { - const status = await getPrintStatus(printId); - if (status === 'PRINTED') { - window.localStorage.removeItem('printId'); - editUser( - { ...user, pagesPrinted: pagesPrinted + pagesToBeUsedInPrintRequest }, - user.token, - ); - - setPrintStatus('Printing succeeded!'); - setPrintStatusColor('success'); - getNumberOfPagesPrintedSoFar(); - - setTimeout(() => { - setPrintStatus(null); - }, 5000); - - clearInterval(interval); - } - }, 1000); + return new Promise((resolve, reject) => { + const interval = setInterval(async () => { + const status = await getPrintStatus(printId); + if (status === 'PRINTED') { + window.localStorage.removeItem('printId'); + editUser( + { ...user, pagesPrinted: pagesPrinted + pagesToBeUsedInPrintRequest }, + user.token, + ); + + setPrintStatus('Printing succeeded!'); + setPrintStatusColor('success'); + getNumberOfPagesPrintedSoFar(); + + setTimeout(() => { + setPrintStatus(null); + }, 5000); + + resolve(); + clearInterval(interval); + } + }, 1000); + }); } useEffect(() => { @@ -221,20 +224,12 @@ export default function Printing() { if (PdfFile.size > 1024 * 1024 * 150) { setPrintStatus('File exceeds 150 MB size limit'); setPrintStatusColor('error'); - setTimeout(() => { - setPrintStatus(null); - }, 5000); - return; } if (window.localStorage.getItem('printId') !== null) { setPrintStatus('You are already printing something - please wait'); setPrintStatusColor('error'); - setTimeout(() => { - setPrintStatus(null); - }, 5000); - return; } @@ -254,14 +249,15 @@ export default function Printing() { } if (!printReq.error) { - tryResolvePrint(printReq.responseData['print_id']); + await tryResolvePrint(printReq.responseData['print_id']); } else { setPrintStatus('Printing failed. Please try again or reach out to SCE Dev team if the issue persists.'); setPrintStatusColor('error'); - setTimeout(() => { - setPrintStatus(null); - }, 5000); } + + setTimeout(() => { + setPrintStatus(null); + }, 5000); } function handleDrop(e) { From 0a57c26844a3f6f275ade922ea8fa2c0b396fa76 Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Mon, 8 Sep 2025 00:31:57 -0700 Subject: [PATCH 09/34] convert /status to GET, require token --- api/main_endpoints/routes/Printer.js | 26 ++++++++++++++++++++------ src/APIFunctions/2DPrinting.js | 11 +++++------ src/Pages/2DPrinting/2DPrinting.js | 16 +++++++++++++--- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index 6428e47ff..a143a2070 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -138,16 +138,30 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => { } }); -router.post('/status', express.json(), async (req, res) => { +router.get('/status/', async (req, res) => { + if (!checkIfTokenSent(req)) { + logger.warn('/status was requested without a token'); + return res.sendStatus(UNAUTHORIZED); + } + + const decodedToken = await decodeToken(req); + if (!decodedToken || Object.keys(decodedToken) === 0) { + logger.warn('/status was requested with an invalid token'); + return res.sendStatus(UNAUTHORIZED); + } + if (!PRINTING.ENABLED) { + logger.warn('Printing is disabled, returning 200 and PRINTED status to mock the printing server'); + return res.status(OK).send({ status: 'PRINTED' }); + } + try { - const response = await fetch(PRINTER_URL + '/status', { - method: 'POST', - body: req.body.printId + const response = await fetch(PRINTER_URL + `/status/?id=${req.query.id}`, { + method: 'GET', }); // { status: string } - const status = await response.json(); - res.status(OK).send(status); + const json = await response.json(); + res.status(OK).send(json); } catch (err) { res.sendStatus(SERVER_ERROR); } diff --git a/src/APIFunctions/2DPrinting.js b/src/APIFunctions/2DPrinting.js index 3488a5997..6c5ea297d 100644 --- a/src/APIFunctions/2DPrinting.js +++ b/src/APIFunctions/2DPrinting.js @@ -60,15 +60,14 @@ export function parseRange(pages, maxPages) { return result; } -export async function getPrintStatus(printId) { - const url = new URL('/api/Printer/status', BASE_API_URL); +export async function getPrintStatus(printId, token) { + const url = new URL('/api/Printer/status/', BASE_API_URL); - const response = await fetch(url.href, { + const response = await fetch(url.href + `?id=${printId}`, { headers: { - 'Content-Type': 'application/json' + 'Authorization': `Bearer ${token}` }, - method: 'POST', - body: JSON.stringify({ printId: printId }) + method: 'GET', }); const json = await response.json(); diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 324341025..362b88e57 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -61,8 +61,11 @@ export default function Printing() { return new Promise((resolve, reject) => { const interval = setInterval(async () => { - const status = await getPrintStatus(printId); - if (status === 'PRINTED') { + try { + const status = await getPrintStatus(printId, user.token); + + if (status !== 'PRINTED') return; + window.localStorage.removeItem('printId'); editUser( { ...user, pagesPrinted: pagesPrinted + pagesToBeUsedInPrintRequest }, @@ -79,6 +82,8 @@ export default function Printing() { resolve(); clearInterval(interval); + } catch (err) { + reject(err); } }, 1000); }); @@ -249,7 +254,12 @@ export default function Printing() { } if (!printReq.error) { - await tryResolvePrint(printReq.responseData['print_id']); + try { + await tryResolvePrint(printReq.responseData['print_id']); + } catch (err) { + setPrintStatus(':('); + setPrintStatusColor('error'); + } } else { setPrintStatus('Printing failed. Please try again or reach out to SCE Dev team if the issue persists.'); setPrintStatusColor('error'); From 86e70a9d8b712172335a03958526bbf19f4ae5c8 Mon Sep 17 00:00:00 2001 From: thebeninator Date: Mon, 8 Sep 2025 13:35:53 -0700 Subject: [PATCH 10/34] multiple print job tracking first pass --- src/Pages/2DPrinting/2DPrinting.js | 44 ++++++++++++++++++------------ 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 362b88e57..b28816659 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -34,6 +34,7 @@ export default function Printing() { const [printerHealthy, setPrinterHealthy] = useState(false); const [loading, setLoading] = useState(true); const [PdfFile, setPdfFile] = useState(null); + const [printJobs, setPrintJobs] = useState({}); async function checkPrinterHealth() { setLoading(true); @@ -53,7 +54,7 @@ export default function Printing() { } } - async function tryResolvePrint(printId) { + async function tryResolvePrint(printId, jobs) { if (printId === null) return; setPrintStatus('Printing in progress'); @@ -66,7 +67,17 @@ export default function Printing() { if (status !== 'PRINTED') return; - window.localStorage.removeItem('printId'); + // PROBLEM: the printJobs state will end up becoming + // stale in this interval, so if we make a req and + // then another req, upon the first job completing + // the printJobs state will be set to an empty object + // since when the interval was started, printJobs + // only contained the first job + const newPrintJobs = {...jobs}; + delete newPrintJobs[printId]; + window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); + setPrintJobs(newPrintJobs); + editUser( { ...user, pagesPrinted: pagesPrinted + pagesToBeUsedInPrintRequest }, user.token, @@ -90,7 +101,14 @@ export default function Printing() { } useEffect(() => { - tryResolvePrint(window.localStorage?.getItem('printId')); + if (window.localStorage !== undefined) { + const jobsFromLocal = JSON.parse(window.localStorage?.getItem('printJobs')); + setPrintJobs(jobsFromLocal); + } +}, []); + + useEffect(() => { + //tryResolvePrint(window.localStorage?.getItem('printId')); checkPrinterHealth(); getNumberOfPagesPrintedSoFar(); }, []); @@ -244,23 +262,15 @@ export default function Printing() { data.append('file', PdfFile); data.append('sides', sides); data.append('copies', copies); - let printReq = await printPage(data, user.token); + const printReq = await printPage(data, user.token); try { - window.localStorage.setItem('printId', JSON.stringify(printReq?.responseData['print_id'])); + const printId = printReq?.responseData['print_id']; + const newPrintJobs = {...printJobs, [printId]: {state: 'PENDING'} }; + setPrintJobs(newPrintJobs); + window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); + await tryResolvePrint(printReq.responseData['print_id'], newPrintJobs); } catch (err) { - setPrintStatus(':('); - setPrintStatusColor('error'); - } - - if (!printReq.error) { - try { - await tryResolvePrint(printReq.responseData['print_id']); - } catch (err) { - setPrintStatus(':('); - setPrintStatusColor('error'); - } - } else { setPrintStatus('Printing failed. Please try again or reach out to SCE Dev team if the issue persists.'); setPrintStatusColor('error'); } From 3f439a454354eac56be139e69f562a0ca7ccddf7 Mon Sep 17 00:00:00 2001 From: thebeninator Date: Mon, 8 Sep 2025 13:37:54 -0700 Subject: [PATCH 11/34] fix lint --- src/Pages/2DPrinting/2DPrinting.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index b28816659..c93e1a1f8 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -101,14 +101,14 @@ export default function Printing() { } useEffect(() => { - if (window.localStorage !== undefined) { - const jobsFromLocal = JSON.parse(window.localStorage?.getItem('printJobs')); - setPrintJobs(jobsFromLocal); - } -}, []); + if (window.localStorage !== undefined) { + const jobsFromLocal = JSON.parse(window.localStorage?.getItem('printJobs')); + setPrintJobs(jobsFromLocal); + } + }, []); useEffect(() => { - //tryResolvePrint(window.localStorage?.getItem('printId')); + // tryResolvePrint(window.localStorage?.getItem('printId')); checkPrinterHealth(); getNumberOfPagesPrintedSoFar(); }, []); From ff60a16537639d22d4e880a45446d7c37b10d1bb Mon Sep 17 00:00:00 2001 From: thebeninator Date: Mon, 8 Sep 2025 14:13:18 -0700 Subject: [PATCH 12/34] fix interval using stale jobs state --- src/Pages/2DPrinting/2DPrinting.js | 117 +++++++++++++++++------------ 1 file changed, 71 insertions(+), 46 deletions(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index c93e1a1f8..f0a99f855 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -54,51 +54,76 @@ export default function Printing() { } } - async function tryResolvePrint(printId, jobs) { - if (printId === null) return; - - setPrintStatus('Printing in progress'); - setPrintStatusColor('success'); - - return new Promise((resolve, reject) => { - const interval = setInterval(async () => { - try { - const status = await getPrintStatus(printId, user.token); - - if (status !== 'PRINTED') return; - - // PROBLEM: the printJobs state will end up becoming - // stale in this interval, so if we make a req and - // then another req, upon the first job completing - // the printJobs state will be set to an empty object - // since when the interval was started, printJobs - // only contained the first job - const newPrintJobs = {...jobs}; - delete newPrintJobs[printId]; - window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); - setPrintJobs(newPrintJobs); - - editUser( - { ...user, pagesPrinted: pagesPrinted + pagesToBeUsedInPrintRequest }, - user.token, - ); - - setPrintStatus('Printing succeeded!'); - setPrintStatusColor('success'); - getNumberOfPagesPrintedSoFar(); - - setTimeout(() => { - setPrintStatus(null); - }, 5000); - - resolve(); - clearInterval(interval); - } catch (err) { - reject(err); - } - }, 1000); - }); - } + useEffect(() => { + if (printJobs === null || Object.keys(printJobs).length === 0) return; + const ids = Object.keys(printJobs); + + const interval = setInterval(async () => { + if (ids.length === 0) { + clearInterval(interval); + return; + } + + ids.map(async (id) => { + const status = await getPrintStatus(id, user.token); + + if (status !== 'PRINTED') return; + + const newPrintJobs = {...printJobs}; + delete newPrintJobs[id]; + setPrintJobs(newPrintJobs); + window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); + }); + }, 1000); + + return () => clearInterval(interval); + }, [printJobs]); + + // async function tryResolvePrint(printId, jobs) { + // if (printId === null) return; + + // setPrintStatus('Printing in progress'); + // setPrintStatusColor('success'); + + // return new Promise((resolve, reject) => { + // const interval = setInterval(async () => { + // try { + // const status = await getPrintStatus(printId, user.token); + + // if (status !== 'PRINTED') return; + + // // PROBLEM: the printJobs state will end up becoming + // // stale in this interval, so if we make a req and + // // then another req, upon the first job completing + // // the printJobs state will be set to an empty object + // // since when the interval was started, printJobs + // // only contained the first job + // const newPrintJobs = {...jobs}; + // delete newPrintJobs[printId]; + // window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); + // setPrintJobs(newPrintJobs); + + // editUser( + // { ...user, pagesPrinted: pagesPrinted + pagesToBeUsedInPrintRequest }, + // user.token, + // ); + + // setPrintStatus('Printing succeeded!'); + // setPrintStatusColor('success'); + // getNumberOfPagesPrintedSoFar(); + + // setTimeout(() => { + // setPrintStatus(null); + // }, 5000); + + // resolve(); + // clearInterval(interval); + // } catch (err) { + // reject(err); + // } + // }, 1000); + // }); + // } useEffect(() => { if (window.localStorage !== undefined) { @@ -269,7 +294,7 @@ export default function Printing() { const newPrintJobs = {...printJobs, [printId]: {state: 'PENDING'} }; setPrintJobs(newPrintJobs); window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); - await tryResolvePrint(printReq.responseData['print_id'], newPrintJobs); + // await tryResolvePrint(printReq.responseData['print_id'], newPrintJobs); } catch (err) { setPrintStatus('Printing failed. Please try again or reach out to SCE Dev team if the issue persists.'); setPrintStatusColor('error'); From b43fd3ea56ccf864466a81d296c5d96f77a83d11 Mon Sep 17 00:00:00 2001 From: thebeninator Date: Tue, 9 Sep 2025 16:24:47 -0700 Subject: [PATCH 13/34] implement doodoo ui for active prints --- src/Pages/2DPrinting/2DPrinting.js | 66 ++++++++---------------------- 1 file changed, 18 insertions(+), 48 deletions(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index f0a99f855..0af124c29 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -70,61 +70,22 @@ export default function Printing() { if (status !== 'PRINTED') return; const newPrintJobs = {...printJobs}; - delete newPrintJobs[id]; + newPrintJobs[id].state = 'PRINTED'; setPrintJobs(newPrintJobs); - window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); + + setTimeout(() => { + const newPrintJobs = {...printJobs}; + delete newPrintJobs[id]; + setPrintJobs(newPrintJobs); + window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); + }, 2000); + }); }, 1000); return () => clearInterval(interval); }, [printJobs]); - // async function tryResolvePrint(printId, jobs) { - // if (printId === null) return; - - // setPrintStatus('Printing in progress'); - // setPrintStatusColor('success'); - - // return new Promise((resolve, reject) => { - // const interval = setInterval(async () => { - // try { - // const status = await getPrintStatus(printId, user.token); - - // if (status !== 'PRINTED') return; - - // // PROBLEM: the printJobs state will end up becoming - // // stale in this interval, so if we make a req and - // // then another req, upon the first job completing - // // the printJobs state will be set to an empty object - // // since when the interval was started, printJobs - // // only contained the first job - // const newPrintJobs = {...jobs}; - // delete newPrintJobs[printId]; - // window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); - // setPrintJobs(newPrintJobs); - - // editUser( - // { ...user, pagesPrinted: pagesPrinted + pagesToBeUsedInPrintRequest }, - // user.token, - // ); - - // setPrintStatus('Printing succeeded!'); - // setPrintStatusColor('success'); - // getNumberOfPagesPrintedSoFar(); - - // setTimeout(() => { - // setPrintStatus(null); - // }, 5000); - - // resolve(); - // clearInterval(interval); - // } catch (err) { - // reject(err); - // } - // }, 1000); - // }); - // } - useEffect(() => { if (window.localStorage !== undefined) { const jobsFromLocal = JSON.parse(window.localStorage?.getItem('printJobs')); @@ -503,6 +464,15 @@ export default function Printing() { return (
+
+

Active Prints

+ { + Object.keys(printJobs).map(id => ( +

{id}: {printJobs[id].state}

+ )) + } +
+ Date: Wed, 10 Sep 2025 12:14:14 -0700 Subject: [PATCH 14/34] store job in local immediately; remove guard clause for 'PRINTED' state --- src/Pages/2DPrinting/2DPrinting.js | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 0af124c29..67f8a6bc7 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -67,19 +67,19 @@ export default function Printing() { ids.map(async (id) => { const status = await getPrintStatus(id, user.token); - if (status !== 'PRINTED') return; - const newPrintJobs = {...printJobs}; - newPrintJobs[id].state = 'PRINTED'; + newPrintJobs[id].state = status; setPrintJobs(newPrintJobs); - - setTimeout(() => { - const newPrintJobs = {...printJobs}; - delete newPrintJobs[id]; - setPrintJobs(newPrintJobs); - window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); - }, 2000); - + window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); + + if (status === 'PRINTED') { + setTimeout(() => { + const newPrintJobs = {...printJobs}; + delete newPrintJobs[id]; + setPrintJobs(newPrintJobs); + window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); + }, 2000); + } }); }, 1000); @@ -88,13 +88,10 @@ export default function Printing() { useEffect(() => { if (window.localStorage !== undefined) { - const jobsFromLocal = JSON.parse(window.localStorage?.getItem('printJobs')); + const jobsFromLocal = JSON.parse(window.localStorage.getItem('printJobs')); setPrintJobs(jobsFromLocal); } - }, []); - useEffect(() => { - // tryResolvePrint(window.localStorage?.getItem('printId')); checkPrinterHealth(); getNumberOfPagesPrintedSoFar(); }, []); @@ -465,7 +462,7 @@ export default function Printing() { return (
-

Active Prints

+

Your Active Prints

{ Object.keys(printJobs).map(id => (

{id}: {printJobs[id].state}

From f48d82f75bcf3996af1ba990bcd7baf017e965ec Mon Sep 17 00:00:00 2001 From: thebeninator Date: Wed, 10 Sep 2025 13:24:28 -0700 Subject: [PATCH 15/34] some clean up --- src/Pages/2DPrinting/2DPrinting.js | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 67f8a6bc7..490300df7 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -68,7 +68,7 @@ export default function Printing() { const status = await getPrintStatus(id, user.token); const newPrintJobs = {...printJobs}; - newPrintJobs[id].state = status; + newPrintJobs[id].status = status; setPrintJobs(newPrintJobs); window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); @@ -232,13 +232,7 @@ export default function Printing() { setPrintStatusColor('error'); return; } - - if (window.localStorage.getItem('printId') !== null) { - setPrintStatus('You are already printing something - please wait'); - setPrintStatusColor('error'); - return; - } - + // send print request with files and configuratiosn in formData const data = new FormData(); @@ -249,10 +243,9 @@ export default function Printing() { try { const printId = printReq?.responseData['print_id']; - const newPrintJobs = {...printJobs, [printId]: {state: 'PENDING'} }; + const newPrintJobs = {...printJobs, [printId]: {status: 'PENDING'} }; setPrintJobs(newPrintJobs); window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); - // await tryResolvePrint(printReq.responseData['print_id'], newPrintJobs); } catch (err) { setPrintStatus('Printing failed. Please try again or reach out to SCE Dev team if the issue persists.'); setPrintStatusColor('error'); @@ -465,7 +458,7 @@ export default function Printing() {

Your Active Prints

{ Object.keys(printJobs).map(id => ( -

{id}: {printJobs[id].state}

+

{id}: {printJobs[id].status}

)) }
From b0f5497121a7081e9b90cbfeb38229a263b5e79b Mon Sep 17 00:00:00 2001 From: thebeninator Date: Wed, 10 Sep 2025 13:26:14 -0700 Subject: [PATCH 16/34] FIX LINT --- src/Pages/2DPrinting/2DPrinting.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 490300df7..267d5f8ff 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -232,7 +232,7 @@ export default function Printing() { setPrintStatusColor('error'); return; } - + // send print request with files and configuratiosn in formData const data = new FormData(); From 2780a0b3751d3ac1fcd078ea691d6f15186b8439 Mon Sep 17 00:00:00 2001 From: thebeninator Date: Mon, 15 Sep 2025 14:14:07 -0700 Subject: [PATCH 17/34] check if localstorage printJobs exists first before setting state --- src/Pages/2DPrinting/2DPrinting.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 267d5f8ff..53fddfda7 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -89,7 +89,9 @@ export default function Printing() { useEffect(() => { if (window.localStorage !== undefined) { const jobsFromLocal = JSON.parse(window.localStorage.getItem('printJobs')); - setPrintJobs(jobsFromLocal); + if (jobsFromLocal !== null) { + setPrintJobs(jobsFromLocal); + } } checkPrinterHealth(); From 4c752de4dc34b92140db061d1d40b7c25201be35 Mon Sep 17 00:00:00 2001 From: thebeninator Date: Mon, 29 Sep 2025 14:19:51 -0700 Subject: [PATCH 18/34] undoodoo the doodoo ui first pass --- src/Pages/2DPrinting/2DPrinting.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 53fddfda7..3034d9965 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -67,18 +67,18 @@ export default function Printing() { ids.map(async (id) => { const status = await getPrintStatus(id, user.token); - const newPrintJobs = {...printJobs}; - newPrintJobs[id].status = status; - setPrintJobs(newPrintJobs); - window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); - - if (status === 'PRINTED') { + if (status === 'completed') { setTimeout(() => { const newPrintJobs = {...printJobs}; delete newPrintJobs[id]; setPrintJobs(newPrintJobs); window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); }, 2000); + } else { + const newPrintJobs = {...printJobs}; + newPrintJobs[id].status = status; + setPrintJobs(newPrintJobs); + window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); } }); }, 1000); @@ -245,7 +245,7 @@ export default function Printing() { try { const printId = printReq?.responseData['print_id']; - const newPrintJobs = {...printJobs, [printId]: {status: 'PENDING'} }; + const newPrintJobs = {...printJobs, [printId]: {status: 'created', fileName: PdfFile.name} }; setPrintJobs(newPrintJobs); window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); } catch (err) { @@ -457,10 +457,14 @@ export default function Printing() { return (
-

Your Active Prints

{ Object.keys(printJobs).map(id => ( -

{id}: {printJobs[id].status}

+
+
+ +

{printJobs[id].fileName} ({id}): {printJobs[id].status}

+
+
)) }
From 2ea0f20d4bb32dd44a708c22be64b652ff49603b Mon Sep 17 00:00:00 2001 From: thebeninator Date: Fri, 14 Nov 2025 22:50:09 -0800 Subject: [PATCH 19/34] implement page escrow --- api/main_endpoints/models/User.js | 4 ++++ api/main_endpoints/routes/Printer.js | 34 ++++++++++++++++++++++++---- api/main_endpoints/routes/User.js | 3 ++- src/APIFunctions/2DPrinting.js | 8 ++++--- src/APIFunctions/User.js | 2 ++ src/Pages/2DPrinting/2DPrinting.js | 25 +++++++++----------- 6 files changed, 53 insertions(+), 23 deletions(-) diff --git a/api/main_endpoints/models/User.js b/api/main_endpoints/models/User.js index 35a3450be..96bc45da3 100644 --- a/api/main_endpoints/models/User.js +++ b/api/main_endpoints/models/User.js @@ -70,6 +70,10 @@ const UserSchema = new Schema( type: Number, default: 0 }, + escrowPagesPrinted: { + type: Number, + default: 0 + }, apiKey: { type: String, default: '' diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index a143a2070..806307930 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -14,10 +14,12 @@ const { UNAUTHORIZED, NOT_FOUND, SERVER_ERROR, + BAD_REQUEST } = require('../../util/constants').STATUS_CODES; const { PRINTING = {} } = require('../../config/config.json'); +const User = require('../models/User.js'); // see https://github.com/SCE-Development/Quasar/tree/dev/docker-compose.dev.yml#L11 let PRINTER_URL = process.env.PRINTER_URL @@ -82,6 +84,7 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => { return res.status(OK).send({ printId: null }); } + const user = await User.findById(decodedToken._id); const dir = path.join(__dirname, 'printing'); const { totalChunks, chunkIdx } = req.body; @@ -90,7 +93,7 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => { return res.sendStatus(OK); } - const { copies, sides, id } = req.body; + const { copies, sides, id, totalPages } = req.body; const chunks = await fs.promises.readdir(dir); const assembledPdfFromChunks = path.join(dir, id + '.pdf'); @@ -109,12 +112,17 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => { } } - const stream = await fs.createReadStream(assembledPdfFromChunks); + const stream = await fs.promises.readFile(assembledPdfFromChunks); const data = new FormData(); data.append('file', stream, {filename: id, type: 'application/pdf'}); data.append('copies', copies); data.append('sides', sides); + if (Number(totalPages) > 30 - user.pagesPrinted - user.escrowPagesPrinted) { + await cleanUpChunks(dir, id); + return res.sendStatus(BAD_REQUEST); + } + try { // full pdf can be sent to quasar no problem const printRes = await axios.post(PRINTER_URL + '/print', data, { @@ -130,6 +138,9 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => { await cleanUpChunks(dir, id); res.status(OK).send(printId); + + user.escrowPagesPrinted += totalPages; + await user.save(); } catch (err) { logger.error('/sendPrintRequest had an error: ', err); @@ -138,7 +149,7 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => { } }); -router.get('/status/', async (req, res) => { +router.get('/status', async (req, res) => { if (!checkIfTokenSent(req)) { logger.warn('/status was requested without a token'); return res.sendStatus(UNAUTHORIZED); @@ -150,8 +161,8 @@ router.get('/status/', async (req, res) => { return res.sendStatus(UNAUTHORIZED); } if (!PRINTING.ENABLED) { - logger.warn('Printing is disabled, returning 200 and PRINTED status to mock the printing server'); - return res.status(OK).send({ status: 'PRINTED' }); + logger.warn('Printing is disabled, returning 200 and completed status to mock the printing server'); + return res.status(OK).send({ status: 'completed' }); } try { @@ -159,8 +170,21 @@ router.get('/status/', async (req, res) => { method: 'GET', }); + const user = await User.findById(decodedToken._id); + // { status: string } const json = await response.json(); + + if (json.status === 'completed') { + user.pagesPrinted += Number(req.query.pages); + user.escrowPagesPrinted -= Number(req.query.pages); + await user.save(); + } + + if (json.status === 'failed') { + user.escrowPagesPrinted -= Number(req.query.pages); + } + res.status(OK).send(json); } catch (err) { res.sendStatus(SERVER_ERROR); diff --git a/api/main_endpoints/routes/User.js b/api/main_endpoints/routes/User.js index 1a48d45f7..e3fa030d4 100644 --- a/api/main_endpoints/routes/User.js +++ b/api/main_endpoints/routes/User.js @@ -108,6 +108,7 @@ router.post('/search', async function(req, res) { lastLogin: result.lastLogin, membershipValidUntil: result.membershipValidUntil, pagesPrinted: result.pagesPrinted, + escrowPagesPrinted: result.escrowPagesPrinted, doorCode: result.doorCode, _id: result._id }; @@ -310,7 +311,7 @@ router.post('/getPagesPrintedCount', async (req, res) => { .status(NOT_FOUND) .send({ message: `${req.body.email} not found.` }); } - return res.status(OK).json(result.pagesPrinted); + return res.status(OK).json(result.pagesPrinted + result.escrowPagesPrinted); }); }); diff --git a/src/APIFunctions/2DPrinting.js b/src/APIFunctions/2DPrinting.js index 6c5ea297d..a0c271d2d 100644 --- a/src/APIFunctions/2DPrinting.js +++ b/src/APIFunctions/2DPrinting.js @@ -60,10 +60,10 @@ export function parseRange(pages, maxPages) { return result; } -export async function getPrintStatus(printId, token) { - const url = new URL('/api/Printer/status/', BASE_API_URL); +export async function getPrintStatus(printId, totalPages, token) { + const url = new URL('/api/Printer/status', BASE_API_URL); - const response = await fetch(url.href + `?id=${printId}`, { + const response = await fetch(url.href + `?id=${printId}&pages=${totalPages}`, { headers: { 'Authorization': `Bearer ${token}` }, @@ -96,6 +96,7 @@ export async function printPage(data, token) { const pdf = data.get('file'); const sides = data.get('sides'); const copies = data.get('copies'); + const totalPages = data.get('totalPages'); const id = crypto.randomUUID(); const CHUNK_SIZE = 1024 * 1024 * 0.5; // 0.5 MB ------- SENT DATA **CANNOT** EXCEED 1 MB const totalChunks = Math.ceil(pdf.size / CHUNK_SIZE); @@ -114,6 +115,7 @@ export async function printPage(data, token) { chunkData.append('id', id); chunkData.append('sides', sides); chunkData.append('copies', copies); + chunkData.append('totalPages', totalPages); } try { diff --git a/src/APIFunctions/User.js b/src/APIFunctions/User.js index cb072a556..bcb9ebbd1 100644 --- a/src/APIFunctions/User.js +++ b/src/APIFunctions/User.js @@ -96,6 +96,7 @@ export async function editUser(userToEdit, token) { discordDiscrim, discordID, pagesPrinted, + escrowPagesPrinted, accessLevel, lastLogin, emailVerified, @@ -122,6 +123,7 @@ export async function editUser(userToEdit, token) { discordDiscrim, discordID, pagesPrinted, + escrowPagesPrinted, accessLevel, lastLogin, emailVerified, diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 3034d9965..531b8dd4a 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -65,21 +65,17 @@ export default function Printing() { } ids.map(async (id) => { - const status = await getPrintStatus(id, user.token); + const status = await getPrintStatus(id, printJobs[id].pages, user.token); + const newPrintJobs = {...printJobs}; if (status === 'completed') { - setTimeout(() => { - const newPrintJobs = {...printJobs}; - delete newPrintJobs[id]; - setPrintJobs(newPrintJobs); - window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); - }, 2000); + delete newPrintJobs[id]; } else { - const newPrintJobs = {...printJobs}; newPrintJobs[id].status = status; - setPrintJobs(newPrintJobs); - window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); } + + setPrintJobs(newPrintJobs); + window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); }); }, 1000); @@ -87,9 +83,9 @@ export default function Printing() { }, [printJobs]); useEffect(() => { - if (window.localStorage !== undefined) { + if (!!window.localStorage) { const jobsFromLocal = JSON.parse(window.localStorage.getItem('printJobs')); - if (jobsFromLocal !== null) { + if (!!jobsFromLocal) { setPrintJobs(jobsFromLocal); } } @@ -241,11 +237,12 @@ export default function Printing() { data.append('file', PdfFile); data.append('sides', sides); data.append('copies', copies); + data.append('totalPages', pagesToBeUsedInPrintRequest); const printReq = await printPage(data, user.token); try { const printId = printReq?.responseData['print_id']; - const newPrintJobs = {...printJobs, [printId]: {status: 'created', fileName: PdfFile.name} }; + const newPrintJobs = {...printJobs, [printId]: {status: 'created', fileName: PdfFile.name, pages: pagesToBeUsedInPrintRequest} }; setPrintJobs(newPrintJobs); window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); } catch (err) { @@ -460,7 +457,7 @@ export default function Printing() { { Object.keys(printJobs).map(id => (
-
+

{printJobs[id].fileName} ({id}): {printJobs[id].status}

From 186b49b60c8d64c1c5a7af16cb83f7bc80789698 Mon Sep 17 00:00:00 2001 From: thebeninator Date: Fri, 14 Nov 2025 22:54:48 -0800 Subject: [PATCH 20/34] some cleanup; actually save escrow modify on print fail --- api/main_endpoints/routes/Printer.js | 8 +++++--- src/Pages/2DPrinting/2DPrinting.js | 1 - 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index 806307930..d805169d2 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -174,15 +174,17 @@ router.get('/status', async (req, res) => { // { status: string } const json = await response.json(); + const pages = Number(req.query.pages); if (json.status === 'completed') { - user.pagesPrinted += Number(req.query.pages); - user.escrowPagesPrinted -= Number(req.query.pages); + user.pagesPrinted += pages; + user.escrowPagesPrinted -= pages; await user.save(); } if (json.status === 'failed') { - user.escrowPagesPrinted -= Number(req.query.pages); + user.escrowPagesPrinted -= pages; + await user.save(); } res.status(OK).send(json); diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 531b8dd4a..050db73a9 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -6,7 +6,6 @@ import { getPagesPrinted, getPrintStatus, } from '../../APIFunctions/2DPrinting'; -import { editUser } from '../../APIFunctions/User'; import { PDFDocument } from 'pdf-lib'; import { healthCheck } from '../../APIFunctions/2DPrinting'; From cc0b02e5f42fe397567b3c305fc7190e4ee35477 Mon Sep 17 00:00:00 2001 From: thebeninator Date: Mon, 17 Nov 2025 19:49:07 -0800 Subject: [PATCH 21/34] failed/completed jobs notifs now persist for 5 secs --- api/main_endpoints/routes/Printer.js | 2 +- src/Components/Printing/JobStatus.js | 12 ++++++++++++ src/Pages/2DPrinting/2DPrinting.js | 25 +++++++++++++++---------- 3 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 src/Components/Printing/JobStatus.js diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index d805169d2..0966b9261 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -139,7 +139,7 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => { await cleanUpChunks(dir, id); res.status(OK).send(printId); - user.escrowPagesPrinted += totalPages; + user.escrowPagesPrinted += Number(totalPages); await user.save(); } catch (err) { logger.error('/sendPrintRequest had an error: ', err); diff --git a/src/Components/Printing/JobStatus.js b/src/Components/Printing/JobStatus.js new file mode 100644 index 000000000..879a93231 --- /dev/null +++ b/src/Components/Printing/JobStatus.js @@ -0,0 +1,12 @@ +import React from 'react'; + +export default function JobStatus(props) { + return ( +
+
+ +

{props.fileName} ({props.id}): {props.status}

+
+
+ ); +} diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 050db73a9..f5b7a0bf5 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -13,6 +13,7 @@ import ConfirmationModal from '../../Components/DecisionModal/ConfirmationModal.js'; import { useSCE } from '../../Components/context/SceContext.js'; +import JobStatus from '../../Components/Printing/JobStatus.js'; export default function Printing() { const { user, setUser } = useSCE(); @@ -64,15 +65,23 @@ export default function Printing() { } ids.map(async (id) => { + if (['completed', 'failed'].includes(printJobs[id].status)) return; + const status = await getPrintStatus(id, printJobs[id].pages, user.token); const newPrintJobs = {...printJobs}; - if (status === 'completed') { - delete newPrintJobs[id]; - } else { - newPrintJobs[id].status = status; + if (['completed', 'failed'].includes(status)) { + setTimeout(() => { + setPrintJobs((prev) => { + const newPrintJobs = {...prev}; + delete newPrintJobs[id]; + window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); + return {...newPrintJobs}; + }); + }, 5000); } + newPrintJobs[id].status = status; setPrintJobs(newPrintJobs); window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); }); @@ -244,6 +253,7 @@ export default function Printing() { const newPrintJobs = {...printJobs, [printId]: {status: 'created', fileName: PdfFile.name, pages: pagesToBeUsedInPrintRequest} }; setPrintJobs(newPrintJobs); window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); + getNumberOfPagesPrintedSoFar(); } catch (err) { setPrintStatus('Printing failed. Please try again or reach out to SCE Dev team if the issue persists.'); setPrintStatusColor('error'); @@ -455,12 +465,7 @@ export default function Printing() {
{ Object.keys(printJobs).map(id => ( -
-
- -

{printJobs[id].fileName} ({id}): {printJobs[id].status}

-
-
+ )) }
From eeb98870ce1b39baeb8b26d185106150ed58263d Mon Sep 17 00:00:00 2001 From: thebeninator Date: Mon, 24 Nov 2025 11:48:44 -0800 Subject: [PATCH 22/34] fix fail/complete notif not being destroyed after page refresh --- api/main_endpoints/routes/Printer.js | 6 ++- src/APIFunctions/2DPrinting.js | 4 +- src/Components/Printing/JobStatus.js | 6 ++- src/Pages/2DPrinting/2DPrinting.js | 55 ++++++++++++++++++++-------- 4 files changed, 50 insertions(+), 21 deletions(-) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index 0966b9261..188497fd1 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -166,7 +166,9 @@ router.get('/status', async (req, res) => { } try { - const response = await fetch(PRINTER_URL + `/status/?id=${req.query.id}`, { + const url = new URL('/status/', PRINTER_URL); + url.searchParams.append('id', req.query.id); + const response = await fetch(url, { method: 'GET', }); @@ -174,7 +176,7 @@ router.get('/status', async (req, res) => { // { status: string } const json = await response.json(); - const pages = Number(req.query.pages); + const pages = Math.abs(Number(req.query.pages)); if (json.status === 'completed') { user.pagesPrinted += pages; diff --git a/src/APIFunctions/2DPrinting.js b/src/APIFunctions/2DPrinting.js index a0c271d2d..51ad4b8b3 100644 --- a/src/APIFunctions/2DPrinting.js +++ b/src/APIFunctions/2DPrinting.js @@ -62,8 +62,10 @@ export function parseRange(pages, maxPages) { export async function getPrintStatus(printId, totalPages, token) { const url = new URL('/api/Printer/status', BASE_API_URL); + url.searchParams.append('id', printId); + url.searchParams.append('pages', totalPages); - const response = await fetch(url.href + `?id=${printId}&pages=${totalPages}`, { + const response = await fetch(url, { headers: { 'Authorization': `Bearer ${token}` }, diff --git a/src/Components/Printing/JobStatus.js b/src/Components/Printing/JobStatus.js index 879a93231..55f01a581 100644 --- a/src/Components/Printing/JobStatus.js +++ b/src/Components/Printing/JobStatus.js @@ -2,9 +2,11 @@ import React from 'react'; export default function JobStatus(props) { return ( -
+
- + + +

{props.fileName} ({props.id}): {props.status}

diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index f5b7a0bf5..06d4c7137 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -54,6 +54,25 @@ export default function Printing() { } } + async function tryDestroyJobStatusNotification(status, id) { + const completedOrFailed = ['completed', 'failed'].includes(status); + if (!completedOrFailed) return; + + setTimeout(() => { + setPrintJobs((prev) => { + const newPrintJobs = {...prev}; + + if (!(id in newPrintJobs)) { + return prev; + } + + delete newPrintJobs[id]; + window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); + return {...newPrintJobs}; + }); + }, 5000); + } + useEffect(() => { if (printJobs === null || Object.keys(printJobs).length === 0) return; const ids = Object.keys(printJobs); @@ -65,25 +84,16 @@ export default function Printing() { } ids.map(async (id) => { - if (['completed', 'failed'].includes(printJobs[id].status)) return; + const completedOrFailed = ['completed', 'failed'].includes(printJobs[id].status); + if (completedOrFailed) return; const status = await getPrintStatus(id, printJobs[id].pages, user.token); const newPrintJobs = {...printJobs}; - - if (['completed', 'failed'].includes(status)) { - setTimeout(() => { - setPrintJobs((prev) => { - const newPrintJobs = {...prev}; - delete newPrintJobs[id]; - window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); - return {...newPrintJobs}; - }); - }, 5000); - } - newPrintJobs[id].status = status; setPrintJobs(newPrintJobs); window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); + + tryDestroyJobStatusNotification(status, id); }); }, 1000); @@ -94,7 +104,14 @@ export default function Printing() { if (!!window.localStorage) { const jobsFromLocal = JSON.parse(window.localStorage.getItem('printJobs')); if (!!jobsFromLocal) { - setPrintJobs(jobsFromLocal); + setPrintJobs(() => { + const ids = Object.keys(jobsFromLocal); + ids.map(async (id) => { + tryDestroyJobStatusNotification(jobsFromLocal[id].status, id); + }); + + return jobsFromLocal; + }); } } @@ -250,7 +267,13 @@ export default function Printing() { try { const printId = printReq?.responseData['print_id']; - const newPrintJobs = {...printJobs, [printId]: {status: 'created', fileName: PdfFile.name, pages: pagesToBeUsedInPrintRequest} }; + const newPrintJobs = {...printJobs, + [printId]: { + status: 'created', + fileName: PdfFile.name, + pages: pagesToBeUsedInPrintRequest + } + }; setPrintJobs(newPrintJobs); window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); getNumberOfPagesPrintedSoFar(); @@ -465,7 +488,7 @@ export default function Printing() {
{ Object.keys(printJobs).map(id => ( - + )) }
From 772c12d2219018e00ed2b5d81f2c1431335f56b7 Mon Sep 17 00:00:00 2001 From: thebeninator Date: Mon, 24 Nov 2025 13:03:57 -0800 Subject: [PATCH 23/34] rename function --- src/Pages/2DPrinting/2DPrinting.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 06d4c7137..505a03eb4 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -54,7 +54,7 @@ export default function Printing() { } } - async function tryDestroyJobStatusNotification(status, id) { + async function tryRemoveJob(status, id) { const completedOrFailed = ['completed', 'failed'].includes(status); if (!completedOrFailed) return; @@ -93,7 +93,7 @@ export default function Printing() { setPrintJobs(newPrintJobs); window.localStorage.setItem('printJobs', JSON.stringify(newPrintJobs)); - tryDestroyJobStatusNotification(status, id); + tryRemoveJob(status, id); }); }, 1000); @@ -107,7 +107,7 @@ export default function Printing() { setPrintJobs(() => { const ids = Object.keys(jobsFromLocal); ids.map(async (id) => { - tryDestroyJobStatusNotification(jobsFromLocal[id].status, id); + tryRemoveJob(jobsFromLocal[id].status, id); }); return jobsFromLocal; From 08d297295f235c49dd7a45de0f6fdfeeea0a2e66 Mon Sep 17 00:00:00 2001 From: evan Date: Mon, 22 Dec 2025 13:30:04 -0800 Subject: [PATCH 24/34] checkiftokensent --- api/main_endpoints/routes/Printer.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index 188497fd1..7ba84e71d 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -150,11 +150,6 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => { }); router.get('/status', async (req, res) => { - if (!checkIfTokenSent(req)) { - logger.warn('/status was requested without a token'); - return res.sendStatus(UNAUTHORIZED); - } - const decodedToken = await decodeToken(req); if (!decodedToken || Object.keys(decodedToken) === 0) { logger.warn('/status was requested with an invalid token'); From 5ec04a63a2e87edceeea85cce1f709430f74cfd8 Mon Sep 17 00:00:00 2001 From: evan Date: Mon, 22 Dec 2025 13:33:59 -0800 Subject: [PATCH 25/34] const user = await User.findById(decoded._id); --- api/main_endpoints/routes/Printer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index 7ba84e71d..aa6f5f245 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -84,7 +84,7 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => { return res.status(OK).send({ printId: null }); } - const user = await User.findById(decodedToken._id); + const user = await User.findById(decoded._id); const dir = path.join(__dirname, 'printing'); const { totalChunks, chunkIdx } = req.body; From 9320b4ff59c24c5286bee50e8d0559e3fc182e71 Mon Sep 17 00:00:00 2001 From: evan Date: Mon, 22 Dec 2025 13:35:26 -0800 Subject: [PATCH 26/34] get ready for some noise --- api/main_endpoints/routes/Printer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index aa6f5f245..3a2246116 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -83,8 +83,8 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => { logger.warn('Printing is disabled, returning 200 and dummy print id to mock the printing server'); return res.status(OK).send({ printId: null }); } - const user = await User.findById(decoded._id); + console.log({decoded, user}) const dir = path.join(__dirname, 'printing'); const { totalChunks, chunkIdx } = req.body; From f9b4d55b622fc2b616a2a8b6774abe50b9977241 Mon Sep 17 00:00:00 2001 From: evan Date: Mon, 22 Dec 2025 13:36:36 -0800 Subject: [PATCH 27/34] const user = await User.findById(decoded.token._id); --- api/main_endpoints/routes/Printer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index 3a2246116..dd05ec416 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -83,8 +83,8 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => { logger.warn('Printing is disabled, returning 200 and dummy print id to mock the printing server'); return res.status(OK).send({ printId: null }); } - const user = await User.findById(decoded._id); - console.log({decoded, user}) + const user = await User.findById(decoded.token._id); + const dir = path.join(__dirname, 'printing'); const { totalChunks, chunkIdx } = req.body; From f74fe1ddd0cd020b3c81ccb0c32eb9bc80e8021f Mon Sep 17 00:00:00 2001 From: evan Date: Mon, 22 Dec 2025 14:12:43 -0800 Subject: [PATCH 28/34] debug zone --- src/Pages/2DPrinting/2DPrinting.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 505a03eb4..b4a39ab24 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -76,6 +76,7 @@ export default function Printing() { useEffect(() => { if (printJobs === null || Object.keys(printJobs).length === 0) return; const ids = Object.keys(printJobs); + console.log('useEffect', {ids, printJobs}) const interval = setInterval(async () => { if (ids.length === 0) { @@ -86,7 +87,7 @@ export default function Printing() { ids.map(async (id) => { const completedOrFailed = ['completed', 'failed'].includes(printJobs[id].status); if (completedOrFailed) return; - + console.log('ids.map', {id, 'printJobs[id]': printJobs[id]}) const status = await getPrintStatus(id, printJobs[id].pages, user.token); const newPrintJobs = {...printJobs}; newPrintJobs[id].status = status; From a234803b49451f6c254f1d01c7fcf377300bac68 Mon Sep 17 00:00:00 2001 From: evan Date: Mon, 22 Dec 2025 14:17:17 -0800 Subject: [PATCH 29/34] logger.error('/status had an error: ', err); --- api/main_endpoints/routes/Printer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index dd05ec416..2edaafd63 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -186,6 +186,7 @@ router.get('/status', async (req, res) => { res.status(OK).send(json); } catch (err) { + logger.error('/status had an error: ', err); res.sendStatus(SERVER_ERROR); } }); From 82aa228e3efc312f13cc12b2c8fb982f1857569a Mon Sep 17 00:00:00 2001 From: evan Date: Mon, 22 Dec 2025 14:19:50 -0800 Subject: [PATCH 30/34] const response = await axios.get(url); --- api/main_endpoints/routes/Printer.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index 2edaafd63..d3475a099 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -163,14 +163,12 @@ router.get('/status', async (req, res) => { try { const url = new URL('/status/', PRINTER_URL); url.searchParams.append('id', req.query.id); - const response = await fetch(url, { - method: 'GET', - }); + const response = await axios.get(url); const user = await User.findById(decodedToken._id); // { status: string } - const json = await response.json(); + const json = response.data; const pages = Math.abs(Number(req.query.pages)); if (json.status === 'completed') { From 12c5b4fa88508775942c0d9a7a4bc36f192a44e7 Mon Sep 17 00:00:00 2001 From: evan Date: Mon, 22 Dec 2025 14:21:50 -0800 Subject: [PATCH 31/34] const response = await axios.get(, { --- api/main_endpoints/routes/Printer.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index d3475a099..767fd717d 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -161,9 +161,11 @@ router.get('/status', async (req, res) => { } try { - const url = new URL('/status/', PRINTER_URL); - url.searchParams.append('id', req.query.id); - const response = await axios.get(url); + const response = await axios.get(`${PRINTER_URL}/status/`, { + params: { + id: req.query.id, + } + }); const user = await User.findById(decodedToken._id); From dde31b7a5ea3e45f8219f8cadc04543175aea6c8 Mon Sep 17 00:00:00 2001 From: evan Date: Mon, 22 Dec 2025 14:23:00 -0800 Subject: [PATCH 32/34] const user = await User.findById(decodedToken.token._id); --- api/main_endpoints/routes/Printer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index 767fd717d..fb4554393 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -167,7 +167,7 @@ router.get('/status', async (req, res) => { } }); - const user = await User.findById(decodedToken._id); + const user = await User.findById(decodedToken.token._id); // { status: string } const json = response.data; From 5fb212830e82906dc7b4d7865b111eef291fc295 Mon Sep 17 00:00:00 2001 From: evan Date: Mon, 22 Dec 2025 14:24:55 -0800 Subject: [PATCH 33/34] one thing --- api/main_endpoints/routes/Printer.js | 2 +- src/Pages/2DPrinting/2DPrinting.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/main_endpoints/routes/Printer.js b/api/main_endpoints/routes/Printer.js index fb4554393..7c310cde6 100644 --- a/api/main_endpoints/routes/Printer.js +++ b/api/main_endpoints/routes/Printer.js @@ -163,7 +163,7 @@ router.get('/status', async (req, res) => { try { const response = await axios.get(`${PRINTER_URL}/status/`, { params: { - id: req.query.id, + id: req.query.id, } }); diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index b4a39ab24..0d0878d71 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -76,8 +76,8 @@ export default function Printing() { useEffect(() => { if (printJobs === null || Object.keys(printJobs).length === 0) return; const ids = Object.keys(printJobs); - console.log('useEffect', {ids, printJobs}) + const interval = setInterval(async () => { if (ids.length === 0) { clearInterval(interval); @@ -87,7 +87,7 @@ export default function Printing() { ids.map(async (id) => { const completedOrFailed = ['completed', 'failed'].includes(printJobs[id].status); if (completedOrFailed) return; - console.log('ids.map', {id, 'printJobs[id]': printJobs[id]}) + const status = await getPrintStatus(id, printJobs[id].pages, user.token); const newPrintJobs = {...printJobs}; newPrintJobs[id].status = status; From f82169222ac2d40058af3ec91b544ee6c1d2db84 Mon Sep 17 00:00:00 2001 From: evan Date: Mon, 22 Dec 2025 14:26:13 -0800 Subject: [PATCH 34/34] one --- src/Pages/2DPrinting/2DPrinting.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Pages/2DPrinting/2DPrinting.js b/src/Pages/2DPrinting/2DPrinting.js index 0d0878d71..ea00de27b 100644 --- a/src/Pages/2DPrinting/2DPrinting.js +++ b/src/Pages/2DPrinting/2DPrinting.js @@ -77,7 +77,7 @@ export default function Printing() { if (printJobs === null || Object.keys(printJobs).length === 0) return; const ids = Object.keys(printJobs); - + const interval = setInterval(async () => { if (ids.length === 0) { clearInterval(interval);