Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion api/main_endpoints/routes/Printer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ const logger = require('../../util/logger');
const fs = require('fs');
const path = require('path');
const { MetricsHandler, register } = require('../../util/metrics.js');
const { cleanUpChunks, cleanUpExpiredChunks, recordPrintingFolderSize } = require('../util/Printer.js');
const {
cleanUpChunks,
cleanUpExpiredChunks,
recordPrintingFolderSize,
modifyPagesPrinted,
getPageCount
} = require('../util/Printer.js');

const {
decodeToken,
Expand Down Expand Up @@ -84,6 +90,9 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => {
logger.warn('/sendPrintRequest was requested with an invalid token');
return res.sendStatus(UNAUTHORIZED);
}

const userId = decodedToken._id;

if (!PRINTING.ENABLED) {
logger.warn('Printing is disabled, returning 200 and dummy print id to mock the printing server');
return res.status(OK).send({ printId: null });
Expand All @@ -99,6 +108,7 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => {

const { copies, sides, id } = req.body;

// read and reassemble the pdf
const chunks = await fs.promises.readdir(dir);
const assembledPdfFromChunks = path.join(dir, id + '.pdf');

Expand All @@ -122,6 +132,12 @@ router.post('/sendPrintRequest', upload.single('chunk'), async (req, res) => {
data.append('copies', copies);
data.append('sides', sides);

// update user's printed pages count
const pagesPrinted = getPageCount(assembledPdfFromChunks);
if (!modifyPagesPrinted(userId, pagesPrinted)) {
return res.sendStatus(SERVER_ERROR);
}

try {
// full pdf can be sent to quasar no problem
const printRes = await axios.post(PRINTER_URL + '/print', data, {
Expand Down
45 changes: 44 additions & 1 deletion api/main_endpoints/util/Printer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ const fs = require('fs');
const path = require('path');
const logger = require('../../util/logger');
const { MetricsHandler } = require('../../util/metrics.js');
const User = require('../models/User.js');
const { PDFDocument } = require('pdf-lib');

/**
* Deletes all chunks with the specified id from a directory
Expand Down Expand Up @@ -74,4 +76,45 @@ async function recordPrintingFolderSize(dir) {
MetricsHandler.currentSizeOfPrintingFolderBytes.set(sizeOfDir);
}

module.exports = { cleanUpChunks, cleanUpExpiredChunks, recordPrintingFolderSize };

/**
* Modify the user's pagesPrinted field based on the length of their print request
* @param {string} userId id of the current user
* @param {Number} numPages the number of pages of the current print request
* @returns {boolean} Returns if the database operation was successful
*/

function modifyPagesPrinted(userId, numPages) {
return new Promise((resolve) => {
try {
User.findByIdAndUpdate(
userId,
{
$inc: { pagesPrinted: numPages },
}, {
new: true,
}
, (error, result) => {
if (error) {
logger.error('modifyPagesPrinted got an error querying mongodb: ', error);
return resolve(false);
}
if (!result) {
logger.info(`User ${userId} not found in the database`);
}
return resolve(!!result);
});
} catch (err) {
logger.error('modifyPagesPrinted encountered an error querying mongodb: ', err);
return resolve(false);
}
});
}

async function getPageCount(file) {
const buffer = await fs.promises.readFile(file);
const pdf = await PDFDocument.load(buffer);
return pdf.getPageCount();
}

module.exports = { cleanUpChunks, cleanUpExpiredChunks, recordPrintingFolderSize, modifyPagesPrinted, getPageCount };
80 changes: 80 additions & 0 deletions api/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"nodemon": "^2.0.4",
"passport": "^0.4.1",
"passport-jwt": "^4.0.0",
"pdf-lib": "^1.17.1",
"prom-client": "^15.1.3"
},
"devDependencies": {
Expand Down
7 changes: 1 addition & 6 deletions src/Pages/2DPrinting/2DPrinting.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React, { useState, useEffect, useRef } from 'react';
import { useState, useEffect, useRef } from 'react';
import PageSelectDropdown from './PageSelectDropdown';
import {
parseRange,
printPage,
getPagesPrinted,
} from '../../APIFunctions/2DPrinting';
import { editUser } from '../../APIFunctions/User';

import { PDFDocument } from 'pdf-lib';
import { healthCheck } from '../../APIFunctions/2DPrinting';
Expand Down Expand Up @@ -203,10 +202,6 @@ export default function Printing() {
let status = await printPage(data, user.token);

if (!status.error) {
editUser(
{ ...user, pagesPrinted: pagesPrinted + pagesToBeUsedInPrintRequest },
user.token,
);
setPrintStatus('Printing succeeded!');
setPrintStatusColor('success');
} else {
Expand Down
24 changes: 24 additions & 0 deletions test/api/Printer.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const tools = require('../util/tools/tools.js');
const crypto = require('crypto');
const token = '';
const printerUtil = require('../../api/main_endpoints/util/Printer.js');
const User = require('../../api/main_endpoints/models/User.js');
const { findByIdAndDelete } = require('../../api/main_endpoints/models/OfficeAccessCard.js');

let app = null;
let test = null;
Expand Down Expand Up @@ -155,4 +157,26 @@ describe('Printer', () => {
expect(chunksProcessed).to.equal(TOTAL_CHUNKS);
});
});

describe('modifyPagesPrinted', () => {
it('Should return true if pages were modified correctly', async () => {
const user = await new User({
firstName: 'nothing',
lastName: 'really',
email: 'alerts@one.sce',
password: 'vibecoding',
pagesPrinted: 1,
}).save();

const userId = user._id;

const tryModifyPagesPrinted = await printerUtil.modifyPagesPrinted(userId, 3);
expect(tryModifyPagesPrinted).to.equal(true);

const updatedUser = await User.findById(userId);
expect(updatedUser.pagesPrinted).to.equal(4);

await User.findByIdAndDelete(userId);
});
});
});
Loading