File size: 5,868 Bytes
c7297b8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/usr/bin/env python3
"""
Hugging Face Spaces Entry Point
This script:
1. Loads secrets from HF Spaces environment variables
2. Creates config.json and credentials.json from those secrets
3. Starts the automation runner in the background
4. Serves the static web interface
"""

import os
import json
import subprocess
import signal
import sys
import time
import threading
from pathlib import Path
from http.server import HTTPServer, SimpleHTTPRequestHandler
from functools import partial

# Configuration
PORT = int(os.getenv('PORT', 7860))
BASE_DIR = Path(__file__).parent
AUTOMATION_RUNNER = BASE_DIR / "scripts" / "automation_runner.py"

# Global process reference for cleanup
automation_process = None


def load_secrets_from_env():
    """Load secrets from HF Spaces environment variables and create config files"""
    print("๐Ÿ” Loading secrets from environment variables...")
    
    # Load config.json from environment
    config_json_str = os.getenv('HF_CONFIG_JSON')
    if config_json_str:
        try:
            config_data = json.loads(config_json_str)
            config_file = BASE_DIR / "config.json"
            with open(config_file, 'w') as f:
                json.dump(config_data, f, indent=2)
            print(f"โœ… Created config.json from HF_CONFIG_JSON secret")
        except json.JSONDecodeError as e:
            print(f"โŒ Error parsing HF_CONFIG_JSON: {e}")
            sys.exit(1)
    else:
        config_file = BASE_DIR / "config.json"
        if not config_file.exists():
            print("โš ๏ธ  HF_CONFIG_JSON not found in environment")
            print("โš ๏ธ  Please set HF_CONFIG_JSON secret in your Hugging Face Space settings")
            print("โš ๏ธ  See SECRETS_SETUP.md for instructions")
            # Don't exit - allow the app to run without automation
    
    # Load credentials.json from environment
    credentials_json_str = os.getenv('HF_CREDENTIALS_JSON')
    if credentials_json_str:
        try:
            credentials_data = json.loads(credentials_json_str)
            credentials_file = BASE_DIR / "credentials.json"
            with open(credentials_file, 'w') as f:
                json.dump(credentials_data, f, indent=2)
            print(f"โœ… Created credentials.json from HF_CREDENTIALS_JSON secret")
        except json.JSONDecodeError as e:
            print(f"โŒ Error parsing HF_CREDENTIALS_JSON: {e}")
            sys.exit(1)
    else:
        credentials_file = BASE_DIR / "credentials.json"
        if not credentials_file.exists():
            print("โš ๏ธ  HF_CREDENTIALS_JSON not found in environment")
            print("โš ๏ธ  Google Sheets sync will not work without credentials")
    
    print()


def start_automation():
    """Start the automation runner in the background"""
    global automation_process
    
    # Check if automation script exists
    if not AUTOMATION_RUNNER.exists():
        print(f"โš ๏ธ  Automation runner not found: {AUTOMATION_RUNNER}")
        return
    
    # Check if config exists
    config_file = BASE_DIR / "config.json"
    if not config_file.exists():
        print("โš ๏ธ  config.json not found, skipping automation startup")
        return
    
    print("๐Ÿš€ Starting automation runner...")
    try:
        automation_process = subprocess.Popen(
            [sys.executable, str(AUTOMATION_RUNNER)],
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            bufsize=1
        )
        
        # Stream automation output in a separate thread
        def stream_output():
            for line in automation_process.stdout:
                print(f"[AUTOMATION] {line}", end='')
        
        threading.Thread(target=stream_output, daemon=True).start()
        print("โœ… Automation runner started\n")
    except Exception as e:
        print(f"โŒ Failed to start automation: {e}\n")


def cleanup(signum=None, frame=None):
    """Cleanup function to terminate background processes"""
    global automation_process
    print("\n\n๐Ÿ›‘ Shutting down...")
    
    if automation_process:
        print("๐Ÿงน Stopping automation runner...")
        automation_process.terminate()
        automation_process.wait(timeout=5)
    
    print("โœ… Cleanup complete\n")
    sys.exit(0)


class CustomHTTPRequestHandler(SimpleHTTPRequestHandler):
    """Custom handler to serve from the correct directory"""
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, directory=str(BASE_DIR), **kwargs)
    
    def log_message(self, format, *args):
        """Custom logging to show requests"""
        print(f"[WEB] {self.address_string()} - {format % args}")


def start_web_server():
    """Start the HTTP server to serve the static files"""
    print(f"๐ŸŒ Starting web server on port {PORT}...")
    
    handler = CustomHTTPRequestHandler
    httpd = HTTPServer(('0.0.0.0', PORT), handler)
    
    print(f"โœ… Web server running at http://0.0.0.0:{PORT}")
    print(f"๐Ÿ“Š Open the map: http://0.0.0.0:{PORT}/index.html")
    print(f"๐Ÿ’ก Press Ctrl+C to stop\n")
    
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    finally:
        httpd.shutdown()


def main():
    """Main entry point"""
    print("=" * 70)
    print("๐Ÿ—บ๏ธ  Telugu Dialect Map - Hugging Face Spaces")
    print("=" * 70)
    print()
    
    # Register signal handlers for graceful shutdown
    signal.signal(signal.SIGINT, cleanup)
    signal.signal(signal.SIGTERM, cleanup)
    
    # Load secrets from environment variables
    load_secrets_from_env()
    
    # Start background automation
    start_automation()
    
    # Give automation a moment to start
    time.sleep(2)
    
    # Start web server (blocks here)
    start_web_server()
    
    # Cleanup (if we ever get here)
    cleanup()


if __name__ == "__main__":
    main()