imetting/backend/scripts/migrate_user_asset_layout.py

98 lines
3.0 KiB
Python

from pathlib import Path
import shutil
import re
from app.core.database import get_db_connection
import app.core.config as config_module
OLD_AVATAR_PREFIX = "/uploads/user/avatar/"
NEW_AVATAR_PREFIX = "/uploads/user/"
OLD_VOICEPRINT_PREFIX = "uploads/user/voiceprint/"
NEW_VOICEPRINT_PREFIX = "uploads/user/"
def move_tree_contents(old_dir: Path, new_dir: Path):
if not old_dir.exists():
return False
new_dir.mkdir(parents=True, exist_ok=True)
moved = False
for item in old_dir.iterdir():
target = new_dir / item.name
if item.resolve() == target.resolve():
continue
if target.exists():
continue
shutil.move(str(item), str(target))
moved = True
return moved
def migrate_avatar_files():
legacy_root = config_module.LEGACY_AVATAR_DIR
if not legacy_root.exists():
return
for user_dir in legacy_root.iterdir():
if not user_dir.is_dir():
continue
target_dir = config_module.get_user_avatar_dir(user_dir.name)
move_tree_contents(user_dir, target_dir)
def migrate_voiceprint_files():
legacy_root = config_module.LEGACY_VOICEPRINT_DIR
if not legacy_root.exists():
return
for user_dir in legacy_root.iterdir():
if not user_dir.is_dir():
continue
target_dir = config_module.get_user_voiceprint_dir(user_dir.name)
move_tree_contents(user_dir, target_dir)
def migrate_avatar_urls(cursor):
cursor.execute("SELECT user_id, avatar_url FROM sys_users WHERE avatar_url LIKE %s", (f"{OLD_AVATAR_PREFIX}%",))
rows = cursor.fetchall()
for row in rows:
avatar_url = row["avatar_url"]
if not avatar_url:
continue
match = re.match(r"^/uploads/user/avatar/(\d+)/(.*)$", avatar_url)
if not match:
continue
user_id, filename = match.groups()
new_url = f"/uploads/user/{user_id}/avatar/{filename}"
cursor.execute("UPDATE sys_users SET avatar_url = %s WHERE user_id = %s", (new_url, row["user_id"]))
def migrate_voiceprint_paths(cursor):
try:
cursor.execute("SELECT vp_id, file_path FROM user_voiceprint WHERE file_path LIKE %s", (f"{OLD_VOICEPRINT_PREFIX}%",))
except Exception:
return
rows = cursor.fetchall()
for row in rows:
file_path = row["file_path"]
if not file_path:
continue
match = re.match(r"^uploads/user/voiceprint/(\d+)/(.*)$", file_path)
if not match:
continue
user_id, filename = match.groups()
new_path = f"uploads/user/{user_id}/voiceprint/{filename}"
cursor.execute("UPDATE user_voiceprint SET file_path = %s WHERE vp_id = %s", (new_path, row["vp_id"]))
def main():
migrate_avatar_files()
migrate_voiceprint_files()
with get_db_connection() as connection:
cursor = connection.cursor(dictionary=True)
migrate_avatar_urls(cursor)
migrate_voiceprint_paths(cursor)
connection.commit()
if __name__ == "__main__":
main()