diff options
Diffstat (limited to 'manage.py')
-rwxr-xr-x | manage.py | 89 |
1 files changed, 44 insertions, 45 deletions
@@ -1,10 +1,8 @@ #!/usr/bin/env python import os -import re -import socket +import platform import sys -import time -from typing import List +from pathlib import Path import django from django.contrib.auth import get_user_model @@ -42,7 +40,7 @@ class SiteManager: --verbose Sets verbose console output. """ - def __init__(self, args: List[str]): + def __init__(self, args: list[str]): self.debug = "--debug" in args self.silent = "--silent" in args @@ -85,38 +83,6 @@ class SiteManager: print(f"Existing bot token found: {token}") @staticmethod - def wait_for_postgres() -> None: - """Wait for the PostgreSQL database specified in DATABASE_URL.""" - print("Waiting for PostgreSQL database.") - - # Get database URL based on environmental variable passed in compose - database_url = os.environ["DATABASE_URL"] - match = re.search(r"@([\w.]+):(\d+)/", database_url) - if not match: - raise OSError("Valid DATABASE_URL environmental variable not found.") - domain = match.group(1) - port = int(match.group(2)) - - # Attempt to connect to the database socket - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - - attempts_left = 10 - while attempts_left: - try: - # Ignore 'incomplete startup packet' - s.connect((domain, port)) - s.shutdown(socket.SHUT_RDWR) - print("Database is ready.") - break - except socket.error: - attempts_left -= 1 - print("Not ready yet, retrying.") - time.sleep(0.5) - else: - print("Database could not be found, exiting.") - sys.exit(1) - - @staticmethod def set_dev_site_name() -> None: """Set the development site domain in admin from default example.""" # import Site model now after django setup @@ -133,15 +99,19 @@ class SiteManager: """Perform preparation tasks before running the server.""" django.setup() - if self.debug: - self.wait_for_postgres() - print("Applying migrations.") call_command("migrate", verbosity=self.verbosity) - print("Collecting static files.") - call_command("collectstatic", interactive=False, clear=True, verbosity=self.verbosity) if self.debug: + # In Production, collectstatic is ran in the Docker image + print("Collecting static files.") + call_command( + "collectstatic", + interactive=False, + clear=True, + verbosity=self.verbosity - 1 + ) + self.set_dev_site_name() self.create_superuser() @@ -169,18 +139,32 @@ class SiteManager: "--preload", "-b", "0.0.0.0:8000", "pydis_site.wsgi:application", - "--threads", "8", "-w", "2", - "--max-requests", "1000", - "--max-requests-jitter", "50", "--statsd-host", "graphite.default.svc.cluster.local:8125", "--statsd-prefix", "site", + "--config", "file:gunicorn.conf.py" ] # Run gunicorn for the production server. gunicorn.app.wsgiapp.run() +def clean_up_static_files(build_folder: Path) -> None: + """Recursively loop over the build directory and fix links.""" + for file in build_folder.iterdir(): + if file.is_dir(): + clean_up_static_files(file) + elif file.name.endswith(".html"): + # Fix parent host url + new = file.read_text(encoding="utf-8").replace(f"//{os.getenv('PARENT_HOST')}", "") + + # Fix windows paths if on windows + if platform.system() == "Windows": + new = new.replace("%5C", "/") + + file.write_text(new, encoding="utf-8") + + def main() -> None: """Entry point for Django management script.""" # Use the custom site manager for launching the server @@ -189,8 +173,23 @@ def main() -> None: # Pass any others directly to standard management commands else: + _static_build = "distill" in sys.argv[1] + + if _static_build: + # Build a static version of the site with no databases and API support + os.environ["STATIC_BUILD"] = "True" + if not os.getenv("PARENT_HOST"): + os.environ["PARENT_HOST"] = "REPLACE_THIS.HOST" + execute_from_command_line(sys.argv) + if _static_build: + # Clean up parent host in generated files + for arg in sys.argv[2:]: + if not arg.startswith("-"): + clean_up_static_files(Path(arg)) + break + if __name__ == '__main__': main() |