AI 生成: IPTV直播源自动采集、检测、去重工具,支持从多个公开源采集直播源,自动检测可用性,去重后输出干净的M3U播放列表。
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Flask Web 应用:展示 IPTV 直播源结果"""
|
||||
|
||||
import os
|
||||
import json
|
||||
from flask import Flask, render_template, jsonify, request
|
||||
from collector import collect_all
|
||||
from checker import check_all
|
||||
from deduplicator import deduplicate, group_by_category
|
||||
from config import OUTPUT_DIR, OUTPUT_FILE
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# 缓存结果
|
||||
_cache = {
|
||||
"channels": [],
|
||||
"groups": {},
|
||||
"checked": False,
|
||||
}
|
||||
|
||||
|
||||
def load_from_file(filepath):
|
||||
"""从 M3U 文件加载频道"""
|
||||
channels = []
|
||||
if not os.path.exists(filepath):
|
||||
return channels
|
||||
with open(filepath, "r", encoding="utf-8") as f:
|
||||
current = None
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line.startswith("#EXTINF"):
|
||||
name = line.split(",", 1)[1] if "," in line else ""
|
||||
import re
|
||||
tvg = re.search(r'tvg-name="([^"]*)"', line)
|
||||
grp = re.search(r'group-title="([^"]*)"', line)
|
||||
current = {
|
||||
"name": name,
|
||||
"tvg_name": tvg.group(1) if tvg else name,
|
||||
"group": grp.group(1) if grp else "其他",
|
||||
"url": "",
|
||||
}
|
||||
elif line and not line.startswith("#") and current:
|
||||
current["url"] = line
|
||||
channels.append(current)
|
||||
current = None
|
||||
return channels
|
||||
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
"""首页"""
|
||||
return render_template("index.html")
|
||||
|
||||
|
||||
@app.route("/api/channels")
|
||||
def api_channels():
|
||||
"""获取频道列表"""
|
||||
return jsonify({
|
||||
"total": len(_cache["channels"]),
|
||||
"channels": _cache["channels"],
|
||||
})
|
||||
|
||||
|
||||
@app.route("/api/groups")
|
||||
def api_groups():
|
||||
"""获取分组统计"""
|
||||
groups = {}
|
||||
for g, items in _cache["groups"].items():
|
||||
groups[g] = len(items)
|
||||
return jsonify(groups)
|
||||
|
||||
|
||||
@app.route("/api/collect", methods=["POST"])
|
||||
def api_collect():
|
||||
"""触发采集+检测"""
|
||||
do_check = request.json.get("check", True) if request.is_json else True
|
||||
|
||||
channels = collect_all()
|
||||
if do_check:
|
||||
channels = check_all(channels)
|
||||
channels = deduplicate(channels)
|
||||
|
||||
_cache["channels"] = channels
|
||||
_cache["groups"] = group_by_category(channels)
|
||||
_cache["checked"] = do_check
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"total": len(channels),
|
||||
})
|
||||
|
||||
|
||||
@app.route("/api/load")
|
||||
def api_load():
|
||||
"""从输出文件加载"""
|
||||
filepath = os.path.join(OUTPUT_DIR, OUTPUT_FILE)
|
||||
channels = load_from_file(filepath)
|
||||
_cache["channels"] = channels
|
||||
_cache["groups"] = group_by_category(channels)
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"total": len(channels),
|
||||
})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 启动时尝试加载已有结果
|
||||
filepath = os.path.join(OUTPUT_DIR, OUTPUT_FILE)
|
||||
if os.path.exists(filepath):
|
||||
channels = load_from_file(filepath)
|
||||
_cache["channels"] = channels
|
||||
_cache["groups"] = group_by_category(channels)
|
||||
print(f"已加载 {len(channels)} 个频道")
|
||||
|
||||
app.run(host="0.0.0.0", port=5000, debug=False)
|
||||
Reference in New Issue
Block a user