89 lines
3.0 KiB
Python
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)
|