# -*- coding: UTF-8 -*- import http.server import socketserver import json import logging import time import os import sys import urllib.parse # Import functions from existing scripts from export_web_view import HTML_TEMPLATE, build_html from get_records import get_all_records import api import config PORT = int(os.getenv("PORT", 18080)) # Globals to store cached HTML cached_html = None last_fetch_time = 0 class ThreadingHTTPServer(socketserver.ThreadingMixIn, http.server.HTTPServer): daemon_threads = True allow_reuse_address = True class FeishuHandler(http.server.SimpleHTTPRequestHandler): def do_GET(self): global cached_html, last_fetch_time parsed_path = urllib.parse.urlparse(self.path) # Serve dynamic HTML at root or outline_view.html if parsed_path.path == '/' or parsed_path.path == '/outline_view.html': self.send_response(200) self.send_header('Content-type', 'text/html; charset=utf-8') self.end_headers() current_time = time.time() if cached_html is None: logging.info("Fetching fresh records from API (Cache missing)...") try: client = api.Client(config.LARK_HOST) access_token = client.get_tenant_access_token(config.APP_ID, config.APP_SECRET) final_html = build_html(client, access_token) cached_html = final_html.encode('utf-8') last_fetch_time = current_time logging.info("Successfully generated new HTML view.") except Exception as e: logging.error(f"Error fetching data: {e}") error_msg = f"
{e}
".encode('utf-8') self.wfile.write(error_msg) return # Write response self.wfile.write(cached_html) elif parsed_path.path == '/api/refresh': logging.info("Ajax refresh requested. Fetching fresh records from API...") try: client = api.Client(config.LARK_HOST) access_token = client.get_tenant_access_token(config.APP_ID, config.APP_SECRET) final_html = build_html(client, access_token) cached_html = final_html.encode('utf-8') self.send_response(200) self.send_header('Content-type', 'application/json; charset=utf-8') self.end_headers() self.wfile.write(b'{"status": "ok"}') except Exception as e: logging.error(f"Ajax Error fetching data: {e}") self.send_response(500) self.send_header('Content-type', 'application/json; charset=utf-8') self.end_headers() self.wfile.write(json.dumps({"status": "error", "message": str(e)}).encode('utf-8')) return # Write response self.wfile.write(cached_html) else: # Fallback to serving static files for any other paths super().do_GET() if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") server_address = ("0.0.0.0", PORT) try: httpd = ThreadingHTTPServer(server_address, FeishuHandler) logging.info(f"🚀 Server successfully started at http://localhost:{PORT}") logging.info("You can now access the viewer directly through the browser.") logging.info("Press Ctrl+C to stop the server.") httpd.serve_forever() except KeyboardInterrupt: logging.info("Shutting down the server...") sys.exit(0) except Exception as e: logging.error(f"Could not start server on port {PORT}: {e}")