移除未使用的 Groq 和 Meteoblue 服务代码及配置
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env python
|
||||
"""Scrub secrets from the codebase for GitHub-safe public reference.
|
||||
|
||||
Run this on the public/github-safe branch before committing.
|
||||
It redacts hardcoded API keys, tokens, and replaces .env files.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
|
||||
# Patterns to redact (value -> REDACTED)
|
||||
SECRET_PATTERNS: list[tuple[str, str]] = [
|
||||
# Hardcoded tokens in settlement_sources.py
|
||||
(
|
||||
r'IMGW_METEO_API_TOKEN\s*=\s*"[^"]*"',
|
||||
'IMGW_METEO_API_TOKEN = os.environ.get("IMGW_METEO_API_TOKEN", "")',
|
||||
),
|
||||
(
|
||||
r'NOAA_WRH_MESO_TOKEN\s*=\s*"[^"]*"',
|
||||
'NOAA_WRH_MESO_TOKEN = os.environ.get("NOAA_WRH_MESO_TOKEN", "")',
|
||||
),
|
||||
# mesoToken in tmp files
|
||||
(
|
||||
r"var\s+mesoToken\s*=\s*'[^']*'",
|
||||
"var mesoToken = 'REDACTED'",
|
||||
),
|
||||
(
|
||||
r"mesoToken\s*=\s*'[^']*'",
|
||||
"mesoToken = 'REDACTED'",
|
||||
),
|
||||
# Any bare synopticdata URLs with tokens
|
||||
(
|
||||
r"https://api\.synopticdata\.com/v2/stations/timeseries\?[^\"'\s]*token=[^\"'&\s]+",
|
||||
"https://api.synopticdata.com/v2/stations/timeseries?token=REDACTED",
|
||||
),
|
||||
]
|
||||
|
||||
# Files to delete entirely (temp files with secrets)
|
||||
DELETE_FILES: list[str] = [
|
||||
"tmp_apikey.js",
|
||||
"tmp_obs.js",
|
||||
]
|
||||
|
||||
# Files to replace with .example counterparts
|
||||
REPLACE_WITH_EXAMPLE: dict[str, str] = {
|
||||
".env": ".env.example",
|
||||
".env.local": ".env.example",
|
||||
"frontend/.env.local": "frontend/.env.example",
|
||||
}
|
||||
|
||||
|
||||
def scrub_file(path: Path) -> bool:
|
||||
"""Apply secret patterns to a single file. Returns True if changed."""
|
||||
try:
|
||||
content = path.read_text(encoding="utf-8")
|
||||
except (UnicodeDecodeError, PermissionError):
|
||||
return False
|
||||
|
||||
original = content
|
||||
for pattern, replacement in SECRET_PATTERNS:
|
||||
content = re.sub(pattern, replacement, content)
|
||||
|
||||
if content != original:
|
||||
path.write_text(content, encoding="utf-8")
|
||||
print(f" SCRUBBED: {path.relative_to(REPO_ROOT)}")
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def main() -> None:
|
||||
print("=== Scrubbing secrets for GitHub-safe reference ===\n")
|
||||
|
||||
changes = 0
|
||||
|
||||
# 1. Delete known temp files with secrets
|
||||
for fname in DELETE_FILES:
|
||||
fpath = REPO_ROOT / fname
|
||||
if fpath.exists():
|
||||
fpath.unlink()
|
||||
print(f" DELETED: {fname}")
|
||||
changes += 1
|
||||
|
||||
# 2. Replace .env files with .example
|
||||
for target, example in REPLACE_WITH_EXAMPLE.items():
|
||||
target_path = REPO_ROOT / target
|
||||
example_path = REPO_ROOT / example
|
||||
if target_path.exists() and example_path.exists():
|
||||
shutil.copy2(example_path, target_path)
|
||||
print(f" REPLACED: {target} -> {example}")
|
||||
changes += 1
|
||||
elif target_path.exists() and not example_path.exists():
|
||||
target_path.unlink()
|
||||
print(f" DELETED: {target} (no .example to replace with)")
|
||||
changes += 1
|
||||
|
||||
# 3. Scrub hardcoded secrets in source files
|
||||
src_dirs = [
|
||||
REPO_ROOT / "src",
|
||||
REPO_ROOT / "web",
|
||||
REPO_ROOT / "frontend",
|
||||
REPO_ROOT / "scripts",
|
||||
]
|
||||
for src_dir in src_dirs:
|
||||
if not src_dir.is_dir():
|
||||
continue
|
||||
for fpath in src_dir.rglob("*.py"):
|
||||
if scrub_file(fpath):
|
||||
changes += 1
|
||||
for fpath in src_dir.rglob("*.js"):
|
||||
if scrub_file(fpath):
|
||||
changes += 1
|
||||
for fpath in src_dir.rglob("*.ts"):
|
||||
if scrub_file(fpath):
|
||||
changes += 1
|
||||
for fpath in src_dir.rglob("*.tsx"):
|
||||
if scrub_file(fpath):
|
||||
changes += 1
|
||||
|
||||
# 4. Also check root-level configs
|
||||
for fpath in REPO_ROOT.glob("*.yaml"):
|
||||
if scrub_file(fpath):
|
||||
changes += 1
|
||||
for fpath in REPO_ROOT.glob("*.yml"):
|
||||
if scrub_file(fpath):
|
||||
changes += 1
|
||||
for fpath in REPO_ROOT.glob("*.json"):
|
||||
if scrub_file(fpath):
|
||||
changes += 1
|
||||
|
||||
print(f"\n=== Done: {changes} changes made ===")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user