mirror of
https://github.com/BobbyWibowo/lolisafe.git
synced 2025-02-21 12:49:07 +00:00
fix: systeminformation v5 breaking changes
Made the codes for stats generation a bit more readable. Usage percentage for file systems will now properly reflect "non-root" usage percentage in ext2/3/4 file systems.
This commit is contained in:
parent
51c9cd2ff4
commit
968494bb37
@ -647,270 +647,287 @@ self.stats = async (req, res, next) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const os = await si.osInfo()
|
const os = await si.osInfo()
|
||||||
await Promise.all([
|
|
||||||
(async () => {
|
|
||||||
// System info
|
|
||||||
const data = statsData.system
|
|
||||||
|
|
||||||
if (!data.cache && data.generating) {
|
const getSystemInfo = async () => {
|
||||||
stats[data.title] = false
|
const data = statsData.system
|
||||||
} else if (((Date.now() - data.generatedAt) <= 1000) || data.generating) {
|
|
||||||
// Use cache for 1000 ms (1 second)
|
|
||||||
stats[data.title] = data.cache
|
|
||||||
} else {
|
|
||||||
data.generating = true
|
|
||||||
data.generatedAt = Date.now()
|
|
||||||
|
|
||||||
const currentLoad = await si.currentLoad()
|
if (!data.cache && data.generating) {
|
||||||
const mem = await si.mem()
|
stats[data.title] = false
|
||||||
const time = si.time()
|
} else if (((Date.now() - data.generatedAt) <= 1000) || data.generating) {
|
||||||
const nodeUptime = process.uptime()
|
// Use cache for 1000 ms (1 second)
|
||||||
|
stats[data.title] = data.cache
|
||||||
|
} else {
|
||||||
|
data.generating = true
|
||||||
|
data.generatedAt = Date.now()
|
||||||
|
|
||||||
if (self.clamscan.instance) {
|
const currentLoad = await si.currentLoad()
|
||||||
try {
|
const mem = await si.mem()
|
||||||
self.clamscan.version = await self.clamscan.instance.get_version().then(s => s.trim())
|
const time = si.time()
|
||||||
} catch (error) {
|
const nodeUptime = process.uptime()
|
||||||
logger.error(error)
|
|
||||||
self.clamscan.version = 'Errored when querying version.'
|
if (self.clamscan.instance) {
|
||||||
}
|
try {
|
||||||
|
self.clamscan.version = await self.clamscan.instance.get_version().then(s => s.trim())
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(error)
|
||||||
|
self.clamscan.version = 'Errored when querying version.'
|
||||||
}
|
}
|
||||||
|
|
||||||
stats[data.title] = {
|
|
||||||
Platform: `${os.platform} ${os.arch}`,
|
|
||||||
Distro: `${os.distro} ${os.release}`,
|
|
||||||
Kernel: os.kernel,
|
|
||||||
Scanner: self.clamscan.version || 'N/A',
|
|
||||||
'CPU Load': `${currentLoad.currentload.toFixed(1)}%`,
|
|
||||||
'CPUs Load': currentLoad.cpus.map(cpu => `${cpu.load.toFixed(1)}%`).join(', '),
|
|
||||||
'System Memory': {
|
|
||||||
value: {
|
|
||||||
used: mem.active,
|
|
||||||
total: mem.total
|
|
||||||
},
|
|
||||||
type: 'byteUsage'
|
|
||||||
},
|
|
||||||
'Memory Usage': {
|
|
||||||
value: process.memoryUsage().rss,
|
|
||||||
type: 'byte'
|
|
||||||
},
|
|
||||||
'System Uptime': {
|
|
||||||
value: time.uptime,
|
|
||||||
type: 'uptime'
|
|
||||||
},
|
|
||||||
'Node.js': `${process.versions.node}`,
|
|
||||||
'Service Uptime': {
|
|
||||||
value: Math.floor(nodeUptime),
|
|
||||||
type: 'uptime'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update cache
|
|
||||||
data.cache = stats[data.title]
|
|
||||||
data.generating = false
|
|
||||||
}
|
}
|
||||||
})(),
|
|
||||||
(async () => {
|
|
||||||
// File systems
|
|
||||||
const data = statsData.fileSystems
|
|
||||||
|
|
||||||
if (!data.cache && data.generating) {
|
stats[data.title] = {
|
||||||
stats[data.title] = false
|
Platform: `${os.platform} ${os.arch}`,
|
||||||
} else if (((Date.now() - data.generatedAt) <= 60000) || data.generating) {
|
Distro: `${os.distro} ${os.release}`,
|
||||||
// Use cache for 60000 ms (60 seconds)
|
Kernel: os.kernel,
|
||||||
stats[data.title] = data.cache
|
Scanner: self.clamscan.version || 'N/A',
|
||||||
} else {
|
'CPU Load': `${currentLoad.currentLoad.toFixed(1)}%`,
|
||||||
data.generating = true
|
'CPUs Load': currentLoad.cpus.map(cpu => `${cpu.load.toFixed(1)}%`).join(', '),
|
||||||
data.generatedAt = Date.now()
|
'System Memory': {
|
||||||
|
value: {
|
||||||
stats[data.title] = {}
|
used: mem.active,
|
||||||
|
total: mem.total
|
||||||
const fsSize = await si.fsSize()
|
},
|
||||||
for (const fs of fsSize) {
|
type: 'byteUsage'
|
||||||
stats[data.title][`${fs.fs} (${fs.type}) on ${fs.mount}`] = {
|
},
|
||||||
value: {
|
'Memory Usage': {
|
||||||
total: fs.size,
|
value: process.memoryUsage().rss,
|
||||||
used: fs.used
|
type: 'byte'
|
||||||
},
|
},
|
||||||
type: 'byteUsage'
|
'System Uptime': {
|
||||||
}
|
value: time.uptime,
|
||||||
|
type: 'uptime'
|
||||||
|
},
|
||||||
|
'Node.js': `${process.versions.node}`,
|
||||||
|
'Service Uptime': {
|
||||||
|
value: Math.floor(nodeUptime),
|
||||||
|
type: 'uptime'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update cache
|
|
||||||
data.cache = stats[data.title]
|
|
||||||
data.generating = false
|
|
||||||
}
|
}
|
||||||
})(),
|
|
||||||
(async () => {
|
|
||||||
// Uploads
|
|
||||||
const data = statsData.uploads
|
|
||||||
|
|
||||||
if (!data.cache && data.generating) {
|
// Update cache
|
||||||
stats[data.title] = false
|
data.cache = stats[data.title]
|
||||||
} else if (data.cache) {
|
data.generating = false
|
||||||
// Cache will be invalidated with self.invalidateStatsCache() after any related operations
|
}
|
||||||
stats[data.title] = data.cache
|
}
|
||||||
} else {
|
|
||||||
data.generating = true
|
|
||||||
data.generatedAt = Date.now()
|
|
||||||
|
|
||||||
stats[data.title] = {
|
const getFileSystems = async () => {
|
||||||
Total: 0,
|
const data = statsData.fileSystems
|
||||||
Images: 0,
|
|
||||||
Videos: 0,
|
if (!data.cache && data.generating) {
|
||||||
Audios: 0,
|
stats[data.title] = false
|
||||||
Others: 0,
|
} else if (((Date.now() - data.generatedAt) <= 60000) || data.generating) {
|
||||||
Temporary: 0,
|
// Use cache for 60000 ms (60 seconds)
|
||||||
'Size in DB': {
|
stats[data.title] = data.cache
|
||||||
value: 0,
|
} else {
|
||||||
type: 'byte'
|
data.generating = true
|
||||||
}
|
data.generatedAt = Date.now()
|
||||||
|
|
||||||
|
stats[data.title] = {}
|
||||||
|
|
||||||
|
const fsSize = await si.fsSize()
|
||||||
|
for (const fs of fsSize) {
|
||||||
|
stats[data.title][`${fs.fs} (${fs.type}) on ${fs.mount}`] = {
|
||||||
|
value: {
|
||||||
|
total: fs.size,
|
||||||
|
used: fs.used,
|
||||||
|
available: fs.available
|
||||||
|
},
|
||||||
|
type: 'byteUsage'
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await Promise.all([
|
// Update cache
|
||||||
(async () => {
|
data.cache = stats[data.title]
|
||||||
const uploads = await db.table('files')
|
data.generating = false
|
||||||
.select('size')
|
}
|
||||||
stats[data.title].Total = uploads.length
|
}
|
||||||
stats[data.title]['Size in DB'].value = uploads.reduce((acc, upload) => acc + parseInt(upload.size), 0)
|
|
||||||
})(),
|
|
||||||
(async () => {
|
|
||||||
stats[data.title].Images = await db.table('files')
|
|
||||||
.where(function () {
|
|
||||||
for (const ext of self.imageExts) {
|
|
||||||
this.orWhere('name', 'like', `%${ext}`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.count('id as count')
|
|
||||||
.then(rows => rows[0].count)
|
|
||||||
})(),
|
|
||||||
(async () => {
|
|
||||||
stats[data.title].Videos = await db.table('files')
|
|
||||||
.where(function () {
|
|
||||||
for (const ext of self.videoExts) {
|
|
||||||
this.orWhere('name', 'like', `%${ext}`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.count('id as count')
|
|
||||||
.then(rows => rows[0].count)
|
|
||||||
})(),
|
|
||||||
(async () => {
|
|
||||||
stats[data.title].Audios = await db.table('files')
|
|
||||||
.where(function () {
|
|
||||||
for (const ext of self.audioExts) {
|
|
||||||
this.orWhere('name', 'like', `%${ext}`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.count('id as count')
|
|
||||||
.then(rows => rows[0].count)
|
|
||||||
})(),
|
|
||||||
(async () => {
|
|
||||||
stats[data.title].Temporary = await db.table('files')
|
|
||||||
.whereNotNull('expirydate')
|
|
||||||
.count('id as count')
|
|
||||||
.then(rows => rows[0].count)
|
|
||||||
})()
|
|
||||||
])
|
|
||||||
|
|
||||||
stats[data.title].Others = stats[data.title].Total -
|
const getUploadsStats = async () => {
|
||||||
|
const data = statsData.uploads
|
||||||
|
|
||||||
|
if (!data.cache && data.generating) {
|
||||||
|
stats[data.title] = false
|
||||||
|
} else if (data.cache) {
|
||||||
|
// Cache will be invalidated with self.invalidateStatsCache() after any related operations
|
||||||
|
stats[data.title] = data.cache
|
||||||
|
} else {
|
||||||
|
data.generating = true
|
||||||
|
data.generatedAt = Date.now()
|
||||||
|
|
||||||
|
stats[data.title] = {
|
||||||
|
Total: 0,
|
||||||
|
Images: 0,
|
||||||
|
Videos: 0,
|
||||||
|
Audios: 0,
|
||||||
|
Others: 0,
|
||||||
|
Temporary: 0,
|
||||||
|
'Size in DB': {
|
||||||
|
value: 0,
|
||||||
|
type: 'byte'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTotalCountAndSize = async () => {
|
||||||
|
const uploads = await db.table('files')
|
||||||
|
.select('size')
|
||||||
|
stats[data.title].Total = uploads.length
|
||||||
|
stats[data.title]['Size in DB'].value = uploads.reduce((acc, upload) => acc + parseInt(upload.size), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getImagesCount = async () => {
|
||||||
|
stats[data.title].Images = await db.table('files')
|
||||||
|
.where(function () {
|
||||||
|
for (const ext of self.imageExts) {
|
||||||
|
this.orWhere('name', 'like', `%${ext}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.count('id as count')
|
||||||
|
.then(rows => rows[0].count)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getVideosCount = async () => {
|
||||||
|
stats[data.title].Videos = await db.table('files')
|
||||||
|
.where(function () {
|
||||||
|
for (const ext of self.videoExts) {
|
||||||
|
this.orWhere('name', 'like', `%${ext}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.count('id as count')
|
||||||
|
.then(rows => rows[0].count)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getAudiosCount = async () => {
|
||||||
|
stats[data.title].Audios = await db.table('files')
|
||||||
|
.where(function () {
|
||||||
|
for (const ext of self.audioExts) {
|
||||||
|
this.orWhere('name', 'like', `%${ext}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.count('id as count')
|
||||||
|
.then(rows => rows[0].count)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getOthersCount = async () => {
|
||||||
|
stats[data.title].Temporary = await db.table('files')
|
||||||
|
.whereNotNull('expirydate')
|
||||||
|
.count('id as count')
|
||||||
|
.then(rows => rows[0].count)
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
getTotalCountAndSize(),
|
||||||
|
getImagesCount(),
|
||||||
|
getVideosCount(),
|
||||||
|
getAudiosCount(),
|
||||||
|
getOthersCount()
|
||||||
|
])
|
||||||
|
|
||||||
|
stats[data.title].Others = stats[data.title].Total -
|
||||||
stats[data.title].Images -
|
stats[data.title].Images -
|
||||||
stats[data.title].Videos -
|
stats[data.title].Videos -
|
||||||
stats[data.title].Audios
|
stats[data.title].Audios
|
||||||
|
|
||||||
// Update cache
|
// Update cache
|
||||||
data.cache = stats[data.title]
|
data.cache = stats[data.title]
|
||||||
data.generating = false
|
data.generating = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUsersStats = async () => {
|
||||||
|
const data = statsData.users
|
||||||
|
|
||||||
|
if (!data.cache && data.generating) {
|
||||||
|
stats[data.title] = false
|
||||||
|
} else if (data.cache) {
|
||||||
|
// Cache will be invalidated with self.invalidateStatsCache() after any related operations
|
||||||
|
stats[data.title] = data.cache
|
||||||
|
} else {
|
||||||
|
data.generating = true
|
||||||
|
data.generatedAt = Date.now()
|
||||||
|
|
||||||
|
stats[data.title] = {
|
||||||
|
Total: 0,
|
||||||
|
Disabled: 0
|
||||||
}
|
}
|
||||||
})(),
|
|
||||||
(async () => {
|
|
||||||
// Users
|
|
||||||
const data = statsData.users
|
|
||||||
|
|
||||||
if (!data.cache && data.generating) {
|
const permissionKeys = Object.keys(perms.permissions).reverse()
|
||||||
stats[data.title] = false
|
permissionKeys.forEach(p => {
|
||||||
} else if (data.cache) {
|
stats[data.title][p] = 0
|
||||||
// Cache will be invalidated with self.invalidateStatsCache() after any related operations
|
})
|
||||||
stats[data.title] = data.cache
|
|
||||||
} else {
|
|
||||||
data.generating = true
|
|
||||||
data.generatedAt = Date.now()
|
|
||||||
|
|
||||||
stats[data.title] = {
|
const users = await db.table('users')
|
||||||
Total: 0,
|
stats[data.title].Total = users.length
|
||||||
Disabled: 0
|
for (const user of users) {
|
||||||
|
if (user.enabled === false || user.enabled === 0) {
|
||||||
|
stats[data.title].Disabled++
|
||||||
}
|
}
|
||||||
|
|
||||||
const permissionKeys = Object.keys(perms.permissions).reverse()
|
user.permission = user.permission || 0
|
||||||
permissionKeys.forEach(p => {
|
for (const p of permissionKeys) {
|
||||||
stats[data.title][p] = 0
|
if (user.permission === perms.permissions[p]) {
|
||||||
})
|
stats[data.title][p]++
|
||||||
|
break
|
||||||
const users = await db.table('users')
|
|
||||||
stats[data.title].Total = users.length
|
|
||||||
for (const user of users) {
|
|
||||||
if (user.enabled === false || user.enabled === 0) {
|
|
||||||
stats[data.title].Disabled++
|
|
||||||
}
|
|
||||||
|
|
||||||
user.permission = user.permission || 0
|
|
||||||
for (const p of permissionKeys) {
|
|
||||||
if (user.permission === perms.permissions[p]) {
|
|
||||||
stats[data.title][p]++
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update cache
|
|
||||||
data.cache = stats[data.title]
|
|
||||||
data.generating = false
|
|
||||||
}
|
}
|
||||||
})(),
|
|
||||||
(async () => {
|
|
||||||
// Albums
|
|
||||||
const data = statsData.albums
|
|
||||||
|
|
||||||
if (!data.cache && data.generating) {
|
// Update cache
|
||||||
stats[data.title] = false
|
data.cache = stats[data.title]
|
||||||
} else if (data.cache) {
|
data.generating = false
|
||||||
// Cache will be invalidated with self.invalidateStatsCache() after any related operations
|
}
|
||||||
stats[data.title] = data.cache
|
}
|
||||||
} else {
|
|
||||||
data.generating = true
|
|
||||||
data.generatedAt = Date.now()
|
|
||||||
|
|
||||||
stats[data.title] = {
|
const getAlbumsStats = async () => {
|
||||||
Total: 0,
|
const data = statsData.albums
|
||||||
Disabled: 0,
|
|
||||||
Public: 0,
|
|
||||||
Downloadable: 0,
|
|
||||||
'ZIP Generated': 0
|
|
||||||
}
|
|
||||||
|
|
||||||
const albums = await db.table('albums')
|
if (!data.cache && data.generating) {
|
||||||
stats[data.title].Total = albums.length
|
stats[data.title] = false
|
||||||
|
} else if (data.cache) {
|
||||||
|
// Cache will be invalidated with self.invalidateStatsCache() after any related operations
|
||||||
|
stats[data.title] = data.cache
|
||||||
|
} else {
|
||||||
|
data.generating = true
|
||||||
|
data.generatedAt = Date.now()
|
||||||
|
|
||||||
const activeAlbums = []
|
stats[data.title] = {
|
||||||
for (const album of albums) {
|
Total: 0,
|
||||||
if (!album.enabled) {
|
Disabled: 0,
|
||||||
stats[data.title].Disabled++
|
Public: 0,
|
||||||
continue
|
Downloadable: 0,
|
||||||
}
|
'ZIP Generated': 0
|
||||||
activeAlbums.push(album.id)
|
|
||||||
if (album.download) stats[data.title].Downloadable++
|
|
||||||
if (album.public) stats[data.title].Public++
|
|
||||||
if (album.zipGeneratedAt) stats[data.title]['ZIP Generated']++
|
|
||||||
}
|
|
||||||
|
|
||||||
stats[data.title]['Files in albums'] = await db.table('files')
|
|
||||||
.whereIn('albumid', activeAlbums)
|
|
||||||
.count('id as count')
|
|
||||||
.then(rows => rows[0].count)
|
|
||||||
|
|
||||||
// Update cache
|
|
||||||
data.cache = stats[data.title]
|
|
||||||
data.generating = false
|
|
||||||
}
|
}
|
||||||
})()
|
|
||||||
|
const albums = await db.table('albums')
|
||||||
|
stats[data.title].Total = albums.length
|
||||||
|
|
||||||
|
const activeAlbums = []
|
||||||
|
for (const album of albums) {
|
||||||
|
if (!album.enabled) {
|
||||||
|
stats[data.title].Disabled++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
activeAlbums.push(album.id)
|
||||||
|
if (album.download) stats[data.title].Downloadable++
|
||||||
|
if (album.public) stats[data.title].Public++
|
||||||
|
if (album.zipGeneratedAt) stats[data.title]['ZIP Generated']++
|
||||||
|
}
|
||||||
|
|
||||||
|
stats[data.title]['Files in albums'] = await db.table('files')
|
||||||
|
.whereIn('albumid', activeAlbums)
|
||||||
|
.count('id as count')
|
||||||
|
.then(rows => rows[0].count)
|
||||||
|
|
||||||
|
// Update cache
|
||||||
|
data.cache = stats[data.title]
|
||||||
|
data.generating = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
getSystemInfo(),
|
||||||
|
getFileSystems(),
|
||||||
|
getUploadsStats(),
|
||||||
|
getUsersStats(),
|
||||||
|
getAlbumsStats()
|
||||||
])
|
])
|
||||||
|
|
||||||
return res.json({ success: true, stats, hrtime: process.hrtime(hrstart) })
|
return res.json({ success: true, stats, hrtime: process.hrtime(hrstart) })
|
||||||
|
@ -2934,9 +2934,14 @@ page.getStatistics = (params = {}) => {
|
|||||||
case 'byte':
|
case 'byte':
|
||||||
parsed = page.getPrettyBytes(value)
|
parsed = page.getPrettyBytes(value)
|
||||||
break
|
break
|
||||||
case 'byteUsage':
|
case 'byteUsage': {
|
||||||
parsed = `${page.getPrettyBytes(value.used)} / ${page.getPrettyBytes(value.total)} (${(value.used / value.total * 100).toFixed(2)}%)`
|
// Reasoning: https://github.com/sebhildebrandt/systeminformation/issues/464#issuecomment-756406053
|
||||||
|
const totalForPercentage = typeof value.available !== 'undefined'
|
||||||
|
? (value.used + value.available)
|
||||||
|
: value.total
|
||||||
|
parsed = `${page.getPrettyBytes(value.used)} / ${page.getPrettyBytes(value.total)} (${(value.used / totalForPercentage * 100).toFixed(2)}%)`
|
||||||
break
|
break
|
||||||
|
}
|
||||||
case 'uptime':
|
case 'uptime':
|
||||||
parsed = page.getPrettyUptime(value)
|
parsed = page.getPrettyUptime(value)
|
||||||
break
|
break
|
||||||
|
Loading…
Reference in New Issue
Block a user