unique_key.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. """Stable business identity helpers for acquired candidate items."""
  2. from __future__ import annotations
  3. from typing import Any
  4. from urllib.parse import parse_qs, urlparse
  5. def _first(params: dict[str, list[str]], key: str) -> str:
  6. values = params.get(key) or []
  7. return values[0].strip() if values and values[0] else ""
  8. def parse_weixin_unique_key(url: str | None) -> str | None:
  9. """Build the Weixin article key from URL params when all parts exist."""
  10. if not url:
  11. return None
  12. params = parse_qs(urlparse(url).query, keep_blank_values=False)
  13. biz = _first(params, "__biz")
  14. mid = _first(params, "mid")
  15. idx = _first(params, "idx")
  16. sn = _first(params, "sn")
  17. if not all([biz, mid, idx, sn]):
  18. return None
  19. return f"wx:{biz}:{mid}:{idx}:{sn}"
  20. def _raw_nested(raw_payload: dict[str, Any] | None, path: tuple[str, ...]) -> str:
  21. current: Any = raw_payload or {}
  22. for key in path:
  23. if not isinstance(current, dict):
  24. return ""
  25. current = current.get(key)
  26. return str(current).strip() if current else ""
  27. def build_unique_key(
  28. platform: str,
  29. *,
  30. platform_item_id: str | None = None,
  31. url: str | None = None,
  32. raw_payload: dict[str, Any] | None = None,
  33. ) -> str | None:
  34. """Return the formal candidate item unique_key, or None if unknown."""
  35. item_id = (platform_item_id or "").strip()
  36. if platform == "xiaohongshu":
  37. item_id = item_id or _raw_nested(raw_payload, ("candidate", "source_id"))
  38. item_id = item_id or _raw_nested(raw_payload, ("detail", "data", "data", "channel_content_id"))
  39. return f"xhs:{item_id}" if item_id else None
  40. if platform == "douyin":
  41. item_id = item_id or _raw_nested(raw_payload, ("candidate", "source_id"))
  42. item_id = item_id or _raw_nested(raw_payload, ("candidate", "raw", "id"))
  43. item_id = item_id or _raw_nested(raw_payload, ("detail", "data", "data", "channel_content_id"))
  44. return f"dy:{item_id}" if item_id else None
  45. if platform == "weixin":
  46. return parse_weixin_unique_key(url)
  47. return None