@fdm-monster/server
Version:
FDM Monster is a bulk OctoPrint manager to set up, configure and monitor 3D printers. Our aim is to provide extremely optimized websocket performance and reliability.
340 lines (339 loc) • 17.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "PrinterFilesController", {
enumerable: true,
get: function() {
return PrinterFilesController;
}
});
const _awilixexpress = require("awilix-express");
const _authenticate = require("../middleware/authenticate");
const _validators = require("../handlers/validators");
const _serverconstants = require("../server.constants");
const _printerfilescontrollervalidation = require("./validation/printer-files-controller.validation");
const _runtimeexceptions = require("../exceptions/runtime.exceptions");
const _printer = require("../middleware/printer");
const _authorizationconstants = require("../constants/authorization.constants");
const _printerfilesstore = require("../state/printer-files.store");
const _settingsstore = require("../state/settings.store");
const _multerservice = require("../services/core/multer.service");
const _printerfilecleantask = require("../tasks/printer-file-clean.task");
const _loggerfactory = require("../handlers/logger-factory");
const _express = require("express");
const _printerapiinterface = require("../services/printer-api.interface");
const _printerthumbnailcache = require("../state/printer-thumbnail.cache");
const _node = require("@sentry/node");
const _errorutils = require("../utils/error.utils");
const _logindto = require("../services/interfaces/login.dto");
const _printerresolver = require("../middleware/printer-resolver");
function _ts_decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function _ts_metadata(k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
}
class PrinterFilesController {
printerApi;
printerLogin;
printerFilesStore;
printerFileCleanTask;
settingsStore;
multerService;
printerThumbnailCache;
logger;
constructor(loggerFactory, printerApi, printerLogin, printerFilesStore, printerFileCleanTask, settingsStore, multerService, printerThumbnailCache){
this.printerApi = printerApi;
this.printerLogin = printerLogin;
this.printerFilesStore = printerFilesStore;
this.printerFileCleanTask = printerFileCleanTask;
this.settingsStore = settingsStore;
this.multerService = multerService;
this.printerThumbnailCache = printerThumbnailCache;
this.logger = loggerFactory(PrinterFilesController.name);
}
async purgeIndexedFiles(req, res) {
await this.printerFilesStore.purgeFiles();
res.send();
}
async getThumbnails(req, res) {
const thumbnails = await this.printerThumbnailCache.getAllValues();
res.send(thumbnails);
}
async getFiles(req, res) {
const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
this.logger.log("Refreshing file storage (eager load)");
const files = await this.printerFilesStore.loadFiles(currentPrinterId);
res.send(files);
}
async reloadThumbnail(req, res) {
const { filePath } = await (0, _validators.validateInput)(req.body, _printerfilescontrollervalidation.startPrintFileSchema);
try {
if (this.settingsStore.isThumbnailSupportEnabled()) {
await this.printerThumbnailCache.loadPrinterThumbnailRemote(this.printerLogin, req.params.id, filePath);
}
} catch (e) {
this.logger.error(`Unexpected error processing thumbnail ${(0, _errorutils.errorSummary)(e)}`);
(0, _node.captureException)(e);
}
res.send();
}
async startPrintFile(req, res) {
const { filePath } = await (0, _validators.validateInput)(req.body, _printerfilescontrollervalidation.startPrintFileSchema);
const encodedFilePath = encodeURIComponent(filePath);
await this.printerApi.startPrint(encodedFilePath);
try {
if (this.settingsStore.isThumbnailSupportEnabled()) {
await this.printerThumbnailCache.loadPrinterThumbnailRemote(this.printerLogin, req.params.id, encodedFilePath);
}
} catch (e) {
this.logger.error(`Unexpected error processing thumbnail ${(0, _errorutils.errorSummary)(e)}`);
(0, _node.captureException)(e);
}
res.send();
}
async getFilesCache(req, res) {
const { currentPrinter } = (0, _printerresolver.getScopedPrinter)(req);
res.send(this.printerFilesStore.getFiles(currentPrinter.id));
}
async downloadFile(req, res) {
this.logger.log(`Downloading file ${req.params.path}`);
const { path } = await (0, _validators.validateInput)(req.params, _printerfilescontrollervalidation.downloadFileSchema);
const encodedFilePath = encodeURIComponent(path);
const response = await this.printerApi.downloadFile(encodedFilePath);
res.setHeader("Content-Type", response.headers["content-type"]);
res.setHeader("Content-Length", response.headers["content-length"]);
res.setHeader("Content-Disposition", response.headers["content-disposition"]);
if (response.headers["etag"]?.length) {
res.setHeader("ETag", response.headers["etag"]);
}
response.data.pipe(res);
}
async deleteFileOrFolder(req, res) {
const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
const { path } = await (0, _validators.validateInput)(req.query, _printerfilescontrollervalidation.getFileSchema);
const encodedFilePath = encodeURIComponent(path);
const result = await this.printerApi.deleteFile(encodedFilePath);
await this.printerFilesStore.deleteFile(currentPrinterId, path);
res.send(result);
}
async clearPrinterFiles(req, res) {
const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
const failedFiles = [];
const succeededFiles = [];
const nonRecursiveFiles = await this.printerApi.getFiles();
for (let file of nonRecursiveFiles){
try {
const encodedFilePath = encodeURIComponent(file.path);
await this.printerApi.deleteFile(encodedFilePath);
succeededFiles.push(file);
} catch (e) {
failedFiles.push(file);
}
}
await this.printerFilesStore.purgePrinterFiles(currentPrinterId);
res.send({
failedFiles,
succeededFiles
});
}
async getPrinterThumbnail(req, res) {
const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
const printerThumbnail = await this.printerThumbnailCache.getValue(currentPrinterId.toString());
res.send(printerThumbnail);
}
async uploadPrinterFile(req, res) {
const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
const files = await this.multerService.multerLoadFileAsync(req, res, _serverconstants.AppConstants.defaultAcceptedGcodeExtensions, true);
const { startPrint: startPrintString } = await (0, _validators.validateInput)(req.body, _printerfilescontrollervalidation.uploadFileSchema);
const startPrint = startPrintString === "true";
if (!files?.length) {
throw new _runtimeexceptions.ValidationException({
error: `No file was available for upload. Did you upload files with one of these extensions: ${_serverconstants.AppConstants.defaultAcceptedGcodeExtensions.join(", ")}?`
});
}
if (files.length > 1) {
throw new _runtimeexceptions.ValidationException({
error: "Only 1 .gcode file can be uploaded at a time"
});
}
const fileCleanEnabled = this.settingsStore.isPreUploadFileCleanEnabled();
if (fileCleanEnabled) {
await this.printerFileCleanTask.cleanPrinterFiles(currentPrinterId);
}
const uploadedFile = files[0];
const token = this.multerService.startTrackingSession(uploadedFile, currentPrinterId);
await this.printerApi.uploadFile(uploadedFile, startPrint, token).catch((e)=>{
try {
this.multerService.clearUploadedFile(uploadedFile);
} catch (e) {
this.logger.error(`Could not remove uploaded file from temporary storage ${(0, _errorutils.errorSummary)(e)}`);
}
throw e;
});
await this.printerFilesStore.loadFiles(currentPrinterId);
try {
if (this.settingsStore.isThumbnailSupportEnabled()) {
await this.printerThumbnailCache.loadPrinterThumbnailLocal(currentPrinterId, files[0].path);
}
} catch (e) {
this.logger.error(`Unexpected error processing thumbnail ${(0, _errorutils.errorSummary)(e)}`);
(0, _node.captureException)(e);
}
try {
this.multerService.clearUploadedFile(uploadedFile);
} catch (e) {
this.logger.error(`Could not remove uploaded file from temporary storage ${(0, _errorutils.errorSummary)(e)}`);
}
res.send();
}
}
_ts_decorate([
(0, _awilixexpress.POST)(),
(0, _awilixexpress.route)("/purge"),
(0, _awilixexpress.before)((0, _authenticate.permission)(_authorizationconstants.PERMS.PrinterFiles.Clear)),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _express.Request === "undefined" ? Object : _express.Request,
typeof _express.Response === "undefined" ? Object : _express.Response
]),
_ts_metadata("design:returntype", Promise)
], PrinterFilesController.prototype, "purgeIndexedFiles", null);
_ts_decorate([
(0, _awilixexpress.GET)(),
(0, _awilixexpress.route)("/thumbnails"),
(0, _awilixexpress.before)((0, _authenticate.permission)(_authorizationconstants.PERMS.PrinterFiles.Get)),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _express.Request === "undefined" ? Object : _express.Request,
typeof _express.Response === "undefined" ? Object : _express.Response
]),
_ts_metadata("design:returntype", Promise)
], PrinterFilesController.prototype, "getThumbnails", null);
_ts_decorate([
(0, _awilixexpress.GET)(),
(0, _awilixexpress.route)("/:id"),
(0, _awilixexpress.before)((0, _authenticate.permission)(_authorizationconstants.PERMS.PrinterFiles.Get)),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _express.Request === "undefined" ? Object : _express.Request,
typeof _express.Response === "undefined" ? Object : _express.Response
]),
_ts_metadata("design:returntype", Promise)
], PrinterFilesController.prototype, "getFiles", null);
_ts_decorate([
(0, _awilixexpress.POST)(),
(0, _awilixexpress.route)("/:id/reload-thumbnail"),
(0, _awilixexpress.before)((0, _authenticate.permission)(_authorizationconstants.PERMS.PrinterFiles.Actions)),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _express.Request === "undefined" ? Object : _express.Request,
typeof _express.Response === "undefined" ? Object : _express.Response
]),
_ts_metadata("design:returntype", Promise)
], PrinterFilesController.prototype, "reloadThumbnail", null);
_ts_decorate([
(0, _awilixexpress.POST)(),
(0, _awilixexpress.route)("/:id/select"),
(0, _awilixexpress.route)("/:id/print"),
(0, _awilixexpress.before)((0, _authenticate.permission)(_authorizationconstants.PERMS.PrinterFiles.Actions)),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _express.Request === "undefined" ? Object : _express.Request,
typeof _express.Response === "undefined" ? Object : _express.Response
]),
_ts_metadata("design:returntype", Promise)
], PrinterFilesController.prototype, "startPrintFile", null);
_ts_decorate([
(0, _awilixexpress.GET)(),
(0, _awilixexpress.route)("/:id/cache"),
(0, _awilixexpress.before)((0, _authenticate.permission)(_authorizationconstants.PERMS.PrinterFiles.Get)),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _express.Request === "undefined" ? Object : _express.Request,
typeof _express.Response === "undefined" ? Object : _express.Response
]),
_ts_metadata("design:returntype", Promise)
], PrinterFilesController.prototype, "getFilesCache", null);
_ts_decorate([
(0, _awilixexpress.GET)(),
(0, _awilixexpress.route)("/:id/download/:path"),
(0, _awilixexpress.before)((0, _authenticate.permission)(_authorizationconstants.PERMS.PrinterFiles.Get)),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _express.Request === "undefined" ? Object : _express.Request,
typeof _express.Response === "undefined" ? Object : _express.Response
]),
_ts_metadata("design:returntype", Promise)
], PrinterFilesController.prototype, "downloadFile", null);
_ts_decorate([
(0, _awilixexpress.DELETE)(),
(0, _awilixexpress.route)("/:id"),
(0, _awilixexpress.before)((0, _authenticate.permission)(_authorizationconstants.PERMS.PrinterFiles.Delete)),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _express.Request === "undefined" ? Object : _express.Request,
typeof _express.Response === "undefined" ? Object : _express.Response
]),
_ts_metadata("design:returntype", Promise)
], PrinterFilesController.prototype, "deleteFileOrFolder", null);
_ts_decorate([
(0, _awilixexpress.DELETE)(),
(0, _awilixexpress.route)("/:id/clear"),
(0, _awilixexpress.before)((0, _authenticate.permission)(_authorizationconstants.PERMS.PrinterFiles.Clear)),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _express.Request === "undefined" ? Object : _express.Request,
typeof _express.Response === "undefined" ? Object : _express.Response
]),
_ts_metadata("design:returntype", Promise)
], PrinterFilesController.prototype, "clearPrinterFiles", null);
_ts_decorate([
(0, _awilixexpress.GET)(),
(0, _awilixexpress.route)("/:id/thumbnail"),
(0, _awilixexpress.before)((0, _authenticate.permission)(_authorizationconstants.PERMS.PrinterFiles.Get)),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _express.Request === "undefined" ? Object : _express.Request,
typeof _express.Response === "undefined" ? Object : _express.Response
]),
_ts_metadata("design:returntype", Promise)
], PrinterFilesController.prototype, "getPrinterThumbnail", null);
_ts_decorate([
(0, _awilixexpress.POST)(),
(0, _awilixexpress.route)("/:id/upload"),
(0, _awilixexpress.before)((0, _authenticate.permission)(_authorizationconstants.PERMS.PrinterFiles.Upload)),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _express.Request === "undefined" ? Object : _express.Request,
typeof _express.Response === "undefined" ? Object : _express.Response
]),
_ts_metadata("design:returntype", Promise)
], PrinterFilesController.prototype, "uploadPrinterFile", null);
PrinterFilesController = _ts_decorate([
(0, _awilixexpress.route)(_serverconstants.AppConstants.apiRoute + "/printer-files"),
(0, _awilixexpress.before)([
(0, _authenticate.authenticate)(),
(0, _authenticate.authorizeRoles)([
_authorizationconstants.ROLES.ADMIN,
_authorizationconstants.ROLES.OPERATOR
]),
(0, _printer.printerResolveMiddleware)()
]),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _loggerfactory.ILoggerFactory === "undefined" ? Object : _loggerfactory.ILoggerFactory,
typeof _printerapiinterface.IPrinterApi === "undefined" ? Object : _printerapiinterface.IPrinterApi,
typeof _logindto.LoginDto === "undefined" ? Object : _logindto.LoginDto,
typeof _printerfilesstore.PrinterFilesStore === "undefined" ? Object : _printerfilesstore.PrinterFilesStore,
typeof _printerfilecleantask.PrinterFileCleanTask === "undefined" ? Object : _printerfilecleantask.PrinterFileCleanTask,
typeof _settingsstore.SettingsStore === "undefined" ? Object : _settingsstore.SettingsStore,
typeof _multerservice.MulterService === "undefined" ? Object : _multerservice.MulterService,
typeof _printerthumbnailcache.PrinterThumbnailCache === "undefined" ? Object : _printerthumbnailcache.PrinterThumbnailCache
])
], PrinterFilesController);
//# sourceMappingURL=printer-files.controller.js.map