Add highlight marking and AI API
This commit is contained in:
@@ -60,6 +60,8 @@ class PlayerHandler(BaseHTTPRequestHandler):
|
||||
return self.send_recordings(request.query)
|
||||
if request.path == "/api/encode/status":
|
||||
return self.send_json(self.server.encode_status)
|
||||
if request.path == "/api/highlights":
|
||||
return self.send_json(self.server.highlights)
|
||||
if request.path == "/video":
|
||||
return self.send_video(request.query)
|
||||
self.send_error(404)
|
||||
@@ -69,8 +71,41 @@ class PlayerHandler(BaseHTTPRequestHandler):
|
||||
if not self.server.encode_status["running"]:
|
||||
threading.Thread(target=run_encoding, args=(self.server,), daemon=True).start()
|
||||
return self.send_json(self.server.encode_status)
|
||||
if urlparse(self.path).path == "/api/highlights":
|
||||
try:
|
||||
length = int(self.headers.get("Content-Length", "0"))
|
||||
item = json.loads(self.rfile.read(length))
|
||||
date = str(item["date"])
|
||||
start = float(item["start"])
|
||||
end = float(item["end"])
|
||||
if not DATE_RE.fullmatch(date) or not (0 <= start < end <= 86400):
|
||||
raise ValueError
|
||||
highlight = {
|
||||
"id": max((entry["id"] for entry in self.server.highlights), default=0) + 1,
|
||||
"date": date,
|
||||
"start": start,
|
||||
"end": end,
|
||||
"label": str(item.get("label", "Untitled highlight"))[:120],
|
||||
}
|
||||
except (KeyError, TypeError, ValueError, json.JSONDecodeError):
|
||||
return self.send_error(400, "Invalid highlight")
|
||||
self.server.highlights.append(highlight)
|
||||
save_highlights(self.server.highlights_path, self.server.highlights)
|
||||
return self.send_json(highlight)
|
||||
self.send_error(404)
|
||||
|
||||
def do_DELETE(self):
|
||||
request = urlparse(self.path)
|
||||
if request.path != "/api/highlights":
|
||||
return self.send_error(404)
|
||||
try:
|
||||
highlight_id = int(parse_qs(request.query).get("id", [""])[0])
|
||||
except ValueError:
|
||||
return self.send_error(400, "Invalid highlight id")
|
||||
self.server.highlights[:] = [item for item in self.server.highlights if item["id"] != highlight_id]
|
||||
save_highlights(self.server.highlights_path, self.server.highlights)
|
||||
self.send_json({"ok": True})
|
||||
|
||||
def send_json(self, payload):
|
||||
data = json.dumps(payload).encode()
|
||||
self.send_response(200)
|
||||
@@ -215,6 +250,8 @@ def main():
|
||||
server.recordings = recordings
|
||||
server.source_root = args.source.expanduser().resolve()
|
||||
server.output_root = args.root.expanduser().resolve()
|
||||
server.highlights_path = server.output_root / "highlights.json"
|
||||
server.highlights = load_highlights(server.highlights_path)
|
||||
server.encode_status = {"running": False, "total": 0, "completed": 0, "skipped": 0, "failed": 0}
|
||||
count = sum(map(len, recordings.values()))
|
||||
print(f"Indexed {count} recordings across {len(recordings)} days")
|
||||
@@ -265,5 +302,20 @@ def run_encoding(server):
|
||||
status["running"] = False
|
||||
|
||||
|
||||
def load_highlights(path):
|
||||
try:
|
||||
data = json.loads(path.read_text())
|
||||
return data if isinstance(data, list) else []
|
||||
except (FileNotFoundError, json.JSONDecodeError, OSError):
|
||||
return []
|
||||
|
||||
|
||||
def save_highlights(path, highlights):
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
temporary = path.with_suffix(".tmp")
|
||||
temporary.write_text(json.dumps(highlights, indent=2) + "\n")
|
||||
temporary.replace(path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user