feat: Add script to restore assets to MinIO and update DB URLs
This commit is contained in:
190
scripts/restore-assets-to-minio.py
Executable file
190
scripts/restore-assets-to-minio.py
Executable file
@@ -0,0 +1,190 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Відновлення assets: оновлення URLs в БД та завантаження файлів в MinIO
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import asyncio
|
||||
import asyncpg
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
# Додати шлях до city-service для імпорту
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent / "services" / "city-service"))
|
||||
|
||||
try:
|
||||
from lib.assets_client import upload_asset, ensure_bucket, settings
|
||||
except ImportError as e:
|
||||
print(f"❌ Помилка імпорту: {e}")
|
||||
print("Переконайтеся що ви в правильній директорії та MinIO клієнт налаштований")
|
||||
sys.exit(1)
|
||||
|
||||
# Маппінг старих URL на нові (якщо файли існують)
|
||||
OLD_TO_NEW_MAPPING = {
|
||||
"/assets/logos/clan.png": "clan",
|
||||
"/assets/logos/soul.png": "soul",
|
||||
"/assets/logos/yaromir.png": "yaromir",
|
||||
"/assets/logos/druid.png": "druid",
|
||||
"/assets/logos/nutra.png": "nutra",
|
||||
"/assets/logos/eonarch.png": "eonarch",
|
||||
"/assets/logos/helion.png": "energy-union",
|
||||
"/assets/logos/greenfood.png": "greenfood",
|
||||
"/assets/logos/daarion.png": "daarion",
|
||||
}
|
||||
|
||||
async def update_database_urls(dry_run: bool = False):
|
||||
"""Оновлює URLs в БД на правильні MinIO URLs"""
|
||||
database_url = os.getenv(
|
||||
"DATABASE_URL",
|
||||
"postgresql://postgres:postgres@localhost:5432/daarion"
|
||||
)
|
||||
|
||||
print("🔗 Підключення до БД...")
|
||||
conn = await asyncpg.connect(database_url)
|
||||
|
||||
try:
|
||||
# Отримуємо всі MicroDAO зі старими URL
|
||||
rows = await conn.fetch("""
|
||||
SELECT id, slug, logo_url, banner_url
|
||||
FROM microdaos
|
||||
WHERE logo_url IS NOT NULL OR banner_url IS NOT NULL
|
||||
""")
|
||||
|
||||
print(f"📊 Знайдено {len(rows)} MicroDAO з assets")
|
||||
|
||||
updated_count = 0
|
||||
|
||||
for row in rows:
|
||||
slug = row['slug']
|
||||
logo_url = row['logo_url']
|
||||
banner_url = row['banner_url']
|
||||
|
||||
updates = []
|
||||
|
||||
# Оновлюємо logo_url якщо потрібно
|
||||
if logo_url and (logo_url.startswith('/assets/') or not logo_url.startswith('http')):
|
||||
# Генеруємо новий URL для MinIO
|
||||
new_logo_url = f"https://assets.daarion.space/daarion-assets/microdao/logo/{slug}.png"
|
||||
|
||||
if not dry_run:
|
||||
# Спробуємо завантажити файл якщо він існує локально
|
||||
local_paths = [
|
||||
f"/opt/microdao-daarion/services/city-service/static/uploads/{slug}.png",
|
||||
f"/opt/microdao-daarion/services/city-service/static/logos/{slug}.png",
|
||||
f"/opt/microdao-daarion/public/assets/logos/{slug}.png",
|
||||
]
|
||||
|
||||
uploaded = False
|
||||
for local_path in local_paths:
|
||||
if os.path.exists(local_path):
|
||||
print(f" 📤 Завантажую логотип: {local_path}")
|
||||
try:
|
||||
with open(local_path, "rb") as f:
|
||||
new_logo_url = upload_asset(
|
||||
f,
|
||||
"image/png",
|
||||
"microdao/logo",
|
||||
filename=f"{slug}.png"
|
||||
)
|
||||
uploaded = True
|
||||
print(f" ✅ Завантажено: {new_logo_url}")
|
||||
break
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Помилка завантаження {local_path}: {e}")
|
||||
|
||||
if not uploaded:
|
||||
print(f" ⚠️ Файл логотипу не знайдено для {slug}, використовую placeholder URL")
|
||||
|
||||
updates.append(f"logo_url = '{new_logo_url}'")
|
||||
print(f" 🔄 {slug}: logo_url -> {new_logo_url}")
|
||||
|
||||
# Оновлюємо banner_url якщо потрібно
|
||||
if banner_url and (banner_url.startswith('/api/static/') or not banner_url.startswith('http')):
|
||||
# Генеруємо новий URL для MinIO
|
||||
new_banner_url = f"https://assets.daarion.space/daarion-assets/microdao/banner/{slug}.png"
|
||||
|
||||
if not dry_run:
|
||||
# Спробуємо завантажити файл якщо він існує локально
|
||||
local_paths = [
|
||||
f"/opt/microdao-daarion/services/city-service/static/uploads/{slug}_banner.png",
|
||||
f"/opt/microdao-daarion/services/city-service/static/banners/{slug}.png",
|
||||
]
|
||||
|
||||
uploaded = False
|
||||
for local_path in local_paths:
|
||||
if os.path.exists(local_path):
|
||||
print(f" 📤 Завантажую банер: {local_path}")
|
||||
try:
|
||||
with open(local_path, "rb") as f:
|
||||
new_banner_url = upload_asset(
|
||||
f,
|
||||
"image/png",
|
||||
"microdao/banner",
|
||||
filename=f"{slug}_banner.png"
|
||||
)
|
||||
uploaded = True
|
||||
print(f" ✅ Завантажено: {new_banner_url}")
|
||||
break
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Помилка завантаження {local_path}: {e}")
|
||||
|
||||
if not uploaded:
|
||||
print(f" ⚠️ Файл банера не знайдено для {slug}, залишаємо null")
|
||||
new_banner_url = None
|
||||
|
||||
if new_banner_url:
|
||||
updates.append(f"banner_url = '{new_banner_url}'")
|
||||
print(f" 🔄 {slug}: banner_url -> {new_banner_url}")
|
||||
else:
|
||||
updates.append("banner_url = NULL")
|
||||
print(f" 🔄 {slug}: banner_url -> NULL")
|
||||
|
||||
# Оновлюємо БД якщо є зміни
|
||||
if updates:
|
||||
if not dry_run:
|
||||
update_sql = f"""
|
||||
UPDATE microdaos
|
||||
SET {', '.join(updates)}
|
||||
WHERE id = $1
|
||||
"""
|
||||
await conn.execute(update_sql, row['id'])
|
||||
updated_count += 1
|
||||
else:
|
||||
print(f" [DRY RUN] Would update: {slug}")
|
||||
|
||||
print(f"\n✅ Оновлено {updated_count} записів")
|
||||
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Відновлення assets в MinIO та оновлення URLs в БД")
|
||||
parser.add_argument(
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
help="Тільки показати що буде зроблено, не змінювати БД"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
print("🚀 Відновлення assets")
|
||||
print(f"🌐 MinIO Endpoint: {settings.minio_endpoint}")
|
||||
print(f"🪣 Bucket: {settings.assets_bucket}")
|
||||
print()
|
||||
|
||||
if not args.dry_run:
|
||||
ensure_bucket()
|
||||
print(f"✅ Bucket '{settings.assets_bucket}' готовий")
|
||||
print()
|
||||
|
||||
asyncio.run(update_database_urls(dry_run=args.dry_run))
|
||||
|
||||
print("\n✅ Відновлення завершено")
|
||||
print("\n💡 Якщо файли відсутні, потрібно:")
|
||||
print(" 1. Завантажити логотипи/банери через UI")
|
||||
print(" 2. Або створити placeholder зображення")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user