mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-11-01 02:55:13 +08:00
update 2026-05-10 09:48:30
This commit is contained in:
1 parent
95ac96413e
commit
0b362674f1
6244 files changed
+2992248
No files matched your search
@@ -0,0 +1,363 @@
|
||||
'use strict';
|
||||
'require baseclass';
|
||||
'require fs';
|
||||
|
||||
document.head.append(E('style', {'type': 'text/css'},
|
||||
`
|
||||
.cpu-status-view-mode-entry {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
margin: 2px 4px 2px 0 !important;
|
||||
padding: 3px 5px;
|
||||
border: 1px solid;
|
||||
border-color: transparent;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
opacity: 0.7;
|
||||
background-color: rgba(100 100 100 / 0.2);
|
||||
}
|
||||
.cpu-status-view-mode-entry:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
.cpu-status-view-mode-entry:active {
|
||||
opacity: 1.0;
|
||||
}
|
||||
.cpu-status-view-mode-entry-checked {
|
||||
border: 1px solid;
|
||||
opacity: 1.0;
|
||||
}
|
||||
.cpu-status-view-mode-entry-checked:hover {
|
||||
opacity: 1.0;
|
||||
}
|
||||
`));
|
||||
|
||||
return baseclass.extend({
|
||||
title : _('CPU Load'),
|
||||
|
||||
viewName : 'cpu_status',
|
||||
|
||||
availableViewModes: {
|
||||
0: [ 'allCPUs', _('Load') ],
|
||||
1: [ 'allCPUsDetail', _('Detailed load') ],
|
||||
2: [ 'eachCPU', _('Load of each CPU') ],
|
||||
3: [ 'eachCPUDetail', _('Detailed load of each CPU') ],
|
||||
},
|
||||
|
||||
viewMode : 0,
|
||||
|
||||
lastStatArray : null,
|
||||
|
||||
restoreSettingsFromLocalStorage() {
|
||||
let viewModeLocal = localStorage.getItem(`luci-app-${this.viewName}-viewMode`);
|
||||
if(viewModeLocal) {
|
||||
this.viewMode = Number(viewModeLocal);
|
||||
};
|
||||
},
|
||||
|
||||
saveSettingsToLocalStorage(viewMode) {
|
||||
if(this.viewMode != viewMode) {
|
||||
localStorage.setItem(
|
||||
`luci-app-${this.viewName}-viewMode`, String(viewMode));
|
||||
};
|
||||
},
|
||||
|
||||
parseProcData(data) {
|
||||
let cpuStatArray = [];
|
||||
let statItemsArray = data.trim().split('\n').filter(s => s.startsWith('cpu'));
|
||||
|
||||
for(let str of statItemsArray) {
|
||||
let arr = str.split(/\s+/).slice(0, 8);
|
||||
arr[0] = (arr[0] == 'cpu') ? Infinity : arr[0].replace('cpu', '');
|
||||
cpuStatArray.push(arr.map(e => Number(e)));
|
||||
};
|
||||
|
||||
cpuStatArray.sort((a, b) => a[0] - b[0]);
|
||||
|
||||
return cpuStatArray;
|
||||
},
|
||||
|
||||
calcCPULoad(cpuStatArray) {
|
||||
let retArray = [];
|
||||
cpuStatArray.forEach((c, i) => {
|
||||
let loadUser = 0,
|
||||
loadNice = 0,
|
||||
loadSys = 0,
|
||||
loadIdle = 0,
|
||||
loadIo = 0,
|
||||
loadIrq = 0,
|
||||
loadSirq = 0,
|
||||
loadAvg = 0;
|
||||
if(this.lastStatArray !== null && this.lastStatArray.cpuNum == c.cpuNum) {
|
||||
let user = c[1] - this.lastStatArray[i][1],
|
||||
nice = c[2] - this.lastStatArray[i][2],
|
||||
sys = c[3] - this.lastStatArray[i][3],
|
||||
idle = c[4] - this.lastStatArray[i][4],
|
||||
io = c[5] - this.lastStatArray[i][5],
|
||||
irq = c[6] - this.lastStatArray[i][6],
|
||||
sirq = c[7] - this.lastStatArray[i][7];
|
||||
let sum = user + nice + sys + idle + io + irq + sirq;
|
||||
loadUser = Number((100 * user / sum).toFixed(1));
|
||||
loadNice = Number((100 * nice / sum).toFixed(1));
|
||||
loadSys = Number((100 * sys / sum).toFixed(1));
|
||||
loadIdle = Number((100 * idle / sum).toFixed(1));
|
||||
loadIo = Number((100 * io / sum).toFixed(1));
|
||||
loadIrq = Number((100 * irq / sum).toFixed(1));
|
||||
loadSirq = Number((100 * sirq / sum).toFixed(1));
|
||||
loadAvg = Math.round(100 * (user + nice + sys + io + irq + sirq) / sum);
|
||||
};
|
||||
retArray.push(
|
||||
{cpuNum: c[0], loadUser, loadNice, loadSys, loadIdle, loadIo, loadIrq, loadSirq, loadAvg});
|
||||
});
|
||||
return retArray;
|
||||
},
|
||||
|
||||
allCPUs: {
|
||||
makeTable() {
|
||||
this.table = E('table', { 'class': 'table' });
|
||||
},
|
||||
append(cpuNum, cpuLoadObj, cpuLoadFlag) {
|
||||
if(cpuNum == Infinity) {
|
||||
this.table.append(
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'width': '33%' },
|
||||
_('Total load')),
|
||||
E('td', { 'class': 'td' },
|
||||
E('div', {
|
||||
'class': 'cbi-progressbar',
|
||||
'title': (cpuLoadFlag) ?
|
||||
cpuLoadObj.loadAvg + '%' :
|
||||
_('Calculating') + '...',
|
||||
},
|
||||
E('div', { 'style': 'width:' + cpuLoadObj.loadAvg + '%' })
|
||||
)
|
||||
),
|
||||
])
|
||||
);
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
allCPUsDetail: {
|
||||
cpuTableTitles: [
|
||||
_('All CPUs'),
|
||||
_('Load'),
|
||||
'user %',
|
||||
'nice %',
|
||||
'system %',
|
||||
'idle %',
|
||||
'iowait %',
|
||||
'irq %',
|
||||
'softirq %',
|
||||
],
|
||||
makeTable() {
|
||||
this.table = E('table', { 'class': 'table' },
|
||||
E('tr', { 'class': 'tr table-titles' }, [
|
||||
E('th', { 'class': 'th left' }, this.cpuTableTitles[0]),
|
||||
E('th', { 'class': 'th left' }, this.cpuTableTitles[1]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[2]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[3]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[4]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[5]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[6]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[7]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[8]),
|
||||
])
|
||||
);
|
||||
},
|
||||
append(cpuNum, cpuLoadObj, cpuLoadFlag) {
|
||||
if(cpuNum == Infinity) {
|
||||
this.table.append(
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': this.cpuTableTitles[0] },
|
||||
_('Total load')),
|
||||
E('td', { 'class': 'td left', 'data-title': this.cpuTableTitles[1] },
|
||||
E('div', {
|
||||
'class': 'cbi-progressbar',
|
||||
'title': (cpuLoadFlag) ?
|
||||
cpuLoadObj.loadAvg + '%' :
|
||||
_('Calculating') + '...',
|
||||
'style': 'min-width:8em !important',
|
||||
},
|
||||
E('div', { 'style': 'width:' + cpuLoadObj.loadAvg + '%' })
|
||||
)
|
||||
),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[2] }, cpuLoadObj.loadUser),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[3] }, cpuLoadObj.loadNice),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[4] }, cpuLoadObj.loadSys),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[5] }, cpuLoadObj.loadIdle),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[6] }, cpuLoadObj.loadIo),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[7] }, cpuLoadObj.loadIrq),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[8] }, cpuLoadObj.loadSirq),
|
||||
])
|
||||
);
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
eachCPU: {
|
||||
makeTable() {
|
||||
this.table = E('table', { 'class': 'table' });
|
||||
},
|
||||
append(cpuNum, cpuLoadObj, cpuLoadFlag) {
|
||||
this.table.append(
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'width': '33%' },
|
||||
(cpuNum == Infinity) ? _('Total load') : _('CPU') + ' ' + cpuNum),
|
||||
E('td', { 'class': 'td' },
|
||||
E('div', {
|
||||
'class': 'cbi-progressbar',
|
||||
'title': (cpuLoadFlag) ?
|
||||
cpuLoadObj.loadAvg + '%' :
|
||||
_('Calculating') + '...',
|
||||
},
|
||||
E('div', { 'style': 'width:' + cpuLoadObj.loadAvg + '%' })
|
||||
)
|
||||
),
|
||||
])
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
eachCPUDetail: {
|
||||
cpuTableTitles: [
|
||||
_('CPU'),
|
||||
_('Load'),
|
||||
'user %',
|
||||
'nice %',
|
||||
'system %',
|
||||
'idle %',
|
||||
'iowait %',
|
||||
'irq %',
|
||||
'softirq %',
|
||||
],
|
||||
makeTable() {
|
||||
this.table = E('table', { 'class': 'table' },
|
||||
E('tr', { 'class': 'tr table-titles' }, [
|
||||
E('th', { 'class': 'th left' }, this.cpuTableTitles[0]),
|
||||
E('th', { 'class': 'th left' }, this.cpuTableTitles[1]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[2]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[3]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[4]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[5]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[6]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[7]),
|
||||
E('th', { 'class': 'th center' }, this.cpuTableTitles[8]),
|
||||
])
|
||||
);
|
||||
},
|
||||
append(cpuNum, cpuLoadObj, cpuLoadFlag) {
|
||||
this.table.append(
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': this.cpuTableTitles[0] },
|
||||
(cpuNum == Infinity) ? _('Total load') : _('CPU') + ' ' + cpuNum),
|
||||
E('td', { 'class': 'td left', 'data-title': this.cpuTableTitles[1] },
|
||||
E('div', {
|
||||
'class': 'cbi-progressbar',
|
||||
'title': (cpuLoadFlag) ?
|
||||
cpuLoadObj.loadAvg + '%' :
|
||||
_('Calculating') + '...',
|
||||
'style': 'min-width:8em !important',
|
||||
},
|
||||
E('div', { 'style': 'width:' + cpuLoadObj.loadAvg + '%' })
|
||||
)
|
||||
),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[2] }, cpuLoadObj.loadUser),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[3] }, cpuLoadObj.loadNice),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[4] }, cpuLoadObj.loadSys),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[5] }, cpuLoadObj.loadIdle),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[6] }, cpuLoadObj.loadIo),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[7] }, cpuLoadObj.loadIrq),
|
||||
E('td', { 'class': 'td center',
|
||||
'data-title': this.cpuTableTitles[8] }, cpuLoadObj.loadSirq),
|
||||
])
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
makeCPUTable(cpuLoadArray) {
|
||||
let currentView = (this.availableViewModes[this.viewMode] !== undefined) ?
|
||||
this[this.availableViewModes[this.viewMode][0]] :
|
||||
this[this.availableViewModes[0][0]];
|
||||
currentView.makeTable();
|
||||
cpuLoadArray.forEach((c, i) => {
|
||||
currentView.append(c.cpuNum, c, (this.lastStatArray !== null));
|
||||
});
|
||||
return currentView.table;
|
||||
},
|
||||
|
||||
load() {
|
||||
this.restoreSettingsFromLocalStorage();
|
||||
return L.resolveDefault(fs.read('/proc/stat'), null);
|
||||
},
|
||||
|
||||
render(cpuData) {
|
||||
if(!cpuData) return;
|
||||
|
||||
let cpuStatArray = this.parseProcData(cpuData);
|
||||
|
||||
// For single-core CPU
|
||||
if(cpuStatArray.length == 2) {
|
||||
cpuStatArray = cpuStatArray.slice(1, 2);
|
||||
delete this.availableViewModes[2];
|
||||
delete this.availableViewModes[3];
|
||||
if(this.viewMode > 1) this.viewMode = 0;
|
||||
};
|
||||
|
||||
let cpuLoadArray = this.calcCPULoad(cpuStatArray);
|
||||
let cpuTable = this.makeCPUTable(cpuLoadArray);
|
||||
|
||||
let viewModeSelectFunc = value => {
|
||||
this.saveSettingsToLocalStorage(value);
|
||||
this.viewMode = value;
|
||||
viewModeEntries.forEach(i => {
|
||||
i.classList.remove('cpu-status-view-mode-entry-checked');
|
||||
});
|
||||
viewModeEntries[value].classList.add('cpu-status-view-mode-entry-checked');
|
||||
let newTable = this.makeCPUTable(cpuLoadArray);
|
||||
cpuTable.replaceWith(newTable);
|
||||
cpuTable = newTable;
|
||||
};
|
||||
|
||||
let viewModeSelectOnClick = ev => {
|
||||
viewModeSelectFunc(ev.target.dataset.value);
|
||||
ev.target.blur();
|
||||
};
|
||||
|
||||
let viewModeEntries = [];
|
||||
|
||||
for(let [i, v] of Object.entries(this.availableViewModes)) {
|
||||
viewModeEntries.push(
|
||||
E('span', {
|
||||
'class' : 'cpu-status-view-mode-entry',
|
||||
'data-value': i,
|
||||
'click' : viewModeSelectOnClick,
|
||||
}, v[1])
|
||||
);
|
||||
};
|
||||
|
||||
viewModeSelectFunc(this.viewMode);
|
||||
|
||||
this.lastStatArray = cpuStatArray;
|
||||
|
||||
return E('div', { 'class': 'cbi-section' }, [
|
||||
E('div', { 'style': 'margin-bottom:1em' },
|
||||
viewModeEntries
|
||||
),
|
||||
cpuTable,
|
||||
]);
|
||||
},
|
||||
});
|
||||
Reference in new issue
Block a user