#!/usr/bin/env python3
"""Static server for the podcast: correct MIME types + HTTP Range support
(needed for audio seeking and for podcast clients that issue partial requests)."""
import os, http.server, socketserver

ROOT = os.path.expanduser("~/Podcasts")  # shared root; one subfolder per show
PORT = 8090

EXT_MIME = {
    ".m4a": "audio/x-m4a",
    ".mp3": "audio/mpeg",
    ".xml": "application/rss+xml; charset=utf-8",
    ".jpg": "image/jpeg",
    ".jpeg": "image/jpeg",
    ".png": "image/png",
}

class Handler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *a, **k):
        super().__init__(*a, directory=ROOT, **k)

    def guess_type(self, path):
        ext = os.path.splitext(path)[1].lower()
        return EXT_MIME.get(ext, super().guess_type(path))

    def end_headers(self):
        self.send_header("Accept-Ranges", "bytes")
        self.send_header("Access-Control-Allow-Origin", "*")
        super().end_headers()

    def do_GET(self):
        rng = self.headers.get("Range")
        path = self.translate_path(self.path)
        if not rng or not os.path.isfile(path):
            return super().do_GET()
        try:
            size = os.path.getsize(path)
            unit, _, rspec = rng.partition("=")
            start_s, _, end_s = rspec.partition("-")
            start = int(start_s) if start_s else 0
            end = int(end_s) if end_s else size - 1
            end = min(end, size - 1)
            if start > end or start >= size:
                self.send_response(416)
                self.send_header("Content-Range", f"bytes */{size}")
                self.end_headers()
                return
            length = end - start + 1
            self.send_response(206)
            self.send_header("Content-Type", self.guess_type(path))
            self.send_header("Content-Range", f"bytes {start}-{end}/{size}")
            self.send_header("Content-Length", str(length))
            self.end_headers()
            with open(path, "rb") as f:
                f.seek(start)
                remaining = length
                while remaining > 0:
                    chunk = f.read(min(65536, remaining))
                    if not chunk:
                        break
                    self.wfile.write(chunk)
                    remaining -= len(chunk)
        except (BrokenPipeError, ConnectionResetError):
            pass
        except Exception as e:
            self.send_error(500, str(e))

class ThreadingServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
    daemon_threads = True

if __name__ == "__main__":
    os.chdir(ROOT)
    with ThreadingServer(("127.0.0.1", PORT), Handler) as httpd:
        print(f"Serving {ROOT} on 127.0.0.1:{PORT}")
        httpd.serve_forever()
