173 lines
4.5 KiB
Python
173 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
start.py – Gunicorn Process Manager for SexyChat.
|
||
|
||
Usage:
|
||
python start.py start # Starts SexyChat in the background
|
||
python start.py stop # Stops the background process
|
||
python start.py restart # Restarts the background process
|
||
python start.py status # Shows if the server is running
|
||
python start.py debug # Runs in the foreground with debug logging
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import json
|
||
import subprocess
|
||
import signal
|
||
import time
|
||
import eventlet
|
||
|
||
# Monkey-patch stdlib BEFORE any other import
|
||
eventlet.monkey_patch()
|
||
|
||
# PID file to track the daemon process
|
||
PID_FILE = "sexchat.pid"
|
||
|
||
def load_config():
|
||
conf = {}
|
||
config_path = os.path.join(os.path.dirname(__file__), "config.json")
|
||
if os.path.exists(config_path):
|
||
try:
|
||
with open(config_path, "r") as f:
|
||
conf = json.load(f)
|
||
except Exception:
|
||
pass
|
||
return conf
|
||
|
||
def _get_conf(key, default=None):
|
||
conf = load_config()
|
||
return os.environ.get(key, conf.get(key, default))
|
||
|
||
def get_pid():
|
||
if os.path.exists(PID_FILE):
|
||
with open(PID_FILE, "r") as f:
|
||
try:
|
||
return int(f.read().strip())
|
||
except ValueError:
|
||
return None
|
||
return None
|
||
|
||
def is_running(pid):
|
||
if not pid:
|
||
return False
|
||
try:
|
||
os.kill(pid, 0)
|
||
except OSError:
|
||
return False
|
||
return True
|
||
|
||
def start_daemon():
|
||
pid = get_pid()
|
||
if is_running(pid):
|
||
print(f"❌ SexChat is already running (PID: {pid}).")
|
||
return
|
||
|
||
print("🚀 Starting SexChat in background...")
|
||
gunicorn_bin = os.path.join(os.path.dirname(__file__), ".venv", "bin", "gunicorn")
|
||
if not os.path.exists(gunicorn_bin):
|
||
gunicorn_bin = "gunicorn" # fallback
|
||
|
||
cmd = [
|
||
gunicorn_bin,
|
||
"--worker-class", "eventlet",
|
||
"-w", "1",
|
||
"--bind", f"{_get_conf('HOST', '0.0.0.0')}:{_get_conf('PORT', 5000)}",
|
||
"--daemon",
|
||
"--pid", PID_FILE,
|
||
"--access-logfile", "access.log",
|
||
"--error-logfile", "error.log",
|
||
"start:application"
|
||
]
|
||
subprocess.run(cmd)
|
||
time.sleep(1)
|
||
|
||
new_pid = get_pid()
|
||
if is_running(new_pid):
|
||
print(f"✅ SexChat started successfully (PID: {new_pid}).")
|
||
else:
|
||
print("❌ Failed to start SexChat. Check error.log for details.")
|
||
|
||
def stop_daemon():
|
||
pid = get_pid()
|
||
if not is_running(pid):
|
||
print("ℹ️ SexChat is not running.")
|
||
if os.path.exists(PID_FILE):
|
||
os.remove(PID_FILE)
|
||
return
|
||
|
||
print(f"🛑 Stopping SexChat (PID: {pid})...")
|
||
try:
|
||
os.kill(pid, signal.SIGTERM)
|
||
# Wait for it to die
|
||
for _ in range(10):
|
||
if not is_running(pid):
|
||
break
|
||
time.sleep(0.5)
|
||
|
||
if is_running(pid):
|
||
print("⚠️ Force killing...")
|
||
os.kill(pid, signal.SIGKILL)
|
||
|
||
if os.path.exists(PID_FILE):
|
||
os.remove(PID_FILE)
|
||
print("✅ SexChat stopped.")
|
||
except Exception as e:
|
||
print(f"❌ Error stopping: {e}")
|
||
|
||
def get_status():
|
||
pid = get_pid()
|
||
if is_running(pid):
|
||
print(f"🟢 SexChat is RUNNING (PID: {pid}).")
|
||
else:
|
||
print("🔴 SexChat is STOPPED.")
|
||
|
||
def run_debug():
|
||
print("🛠️ Starting SexChat in DEBUG mode (foreground)...")
|
||
gunicorn_bin = os.path.join(os.path.dirname(__file__), ".venv", "bin", "gunicorn")
|
||
if not os.path.exists(gunicorn_bin):
|
||
gunicorn_bin = "gunicorn" # fallback
|
||
|
||
cmd = [
|
||
gunicorn_bin,
|
||
"--worker-class", "eventlet",
|
||
"-w", "1",
|
||
"--bind", f"{_get_conf('HOST', '0.0.0.0')}:{_get_conf('PORT', 5000)}",
|
||
"--log-level", "debug",
|
||
"--access-logfile", "-",
|
||
"--error-logfile", "-",
|
||
"start:application"
|
||
]
|
||
try:
|
||
subprocess.run(cmd)
|
||
except KeyboardInterrupt:
|
||
print("\n👋 Debug session ended.")
|
||
|
||
# This is the Flask Application instance for Gunicorn
|
||
from app import create_app
|
||
application = create_app()
|
||
|
||
if __name__ == "__main__":
|
||
if len(sys.argv) < 2:
|
||
print(__doc__)
|
||
sys.exit(1)
|
||
|
||
command = sys.argv[1].lower()
|
||
|
||
if command == "start":
|
||
start_daemon()
|
||
elif command == "stop":
|
||
stop_daemon()
|
||
elif command == "restart":
|
||
stop_daemon()
|
||
time.sleep(1)
|
||
start_daemon()
|
||
elif command == "status":
|
||
get_status()
|
||
elif command == "debug":
|
||
run_debug()
|
||
else:
|
||
print(f"❌ Unknown command: {command}")
|
||
print(__doc__)
|
||
sys.exit(1)
|