Skip to content

Commit b1f0a7a

Browse files
committed
experimenting with upload volume limits
1 parent b0542b7 commit b1f0a7a

File tree

2 files changed

+179
-23
lines changed

2 files changed

+179
-23
lines changed

src/js/core/UploadInterceptor/UploadInterceptor.js

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,17 @@ class UploadInterceptor {
108108
// 'this' refers to the UploaderModel.UploadItem instance
109109
const uploadItem = this;
110110

111-
// Execute the original upload logic first
112-
const originalPromise = self.originalUploadPresigned.apply(uploadItem, arguments);
111+
// Call beforeUpload hooks first to allow blocking
112+
const shouldProceed = self.callPluginHooks('beforeUpload', uploadItem);
113+
114+
// If any plugin returned false, block the upload
115+
if (shouldProceed === false) {
116+
console.log('UploadInterceptor: Upload blocked by plugin for:', uploadItem._label);
117+
return Promise.reject(new Error('Upload blocked by volume checker'));
118+
}
113119

114-
// Call beforeUpload hooks
115-
self.callPluginHooks('beforeUpload', uploadItem);
120+
// Execute the original upload logic
121+
const originalPromise = self.originalUploadPresigned.apply(uploadItem, arguments);
116122

117123
// Create observer to watch for upload status changes
118124
const observer = (status) => {
@@ -146,15 +152,28 @@ class UploadInterceptor {
146152
* Call a specific hook on all registered plugins
147153
* @param {string} hookName - Name of hook to call
148154
* @param {...any} args - Arguments to pass to hook
155+
* @returns {any} For beforeUpload, returns false if any plugin blocks, otherwise undefined
149156
*/
150157
callPluginHooks(hookName, ...args) {
151158
for (const [pluginName, plugin] of this.plugins) {
152159
try {
153160
if (plugin.hooks && typeof plugin.hooks[hookName] === 'function') {
154-
plugin.hooks[hookName](...args);
161+
const result = plugin.hooks[hookName].call(plugin, ...args);
162+
163+
// For beforeUpload hook, if any plugin returns false, block the upload
164+
if (hookName === 'beforeUpload' && result === false) {
165+
console.log(`UploadInterceptor: Plugin '${pluginName}' blocked upload`);
166+
return false;
167+
}
155168
}
156169
} catch (error) {
157170
console.error(`UploadInterceptor: Error in plugin '${pluginName}' hook '${hookName}':`, error);
171+
172+
// For beforeUpload, treat errors as blocking
173+
if (hookName === 'beforeUpload') {
174+
console.log(`UploadInterceptor: Plugin '${pluginName}' error treated as block`);
175+
return false;
176+
}
158177
}
159178
}
160179
}
Lines changed: 155 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,186 @@
1+
import CurateUi from '../../../CurateFunctions/CurateUi.js';
2+
13
/**
24
* UploadVolumeChecker Plugin
35
*
46
* Monitors and restricts upload volume based on configurable thresholds.
57
* Provides warnings and blocks uploads that exceed specified limits.
68
*/
79

8-
// TODO: Implement volume checking logic
9-
// This is a placeholder for the actual implementation
10-
1110
export default {
1211
name: 'UploadVolumeChecker',
1312

1413
// Configuration (can be made configurable later)
1514
config: {
16-
maxFileCount: 1000, // Maximum number of files in a single upload
17-
warningFileCount: 500, // Show warning at this threshold
15+
maxFileCount: 100, // Maximum number of files in a single upload (lowered for testing)
16+
warningFileCount: 50, // Show warning at this threshold
1817
maxTotalSize: 10 * 1024 * 1024 * 1024, // 10GB max total size
1918
warningTotalSize: 5 * 1024 * 1024 * 1024, // 5GB warning threshold
19+
blockUploads: true, // For experimentation - blocks uploads above threshold
20+
},
21+
22+
// Track current upload session
23+
currentUploadSession: {
24+
fileCount: 0,
25+
totalSize: 0,
26+
files: [],
27+
isBlocked: false,
2028
},
2129

2230
hooks: {
23-
beforeUpload: (uploadItem) => {
31+
beforeUpload: function(uploadItem) {
32+
// 'this' refers to the plugin object due to .call() in UploadInterceptor
33+
const config = this.config;
34+
const session = this.currentUploadSession;
35+
2436
console.log('UploadVolumeChecker: Checking upload volume for:', uploadItem._label);
2537

26-
// TODO: Implement volume checking logic
27-
// - Count files in current upload
28-
// - Calculate total size
29-
// - Check against thresholds
30-
// - Show warnings or block upload
38+
// If this is the first file in a new session, reset counters
39+
if (session.fileCount === 0) {
40+
session.files = [];
41+
session.totalSize = 0;
42+
session.isBlocked = false;
43+
console.log('UploadVolumeChecker: Starting new upload session');
44+
}
45+
46+
// Add current file to session tracking
47+
session.fileCount++;
48+
session.totalSize += uploadItem._file.size;
49+
session.files.push({
50+
name: uploadItem._label,
51+
size: uploadItem._file.size,
52+
path: uploadItem._file.webkitRelativePath || uploadItem._label
53+
});
54+
55+
console.log(`UploadVolumeChecker: Session stats - Files: ${session.fileCount}, Total Size: ${(session.totalSize / 1024 / 1024).toFixed(2)}MB`);
56+
57+
// Check thresholds
58+
const exceedsMaxFiles = session.fileCount > config.maxFileCount;
59+
const exceedsWarningFiles = session.fileCount > config.warningFileCount;
60+
const exceedsMaxSize = session.totalSize > config.maxTotalSize;
61+
const exceedsWarningSize = session.totalSize > config.warningTotalSize;
62+
63+
// Determine action needed
64+
if (exceedsMaxFiles || exceedsMaxSize) {
65+
// Block upload
66+
session.isBlocked = true;
67+
this.showBlockingModal(session, config);
68+
return false; // Block the upload
69+
} else if (exceedsWarningFiles || exceedsWarningSize) {
70+
// Show warning but allow upload
71+
this.showWarningModal(session, config);
72+
}
73+
74+
return true; // Allow upload to proceed
3175
},
3276

3377
onUploadComplete: (uploadItem) => {
3478
console.log('UploadVolumeChecker: Upload completed for:', uploadItem._label);
35-
36-
// TODO: Implement post-upload cleanup
37-
// - Reset counters
38-
// - Log upload statistics
79+
// Note: We don't reset session here as multiple files might be uploading concurrently
3980
},
4081

4182
onUploadError: (uploadItem) => {
4283
console.log('UploadVolumeChecker: Upload failed for:', uploadItem._label);
84+
// Could implement error tracking here
85+
}
86+
},
87+
88+
// Show blocking modal when limits are exceeded
89+
showBlockingModal: function(session, config) {
90+
const fileCountIssue = session.fileCount > config.maxFileCount;
91+
const sizeIssue = session.totalSize > config.maxTotalSize;
92+
93+
let message = 'Upload blocked due to volume limits:\n\n';
94+
95+
if (fileCountIssue) {
96+
message += `• File count: ${session.fileCount} files (limit: ${config.maxFileCount})\n`;
97+
}
4398

44-
// TODO: Implement error handling
45-
// - Reset counters
46-
// - Log error statistics
99+
if (sizeIssue) {
100+
const sizeMB = (session.totalSize / 1024 / 1024).toFixed(2);
101+
const limitMB = (config.maxTotalSize / 1024 / 1024).toFixed(2);
102+
message += `• Total size: ${sizeMB}MB (limit: ${limitMB}MB)\n`;
47103
}
104+
105+
message += '\nPlease reduce the number of files or total size and try again.';
106+
107+
const popup = new CurateUi.modals.curatePopup(
108+
{
109+
title: 'Upload Volume Limit Exceeded',
110+
message: message,
111+
type: 'error',
112+
buttonType: 'close'
113+
},
114+
{
115+
afterLoaded: () => {
116+
console.log('UploadVolumeChecker: Blocking modal displayed');
117+
},
118+
afterClosed: () => {
119+
console.log('UploadVolumeChecker: Blocking modal closed');
120+
// Reset session after user acknowledges
121+
this.resetSession();
122+
}
123+
}
124+
);
125+
126+
popup.fire();
127+
},
128+
129+
// Show warning modal when approaching limits
130+
showWarningModal: function(session, config) {
131+
const fileCountWarning = session.fileCount > config.warningFileCount;
132+
const sizeWarning = session.totalSize > config.warningTotalSize;
133+
134+
let message = 'Upload volume warning:\n\n';
135+
136+
if (fileCountWarning) {
137+
message += `• File count: ${session.fileCount} files (warning threshold: ${config.warningFileCount})\n`;
138+
}
139+
140+
if (sizeWarning) {
141+
const sizeMB = (session.totalSize / 1024 / 1024).toFixed(2);
142+
const warnMB = (config.warningTotalSize / 1024 / 1024).toFixed(2);
143+
message += `• Total size: ${sizeMB}MB (warning threshold: ${warnMB}MB)\n`;
144+
}
145+
146+
message += '\nConsider breaking this into smaller uploads for better performance.';
147+
148+
const popup = new CurateUi.modals.curatePopup(
149+
{
150+
title: 'Large Upload Volume Detected',
151+
message: message,
152+
type: 'warning',
153+
buttonType: 'close'
154+
},
155+
{
156+
afterLoaded: () => {
157+
console.log('UploadVolumeChecker: Warning modal displayed');
158+
},
159+
afterClosed: () => {
160+
console.log('UploadVolumeChecker: Warning modal closed');
161+
}
162+
}
163+
);
164+
165+
popup.fire();
166+
},
167+
168+
// Reset the current upload session
169+
resetSession: function() {
170+
this.currentUploadSession = {
171+
fileCount: 0,
172+
totalSize: 0,
173+
files: [],
174+
isBlocked: false,
175+
};
176+
console.log('UploadVolumeChecker: Session reset');
177+
},
178+
179+
// Get current session statistics
180+
getSessionStats: function() {
181+
return {
182+
...this.currentUploadSession,
183+
totalSizeMB: (this.currentUploadSession.totalSize / 1024 / 1024).toFixed(2)
184+
};
48185
}
49186
};

0 commit comments

Comments
 (0)