"""生成 m3u 播放列表文件。""" from pathlib import Path from .parser import Channel # 分类顺序 _GROUP_ORDER = ["央视", "卫视", "地方台", "港澳台", "其他"] # 分类关键词 _CCTV_KEYWORDS = ("cctv", "cgtn", "央视", "中央") _SAT_KEYWORDS = ("卫视", "satellite") _LOCAL_KEYWORDS = ( "北京", "上海", "天津", "重庆", "广东", "江苏", "浙江", "湖南", "湖北", "河南", "河北", "山东", "山西", "陕西", "四川", "云南", "贵州", "广西", "福建", "江西", "安徽", "辽宁", "吉林", "黑龙江", "甘肃", "青海", "宁夏", "新疆", "西藏", "内蒙古", "海南", "深圳", "广州", "杭州", "南京", "武汉", "成都", "西安", ) _HMT_KEYWORDS = ("香港", "澳门", "台湾", "翡翠", "明珠", "凤凰", "tvb", "hkstv", "澳视", "莲花") def _classify(ch: Channel) -> str: """根据频道名/分组归类。""" text = f"{ch.group} {ch.name}".lower() if any(k in text for k in _CCTV_KEYWORDS): return "央视" if any(k in text for k in _HMT_KEYWORDS): return "港澳台" if any(k in text for k in _SAT_KEYWORDS): return "卫视" if any(k in ch.name for k in _LOCAL_KEYWORDS): return "地方台" return "其他" def build_m3u(channels: list[Channel]) -> str: """将频道列表转换为 m3u 字符串。""" # 分组 grouped: dict[str, list[Channel]] = {g: [] for g in _GROUP_ORDER} for ch in channels: grouped[_classify(ch)].append(ch) lines: list[str] = ["#EXTM3U"] for group in _GROUP_ORDER: items = grouped.get(group, []) if not items: continue for ch in items: attrs = [] if ch.tvg_id: attrs.append(f'tvg-id="{ch.tvg_id}"') attrs.append(f'tvg-name="{ch.name}"') if ch.logo: attrs.append(f'tvg-logo="{ch.logo}"') attrs.append(f'group-title="{group}"') attr_str = " ".join(attrs) lines.append(f"#EXTINF:-1 {attr_str},{ch.name}") lines.append(ch.url) return "\n".join(lines) + "\n" def write_m3u(channels: list[Channel], out_path: str | Path) -> Path: """写出 m3u 文件,自动创建目录。""" out = Path(out_path) out.parent.mkdir(parents=True, exist_ok=True) out.write_text(build_m3u(channels), encoding="utf-8") return out