#!/usr/bin/env python3 import io p = '/opt/dshs/web/admin.html' s = io.open(p, encoding='utf-8').read() anchor = """
用户名角色注册时间操作
""" assert anchor in s block = anchor + """

存储用量

用户工作区会话回收站可清理

工作区达 / 会话达 时由每日维护任务自动清理(工作区 90 天、会话 365 天前的记录;均先入回收站保留 30 天)。

""" 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) => ` ${esc(u.username)} ${fmtB(u.ws)} ${fmtB(u.sessions)} ${fmtB(u.trash)} ${u.cleanableT1 + u.cleanableT2} 项 / ${fmtB(u.cleanableBytes)} `).join('') || `${esc(r.note ?? '暂无数据')}` } catch { tbody.innerHTML = '读取失败' } } """ + 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 用量区块已写入')