diff --git a/libs/monitor/utils.js b/libs/monitor/utils.js index 3f2c5cbd..b0d95501 100644 --- a/libs/monitor/utils.js +++ b/libs/monitor/utils.js @@ -582,7 +582,7 @@ module.exports = (s,config,lang) => { const binDir = s.dir.fileBin + `${groupKey}/${monitorId}` // videos and addStorage - await adjustSpaceCounterForTableWithAddStorage('Timelapse Frames','timelapeFrames') + await adjustSpaceCounterForTableWithAddStorage('Timelapse Frames','timelapseFrames') await adjustSpaceCounterForTableWithAddStorage('Videos') await deleteFromTable('Videos') await deletePath(videosDir) @@ -594,7 +594,7 @@ module.exports = (s,config,lang) => { } // timelapse frames - await adjustSpaceCounter('Timelapse Frames','timelapeFrames') + await adjustSpaceCounter('Timelapse Frames','timelapseFrames') await deleteFromTable('Timelapse Frames') await deletePath(videosDir + '_timelapse') diff --git a/libs/startup.js b/libs/startup.js index 91e66187..660ec1c1 100644 --- a/libs/startup.js +++ b/libs/startup.js @@ -172,7 +172,7 @@ module.exports = function(s,config,lang,io){ var addStorageData = { files: [], videos: [], - timelapeFrames: [], + timelapseFrames: [], } if(videos && videos[0]){ videos.forEach(function(video){ @@ -190,7 +190,7 @@ module.exports = function(s,config,lang,io){ if(!frame.details.dir){ usedSpaceTimelapseFrames += frame.size }else{ - addStorageData.timelapeFrames.push(frame) + addStorageData.timelapseFrames.push(frame) } }) } @@ -315,6 +315,8 @@ module.exports = function(s,config,lang,io){ storageIndex.path = path storageIndex.usedSpace = 0 storageIndex.sizeLimit = parseFloat(storageData.limit) || parseFloat(userDetails.size) || 10000 + storageIndex.videoPercent = parseFloat(storageData.videoPercent) || parseFloat(userDetails.size_video_percent) || 95 + storageIndex.timelapsePercent = parseFloat(storageData.timelapsePercent) || parseFloat(userDetails.size_timelapse_percent) || 5 var usedSpaceVideos = 0 var usedSpaceTimelapseFrames = 0 var usedSpaceFilebin = 0 @@ -327,7 +329,7 @@ module.exports = function(s,config,lang,io){ } if(timelapseFrames && timelapseFrames[0]){ timelapseFrames.forEach(function(frame){ - if(video.details.dir === storage.value){ + if(frame.details.dir === storage.value){ usedSpaceTimelapseFrames += frame.size } }) diff --git a/libs/timelapse.js b/libs/timelapse.js index ef1613e6..5e72be1f 100644 --- a/libs/timelapse.js +++ b/libs/timelapse.js @@ -65,12 +65,25 @@ module.exports = function(s,config,lang,app,io){ } } s.insertTimelapseFrameDatabaseRow = function(e,queryInfo,filePath){ + const groupKey = e.ke + const theGroup = s.group[groupKey] + const frameDetails = Object.assign({},s.parseJSON(queryInfo.details) || {}) + const storageId = e.details.dir + const storageIndex = theGroup.addStorageUse[storageId] + const fileSize = queryInfo.size / 1048576 s.knexQuery({ action: "insert", table: "Timelapse Frames", insert: queryInfo }) - s.setDiskUsedForGroup(e.ke,queryInfo.size / 1048576,'timelapeFrames') + if(storageIndex){ + s.setDiskUsedForGroupAddStorage(groupKey,{ + size: fileSize, + storageIndex: storageIndex + },'timelapseFrames') + }else{ + s.setDiskUsedForGroup(groupKey, fileSize, 'timelapseFrames') + } s.purgeDiskForGroup(e.ke) s.onInsertTimelapseFrameExtensions.forEach(function(extender){ extender(e,queryInfo,filePath) @@ -149,7 +162,7 @@ module.exports = function(s,config,lang,app,io){ where: frameSelector, limit: 1 },async function(){ - s.setDiskUsedForGroup(e.ke,-(r.size / 1048576),'timelapeFrames') + s.setDiskUsedForGroup(e.ke,-(r.size / 1048576),'timelapseFrames') s.file('delete',e.fileLocation) const fileDirectory = getFileDirectory(folderPath); const folderIsEmpty = (await fs.promises.readdir(folderPath)).filter(file => file.indexOf('.jpg') > -1).length === 0; diff --git a/libs/user.js b/libs/user.js index 46e86f37..ea580253 100644 --- a/libs/user.js +++ b/libs/user.js @@ -12,6 +12,7 @@ module.exports = function(s,config,lang){ deleteAddStorageVideos, deleteMainVideos, deleteTimelapseFrames, + deleteAddStorageTimelapseFrames, deleteFileBinFiles, deleteCloudVideos, deleteCloudTimelapseFrames, @@ -30,13 +31,16 @@ module.exports = function(s,config,lang){ deleteMainVideos(groupKey,() => { s.debugLog(`${groupKey} deleteTimelapseFrames`) deleteTimelapseFrames(groupKey,() => { - s.debugLog(`${groupKey} deleteFileBinFiles`) - deleteFileBinFiles(groupKey,() => { - s.debugLog(`${groupKey} deleteAddStorageVideos`) - deleteAddStorageVideos(groupKey,() => { - s.group[groupKey].sizePurging = false - s.sendDiskUsedAmountToClients(groupKey) - callback(); + s.debugLog(`${groupKey} deleteAddStorageTimelapseFrames`) + deleteAddStorageTimelapseFrames(groupKey,() => { + s.debugLog(`${groupKey} deleteFileBinFiles`) + deleteFileBinFiles(groupKey,() => { + s.debugLog(`${groupKey} deleteAddStorageVideos`) + deleteAddStorageVideos(groupKey,() => { + s.group[groupKey].sizePurging = false + s.sendDiskUsedAmountToClients(groupKey) + callback(); + }) }) }) }) @@ -190,7 +194,7 @@ module.exports = function(s,config,lang){ //change global size value cloudDisk.usedSpace = cloudDisk.usedSpace + amount switch(storagePoint){ - case'timelapeFrames': + case'timelapseFrames': cloudDisk.usedSpaceTimelapseFrames += amount break; case'fileBin': @@ -225,7 +229,7 @@ module.exports = function(s,config,lang){ s.group[e.ke].usedSpace += currentChange s.group[e.ke].usedSpace = s.group[e.ke].usedSpace < 0 ? 0 : s.group[e.ke].usedSpace switch(storageType){ - case'timelapeFrames': + case'timelapseFrames': s.group[e.ke].usedSpaceTimelapseFrames += currentChange s.group[e.ke].usedSpaceTimelapseFrames = s.group[e.ke].usedSpaceTimelapseFrames < 0 ? 0 : s.group[e.ke].usedSpaceTimelapseFrames break; @@ -256,7 +260,7 @@ module.exports = function(s,config,lang){ //change global size value storageIndex.usedSpace += currentSize switch(storageType){ - case'timelapeFrames': + case'timelapseFrames': storageIndex.usedSpaceTimelapseFrames += currentSize break; case'fileBin': @@ -342,6 +346,7 @@ module.exports = function(s,config,lang){ if(details.size){formDetails.size = details.size;} if(details.days){formDetails.days = details.days;} } + const theGroup = s.group[d.ke] var newSize = parseFloat(formDetails.size) || 10000 //load addStorageUse var currentStorageNumber = 0 @@ -365,11 +370,10 @@ module.exports = function(s,config,lang){ storageIndex.name = storage.name storageIndex.path = path storageIndex.usedSpace = storageIndex.usedSpace || 0 - if(detailsContainerAddStorage && detailsContainerAddStorage[path] && detailsContainerAddStorage[path].limit){ - storageIndex.sizeLimit = parseFloat(detailsContainerAddStorage[path].limit) - }else{ - storageIndex.sizeLimit = newSize - } + const storageInfoToSave = detailsContainerAddStorage && detailsContainerAddStorage[path] ? detailsContainerAddStorage[path] : {} + storageIndex.sizeLimit = parseFloat(storageInfoToSave.limit) || newSize + storageIndex.videoPercent = parseFloat(storageInfoToSave.videoPercent) || theGroup.sizeLimitVideoPercent + storageIndex.timelapsePercent = parseFloat(storageInfoToSave.timelapsePercent) || theGroup.sizeLimitTimelapseFramesPercent } readStorageArray() /// diff --git a/libs/user/utils.js b/libs/user/utils.js index 2cfb0df0..10f9a253 100644 --- a/libs/user/utils.js +++ b/libs/user/utils.js @@ -92,13 +92,6 @@ module.exports = (s,config,lang) => { whereGroup.push(queryGroup) fs.rm(fileLocationMid,function(err){ ++completedCheck - if(err){ - fs.stat(fileLocationMid,function(err){ - if(!err){ - fs.unlink(fileLocationMid) - } - }) - } const whereGroupLength = whereGroup.length if(whereGroupLength > 0 && whereGroupLength === completedCheck){ whereQuery[1] = whereGroup @@ -115,9 +108,9 @@ module.exports = (s,config,lang) => { s.setDiskUsedForGroupAddStorage(groupKey,{ size: -(frame.size/1048576), storageIndex: storageIndex - },'timelapeFrames') + },'timelapseFrames') }else{ - s.setDiskUsedForGroup(groupKey,-(frame.size/1048576),'timelapeFrames') + s.setDiskUsedForGroup(groupKey,-(frame.size/1048576),'timelapseFrames') } // s.tx({ // f: 'timelapse_frame_delete', @@ -193,7 +186,8 @@ module.exports = (s,config,lang) => { return deleteAddStorageVideos(groupKey,callback) } var currentStorageNumber = 0 - var readStorageArray = function(){ + function readStorageArray(){ + const theGroup = s.group[groupKey] setTimeout(function(){ reRunCheck = readStorageArray var storage = s.listOfStorage[currentStorageNumber] @@ -203,14 +197,15 @@ module.exports = (s,config,lang) => { return } var storageId = storage.value - if(storageId === '' || !s.group[groupKey].addStorageUse[storageId]){ + if(storageId === '' || !theGroup.addStorageUse[storageId]){ ++currentStorageNumber readStorageArray() return } - var storageIndex = s.group[groupKey].addStorageUse[storageId] + var storageIndex = theGroup.addStorageUse[storageId] //run purge command - if(storageIndex.usedSpace > (storageIndex.sizeLimit * (storageIndex.deleteOffset || config.cron.deleteOverMaxOffset))){ + const maxSize = (storageIndex.sizeLimit * (storageIndex.videoPercent / 100) * config.cron.deleteOverMaxOffset); + if(storageIndex.usedSpaceVideos > maxSize){ s.knexQuery({ action: "select", columns: "*", @@ -242,19 +237,62 @@ module.exports = (s,config,lang) => { } readStorageArray() } + const deleteAddStorageTimelapseFrames = function(groupKey,callback){ + const theGroup = s.group[groupKey] + reRunCheck = function(){ + s.debugLog('deleteAddStorageTimelapseFrames') + return deleteAddStorageTimelapseFrames(groupKey,callback) + } + var currentStorageNumber = 0 + function readStorageArray(){ + setTimeout(function(){ + reRunCheck = readStorageArray + var storage = s.listOfStorage[currentStorageNumber] + if(!storage){ + //done all checks, move on to next user + callback() + return + } + var storageId = storage.value + if(storageId === '' || !theGroup.addStorageUse[storageId]){ + ++currentStorageNumber + readStorageArray() + return + } + var storageIndex = theGroup.addStorageUse[storageId] + //run purge command + const maxSize = (storageIndex.sizeLimit * (storageIndex.timelapsePercent / 100) * config.cron.deleteOverMaxOffset); + if(storageIndex.usedSpaceTimelapseFrames > maxSize){ + s.knexQuery({ + action: "select", + columns: "*", + table: "Timelapse Frames", + where: [ + ['ke','=',groupKey], + ['details','LIKE',`%"dir":"${storage.value}"%`], + ], + orderBy: ['time','asc'], + limit: 3 + },(err,frames) => { + deleteSetOfTimelapseFrames({ + groupKey: groupKey, + err: err, + frames: frames, + storageIndex: storageIndex, + reRunCheck: () => { + return readStorageArray() + } + },callback) + }) + }else{ + ++currentStorageNumber + readStorageArray() + } + }) + } + readStorageArray() + } const deleteMainVideos = function(groupKey,callback){ - // //run purge command - // s.debugLog('!!!!!!!!!!!deleteMainVideos') - // s.debugLog('s.group[groupKey].usedSpaceVideos > (s.group[groupKey].sizeLimit * (s.group[groupKey].sizeLimitVideoPercent / 100) * config.cron.deleteOverMaxOffset)') - // s.debugLog(s.group[groupKey].usedSpaceVideos > (s.group[groupKey].sizeLimit * (s.group[groupKey].sizeLimitVideoPercent / 100) * config.cron.deleteOverMaxOffset)) - // s.debugLog('s.group[groupKey].usedSpaceVideos') - // s.debugLog(s.group[groupKey].usedSpaceVideos) - // s.debugLog('s.group[groupKey].sizeLimit * (s.group[groupKey].sizeLimitVideoPercent / 100) * config.cron.deleteOverMaxOffset') - // s.debugLog(s.group[groupKey].sizeLimit * (s.group[groupKey].sizeLimitVideoPercent / 100) * config.cron.deleteOverMaxOffset) - // s.debugLog('s.group[groupKey].sizeLimitVideoPercent / 100') - // s.debugLog(s.group[groupKey].sizeLimitVideoPercent / 100) - // s.debugLog('s.group[groupKey].sizeLimit') - // s.debugLog(s.group[groupKey].sizeLimit) if(s.group[groupKey].usedSpaceVideos > (s.group[groupKey].sizeLimit * (s.group[groupKey].sizeLimitVideoPercent / 100) * config.cron.deleteOverMaxOffset)){ s.knexQuery({ action: "select", @@ -295,7 +333,7 @@ module.exports = (s,config,lang) => { table: "Timelapse Frames", where: [ ['ke','=',groupKey], - ['archive','!=',`1`], + ['details','NOT LIKE',`%"dir"%`], ], orderBy: ['time','asc'], limit: 3 @@ -508,6 +546,7 @@ module.exports = (s,config,lang) => { deleteAddStorageVideos: deleteAddStorageVideos, deleteMainVideos: deleteMainVideos, deleteTimelapseFrames: deleteTimelapseFrames, + deleteAddStorageTimelapseFrames, deleteFileBinFiles: deleteFileBinFiles, deleteCloudVideos: deleteCloudVideos, deleteCloudTimelapseFrames: deleteCloudTimelapseFrames, diff --git a/web/assets/js/bs5.accountSettings.js b/web/assets/js/bs5.accountSettings.js index b77ea736..0afc888c 100644 --- a/web/assets/js/bs5.accountSettings.js +++ b/web/assets/js/bs5.accountSettings.js @@ -10,14 +10,22 @@ $(document).ready(function(){ var addStorageData = JSON.parse($user.details.addStorage || '{}') var html = '' $.each(addStorage,function(n,storage){ - var limit = "" - if(addStorageData[storage.path] && addStorageData[storage.path].limit){ - limit = addStorageData[storage.path].limit - } - html += `
-
${lang['Max Storage Amount']} : ${storage.name}
-
-
` + var theStorage = addStorageData[storage.path] + html += ` +
+
+
${lang['Max Storage Amount']} : ${storage.name}
+
+
+
+
${lang["Video Share"]} : ${storage.name}
+
+
+
+
${lang["Timelapse Frames Share"]} : ${storage.name}
+
+
+
` }) addStorageMaxAmounts.html(html) }catch(err){ @@ -35,20 +43,25 @@ $(document).ready(function(){ extender(theForm) }) } - addStorageMaxAmounts.on('change','[addStorageLimit]',function(){ + function getAddStorageFields(){ var json = {} $.each(addStorage,function(n,storage){ var storageId = storage.path - var el = addStorageMaxAmounts.find('[addStorageLimit="' + storageId + '"]') - var value = el.val() + var miniContainer = addStorageMaxAmounts.find(`[addStorageFields="${storageId}"]`) + var fields = miniContainer.find('[addStorageItem]') json[storageId] = { name: storage.name, path: storage.path, - limit: value } + $.each(fields,function(n,el){ + var field = $(el) + var keyName = field.attr('addStorageItem') + var value = field.val() + json[storageId][keyName] = value + }) }) - addStorageMaxAmountsField.val(JSON.stringify(json)) - }) + return json + } $('body') theForm.find('[detail]').change(onDetailFieldChange) theForm.find('[detail]').change(function(){ @@ -77,6 +90,7 @@ $(document).ready(function(){ }) var details = getDetailValues(theForm) formData.details = details + formData.details.addStorage = getAddStorageFields() accountSettings.onSaveFieldsExtensions.forEach(function(extender){ extender(formData) }) diff --git a/web/assets/js/bs5.dashboard-base.js b/web/assets/js/bs5.dashboard-base.js index 3ed40b4c..7ba5d49a 100644 --- a/web/assets/js/bs5.dashboard-base.js +++ b/web/assets/js/bs5.dashboard-base.js @@ -911,9 +911,13 @@ function drawIndicatorBar(item){
-
+ ${!item.multiple ? `
-
+
` : `
+
+
+
+
`}
` diff --git a/web/assets/js/bs5.startup.js b/web/assets/js/bs5.startup.js index 6da77bc4..87c3b5b2 100644 --- a/web/assets/js/bs5.startup.js +++ b/web/assets/js/bs5.startup.js @@ -91,6 +91,7 @@ function loadBoxWrappers() { function drawAddStorageIndicators(){ $.each(addStorage,function(n,storage){ drawIndicatorBar({ + multiple: true, icon: 'hdd-o', name: storage.name, label: `${storage.name} : `, @@ -199,16 +200,25 @@ onWebSocketEvent(function (d){ diskIndicatorBar[2].title = `${lang['FileBin Share']} : ${fileBinPercent}` if(d.addStorage){ $.each(d.addStorage,function(n,storage){ - var percent = parseInt((storage.usedSpace/storage.sizeLimit)*100)+'%' + var diskIndicator = loadedIndicators[storage.name] + var diskIndicatorBars = diskIndicator.progressBar + var diskLimit = storage.sizeLimit + var percent = parseDiskUsePercent(storage.usedSpace,diskLimit); + var videosPercent = parseDiskUsePercent(storage.usedSpaceVideos,diskLimit); + var timelapsePercent = parseDiskUsePercent(storage.usedSpaceTimelapseFrames,diskLimit); + // var humanValue = parseFloat(storage.usedSpace) if(humanValue > 1000){ humanValue = (humanValue/1000).toFixed(2)+' GB' }else{ humanValue = humanValue.toFixed(2)+' MB' } - loadedIndicators[storage.name].value.html(humanValue) - loadedIndicators[storage.name].percent.html(percent) - loadedIndicators[storage.name].progressBar.css('width',percent) + diskIndicator.value.html(humanValue) + diskIndicator.percent.html(percent) + diskIndicatorBars[0].style.width = videosPercent + diskIndicatorBars[0].title = `${lang['Video Share']} : ${videosPercent}` + diskIndicatorBars[1].style.width = timelapsePercent + diskIndicatorBars[1].title = `${lang['Timelapse Frames Share']} : ${timelapsePercent}` }) } break;