182 lines
5.1 KiB
JavaScript

import dotenv from 'dotenv';
import { printerModel } from '../../schemas/production/printer.schema.js';
import log4js from 'log4js';
import { newAuditLog, getAuditLogs } from '../../utils.js';
dotenv.config();
const logger = log4js.getLogger('Printers');
logger.level = process.env.LOG_LEVEL;
export const listPrintersRouteHandler = async (req, res, page = 1, limit = 25) => {
try {
// Calculate the skip value based on the page number and limit
const skip = (page - 1) * limit;
// Fetch users with pagination
const printers = await printerModel.find().skip(skip).limit(limit);
logger.trace(`List of printers (Page ${page}, Limit ${limit}):`);
res.send(printers);
} catch (error) {
logger.error('Error listing users:', error);
res.status(500).send({ error: error });
}
};
export const getPrinterRouteHandler = async (req, res) => {
const id = req.params.id;
try {
// Fetch the printer with the given remote address
const printer = await printerModel
.findOne({ _id: id })
.populate('subJobs')
.populate('currentJob')
.populate({
path: 'currentJob',
populate: {
path: 'gcodeFile',
},
})
.populate('currentSubJob')
.populate({
path: 'subJobs',
populate: {
path: 'job',
},
})
.populate('vendor')
.populate({
path: 'currentFilamentStock',
populate: {
path: 'filament',
},
});
if (!printer) {
logger.warn(`Printer with id ${id} not found.`);
return res.status(404).send({ error: 'Printer not found' });
}
logger.trace(`Printer with id ${id}:`, printer);
const auditLogs = await getAuditLogs(id);
res.send({ ...printer._doc, auditLogs: auditLogs });
} catch (error) {
logger.error('Error fetching printer:', error);
res.status(500).send({ error: error.message });
}
};
export const editPrinterRouteHandler = async (req, res) => {
const id = req.params.id;
try {
// Fetch the printer first to get the old state
const printer = await printerModel.findOne({ _id: id });
if (!printer) {
logger.warn(`Printer not found with supplied id.`);
return res.status(404).send({ error: 'Printer not found.' });
}
try {
const updateData = {
updatedAt: new Date(),
moonraker: req.body.moonraker,
tags: req.body.tags,
name: req.body.name,
vendor: req.body.vendor.id,
};
// Create audit log before updating
await newAuditLog(printer.toObject(), updateData, id, 'printer', req.user._id, 'user');
const result = await printerModel.updateOne({ _id: id }, { $set: updateData });
if (result.nModified === 0) {
logger.error('No printers updated.');
res.status(500).send({ error: 'No printers updated.' });
}
} catch (updateError) {
logger.error('Error updating printer:', updateError);
res.status(500).send({ error: updateError.message });
}
res.send('OK');
} catch (fetchError) {
logger.error('Error fetching printer:', fetchError);
res.status(500).send({ error: fetchError.message });
}
};
export const createPrinterRouteHandler = async (req, res) => {
try {
const { name, moonraker, tags = [], firmware = 'n/a' } = req.body;
// Validate required fields
if (!name || !moonraker) {
logger.warn('Missing required fields in printer creation request');
return res.status(400).send({
error: 'Missing required fields. name and moonraker configuration are required.',
});
}
// Validate moonraker configuration
if (!moonraker.host || !moonraker.port || !moonraker.protocol) {
logger.warn('Invalid moonraker configuration in printer creation request');
return res.status(400).send({
error: 'Invalid moonraker configuration. host, port, protocol are required.',
});
}
// Create new printer instance
const newPrinter = new printerModel({
name,
moonraker,
tags,
firmware,
online: false,
state: {
type: 'offline',
},
});
// Save the printer
const savedPrinter = await newPrinter.save();
// Create audit log for new printer
await newAuditLog({}, newPrinter.toObject(), savedPrinter._id, 'printer', req.user._id, 'user');
logger.info(`Created new printer: ${name}`);
res.status(201).send(savedPrinter);
} catch (error) {
logger.error('Error creating printer:', error);
res.status(500).send({ error: error.message });
}
};
export const getPrinterStatsRouteHandler = async (req, res) => {
try {
const stats = await printerModel.aggregate([
{
$group: {
_id: '$state.type',
count: { $sum: 1 },
},
},
]);
// Transform the results into a more readable format
const formattedStats = stats.reduce((acc, curr) => {
acc[curr._id] = curr.count;
return acc;
}, {});
logger.trace('Printer stats by state:', formattedStats);
res.send(formattedStats);
} catch (error) {
logger.error('Error fetching printer stats:', error);
res.status(500).send({ error: error.message });
}
};