@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.
235 lines (234 loc) • 8.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "PrusaLinkApi", {
enumerable: true,
get: function() {
return PrusaLinkApi;
}
});
const _printerapiinterface = require("../printer-api.interface");
const _prusalinkhttpclientbuilder = require("./utils/prusa-link-http-client.builder");
const _fs = require("fs");
const _eventconstants = require("../../constants/event.constants");
const _runtimeexceptions = require("../../exceptions/runtime.exceptions");
const defaultLog = {
adapter: "prusa-link"
};
class PrusaLinkApi {
eventEmitter2;
httpClientFactory;
settingsStore;
printerLogin;
logger;
authHeader;
constructor(loggerFactory, eventEmitter2, httpClientFactory, settingsStore, printerLogin){
this.eventEmitter2 = eventEmitter2;
this.httpClientFactory = httpClientFactory;
this.settingsStore = settingsStore;
this.printerLogin = printerLogin;
this.authHeader = null;
this.logger = loggerFactory(PrusaLinkApi.name);
this.logger.debug("Constructed api client", this.logMeta());
}
get type() {
return _printerapiinterface.PrusaLinkType;
}
set login(login) {
this.printerLogin = login;
}
get client() {
return this.createClient();
}
async getVersion() {
const response = await this.client.get("/api/version");
return response.data.server;
}
async getFiles() {
const response = await this.client.get("/api/files");
return response.data.files.filter((dir)=>dir.path === "/usb")[0].children.map((f)=>({
path: f.display,
date: null,
size: -1
}));
}
async getFile(path) {
const response = await this.getFileRaw(path);
return {
path: response.data.name,
size: response.data.size,
date: null
};
}
async getStatus() {
const response = await this.client.get("/api/v1/status");
return response.data;
}
async getPrinterState() {
const response = await this.client.get("/api/printer");
return response.data;
}
async getJobState() {
const response = await this.client.get("/api/job");
return response.data;
}
connect() {
throw new Error("Method not implemented.");
}
disconnect() {
throw new Error("Method not implemented.");
}
restartServer() {
throw new Error("Method not implemented.");
}
restartHost() {
throw new Error("Method not implemented.");
}
restartPrinterFirmware() {
throw new Error("Method not implemented.");
}
async startPrint(path) {
await this.client.post(`/api/v1/files/usb/${path}`);
}
async pausePrint() {
const jobId = await this.getCurrentJobId();
if (!jobId) {
this.logger.warn("Job pause command did not complete, job or job id not set");
return;
}
await this.client.put(`/api/v1/job/${jobId}/pause`);
}
async resumePrint() {
const jobId = await this.getCurrentJobId();
if (!jobId) {
this.logger.warn("Job resume command did not complete, job or job id not set");
return;
}
await this.client.put(`/api/v1/job/${jobId}/resume`);
}
async cancelPrint() {
const jobId = await this.getCurrentJobId();
if (!jobId) {
this.logger.warn("Job cancel command did not complete, job or job id not set");
return;
}
await this.client.delete(`/api/v1/job/${jobId}`);
}
quickStop() {
throw new Error("Method not implemented.");
}
sendGcode(script) {
throw new Error("Method not implemented.");
}
movePrintHead(amounts) {
throw new Error("Method not implemented.");
}
homeAxes(axes) {
throw new Error("Method not implemented.");
}
async downloadFile(path) {
const fileReference = await this.getFileRaw(path);
const pathUrl = fileReference.data.refs.download;
return await this.client.get(pathUrl, {
responseType: "stream"
});
}
async getFileChunk(path, startBytes, endBytes) {
const fileReference = await this.getFileRaw(path);
const pathUrl = fileReference.data.refs.download;
return await this.createClient((o)=>o.withHeaders({
Range: `bytes=${startBytes}-${endBytes}`
})).get(pathUrl);
}
async uploadFile(multerFileOrBuffer, startPrint, progressToken) {
try {
let fileBuffer;
const filename = multerFileOrBuffer.originalname;
if (Buffer.isBuffer(multerFileOrBuffer)) {
this.logger.log("Using file directly from memory buffer for upload");
fileBuffer = multerFileOrBuffer;
} else {
const filePath = multerFileOrBuffer.path;
this.logger.log(`Reading file from disk for upload: ${filePath}`);
fileBuffer = (0, _fs.readFileSync)(filePath);
}
const contentLength = fileBuffer.length;
const response = await this.createClient((b)=>{
b.withHeaders({
"Content-Length": contentLength.toString(),
"Overwrite": "?1",
"Print-After-Upload": startPrint ? "?1" : "?0"
}).withTimeout(this.settingsStore.getTimeoutSettings().apiUploadTimeout).withOnUploadProgress((p)=>{
if (progressToken) {
this.eventEmitter2.emit(`${(0, _eventconstants.uploadProgressEvent)(progressToken)}`, progressToken, p);
}
});
}).put(`/api/v1/files/usb/${encodeURIComponent(filename)}`, fileBuffer);
if (progressToken) {
this.eventEmitter2.emit(`${(0, _eventconstants.uploadDoneEvent)(progressToken)}`, progressToken);
}
return response.data;
} catch (e) {
if (progressToken) {
this.eventEmitter2.emit(`${(0, _eventconstants.uploadFailedEvent)(progressToken)}`, progressToken, e?.message);
}
let data;
try {
data = JSON.parse(e.response?.body);
} catch {
data = e.response?.body;
}
throw new _runtimeexceptions.ExternalServiceError({
error: e.message,
statusCode: e.response?.statusCode,
data,
success: false,
stack: e.stack
}, "Prusa-Link");
}
}
async deleteFile(path) {
await this.client.delete(`/api/v1/files/usb/${path}`);
}
async deleteFolder(path) {
await this.client.delete(`/api/v1/files/usb/${path}`);
}
getSettings() {
throw new Error("Method not implemented.");
}
getReprintState() {
throw new Error("Method not implemented.");
}
getFileRaw(path) {
return this.client.get(`/api/v1/files/usb/${path}`);
}
async getCurrentJobId() {
const status = await this.getStatus();
return status.job?.id;
}
createClient(buildFluentOptions) {
const builder = new _prusalinkhttpclientbuilder.PrusaLinkHttpClientBuilder();
return this.httpClientFactory.createClientWithBaseUrl(builder, this.printerLogin.printerURL, (b)=>{
this.logger.debug("Building API client", this.logMeta());
b.withDigestAuth(this.printerLogin.username, this.printerLogin.password, (error)=>{
this.logger.error("Authentication error occurred", error);
}, (error, attemptCount)=>{
this.logger.log(`Authentication attempt count ${attemptCount} for method ${error.config?.method?.toUpperCase()} path ${error.config?.url}`, this.logMeta());
}, (authHeader)=>{
this.logger.debug("Authentication successful, saving auth header for later reuse", this.logMeta());
this.authHeader = authHeader;
});
if (this.authHeader) {
b.withAuthHeader(this.authHeader);
}
if (buildFluentOptions && typeof buildFluentOptions === "function") {
buildFluentOptions(b);
}
});
}
logMeta() {
return defaultLog;
}
}
//# sourceMappingURL=prusa-link.api.js.map