Files
bellsystems-cp/backend/scripts/fix_storage_acl.py
2026-04-03 18:08:07 +03:00

89 lines
3.0 KiB
Python

"""
Fixup: call make_public() on every .bsm binary blob under melodies/ in Firebase Storage.
Run this if blobs were uploaded but are returning AccessDenied.
docker exec -it bellsystems-backend python scripts/fix_storage_acl.py --dry-run
docker exec -it bellsystems-backend python scripts/fix_storage_acl.py
"""
import argparse
import os
import sys
from pathlib import Path
# ---------------------------------------------------------------------------
# .env loader
# ---------------------------------------------------------------------------
def _load_env() -> dict:
search = Path(__file__).resolve().parent
for _ in range(4):
env_file = search / ".env"
if env_file.exists():
result = {}
for line in env_file.read_text(encoding="utf-8").splitlines():
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, _, val = line.partition("=")
result[key.strip()] = val.strip().strip('"').strip("'")
print(f"[INFO] Loaded config from {env_file}")
return result
search = search.parent
return {}
_env = _load_env()
def _cfg(key: str, default: str = "") -> str:
return _env.get(key) or os.environ.get(key) or default
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
def run(dry_run: bool = False):
label = "[DRY-RUN]" if dry_run else "[LIVE]"
sa_path = _cfg("FIREBASE_SERVICE_ACCOUNT_PATH", "./firebase-service-account.json")
bucket_name = _cfg("FIREBASE_STORAGE_BUCKET")
if not bucket_name:
print("ERROR: FIREBASE_STORAGE_BUCKET not set in .env")
sys.exit(1)
import firebase_admin
from firebase_admin import credentials, storage as fb_storage
cred = credentials.Certificate(sa_path)
firebase_admin.initialize_app(cred, {"storageBucket": bucket_name})
bucket = fb_storage.bucket()
print(f"\n{label} Scanning melodies/ in bucket: {bucket_name}\n")
blobs = list(bucket.list_blobs(prefix="melodies/"))
bsm_blobs = [b for b in blobs if b.name.lower().endswith(".bsm")]
print(f"Found {len(bsm_blobs)} .bsm blob(s)\n")
fixed = 0
for blob in bsm_blobs:
print(f" {'[skip] ' if dry_run else '[fix] '}{blob.name}")
if not dry_run:
try:
blob.make_public()
fixed += 1
except Exception as e:
print(f" ERROR: {e}")
print(f"\n{label} Done. {fixed if not dry_run else len(bsm_blobs)} blob(s) {'would be ' if dry_run else ''}made public.")
if dry_run:
print("Run without --dry-run to apply.")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Make all melody .bsm blobs public in Firebase Storage")
parser.add_argument("--dry-run", action="store_true")
args = parser.parse_args()
run(dry_run=args.dry_run)