import re from pathlib import Path def ensure_dir(path: Path): path.mkdir(parents=True, exist_ok=True) def _add_to_installed_apps(content: str, app_name: str) -> str: """ Safely add an app to INSTALLED_APPS if not already present. """ pattern = re.compile(r"INSTALLED_APPS\s*=\s*\[(.*?)\]", re.DOTALL) match = pattern.search(content) if not match: return content apps_block = match.group(1) if f"'{app_name}'" in apps_block or f'"{app_name}"' in apps_block: return content updated_apps = apps_block.rstrip() + f"\n '{app_name}'," return content[:match.start(1)] + updated_apps + content[match.end(1):] def update_settings_py(settings_path, db_spec, app_names=None): settings_path = Path(settings_path) content = settings_path.read_text(encoding="utf-8") # -------------------------------------------------- # 1. Ensure BASE_DIR # -------------------------------------------------- if "BASE_DIR" not in content: content = ( "from pathlib import Path\n\n" "BASE_DIR = Path(__file__).resolve().parent.parent\n\n" + content ) # -------------------------------------------------- # 2. Ensure rest_framework + project apps # -------------------------------------------------- content = _add_to_installed_apps(content, "rest_framework") if app_names: for app in app_names: content = _add_to_installed_apps(content, app) # -------------------------------------------------- # 3. Database config (ONLY if NOT sqlite) # -------------------------------------------------- engine = (db_spec or {}).get("engine", "").lower() if engine and engine != "sqlite": engine_map = { "postgresql": "django.db.backends.postgresql", "postgres": "django.db.backends.postgresql", "mysql": "django.db.backends.mysql", "mariadb": "django.db.backends.mysql", } django_engine = engine_map.get(engine) if not django_engine: raise ValueError(f"Unsupported DB engine: {engine}") database_block = f""" DATABASES = {{ 'default': {{ 'ENGINE': '{django_engine}', 'NAME': '{db_spec.get("name")}', 'USER': '{db_spec.get("user", "")}', 'PASSWORD': '{db_spec.get("password", "")}', 'HOST': '{db_spec.get("host", "")}', 'PORT': '{db_spec.get("port", "")}', }} }} """.strip() content = re.sub( r"DATABASES\s*=\s*\{.*?\}\s*\}\s*", database_block + "\n\n", content, flags=re.DOTALL ) # -------------------------------------------------- # 4. Static & Media (idempotent) # -------------------------------------------------- if "STATIC_ROOT" not in content: content += """ # Static files STATIC_URL = "/static/" STATIC_ROOT = BASE_DIR / "staticfiles" STATICFILES_DIRS = [BASE_DIR / "static"] # Media files MEDIA_URL = "/media/" MEDIA_ROOT = BASE_DIR / "media" """ # -------------------------------------------------- # 5. Write file # -------------------------------------------------- settings_path.write_text(content, encoding="utf-8") # -------------------------------------------------- # 6. Create folders # -------------------------------------------------- project_root = settings_path.parents[2] ensure_dir(project_root / "static") ensure_dir(project_root / "media") ensure_dir(project_root / "staticfiles") #print("✅ settings.py updated correctly")