UNPKG

@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
"use strict"; 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