49 lines
2.7 KiB
Python
49 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
||||
|
|
import io
|
|||
|
|
p = '/opt/dshs/web/admin.html'
|
|||
|
|
s = io.open(p, encoding='utf-8').read()
|
|||
|
|
anchor = """ <table class="admin">
|
|||
|
|
<thead><tr><th>用户名</th><th>角色</th><th>注册时间</th><th>操作</th></tr></thead>
|
|||
|
|
<tbody id="users"></tbody>
|
|||
|
|
</table>
|
|||
|
|
"""
|
|||
|
|
assert anchor in s
|
|||
|
|
block = anchor + """
|
|||
|
|
<h3 style="margin:22px 0 8px">存储用量 <span class="auth-sub" id="storageAt" style="font-weight:400"></span></h3>
|
|||
|
|
<table class="admin">
|
|||
|
|
<thead><tr><th>用户</th><th>工作区</th><th>会话</th><th>回收站</th><th>可清理</th></tr></thead>
|
|||
|
|
<tbody id="storage"></tbody>
|
|||
|
|
</table>
|
|||
|
|
<p class="auth-sub" style="margin:6px 0 0">工作区达 <span id="thWs"></span> / 会话达 <span id="thSess"></span> 时由每日维护任务自动清理(工作区 90 天、会话 365 天前的记录;均先入回收站保留 30 天)。</p>
|
|||
|
|
"""
|
|||
|
|
s = s.replace(anchor, block, 1)
|
|||
|
|
js_anchor = " document.getElementById('logoutBtn').addEventListener('click', async () => {"
|
|||
|
|
assert js_anchor in s
|
|||
|
|
js = """ function fmtB(b) { return b >= 1073741824 ? (b / 1073741824).toFixed(2) + ' GB' : (b / 1048576).toFixed(1) + ' MB' }
|
|||
|
|
async function loadStorage() {
|
|||
|
|
const tbody = document.getElementById('storage')
|
|||
|
|
try {
|
|||
|
|
const r = await (await fetch('/api/admin/storage')).json()
|
|||
|
|
document.getElementById('storageAt').textContent = r.generatedAt ? `(更新于 ${new Date(r.generatedAt).toLocaleString()})` : ''
|
|||
|
|
if (r.thresholds) {
|
|||
|
|
document.getElementById('thWs').textContent = r.thresholds.wsMB + ' MB'
|
|||
|
|
document.getElementById('thSess').textContent = r.thresholds.sessionsMB + ' MB'
|
|||
|
|
}
|
|||
|
|
tbody.innerHTML = (r.users ?? []).map((u) => `<tr>
|
|||
|
|
<td>${esc(u.username)}</td>
|
|||
|
|
<td style="${u.wsOver ? 'color:var(--danger)' : ''}">${fmtB(u.ws)}</td>
|
|||
|
|
<td style="${u.sessionsOver ? 'color:var(--danger)' : ''}">${fmtB(u.sessions)}</td>
|
|||
|
|
<td>${fmtB(u.trash)}</td>
|
|||
|
|
<td>${u.cleanableT1 + u.cleanableT2} 项 / ${fmtB(u.cleanableBytes)}</td>
|
|||
|
|
</tr>`).join('') || `<tr><td colspan="5" class="auth-sub">${esc(r.note ?? '暂无数据')}</td></tr>`
|
|||
|
|
} catch { tbody.innerHTML = '<tr><td colspan="5" class="auth-sub">读取失败</td></tr>' }
|
|||
|
|
}
|
|||
|
|
""" + js_anchor
|
|||
|
|
s = s.replace(js_anchor, js, 1)
|
|||
|
|
call_anchor = " await loadUsers()"
|
|||
|
|
if call_anchor in s:
|
|||
|
|
s = s.replace(call_anchor, call_anchor + "\n await loadStorage()", 1)
|
|||
|
|
else:
|
|||
|
|
s = s.replace("loadUsers()", "loadUsers(); loadStorage()", 1)
|
|||
|
|
io.open(p, 'w', encoding='utf-8', newline='').write(s)
|
|||
|
|
print('E admin.html 用量区块已写入')
|