#!/usr/bin/env python3
"""zt_server.py — 看板专用静态服务: gzip 压缩 + ETag 缓存 + 线程池
替代 python -m http.server（无压缩无缓存, 12MB 页面每次全量传）
"""
import os, gzip, hashlib, threading
from http.server import HTTPServer, SimpleHTTPRequestHandler
from functools import partial

ROOT = '/Users/xpresso/zt_app'

class CacheHandler(SimpleHTTPRequestHandler):
    protocol_version = 'HTTP/1.0'  # 短连接模式, 简单可靠

    def do_GET(self):
        path = self.translate_path(self.path)
        if os.path.isfile(path):
            mtime = os.path.getmtime(path)
            # ETag 用内容哈希(md5前16位)而非 mtime: 内容一变ETag必变, 避免mtime精度/时区导致的304误命中
            with open(path, 'rb') as f:
                data = f.read()
            etag = '"' + hashlib.md5(data).hexdigest()[:16] + '"'
            if self.headers.get('If-None-Match') == etag:
                self.send_response(304)
                self.send_header('ETag', etag)
                self.send_header('Cache-Control', 'no-cache')
                self.end_headers()
                return
            # gzip 大文本资源（html/json/png 均受益, PNG 已压缩但 gzip 无害）
            accept = self.headers.get('Accept-Encoding', '')
            ext = path.rsplit('.', 1)[-1].lower()
            if 'gzip' in accept and ext in ('html', 'json', 'js', 'css', 'csv'):
                gz = gzip.compress(data, compresslevel=6)
                if len(gz) < len(data):
                    self.send_response(200)
                    self.send_header('Content-Type', self.guess_type(path))
                    self.send_header('Content-Encoding', 'gzip')
                    self.send_header('Content-Length', str(len(gz)))
                    self.send_header('ETag', etag)
                    self.send_header('Cache-Control', 'no-cache')
                    self.end_headers()
                    self.wfile.write(gz)
                    return
            self.send_response(200)
            self.send_header('Content-Type', self.guess_type(path))
            self.send_header('Content-Length', str(len(data)))
            self.send_header('ETag', etag)
            self.send_header('Cache-Control', 'no-cache')
            self.end_headers()
            self.wfile.write(data)
        else:
            super().do_GET()

    def log_message(self, fmt, *args):
        pass  # 静默日志

class ThreadedServer(HTTPServer):
    daemon_threads = True
    allow_reuse_address = True

if __name__ == '__main__':
    os.chdir(ROOT)
    srv = ThreadedServer(('0.0.0.0', 8766), CacheHandler)
    print('zt_server on :8766 (gzip+etag+threads)', flush=True)
    try:
        srv.serve_forever()
    except KeyboardInterrupt:
        pass
