返回 douyin-downloader
collect_mix_strategy.py
根目录 / core / user_modes / collect_mix_strategy.py
1 from __future__ import annotations
2
3 from typing import Any, Dict, List
4
5 from core.user_modes.base_strategy import BaseUserModeStrategy
6 from utils.logger import setup_logger
7
8 logger = setup_logger("CollectMixUserModeStrategy")
9
10
11 class CollectMixUserModeStrategy(BaseUserModeStrategy):
12 mode_name = "collectmix"
13 api_method_name = "get_user_collect_mix"
14
15 async def collect_items(self, sec_uid: str, user_info: Dict[str, Any]) -> List[Dict[str, Any]]:
16 fetch_collect_mix = getattr(self.downloader.api_client, self.api_method_name, None)
17 if not callable(fetch_collect_mix):
18 logger.warning("API client missing %s", self.api_method_name)
19 return []
20
21 raw_items = await self._collect_paged_entries(fetch_collect_mix, sec_uid)
22 aweme_items: List[Dict[str, Any]] = []
23 metadata_items: List[Dict[str, Any]] = []
24
25 for item in raw_items:
26 aweme = self._extract_aweme_from_item(item)
27 if aweme is not None:
28 aweme_items.append(aweme)
29 continue
30 metadata_items.append(self._normalize_mix_item(item))
31
32 if not metadata_items:
33 return aweme_items
34
35 expanded_items = await self._expand_metadata_items(
36 metadata_items,
37 id_field="mix_id",
38 id_aliases=["mixId"],
39 fetch_method_name="get_mix_aweme",
40 )
41 if not aweme_items:
42 return expanded_items
43
44 merged_items: List[Dict[str, Any]] = []
45 seen_aweme_ids: set[str] = set()
46 for item in aweme_items + expanded_items:
47 aweme_id = str(item.get("aweme_id") or "")
48 if not aweme_id or aweme_id in seen_aweme_ids:
49 continue
50 seen_aweme_ids.add(aweme_id)
51 merged_items.append(item)
52
53 return merged_items
54
55 @staticmethod
56 def _normalize_mix_item(item: Any) -> Dict[str, Any]:
57 if not isinstance(item, dict):
58 return {}
59 if item.get("mix_id") or item.get("mixId"):
60 return item
61 mix_info = item.get("mix_info")
62 if isinstance(mix_info, dict):
63 return {
64 **item,
65 "mix_id": mix_info.get("mix_id") or mix_info.get("id"),
66 }
67 return item
68
68 lines PYTHON