Files
diary-news/backend/app/scripts/seed_sources.py
Mavis 6635b8fea8 fix: enum 写入 PG 用 value 而非 name
Source/SourceKind、UserRole、SubscriptionMatch 三个 enum 改用 values_callable
保证 PG 看到 'rss' / 'owner' / 'any' 等小写 value,而非 'RSS' 大写 name。
seed_sources 同步改为显式字符串。
2026-06-07 23:11:32 +08:00

116 lines
3.1 KiB
Python

"""种子:导入 MVP 5 源。
- Reuters World
- BBC World
- Al Jazeera
- NHK World
- DW
RSS 链接为公开 feed,实际链接可能变更;若 fetch 失败,先看 /admin/health。
"""
from __future__ import annotations
import asyncio
import sys
from sqlalchemy import select
from sqlalchemy.dialects.postgresql import insert as pg_insert
from sqlalchemy.exc import IntegrityError
from app.database import AsyncSessionLocal
from app.models.source import Source
# 用字符串避免 SQLAlchemy 把 enum 写成 name(大写)而非 value(小写)
SEEDS = [
{
"name": "Reuters World",
"slug": "reuters-world",
"kind": "rss",
"url": "https://feeds.reuters.com/Reuters/worldNews",
"region": "global",
"language_src": "en",
"priority": 90,
"fetch_interval_min": 30,
"translate_to": "zh",
"enabled": True,
},
{
"name": "BBC World",
"slug": "bbc-world",
"kind": "rss",
"url": "https://feeds.bbci.co.uk/news/world/rss.xml",
"region": "global",
"language_src": "en",
"priority": 85,
"fetch_interval_min": 30,
"translate_to": "zh",
"enabled": True,
},
{
"name": "Al Jazeera",
"slug": "aljazeera",
"kind": "rss",
"url": "https://www.aljazeera.com/xml/rss/all.xml",
"region": "mena",
"language_src": "en",
"priority": 80,
"fetch_interval_min": 45,
"translate_to": "zh",
"enabled": True,
},
{
"name": "NHK World",
"slug": "nhk-world",
"kind": "rss",
"url": "https://www3.nhk.or.jp/rss/news/cat0.xml",
"region": "asia",
"language_src": "en",
"priority": 70,
"fetch_interval_min": 60,
"translate_to": "zh",
"enabled": True,
},
{
"name": "DW (Deutsche Welle)",
"slug": "dw",
"kind": "rss",
"url": "https://rss.dw.com/xml/rss-en-all",
"region": "eu",
"language_src": "en",
"priority": 70,
"fetch_interval_min": 60,
"translate_to": "zh",
"enabled": True,
},
]
async def main() -> int:
async with AsyncSessionLocal() as session:
inserted = 0
for row in SEEDS:
stmt = (
pg_insert(Source)
.values(**row)
.on_conflict_do_nothing(index_elements=["slug"])
.returning(Source.id)
)
try:
r = await session.execute(stmt)
rid = r.scalar_one_or_none()
if rid is not None:
inserted += 1
print(f" + {row['slug']} (id={rid})")
else:
print(f" = {row['slug']} (already exists)")
except IntegrityError as e:
print(f" ! {row['slug']}: {e}", file=sys.stderr)
await session.rollback()
await session.commit()
print(f"seeded {inserted} new source(s)")
return 0
if __name__ == "__main__":
sys.exit(asyncio.run(main()))