210 lines
5.4 KiB
JavaScript

import dotenv from "dotenv";
import { printerModel } from "../../schemas/printer.schema.js";
import log4js from "log4js";
import { newAuditLog } from "../../util/index.js";
import mongoose from "mongoose";
import { auditLogModel } from "../../schemas/auditlog.schema.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 auditLogModel.find({
target: new mongoose.Types.ObjectId(id)
}).populate('owner');
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 });
}
};