Build and deploy lightweight Flask web tools (file managers, dashboards, admin panels) on Linux servers. Covers Chinese/i18n filenames, mobile touch UX, simple auth, and Docker-free deployment.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Build and deploy lightweight Flask web tools (file managers, dashboards, admin panels) on Linux servers. Covers Chinese/i18n filenames, mobile touch UX, simple auth, and Docker-free deployment.
triggers
["user asks to build a web UI, file manager, admin panel, or dashboard","user asks to deploy a Python web app on a server","user mentions 文件管理, 网盘, file manager, or web tool","user needs a simple internal tool with a web interface"]
Flask Web Tools
Build lightweight, single-file Flask web tools for server deployment. No heavy frameworks — Flask + inline HTML templates + vanilla JS.
werkzeug.utils.secure_filename removes ALL non-ASCII characters. Chinese filenames become empty strings.
Fix — custom safe_filename:
defsafe_filename(name):
"""安全文件名:支持中文,防止路径穿越"""
name = name.replace("\\", "/").split("/")[-1]
name = name.replace("\x00", "")
name = name.replace("..", "")
name = name.strip(". ")
ifnot name:
return""return name
Use this instead of secure_filename for all user-provided filenames.
Pitfall: Hover-only buttons invisible on mobile
CSS opacity: 0 with :hover { opacity: 1 } makes buttons invisible on touch devices (no hover state).
Long-press action sheet (better UX): Add touch event handlers for mobile context menu
Pitfall: AJAX login forms can fail silently
Complex fetch()-based login can fail due to CORS, content-type mismatch, or JS errors. For simple tools, use plain HTML form POST — it's more reliable and works without JavaScript.
Using secrets.token_hex(32) generates a new key each restart, invalidating all session cookies. Use a fixed secret key for tools that need persistent sessions.
Pitfall: Python version mismatch on pip install
On systems with multiple Python versions, pip3 install may install to the wrong Python. Use the specific python binary:
/home/admin/.hermes/hermes-agent/venv/bin/python -m pip install flask
# or
uv pip install flask # if using uv-managed venv
Mobile Long-Press Context Menu
For file managers and list-based UIs, add touch-based long-press:
let pressTimer = null;
let actionFile = null;
functionpressStart(e, idx) {
pressEnd(e);
pressTimer = setTimeout(() => {
const f = window._files[idx];
showActionSheet(f);
if (navigator.vibrate) navigator.vibrate(50); // haptic feedback
}, 500); // 500ms threshold
}
functionpressEnd(e) {
if (pressTimer) { clearTimeout(pressTimer); pressTimer = null; }
}
Attach to rows: ontouchstart, ontouchend, ontouchmove, ontouchcancel, onmousedown, onmouseup, onmouseleave.
Always validate file paths to prevent ../../../etc/passwd attacks:
defget_safe_path(path):
path = path.strip('/')
parts = []
for part in path.split('/'):
if part in ('', '.'): continueif part == '..':
if parts: parts.pop()
continue
parts.append(part)
safe_path = STORAGE_ROOT.joinpath(*parts)
try:
safe_path.resolve().relative_to(STORAGE_ROOT.resolve())
return safe_path
except ValueError:
return STORAGE_ROOT # fallback to root if path escapes
File Viewer / Preview
Add inline file viewing so users can click a file and see it without downloading.
⚠️ PITFALL: This route MUST be placed BEFORE if __name__ == '__main__':.
Flask ignores routes defined after the main block. If you append with cat >>, the route won't register.
Viewer CSS: full-screen dark overlay (z-index: 200), top bar with filename + close + download buttons, body centered with scrollable content.
Office preview caveat: Microsoft's online viewer requires the file URL to be publicly accessible. Works on public servers, won't work on localhost/LAN.
Critical Pitfall: Flask Route Placement
⚠️ Routes defined AFTER if __name__ == '__main__': are NOT registered.
When appending routes (e.g., cat >> app.py), always insert BEFORE the main block:
Use case: Self-contained tools where the admin UI and API client scripts are served from the same Flask app. Users access http://server/admin.html directly without logging into the file manager.