Skip to content

Commit 124adfb

Browse files
authored
Merge pull request #91 from penwern/fix/checksum-path-construction
fixed issue with constructing file path when nested under a folder
2 parents 4ff600f + 5b647dc commit 124adfb

File tree

2 files changed

+37
-54
lines changed

2 files changed

+37
-54
lines changed

src/js/core/UploadInterceptor/plugins/ChecksumValidation/ChecksumValidation.js

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ function updateMetaField(uuid, namespace, value) {
3333
};
3434

3535
Curate.api.fetchCurate(url, "PUT", metadatas);
36-
console.log(`Attempted to update metadata '${namespace}' for UUID ${uuid}`);
3736
}
3837

3938
function fetchCurateStats(filePath, expectedChecksum, retryCount) {
@@ -107,7 +106,6 @@ let workerManager = null;
107106
async function generateChecksum(uploadItem) {
108107
if (!workerManager) {
109108
workerManager = new ChecksumWorkerManager();
110-
console.log("ChecksumWorkerManager initialized");
111109
}
112110

113111
const multipartDecisionThreshold = PydioApi.getMultipartThreshold();
@@ -119,10 +117,6 @@ async function generateChecksum(uploadItem) {
119117
// Calculate checksum: use multipart calculation for large files, single MD5 for smaller ones.
120118
if (uploadItem._file.size > multipartDecisionThreshold) {
121119
// Multipart checksum logic:
122-
console.log(
123-
"File exceeds multipart threshold, generating part checksums for:",
124-
uploadItem._label
125-
);
126120
const partSize = multipartPartSize;
127121
const parts = Math.ceil(uploadItem._file.size / partSize);
128122
const partChecksumsHex = []; // Store hex for potential debugging
@@ -153,10 +147,6 @@ async function generateChecksum(uploadItem) {
153147
);
154148
} else {
155149
// Single part checksum calculation for smaller files.
156-
console.log(
157-
"File below multipart threshold, generating single checksum for:",
158-
uploadItem._label
159-
);
160150
const checksumData = await workerManager.generateChecksum(uploadItem._file);
161151
finalChecksum = checksumData.hash;
162152
console.log("Generated single checksum:", finalChecksum);
@@ -175,50 +165,68 @@ async function generateChecksum(uploadItem) {
175165
}
176166

177167
function constructFilePath(uploadItem) {
178-
// This logic determines the correct path to query for stats, accounting for
179-
// potential server-side renaming on filename collision (e.g., file.txt -> file-1.txt).
168+
console.log("constructing file path for item: ", uploadItem);
169+
170+
// Extract the file path from the presigned URL responseURL.
171+
// This is the source of truth for where the file was actually uploaded.
172+
const responseURL = uploadItem.xhr?.responseURL;
173+
174+
if (responseURL) {
175+
try {
176+
// Parse the URL to extract the path between /io/ and the query parameters
177+
const url = new URL(responseURL);
178+
const pathname = url.pathname;
179+
180+
// Extract everything after /io/
181+
const ioIndex = pathname.indexOf('/io/');
182+
if (ioIndex !== -1) {
183+
const pathAfterIo = pathname.substring(ioIndex + 4); // +4 to skip '/io/'
184+
// Decode URI components to handle encoded characters
185+
const decodedPath = decodeURIComponent(pathAfterIo);
186+
console.log("Extracted path from responseURL:", decodedPath);
187+
return decodedPath;
188+
}
189+
} catch (error) {
190+
console.error("Failed to parse responseURL:", error);
191+
// Fall through to legacy path construction
192+
}
193+
}
194+
195+
// Fallback to legacy path construction if responseURL is unavailable
196+
console.warn("responseURL not available, using legacy path construction");
180197
const workspace = Curate.workspaces.getOpenWorkspace();
181-
const targetPath = uploadItem._targetNode._path; // Path of the destination folder.
182-
const relativeFilePath = uploadItem._file.webkitRelativePath; // Original path *within* an uploaded folder structure, or "" for single files.
183-
const finalLabel = uploadItem._label; // This property is updated by the UploaderModel to reflect the FINAL filename after potential renaming.
198+
const targetPath = uploadItem._targetNode._path;
199+
const relativeFilePath = uploadItem._file.webkitRelativePath;
200+
const finalLabel = uploadItem._label;
184201

185-
// Normalize workspace and target paths to ensure correct slash handling.
186202
const normWorkspace = workspace.endsWith("/") ? workspace : workspace + "/";
187203
let normTarget = "";
188204
if (targetPath && targetPath !== "/") {
189-
// Handle root path '/'
190-
normTarget = targetPath.replace(/^\/+|\/+$/g, ""); // Remove leading/trailing slashes
205+
normTarget = targetPath.replace(/^\/+|\/+$/g, "");
191206
}
192207

193208
let fileComponent = "";
194-
// Check if a folder structure was uploaded (relativeFilePath is not empty).
195209
if (relativeFilePath) {
196-
// Combine the original directory structure from relativeFilePath with the FINAL filename from finalLabel.
197210
const lastSlashIndex = relativeFilePath.lastIndexOf("/");
198211
if (lastSlashIndex !== -1) {
199-
// Extract the directory part (e.g., "folder/subfolder/")
200212
const dirPart = relativeFilePath.substring(0, lastSlashIndex + 1);
201-
fileComponent = dirPart + finalLabel; // Append the final filename
213+
fileComponent = dirPart + finalLabel;
202214
} else {
203-
// Relative path contained only the original filename, so just use the final label.
204215
fileComponent = finalLabel;
205216
}
206-
// Ensure no leading slash inherited from relativeFilePath.
207217
if (fileComponent.startsWith("/")) {
208218
fileComponent = fileComponent.substring(1);
209219
}
210220
} else {
211-
// Single file upload, use the final label directly as the file component.
212221
fileComponent = finalLabel;
213222
}
214223

215-
// Combine all parts into the final path.
216224
let filename = normWorkspace;
217225
if (normTarget) {
218-
filename += normTarget + "/"; // Add normalized target path if not root
226+
filename += normTarget + "/";
219227
}
220-
filename += fileComponent; // Add the final file/path component
221-
filename = filename.replace(/\/+/g, "/"); // Clean up any resulting double slashes.
228+
filename += fileComponent;
229+
filename = filename.replace(/\/+/g, "/");
222230

223231
return filename;
224232
}
@@ -229,7 +237,6 @@ export default {
229237

230238
hooks: {
231239
onUploadComplete: async (uploadItem) => {
232-
console.log('ChecksumValidation: Processing upload completion for:', uploadItem._label);
233240

234241
try {
235242
// Generate checksum for the uploaded file

src/js/core/UploadInterceptor/plugins/ChecksumValidation/ChecksumWorkerManager.js

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ class ChecksumWorkerManager {
1717
this.healthCheckTimer = null;
1818
this.isShuttingDown = false;
1919

20-
console.log('ChecksumWorkerManager: Initialized');
2120
this.startHealthMonitoring();
2221
}
2322

@@ -49,7 +48,6 @@ class ChecksumWorkerManager {
4948
// Store worker with metadata
5049
this.workers.set(workerId, { worker, metadata });
5150

52-
console.log(`ChecksumWorkerManager: Created worker ${workerId} (total: ${this.workers.size})`);
5351
return workerId;
5452
}
5553

@@ -86,11 +84,8 @@ class ChecksumWorkerManager {
8684
// Remove from current tasks
8785
this.currentTasks.delete(workerId);
8886

89-
console.log(`✅ ChecksumWorkerManager: Worker ${workerId} completed task ${metadata.taskCount}`);
90-
9187
// Check if worker needs recycling
9288
if (metadata.taskCount >= this.config.maxTasksPerWorker) {
93-
console.log(`♻️ ChecksumWorkerManager: Recycling worker ${workerId} after ${metadata.taskCount} tasks`);
9489
this.recycleWorker(workerId);
9590
} else {
9691
// Process next task or start idle timer
@@ -130,8 +125,6 @@ class ChecksumWorkerManager {
130125
const task = { file, resolve, reject, createdAt: Date.now() };
131126
this.taskQueue.push(task);
132127

133-
console.log(`ChecksumWorkerManager: Queued task for ${file.name} (queue size: ${this.taskQueue.length})`);
134-
135128
// Try to assign to available worker or create new one
136129
this.assignTask();
137130
});
@@ -160,8 +153,6 @@ class ChecksumWorkerManager {
160153
// Assign task if worker available
161154
if (availableWorkerId) {
162155
this.processNextTask(availableWorkerId);
163-
} else {
164-
console.log(`⏳ ChecksumWorkerManager: All workers busy, task queued (${this.taskQueue.length} waiting)`);
165156
}
166157
}
167158

@@ -200,8 +191,6 @@ class ChecksumWorkerManager {
200191
const multipartThreshold = PydioApi.getMultipartThreshold();
201192
const multipartPartSize = PydioApi.getMultipartPartSize();
202193

203-
console.log(`ChecksumWorkerManager: Assigned task to worker ${workerId} for ${task.file.name}`);
204-
205194
worker.postMessage({
206195
file: task.file,
207196
msg: "begin hash",
@@ -231,12 +220,9 @@ class ChecksumWorkerManager {
231220

232221
metadata.idleTimer = setTimeout(() => {
233222
if (this.taskQueue.length === 0 && !this.currentTasks.has(workerId)) {
234-
console.log(`🧹 ChecksumWorkerManager: Cleaning up idle worker ${workerId}`);
235223
this.removeWorker(workerId);
236224
}
237225
}, this.config.idleTimeoutMs);
238-
239-
console.log(`💤 ChecksumWorkerManager: Worker ${workerId} idle, cleanup in ${this.config.idleTimeoutMs}ms`);
240226
}
241227

242228
/**
@@ -286,8 +272,6 @@ class ChecksumWorkerManager {
286272
// Remove from maps
287273
this.workers.delete(workerId);
288274
this.currentTasks.delete(workerId);
289-
290-
console.log(`🗑️ ChecksumWorkerManager: Removed worker ${workerId} (remaining: ${this.workers.size})`);
291275
}
292276

293277
/**
@@ -306,14 +290,10 @@ class ChecksumWorkerManager {
306290
const age = now - metadata.lastActivity;
307291

308292
if (age > this.config.taskTimeoutMs * 2) {
309-
console.warn(`ChecksumWorkerManager: Worker ${workerId} appears stale (${age}ms since activity)`);
310293
this.replaceWorker(workerId);
311294
}
312295
}
313296

314-
// Log status
315-
console.log(`ChecksumWorkerManager: Health check - Workers: ${this.workers.size}, Queue: ${this.taskQueue.length}, Active: ${this.currentTasks.size}`);
316-
317297
}, this.config.healthCheckIntervalMs);
318298
}
319299

@@ -341,8 +321,6 @@ class ChecksumWorkerManager {
341321
* Shutdown all workers
342322
*/
343323
terminate() {
344-
console.log('ChecksumWorkerManager: Shutting down...');
345-
346324
this.isShuttingDown = true;
347325

348326
// Clear health monitoring
@@ -359,8 +337,6 @@ class ChecksumWorkerManager {
359337
// Clear queues
360338
this.taskQueue = [];
361339
this.currentTasks.clear();
362-
363-
console.log('ChecksumWorkerManager: Shutdown complete');
364340
}
365341
}
366342

0 commit comments

Comments
 (0)