@@ -15,8 +15,9 @@ const port = process.env.PORT || 3000;
15
15
const uploadDir = './uploads' ; // Local development
16
16
const maxFileSize = parseInt ( process . env . MAX_FILE_SIZE || '1024' ) * 1024 * 1024 ; // Convert MB to bytes
17
17
const APPRISE_URL = process . env . APPRISE_URL ;
18
- const APPRISE_MESSAGE = process . env . APPRISE_MESSAGE || 'File uploaded: {filename}' ;
18
+ const APPRISE_MESSAGE = process . env . APPRISE_MESSAGE || 'New file uploaded - {filename} ({size}), Storage used: {storage }' ;
19
19
const siteTitle = process . env . DUMBDROP_TITLE || 'DumbDrop' ;
20
+ const APPRISE_SIZE_UNIT = process . env . APPRISE_SIZE_UNIT ;
20
21
21
22
// Brute force protection setup
22
23
const loginAttempts = new Map ( ) ; // Stores IP addresses and their attempt counts
@@ -259,7 +260,7 @@ app.post('/upload/init', async (req, res) => {
259
260
app . post ( '/upload/chunk/:uploadId' , express . raw ( {
260
261
limit : '10mb' ,
261
262
type : 'application/octet-stream'
262
- } ) , ( req , res ) => {
263
+ } ) , async ( req , res ) => {
263
264
const { uploadId } = req . params ;
264
265
const upload = uploads . get ( uploadId ) ;
265
266
const chunkSize = req . body . length ;
@@ -273,7 +274,7 @@ app.post('/upload/chunk/:uploadId', express.raw({
273
274
upload . bytesReceived += chunkSize ;
274
275
275
276
const progress = Math . round ( ( upload . bytesReceived / upload . fileSize ) * 100 ) ;
276
- log . info ( `Received chunk for ${ upload . filename } : ${ progress } %` ) ;
277
+ log . info ( `Received chunk for ${ upload . safeFilename } : ${ progress } %` ) ;
277
278
278
279
res . json ( {
279
280
bytesReceived : upload . bytesReceived ,
@@ -284,10 +285,10 @@ app.post('/upload/chunk/:uploadId', express.raw({
284
285
if ( upload . bytesReceived >= upload . fileSize ) {
285
286
upload . writeStream . end ( ) ;
286
287
uploads . delete ( uploadId ) ;
287
- log . success ( `Upload completed: ${ upload . filename } ` ) ;
288
+ log . success ( `Upload completed: ${ upload . safeFilename } ` ) ;
288
289
289
- // Add notification here
290
- sendNotification ( upload . filename ) ;
290
+ // Update notification call to use safeFilename
291
+ await sendNotification ( upload . safeFilename , upload . fileSize ) ;
291
292
}
292
293
} catch ( err ) {
293
294
log . error ( `Chunk upload failed: ${ err . message } ` ) ;
@@ -305,7 +306,7 @@ app.post('/upload/cancel/:uploadId', (req, res) => {
305
306
if ( err ) log . error ( `Failed to delete incomplete upload: ${ err . message } ` ) ;
306
307
} ) ;
307
308
uploads . delete ( uploadId ) ;
308
- log . info ( `Upload cancelled: ${ upload . filename } ` ) ;
309
+ log . info ( `Upload cancelled: ${ upload . safeFilename } ` ) ;
309
310
}
310
311
311
312
res . json ( { message : 'Upload cancelled' } ) ;
@@ -346,16 +347,63 @@ app.listen(port, () => {
346
347
}
347
348
} ) ;
348
349
349
- // Add this helper function after other helper functions
350
- async function sendNotification ( filename ) {
350
+ // Remove async from formatFileSize function
351
+ function formatFileSize ( bytes ) {
352
+ const units = [ 'B' , 'KB' , 'MB' , 'GB' , 'TB' ] ;
353
+ let size = bytes ;
354
+ let unitIndex = 0 ;
355
+
356
+ // If a specific unit is requested
357
+ if ( APPRISE_SIZE_UNIT ) {
358
+ const requestedUnit = APPRISE_SIZE_UNIT . toUpperCase ( ) ;
359
+ const unitIndex = units . indexOf ( requestedUnit ) ;
360
+ if ( unitIndex !== - 1 ) {
361
+ size = bytes / Math . pow ( 1024 , unitIndex ) ;
362
+ return size . toFixed ( 2 ) + requestedUnit ;
363
+ }
364
+ }
365
+
366
+ // Auto format to nearest unit
367
+ while ( size >= 1024 && unitIndex < units . length - 1 ) {
368
+ size /= 1024 ;
369
+ unitIndex ++ ;
370
+ }
371
+
372
+ // Round to 2 decimal places
373
+ return size . toFixed ( 2 ) + units [ unitIndex ] ;
374
+ }
375
+
376
+ // Add this helper function
377
+ function calculateDirectorySize ( directoryPath ) {
378
+ let totalSize = 0 ;
379
+ const files = fs . readdirSync ( directoryPath ) ;
380
+
381
+ files . forEach ( file => {
382
+ const filePath = path . join ( directoryPath , file ) ;
383
+ const stats = fs . statSync ( filePath ) ;
384
+ if ( stats . isFile ( ) ) {
385
+ totalSize += stats . size ;
386
+ }
387
+ } ) ;
388
+
389
+ return totalSize ;
390
+ }
391
+
392
+ // Modify the sendNotification function
393
+ async function sendNotification ( filename , fileSize ) {
351
394
if ( ! APPRISE_URL ) return ;
352
395
353
396
try {
354
- const message = APPRISE_MESSAGE . replace ( '{filename}' , filename ) ;
397
+ const formattedSize = formatFileSize ( fileSize ) ;
398
+ const totalStorage = formatFileSize ( calculateDirectorySize ( uploadDir ) ) ;
399
+ const message = APPRISE_MESSAGE
400
+ . replace ( '{filename}' , filename )
401
+ . replace ( '{size}' , formattedSize )
402
+ . replace ( '{storage}' , totalStorage ) ;
355
403
356
404
// Execute apprise command
357
405
await execAsync ( `apprise "${ APPRISE_URL } " -b "${ message } "` ) ;
358
- log . info ( `Notification sent for: ${ filename } ` ) ;
406
+ log . info ( `Notification sent for: ${ filename } ( ${ formattedSize } , Total storage: ${ totalStorage } ) ` ) ;
359
407
} catch ( err ) {
360
408
log . error ( `Failed to send notification: ${ err . message } ` ) ;
361
409
}
0 commit comments