diff --git a/share.py b/share.py index 0f974a7..7f26fbc 100755 --- a/share.py +++ b/share.py @@ -74,6 +74,18 @@ def ensure_cert(cert_dir: Path, extra_ips: list[str] | None = None) -> tuple[Pat BASE_DIR = Path(__file__).resolve().parent +def _file_type(path: Path) -> str: + ct = mimetypes.guess_type(path.name)[0] or '' + if ct.startswith('image/'): + return 'image' + if ct.startswith('text/'): + return 'text' + try: + with open(path, 'rb') as f: + return 'text' if b'\x00' not in f.read(8192) else 'other' + except OSError: + return 'other' + # ── HTTP Handler ── @@ -149,7 +161,7 @@ class Handler(http.server.BaseHTTPRequestHandler): files = [] for p in sorted(self.server.upload_dir.iterdir(), key=lambda p: p.stat().st_mtime, reverse=True): if p.is_file(): - files.append({"name": p.name, "size": p.stat().st_size}) + files.append({"name": p.name, "size": p.stat().st_size, "type": _file_type(p)}) self._json(files) def _route_download(self): diff --git a/static/index.html b/static/index.html index 5618c8a..3e9d462 100644 --- a/static/index.html +++ b/static/index.html @@ -259,10 +259,7 @@ $('lang-sw').addEventListener('click', e => { if (e.target.dataset.l) setLang(e.target.dataset.l); }); -const TEXT_EXT = new Set( - 'txt,log,json,xml,csv,html,css,js,ts,py,md,sh,yml,yaml,toml,ini,cfg,conf,env,sql,rs,go,java,c,h,cpp,rb,php'.split(',') -); -const IMG_EXT = new Set('png,jpg,jpeg,gif,webp,bmp,ico,svg'.split(',')); +/* File type is determined server-side via /files API ("text" | "image" | "other") */ /* ── Helpers ── */ @@ -287,10 +284,6 @@ function esc(s) { .replace(/"/g,'"').replace(/'/g,'''); } -function fileExt(name) { - return (name.split('.').pop() || '').toLowerCase(); -} - /* ── Clipboard ── */ function fallbackCopy(text) { @@ -332,15 +325,14 @@ function toPngBlob(blob) { }); } -function copyFile(name) { +function copyFile(name, type) { const url = '/dl/' + encodeURIComponent(name); - const ext = fileExt(name); - if (TEXT_EXT.has(ext)) { + if (type === 'text') { fetch(url).then(r => r.text()).then(text => copyText(text)) .catch(() => toast(t().copyFail)); - } else if (IMG_EXT.has(ext)) { + } else if (type === 'image') { const link = location.origin + url; if (!navigator.clipboard?.write) { copyText(link, t().linkCopied); @@ -457,7 +449,7 @@ function renderFiles() { flist.innerHTML = slice.map(f => `