@fdm-monster/server 2.0.6 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.yarn/install-state.gz +0 -0
- package/RELEASE_NOTES.MD +8 -0
- package/dist/consoles/bambu-mqtt-diagnostic.console.js +565 -0
- package/dist/consoles/bambu-mqtt-diagnostic.console.js.map +1 -0
- package/dist/consoles/mock-bambu.server.js +114 -88
- package/dist/consoles/mock-bambu.server.js.map +1 -1
- package/dist/controllers/file-storage.controller.js +34 -14
- package/dist/controllers/file-storage.controller.js.map +1 -1
- package/dist/controllers/print-job.controller.js +35 -99
- package/dist/controllers/print-job.controller.js.map +1 -1
- package/dist/server.constants.js +1 -1
- package/dist/services/bambu/bambu-ftp.adapter.js +13 -11
- package/dist/services/bambu/bambu-ftp.adapter.js.map +1 -1
- package/dist/services/bambu/bambu-mqtt.adapter.js +86 -32
- package/dist/services/bambu/bambu-mqtt.adapter.js.map +1 -1
- package/dist/services/bambu/bambu.client.js.map +1 -1
- package/dist/services/bambu.api.js +5 -6
- package/dist/services/bambu.api.js.map +1 -1
- package/package.json +12 -9
|
@@ -31,19 +31,12 @@ console.log(`[BAMBU MOCK] Serial: ${serial}`);
|
|
|
31
31
|
console.log(`[BAMBU MOCK] Access Code: ${accessCode}`);
|
|
32
32
|
console.log(`[BAMBU MOCK] Username: bblp`);
|
|
33
33
|
const ftpDir = _nodepath.default.join(_nodeos.default.tmpdir(), "bambu-mock-ftp", serial);
|
|
34
|
-
const sdcardDir = _nodepath.default.join(ftpDir, "sdcard");
|
|
35
34
|
if (!_nodefs.default.existsSync(ftpDir)) {
|
|
36
35
|
console.log(`[BAMBU MOCK] Creating FTP directory: ${ftpDir}`);
|
|
37
36
|
_nodefs.default.mkdirSync(ftpDir, {
|
|
38
37
|
recursive: true
|
|
39
38
|
});
|
|
40
39
|
}
|
|
41
|
-
if (!_nodefs.default.existsSync(sdcardDir)) {
|
|
42
|
-
console.log(`[BAMBU MOCK] Creating sdcard directory: ${sdcardDir}`);
|
|
43
|
-
_nodefs.default.mkdirSync(sdcardDir, {
|
|
44
|
-
recursive: true
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
40
|
async function generateSelfSignedCert() {
|
|
48
41
|
console.log(`[BAMBU MOCK] Generating self-signed certificate for TLS...`);
|
|
49
42
|
const attrs = [
|
|
@@ -84,10 +77,12 @@ let nozzleTemp = 25;
|
|
|
84
77
|
let bedTemp = 25;
|
|
85
78
|
let printStartTime = 0;
|
|
86
79
|
const PRINT_DURATION = 20;
|
|
80
|
+
let hasReceivedPushall = false;
|
|
81
|
+
let publishInterval = null;
|
|
87
82
|
(async ()=>{
|
|
88
83
|
const tlsCerts = await generateSelfSignedCert();
|
|
89
84
|
const ftpServer = new _ftpsrv.default({
|
|
90
|
-
url: `
|
|
85
|
+
url: `ftps://0.0.0.0:${port}`,
|
|
91
86
|
pasv_url: "127.0.0.1",
|
|
92
87
|
pasv_min: 1024,
|
|
93
88
|
pasv_max: 1048,
|
|
@@ -113,7 +108,7 @@ const PRINT_DURATION = 20;
|
|
|
113
108
|
console.error(`[BAMBU MOCK FTP] Client error:`, error);
|
|
114
109
|
});
|
|
115
110
|
ftpServer.listen().then(()=>{
|
|
116
|
-
console.log(`[BAMBU MOCK FTP] FTP server is running on port ${port}`);
|
|
111
|
+
console.log(`[BAMBU MOCK FTP] FTP server is running on port ${port} with implicit TLS`);
|
|
117
112
|
console.log(`[BAMBU MOCK FTP] FTP directory: ${ftpDir}`);
|
|
118
113
|
});
|
|
119
114
|
const mqttClient = _mqtt.default.connect(`mqtts://localhost:${mqttPort}`, {
|
|
@@ -122,100 +117,121 @@ const PRINT_DURATION = 20;
|
|
|
122
117
|
password: accessCode,
|
|
123
118
|
rejectUnauthorized: false
|
|
124
119
|
});
|
|
120
|
+
const reportTopic = `device/${serial}/report`;
|
|
121
|
+
const publishState = (sequenceId)=>{
|
|
122
|
+
if (isFinished) {
|
|
123
|
+
isFinished = false;
|
|
124
|
+
finishedFileName = "";
|
|
125
|
+
currentPrintFile = "";
|
|
126
|
+
printProgress = 0;
|
|
127
|
+
} else if (isPrinting && !isPaused) {
|
|
128
|
+
const elapsedSeconds = (Date.now() - printStartTime) / 1000;
|
|
129
|
+
printProgress = Math.min(elapsedSeconds / PRINT_DURATION * 100, 100);
|
|
130
|
+
if (printProgress < 10) {
|
|
131
|
+
nozzleTemp = Math.min(nozzleTemp + 10, 220);
|
|
132
|
+
bedTemp = Math.min(bedTemp + 5, 60);
|
|
133
|
+
} else {
|
|
134
|
+
nozzleTemp = 220;
|
|
135
|
+
bedTemp = 60;
|
|
136
|
+
}
|
|
137
|
+
if (printProgress >= 100) {
|
|
138
|
+
isFinished = true;
|
|
139
|
+
finishedFileName = currentPrintFile;
|
|
140
|
+
isPrinting = false;
|
|
141
|
+
printProgress = 100;
|
|
142
|
+
console.log(`[BAMBU MOCK MQTT] Print completed: ${currentPrintFile}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (!isPrinting && !isFinished && nozzleTemp > 25) {
|
|
146
|
+
nozzleTemp = Math.max(nozzleTemp - 2, 25);
|
|
147
|
+
bedTemp = Math.max(bedTemp - 1, 25);
|
|
148
|
+
}
|
|
149
|
+
let gcodeState = "IDLE";
|
|
150
|
+
if (isFinished) gcodeState = "FINISHED";
|
|
151
|
+
else if (isPrinting && isPaused) gcodeState = "PAUSE";
|
|
152
|
+
else if (isPrinting) gcodeState = "PRINTING";
|
|
153
|
+
const fileName = isFinished ? finishedFileName : currentPrintFile;
|
|
154
|
+
const hasJob = isPrinting || isFinished;
|
|
155
|
+
const finishedLabel = isFinished ? "finished" : "printing";
|
|
156
|
+
const printingLabel = isPaused ? "paused" : finishedLabel;
|
|
157
|
+
const progressOrFinished = isFinished ? 100 : printProgress;
|
|
158
|
+
const state = {
|
|
159
|
+
print: {
|
|
160
|
+
nozzle_temper: Math.round(nozzleTemp),
|
|
161
|
+
nozzle_target_temper: isPrinting ? 220 : 0,
|
|
162
|
+
bed_temper: Math.round(bedTemp),
|
|
163
|
+
bed_target_temper: isPrinting ? 60 : 0,
|
|
164
|
+
chamber_temper: 30,
|
|
165
|
+
mc_percent: isFinished ? 100 : Math.round(printProgress),
|
|
166
|
+
mc_remaining_time: hasJob ? Math.round(Math.max(0, (PRINT_DURATION - (Date.now() - printStartTime) / 1000) / 60)) : 0,
|
|
167
|
+
mc_print_stage: hasJob ? printingLabel : "idle",
|
|
168
|
+
gcode_state: gcodeState,
|
|
169
|
+
gcode_file: fileName || "",
|
|
170
|
+
wifi_signal: "-45dBm",
|
|
171
|
+
layer_num: hasJob ? Math.floor(progressOrFinished / 2) : 0,
|
|
172
|
+
total_layer_num: hasJob ? 50 : 0,
|
|
173
|
+
subtask_name: fileName || "",
|
|
174
|
+
heatbreak_fan_speed: isPrinting ? "5000" : "0",
|
|
175
|
+
cooling_fan_speed: isPrinting ? "8000" : "0",
|
|
176
|
+
big_fan1_speed: isPrinting ? "3000" : "0",
|
|
177
|
+
big_fan2_speed: isPrinting ? "3000" : "0",
|
|
178
|
+
spd_lvl: 2,
|
|
179
|
+
spd_mag: 100,
|
|
180
|
+
print_error: 0,
|
|
181
|
+
lifecycle: "product",
|
|
182
|
+
command: "push_status",
|
|
183
|
+
msg: 0,
|
|
184
|
+
sequence_id: sequenceId ? String(Date.now()) : String(sequenceId)
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
mqttClient.publish(reportTopic, JSON.stringify(state), {
|
|
188
|
+
qos: 0
|
|
189
|
+
}, (err)=>{
|
|
190
|
+
if (err) {
|
|
191
|
+
console.error(`[BAMBU MOCK MQTT] Failed to publish state:`, err);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
};
|
|
125
195
|
mqttClient.on("connect", ()=>{
|
|
126
196
|
console.log(`[BAMBU MOCK MQTT] Connected to MQTT broker at localhost:${mqttPort}`);
|
|
127
197
|
console.log(`[BAMBU MOCK MQTT] Publishing to topic: device/${serial}/report`);
|
|
128
|
-
|
|
129
|
-
const requestTopic = `device/${serial}/request`;
|
|
130
|
-
mqttClient.subscribe(requestTopic, (err)=>{
|
|
198
|
+
mqttClient.subscribe(reportTopic, (err)=>{
|
|
131
199
|
if (err) {
|
|
132
|
-
console.error(`[BAMBU MOCK MQTT] Failed to subscribe to ${
|
|
200
|
+
console.error(`[BAMBU MOCK MQTT] Failed to subscribe to ${reportTopic}:`, err);
|
|
133
201
|
} else {
|
|
134
|
-
console.log(`[BAMBU MOCK MQTT] Subscribed to topic: ${
|
|
202
|
+
console.log(`[BAMBU MOCK MQTT] Subscribed to topic: ${reportTopic}`);
|
|
135
203
|
}
|
|
136
204
|
});
|
|
137
|
-
|
|
138
|
-
if (isFinished) {
|
|
139
|
-
isFinished = false;
|
|
140
|
-
finishedFileName = "";
|
|
141
|
-
currentPrintFile = "";
|
|
142
|
-
printProgress = 0;
|
|
143
|
-
} else if (isPrinting && !isPaused) {
|
|
144
|
-
const elapsedSeconds = (Date.now() - printStartTime) / 1000;
|
|
145
|
-
printProgress = Math.min(elapsedSeconds / PRINT_DURATION * 100, 100);
|
|
146
|
-
if (printProgress < 10) {
|
|
147
|
-
nozzleTemp = Math.min(nozzleTemp + 10, 220);
|
|
148
|
-
bedTemp = Math.min(bedTemp + 5, 60);
|
|
149
|
-
} else {
|
|
150
|
-
nozzleTemp = 220;
|
|
151
|
-
bedTemp = 60;
|
|
152
|
-
}
|
|
153
|
-
if (printProgress >= 100) {
|
|
154
|
-
isFinished = true;
|
|
155
|
-
finishedFileName = currentPrintFile;
|
|
156
|
-
isPrinting = false;
|
|
157
|
-
printProgress = 100;
|
|
158
|
-
console.log(`[BAMBU MOCK MQTT] Print completed: ${currentPrintFile}`);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
if (!isPrinting && !isFinished && nozzleTemp > 25) {
|
|
162
|
-
nozzleTemp = Math.max(nozzleTemp - 2, 25);
|
|
163
|
-
bedTemp = Math.max(bedTemp - 1, 25);
|
|
164
|
-
}
|
|
165
|
-
let gcodeState = "IDLE";
|
|
166
|
-
if (isFinished) gcodeState = "FINISHED";
|
|
167
|
-
else if (isPrinting && isPaused) gcodeState = "PAUSE";
|
|
168
|
-
else if (isPrinting) gcodeState = "PRINTING";
|
|
169
|
-
const fileName = isFinished ? finishedFileName : currentPrintFile;
|
|
170
|
-
const hasJob = isPrinting || isFinished;
|
|
171
|
-
const printingLabel = isPaused ? "paused" : isFinished ? "finished" : "printing";
|
|
172
|
-
const state = {
|
|
173
|
-
print: {
|
|
174
|
-
nozzle_temper: Math.round(nozzleTemp),
|
|
175
|
-
nozzle_target_temper: isPrinting ? 220 : 0,
|
|
176
|
-
bed_temper: Math.round(bedTemp),
|
|
177
|
-
bed_target_temper: isPrinting ? 60 : 0,
|
|
178
|
-
chamber_temper: 30,
|
|
179
|
-
mc_percent: isFinished ? 100 : Math.round(printProgress),
|
|
180
|
-
mc_remaining_time: hasJob ? Math.round(Math.max(0, (PRINT_DURATION - (Date.now() - printStartTime) / 1000) / 60)) : 0,
|
|
181
|
-
mc_print_stage: hasJob ? printingLabel : "idle",
|
|
182
|
-
gcode_state: gcodeState,
|
|
183
|
-
gcode_file: fileName || "",
|
|
184
|
-
wifi_signal: "-45dBm",
|
|
185
|
-
layer_num: hasJob ? Math.floor((isFinished ? 100 : printProgress) / 2) : 0,
|
|
186
|
-
total_layer_num: hasJob ? 50 : 0,
|
|
187
|
-
subtask_name: fileName || "",
|
|
188
|
-
heatbreak_fan_speed: isPrinting ? "5000" : "0",
|
|
189
|
-
cooling_fan_speed: isPrinting ? "8000" : "0",
|
|
190
|
-
big_fan1_speed: isPrinting ? "3000" : "0",
|
|
191
|
-
big_fan2_speed: isPrinting ? "3000" : "0",
|
|
192
|
-
spd_lvl: 2,
|
|
193
|
-
spd_mag: 100,
|
|
194
|
-
print_error: 0,
|
|
195
|
-
lifecycle: "product",
|
|
196
|
-
command: "push_status",
|
|
197
|
-
msg: 0,
|
|
198
|
-
sequence_id: String(Date.now())
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
mqttClient.publish(reportTopic, JSON.stringify(state), {
|
|
202
|
-
qos: 0
|
|
203
|
-
}, (err)=>{
|
|
204
|
-
if (err) {
|
|
205
|
-
console.error(`[BAMBU MOCK MQTT] Failed to publish state:`, err);
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
};
|
|
209
|
-
setInterval(publishState, MESSAGE_INTERVAL);
|
|
205
|
+
console.log(`[BAMBU MOCK MQTT] Sending initial status update`);
|
|
210
206
|
publishState();
|
|
207
|
+
if (!hasReceivedPushall) {
|
|
208
|
+
console.log(`[BAMBU MOCK MQTT] Waiting for pushall command to start periodic updates...`);
|
|
209
|
+
}
|
|
211
210
|
});
|
|
212
211
|
mqttClient.on("message", (topic, message)=>{
|
|
213
212
|
try {
|
|
214
213
|
const payload = JSON.parse(message.toString());
|
|
214
|
+
if (payload.print?.command === "push_status") {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
215
217
|
console.log(`[BAMBU MOCK MQTT] Received command on ${topic}:`, JSON.stringify(payload));
|
|
218
|
+
if (payload.pushing?.command === "pushall") {
|
|
219
|
+
const sequenceId = payload.pushing.sequence_id;
|
|
220
|
+
console.log(`[BAMBU MOCK MQTT] Received pushall command with sequence_id: ${sequenceId}`);
|
|
221
|
+
if (hasReceivedPushall) {
|
|
222
|
+
publishState(sequenceId);
|
|
223
|
+
} else {
|
|
224
|
+
hasReceivedPushall = true;
|
|
225
|
+
console.log(`[BAMBU MOCK MQTT] Starting periodic state publishing every ${MESSAGE_INTERVAL}ms`);
|
|
226
|
+
publishState(sequenceId);
|
|
227
|
+
publishInterval = setInterval(publishState, MESSAGE_INTERVAL);
|
|
228
|
+
}
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
216
231
|
if (payload.print?.command) {
|
|
217
232
|
const command = payload.print.command;
|
|
218
|
-
|
|
233
|
+
const sequenceId = payload.print.sequence_id;
|
|
234
|
+
console.log(`[BAMBU MOCK MQTT] Processing command: ${command} with sequence_id: ${sequenceId}`);
|
|
219
235
|
if (command === "project_file" || command === "start") {
|
|
220
236
|
const filename = payload.print.param || payload.print.subtask_name || "unknown.gcode";
|
|
221
237
|
if (filename.endsWith(".gcode") || filename.endsWith(".3mf")) {
|
|
@@ -254,6 +270,8 @@ const PRINT_DURATION = 20;
|
|
|
254
270
|
}, MESSAGE_INTERVAL * 2);
|
|
255
271
|
}
|
|
256
272
|
}
|
|
273
|
+
console.log(`[BAMBU MOCK MQTT] Sending response with sequence_id: ${sequenceId}`);
|
|
274
|
+
publishState(sequenceId);
|
|
257
275
|
}
|
|
258
276
|
} catch (error) {
|
|
259
277
|
console.error(`[BAMBU MOCK MQTT] Error processing message:`, error);
|
|
@@ -267,6 +285,10 @@ const PRINT_DURATION = 20;
|
|
|
267
285
|
});
|
|
268
286
|
process.on("SIGINT", async ()=>{
|
|
269
287
|
console.log("\n[BAMBU MOCK] Shutting down gracefully...");
|
|
288
|
+
if (publishInterval) {
|
|
289
|
+
clearInterval(publishInterval);
|
|
290
|
+
publishInterval = null;
|
|
291
|
+
}
|
|
270
292
|
if (mqttClient.connected) {
|
|
271
293
|
console.log("[BAMBU MOCK MQTT] Disconnecting MQTT client...");
|
|
272
294
|
await mqttClient.endAsync();
|
|
@@ -278,6 +300,10 @@ const PRINT_DURATION = 20;
|
|
|
278
300
|
});
|
|
279
301
|
process.on("SIGTERM", async ()=>{
|
|
280
302
|
console.log("\n[BAMBU MOCK] Received SIGTERM. Shutting down...");
|
|
303
|
+
if (publishInterval) {
|
|
304
|
+
clearInterval(publishInterval);
|
|
305
|
+
publishInterval = null;
|
|
306
|
+
}
|
|
281
307
|
if (mqttClient.connected) {
|
|
282
308
|
await mqttClient.endAsync();
|
|
283
309
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/consoles/mock-bambu.server.ts"],"names":["DEFAULT_PORT","DEFAULT_MQTT_PORT","DEFAULT_SERIAL","DEFAULT_ACCESS_CODE","MESSAGE_INTERVAL","DEFAULT_USERNAME","port","process","argv","Number","parseInt","mqttPort","serial","accessCode","console","log","ftpDir","path","join","os","tmpdir","
|
|
1
|
+
{"version":3,"sources":["../../src/consoles/mock-bambu.server.ts"],"names":["DEFAULT_PORT","DEFAULT_MQTT_PORT","DEFAULT_SERIAL","DEFAULT_ACCESS_CODE","MESSAGE_INTERVAL","DEFAULT_USERNAME","port","process","argv","Number","parseInt","mqttPort","serial","accessCode","console","log","ftpDir","path","join","os","tmpdir","fs","existsSync","mkdirSync","recursive","generateSelfSignedCert","attrs","name","value","options","days","algorithm","keySize","pems","selfsigned","generate","key","private","cert","minVersion","ciphers","isPrinting","isFinished","currentPrintFile","finishedFileName","printProgress","isPaused","nozzleTemp","bedTemp","printStartTime","PRINT_DURATION","hasReceivedPushall","publishInterval","tlsCerts","ftpServer","FtpSrv","url","pasv_url","pasv_min","pasv_max","tls","anonymous","greeting","on","username","password","resolve","reject","root","Error","error","listen","then","mqttClient","mqtt","connect","clientId","Date","now","rejectUnauthorized","reportTopic","publishState","sequenceId","elapsedSeconds","Math","min","max","gcodeState","fileName","hasJob","finishedLabel","printingLabel","progressOrFinished","state","print","nozzle_temper","round","nozzle_target_temper","bed_temper","bed_target_temper","chamber_temper","mc_percent","mc_remaining_time","mc_print_stage","gcode_state","gcode_file","wifi_signal","layer_num","floor","total_layer_num","subtask_name","heatbreak_fan_speed","cooling_fan_speed","big_fan1_speed","big_fan2_speed","spd_lvl","spd_mag","print_error","lifecycle","command","msg","sequence_id","String","publish","JSON","stringify","qos","err","subscribe","topic","message","payload","parse","toString","pushing","setInterval","filename","param","endsWith","pausedProgress","stoppedFile","setTimeout","clearInterval","connected","endAsync","close","exit","catch"],"mappings":"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"}
|
|
@@ -43,17 +43,25 @@ class FileStorageController {
|
|
|
43
43
|
try {
|
|
44
44
|
const files = await this.fileStorageService.listAllFiles();
|
|
45
45
|
res.send({
|
|
46
|
-
files: files.map((file)=>
|
|
46
|
+
files: files.map((file)=>{
|
|
47
|
+
const thumbnails = (file.metadata?._thumbnails || []).map((thumb)=>({
|
|
48
|
+
index: thumb.index,
|
|
49
|
+
width: thumb.width,
|
|
50
|
+
height: thumb.height,
|
|
51
|
+
format: thumb.format,
|
|
52
|
+
size: thumb.size
|
|
53
|
+
}));
|
|
54
|
+
return {
|
|
47
55
|
fileStorageId: file.fileStorageId,
|
|
48
56
|
fileName: file.fileName,
|
|
49
57
|
fileFormat: file.fileFormat,
|
|
50
58
|
fileSize: file.fileSize,
|
|
51
59
|
fileHash: file.fileHash,
|
|
52
60
|
createdAt: file.createdAt,
|
|
53
|
-
|
|
54
|
-
thumbnailsUrl: file.thumbnailCount > 0 ? `/api/file-storage/${file.fileStorageId}/thumbnail/0` : null,
|
|
61
|
+
thumbnails,
|
|
55
62
|
metadata: file.metadata
|
|
56
|
-
}
|
|
63
|
+
};
|
|
64
|
+
}),
|
|
57
65
|
totalCount: files.length
|
|
58
66
|
});
|
|
59
67
|
} catch (error) {
|
|
@@ -73,6 +81,13 @@ class FileStorageController {
|
|
|
73
81
|
});
|
|
74
82
|
return;
|
|
75
83
|
}
|
|
84
|
+
const thumbnails = (file.metadata?._thumbnails || []).map((thumb)=>({
|
|
85
|
+
index: thumb.index,
|
|
86
|
+
width: thumb.width,
|
|
87
|
+
height: thumb.height,
|
|
88
|
+
format: thumb.format,
|
|
89
|
+
size: thumb.size
|
|
90
|
+
}));
|
|
76
91
|
res.send({
|
|
77
92
|
fileStorageId: file.fileStorageId,
|
|
78
93
|
fileName: file.fileName,
|
|
@@ -80,8 +95,7 @@ class FileStorageController {
|
|
|
80
95
|
fileSize: file.fileSize,
|
|
81
96
|
fileHash: file.fileHash,
|
|
82
97
|
createdAt: file.createdAt,
|
|
83
|
-
|
|
84
|
-
thumbnailsUrl: file.thumbnailCount > 0 ? `/api/file-storage/${file.fileStorageId}/thumbnail/0` : null,
|
|
98
|
+
thumbnails,
|
|
85
99
|
metadata: file.metadata
|
|
86
100
|
});
|
|
87
101
|
} catch (error) {
|
|
@@ -146,7 +160,7 @@ class FileStorageController {
|
|
|
146
160
|
});
|
|
147
161
|
}
|
|
148
162
|
}
|
|
149
|
-
async
|
|
163
|
+
async getThumbnailByIndex(req, res) {
|
|
150
164
|
const { fileStorageId, index } = req.params;
|
|
151
165
|
const thumbnailIndex = Number.parseInt(index);
|
|
152
166
|
if (Number.isNaN(thumbnailIndex)) {
|
|
@@ -164,12 +178,18 @@ class FileStorageController {
|
|
|
164
178
|
return;
|
|
165
179
|
}
|
|
166
180
|
const isJPG = thumbnail[0] === 0xFF && thumbnail[1] === 0xD8;
|
|
167
|
-
|
|
168
|
-
if (
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
181
|
+
const isQOI = thumbnail[0] === 0x71 && thumbnail[1] === 0x6F && thumbnail[2] === 0x69 && thumbnail[3] === 0x66;
|
|
182
|
+
if (isQOI) {
|
|
183
|
+
res.status(404).send({
|
|
184
|
+
error: "Thumbnail format not supported (QOI)"
|
|
185
|
+
});
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const mimeType = isJPG ? 'image/jpeg' : 'image/png';
|
|
189
|
+
const base64 = thumbnail.toString('base64');
|
|
190
|
+
res.send({
|
|
191
|
+
thumbnailBase64: `data:${mimeType};base64,${base64}`
|
|
192
|
+
});
|
|
173
193
|
} catch (error) {
|
|
174
194
|
this.logger.error(`Failed to get thumbnail ${thumbnailIndex} for ${fileStorageId}: ${error}`);
|
|
175
195
|
res.status(500).send({
|
|
@@ -287,7 +307,7 @@ _ts_decorate([
|
|
|
287
307
|
typeof _express.Response === "undefined" ? Object : _express.Response
|
|
288
308
|
]),
|
|
289
309
|
_ts_metadata("design:returntype", Promise)
|
|
290
|
-
], FileStorageController.prototype, "
|
|
310
|
+
], FileStorageController.prototype, "getThumbnailByIndex", null);
|
|
291
311
|
_ts_decorate([
|
|
292
312
|
(0, _awilixexpress.POST)(),
|
|
293
313
|
(0, _awilixexpress.route)("/upload"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/controllers/file-storage.controller.ts"],"names":["FileStorageController","logger","loggerFactory","fileStorageService","multerService","fileAnalysisService","name","listFiles","req","res","files","listAllFiles","send","map","file","
|
|
1
|
+
{"version":3,"sources":["../../src/controllers/file-storage.controller.ts"],"names":["FileStorageController","logger","loggerFactory","fileStorageService","multerService","fileAnalysisService","name","listFiles","req","res","files","listAllFiles","send","map","file","thumbnails","metadata","_thumbnails","thumb","index","width","height","format","size","fileStorageId","fileName","fileFormat","fileSize","fileHash","createdAt","totalCount","length","error","status","getFileMetadata","params","getFileInfo","deleteFile","log","message","analyzeFile","filePath","getFilePath","fileExists","existingMetadata","loadMetadata","analysisResult","totalLayers","gcodePrintTimeSeconds","calculateFileHash","originalFileName","_originalFileName","thumbnailMetadata","saveThumbnails","saveMetadata","thumbnailCount","getThumbnailByIndex","thumbnailIndex","Number","parseInt","isNaN","thumbnail","getThumbnail","isJPG","isQOI","mimeType","base64","toString","thumbnailBase64","uploadFile","acceptedExtensions","multerLoadFileAsync","ext","extname","originalname","tempPathWithExt","path","copyFileSync","filamentUsedGrams","saveFile","existsSync","unlinkSync","AppConstants","apiRoute","authenticate","authorizeRoles","ROLES","ADMIN","OPERATOR"],"mappings":"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"}
|