Ai_GirlFriend/upload_gifts_to_oss.py

201 lines
6.8 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
礼物图片上传到阿里云 OSS 脚本仅上传现有的 29 个图片
"""
import os
import sys
from pathlib import Path
import oss2
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
# OSS 配置
ACCESS_KEY_ID = os.getenv('ALIYUN_OSS_ACCESS_KEY_ID')
ACCESS_KEY_SECRET = os.getenv('ALIYUN_OSS_ACCESS_KEY_SECRET')
BUCKET_NAME = os.getenv('ALIYUN_OSS_BUCKET_NAME')
ENDPOINT = os.getenv('ALIYUN_OSS_ENDPOINT', 'https://oss-cn-hangzhou.aliyuncs.com')
CDN_DOMAIN = os.getenv('ALIYUN_OSS_CDN_DOMAIN')
# 图片源目录
SOURCE_DIR = Path('开发/2026年2月4日/Gift')
# 文件映射(源文件名 -> OSS 对象名)- 仅包含实际存在的 29 个文件
FILE_MAP = {
# 经济类礼物10-50金币- 10个
"玫瑰花.png": "uploads/gifts/rose.png",
"棒棒糖.png": "uploads/gifts/lollipop.png",
"咖啡.png": "uploads/gifts/coffee.png",
"冰淇淋.png": "uploads/gifts/icecream.png",
"小蛋糕.png": "uploads/gifts/cake.png",
"巧克力.png": "uploads/gifts/chocolate.png",
"奶茶.png": "uploads/gifts/milktea.png",
"爱心气球.png": "uploads/gifts/heart_balloon.png",
"小礼物盒.png": "uploads/gifts/gift_box.png",
"彩虹.png": "uploads/gifts/rainbow.png",
# 中档礼物50-200金币- 9个
"香槟.png": "uploads/gifts/champagne.png",
"钻石.png": "uploads/gifts/diamond.png",
"王冠.png": "uploads/gifts/crown.png",
"爱心.png": "uploads/gifts/big_heart.png",
"月亮.png": "uploads/gifts/moon.png",
"烟花.png": "uploads/gifts/fireworks.png",
"水晶球.png": "uploads/gifts/crystal_ball.png",
"玫瑰花束.png": "uploads/gifts/rose_bouquet.png",
"星星项链.png": "uploads/gifts/star_necklace.png",
# 高级礼物200-500金币- 4个
"跑车.png": "uploads/gifts/sports_car.png",
"飞机.png": "uploads/gifts/airplane.png",
"游艇.png": "uploads/gifts/yacht.png",
"城堡.png": "uploads/gifts/castle.png",
# 特殊礼物500+金币)- 2个
"宇宙飞船.png": "uploads/gifts/spaceship.png",
"魔法棒.png": "uploads/gifts/magic_wand.png",
# 节日限定礼物 - 4个
"圣诞树.png": "uploads/gifts/christmas_tree.png",
"情人节巧克力.png": "uploads/gifts/valentine_chocolate.png",
"生日蛋糕.png": "uploads/gifts/birthday_cake.png",
"万圣节南瓜.png": "uploads/gifts/halloween_pumpkin.png",
}
def upload_to_oss():
"""上传图片到 OSS"""
# 检查配置
if not all([ACCESS_KEY_ID, ACCESS_KEY_SECRET, BUCKET_NAME]):
print("❌ 错误OSS 配置不完整")
print(f"ACCESS_KEY_ID: {'已配置' if ACCESS_KEY_ID else '未配置'}")
print(f"ACCESS_KEY_SECRET: {'已配置' if ACCESS_KEY_SECRET else '未配置'}")
print(f"BUCKET_NAME: {BUCKET_NAME or '未配置'}")
return False
print("=" * 70)
print(" 礼物图片上传到阿里云 OSS")
print("=" * 70)
print()
print(f"📦 OSS Bucket: {BUCKET_NAME}")
print(f"🌐 OSS Endpoint: {ENDPOINT}")
print(f"🚀 CDN Domain: {CDN_DOMAIN or '未配置'}")
print(f"📁 源目录: {SOURCE_DIR}")
print(f"📊 待上传文件数: {len(FILE_MAP)}")
print()
# 初始化 OSS
try:
auth = oss2.Auth(ACCESS_KEY_ID, ACCESS_KEY_SECRET)
# 去掉 endpoint 中的 https://
endpoint_clean = ENDPOINT.replace('https://', '').replace('http://', '')
bucket = oss2.Bucket(auth, endpoint_clean, BUCKET_NAME)
# 测试连接
bucket.get_bucket_info()
print("✓ OSS 连接成功")
print()
except Exception as e:
print(f"❌ OSS 连接失败: {e}")
return False
# 检查源目录
if not SOURCE_DIR.exists():
print(f"❌ 错误:源目录不存在: {SOURCE_DIR}")
return False
# 上传文件
uploaded_count = 0
failed_count = 0
skipped_count = 0
print("开始上传图片...")
print()
for idx, (source_file, oss_object) in enumerate(FILE_MAP.items(), 1):
source_path = SOURCE_DIR / source_file
if not source_path.exists():
print(f"[{idx}/{len(FILE_MAP)}] ⚠️ 跳过(文件不存在): {source_file}")
skipped_count += 1
continue
try:
# 读取文件
with open(source_path, 'rb') as f:
file_data = f.read()
file_size = len(file_data) / 1024 # KB
# 上传到 OSS
bucket.put_object(oss_object, file_data)
# 生成访问 URL
if CDN_DOMAIN:
url = f"{CDN_DOMAIN.rstrip('/')}/{oss_object}"
else:
url = f"https://{BUCKET_NAME}.{endpoint_clean}/{oss_object}"
print(f"[{idx}/{len(FILE_MAP)}] ✓ 已上传: {source_file}")
print(f" 大小: {file_size:.1f} KB")
print(f" OSS: {oss_object}")
print(f" URL: {url}")
print()
uploaded_count += 1
except Exception as e:
print(f"[{idx}/{len(FILE_MAP)}] ❌ 上传失败: {source_file}")
print(f" 错误: {e}")
print()
failed_count += 1
# 统计结果
print("=" * 70)
print(" 上传完成")
print("=" * 70)
print()
print(f"✓ 成功上传: {uploaded_count} 个文件")
if failed_count > 0:
print(f"✗ 上传失败: {failed_count} 个文件")
if skipped_count > 0:
print(f"⚠ 跳过文件: {skipped_count} 个文件")
print()
if uploaded_count > 0:
print("=" * 70)
print(" 下一步操作")
print("=" * 70)
print()
print("1⃣ 执行 SQL 文件导入数据库")
print(" 📄 文件:开发/2026年2月4日/数据填充_礼物种类_最终版.sql")
print()
print("2⃣ 重启 Python 服务(如果需要)")
print(" 💻 命令python -m uvicorn lover.main:app --host 0.0.0.0 --port 30101 --reload")
print()
print("3⃣ 测试前端礼物功能")
print(" 📱 打开前端应用 → 查看礼物列表")
print()
print("4⃣ 验证图片访问")
print(f" 🌐 示例:{CDN_DOMAIN or f'https://{BUCKET_NAME}.{endpoint_clean}'}/uploads/gifts/rose.png")
print()
return uploaded_count > 0
if __name__ == "__main__":
try:
success = upload_to_oss()
sys.exit(0 if success else 1)
except KeyboardInterrupt:
print("\n\n⚠️ 用户中断")
sys.exit(1)
except Exception as e:
print(f"\n❌ 发生错误: {e}")
import traceback
traceback.print_exc()
sys.exit(1)