obs-r2-uploader/scripts/build-worker.py

115 lines
3.8 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Build script to embed admin.html into the Cloudflare Worker.
This creates a single deployable worker file with the admin interface embedded.
"""
import os
import sys
from pathlib import Path
def main():
# Get project root
script_dir = Path(__file__).parent
project_dir = script_dir.parent
worker_dir = project_dir / "worker"
admin_html_path = worker_dir / "admin.html"
worker_template_path = worker_dir / "video-server-enhanced.js"
output_path = worker_dir / "video-server.js"
# Check if files exist
if not admin_html_path.exists():
print(f"Error: {admin_html_path} not found")
sys.exit(1)
if not worker_template_path.exists():
print(f"Error: {worker_template_path} not found")
sys.exit(1)
print("=" * 50)
print("Building Cloudflare Worker with Embedded Admin")
print("=" * 50)
print()
# Read admin HTML
print("Reading admin.html...")
with open(admin_html_path, 'r', encoding='utf-8') as f:
admin_html = f.read()
# Escape the HTML for JavaScript template literal
admin_html_escaped = admin_html.replace('\\', '\\\\').replace('`', '\\`').replace('${', '\\${')
# Read worker template
print("Reading worker template...")
with open(worker_template_path, 'r', encoding='utf-8') as f:
worker_code = f.read()
# Replace the getAdminHTML function with one that returns the embedded HTML
placeholder = '''async function getAdminHTML() {
// In production, you'd embed this or fetch from R2
// For now, we'll import it as a module or use a fetch
// Since we can't easily read files in Workers, we'll need to inline it or use a build step
// For this implementation, we'll fetch it from a constant
// In production, use wrangler's module support or embed it
return `
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>Admin Panel</title></head>
<body>
<h1>Admin Panel</h1>
<p>Please replace this with the full admin.html content using a build step or module import.</p>
<p>For now, use: <a href="/admin/api/videos">/admin/api/videos</a> to see the API.</p>
</body>
</html>
`;
// TODO: In production, import admin.html content here
}'''
replacement = f'''async function getAdminHTML() {{
return `{admin_html_escaped}`;
}}'''
# Replace the placeholder
if placeholder in worker_code:
worker_code = worker_code.replace(placeholder, replacement)
print("✓ Embedded admin.html into worker")
else:
print("⚠️ Could not find placeholder to replace")
print(" Adding admin HTML as a constant instead...")
# Alternative: add at the top
const_declaration = f'\nconst ADMIN_HTML = `{admin_html_escaped}`;\n\n'
worker_code = const_declaration + worker_code
# Replace the simple return
simple_placeholder = 'async function getAdminHTML() {\n return ADMIN_HTML;'
if simple_placeholder not in worker_code:
worker_code = worker_code.replace(
'async function getAdminHTML() {',
f'async function getAdminHTML() {{\n return ADMIN_HTML;\n /*'
)
worker_code = worker_code.replace(' // TODO: In production', ' */')
# Write output
print(f"Writing output to {output_path}...")
with open(output_path, 'w', encoding='utf-8') as f:
f.write(worker_code)
print()
print("=" * 50)
print("Build Complete!")
print("=" * 50)
print()
print(f"Output: {output_path}")
print()
print("Next steps:")
print("1. Make sure wrangler.toml is configured (use wrangler-enhanced.toml as template)")
print("2. Deploy: cd worker && wrangler deploy")
print("3. Access admin at: https://videos.jeffemmett.com/admin")
print()
if __name__ == "__main__":
main()