fix: корректные source_url для VK постов (screen_name формат)

- VkSource: добавлено поле screen_name, заполняется из VK API при добавлении источника
- vk_parser: source_url теперь в формате vk.com/{screen_name}?w=wall{owner}_{post}
  вместо устаревшего vk.com/wall{owner}_{post}
- _vk_post_exists: проверка через LIKE чтобы находить оба формата URL
- admin_vk: автоматически получает screen_name при создании/обновлении источника
- admin_system: исправлен regex в repair-media-urls — только /news-media/ URL
- Alembic миграция: b2c3d4e5f6a7 добавляет колонку screen_name в vk_sources

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jze9
2026-05-20 19:32:28 +05:00
parent 9e277de65d
commit 615c819e97
5 changed files with 62 additions and 8 deletions

View File

@@ -361,8 +361,8 @@ async def _slug_exists(slug: str, db: AsyncSession) -> bool:
async def _vk_post_exists(owner_id: int, post_id: int, db: AsyncSession) -> bool:
source_url = f"https://vk.com/wall{owner_id}_{post_id}"
r = await db.execute(select(Article.id).where(Article.source_url == source_url))
pattern = f"%wall{owner_id}_{post_id}%"
r = await db.execute(select(Article.id).where(Article.source_url.like(pattern)))
return r.scalar_one_or_none() is not None
@@ -388,7 +388,7 @@ async def _get_or_create_tag(name: str, db: AsyncSession) -> Tag:
# ── Post processing ───────────────────────────────────────────────────────────
async def _process_post(post: dict, category_name: str, db: AsyncSession, strict_filter: bool = True) -> bool:
async def _process_post(post: dict, category_name: str, db: AsyncSession, strict_filter: bool = True, screen_name: str | None = None) -> bool:
owner_id = post["owner_id"]
post_id = post["id"]
vk_slug = _vk_slug(owner_id, post_id)
@@ -562,7 +562,10 @@ async def _process_post(post: dict, category_name: str, db: AsyncSession, strict
created_at = datetime.utcfromtimestamp(ts)
published_at = created_at if status == ArticleStatus.published else None
source_url = f"https://vk.com/wall{owner_id}_{post_id}"
if screen_name:
source_url = f"https://vk.com/{screen_name}?w=wall{owner_id}_{post_id}"
else:
source_url = f"https://vk.com/wall{owner_id}_{post_id}"
article = Article(
id=article_id,
@@ -673,7 +676,7 @@ async def run_import() -> dict:
batch_new = 0
for post in posts:
try:
ok = await _process_post(post, source.group_name, db, source.strict_filter)
ok = await _process_post(post, source.group_name, db, source.strict_filter, screen_name=source.screen_name)
if ok:
imported += 1; grp_new += 1; batch_new += 1
else: