feat:open_use_old_result and open_keep_all

This commit is contained in:
guorong.zheng 2024-07-31 17:31:51 +08:00
parent 9289828af0
commit 7de4615181
6 changed files with 155 additions and 73 deletions

@ -1,4 +1,5 @@
open_update = True
open_use_old_result = True
source_file = "demo.txt"
final_file = "result.txt"
favorite_list = [
@ -18,6 +19,7 @@ open_online_search = True
favorite_page_num = 5
default_page_num = 3
urls_limit = 15
open_keep_all = False
open_sort = True
response_time_weight = 0.5
resolution_weight = 0.5

@ -1,6 +1,7 @@
| 配置项 | 默认值 | 描述 |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| open_update | True | 开启更新,若关闭则只运行结果页面服务 |
| open_use_old_result | True | 开启使用历史更新结果,合并至本次更新中 |
| open_driver | False | 开启浏览器运行,若更新无数据可开启此模式,较消耗性能 |
| open_proxy | True | 开启代理,自动获取免费可用代理,若更新无数据可开启此模式 |
| source_file | "demo.txt" | 模板文件名称 |
@ -10,6 +11,7 @@
| favorite_page_num | 5 | 关注频道获取分页数量 |
| default_page_num | 3 | 常规频道获取分页数量 |
| urls_limit | 10 | 单个频道接口数量 |
| open_keep_all | False | 保留所有检索结果,会保留非模板频道名称的结果,推荐手动维护时开启 |
| open_sort | True | 开启排序功能(响应速度、日期、分辨率) |
| response_time_weight | 0.5 | 响应时间权重值(所有权重值总和应为 1 |
| resolution_weight | 0.5 | 分辨率权重值 (所有权重值总和应为 1 |

@ -1,23 +1,25 @@
| Configuration Item | Default Value | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| open_update | True | Enable updates, if disabled then only the result page service is run |
| open_driver | False | Enable browser execution, If there are no updates, this mode can be enabled, which consumes more performance |
| open_proxy | True | Enable proxy, automatically obtains free available proxies, If there are no updates, this mode can be enabled |
| source_file | "demo.txt" | Template file name |
| final_file | "result.txt" | Generated file name |
| favorite_list | ["广东珠江","CCTV-1","CCTV-5","CCTV-5+","CCTV-13","广东体育","广东卫视","大湾区卫视","浙江卫视","湖南卫视","翡翠台"] | List of favorite channel names (used only to distinguish from regular channels, custom page retrieval quantity) |
| open_online_search | False | Enable online search source feature |
| favorite_page_num | 5 | Page retrieval quantity for favorite channels |
| default_page_num | 3 | Page retrieval quantity for regular channels |
| urls_limit | 10 | Number of interfaces per channel |
| open_sort | True | Enable the sorting function (response speed, date, resolution) |
| response_time_weight | 0.5 | Response time weight value (the sum of all weight values should be 1) |
| resolution_weight | 0.5 | Resolution weight value (the sum of all weight values should be 1) |
| recent_days | 30 | Retrieve interfaces updated within a recent time range (in days), reducing appropriately can avoid matching issues |
| ipv_type | "ipv4" | The type of interface in the generated result, optional values: "ipv4", "ipv6", "all" |
| domain_blacklist | ["epg.pw"] | Interface domain blacklist, used to filter out interfaces with low-quality, ad-inclusive domains |
| url_keywords_blacklist | [] | Interface keyword blacklist, used to filter out interfaces containing specific characters |
| open_subscribe | True | Enable subscription source feature |
| subscribe_urls | ["https://m3u.ibert.me/txt/fmml_dv6.txt",<br>"https://m3u.ibert.me/txt/o_cn.txt",<br>"https://m3u.ibert.me/txt/j_iptv.txt"] | Subscription source list |
| open_multicast | True | Enable multicast source function |
| region_list | ["all"] | Multicast source region list, [more regions](./fofa_map.py, "all" means all regions) |
| Configuration Item | Default Value | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| open_update | True | Enable updates, if disabled then only the result page service is run |
| open_use_old_result | True | Enable the use of historical update results and merge them into the current update |
| open_driver | False | Enable browser execution, If there are no updates, this mode can be enabled, which consumes more performance |
| open_proxy | True | Enable proxy, automatically obtains free available proxies, If there are no updates, this mode can be enabled |
| source_file | "demo.txt" | Template file name |
| final_file | "result.txt" | Generated file name |
| favorite_list | ["广东珠江","CCTV-1","CCTV-5","CCTV-5+","CCTV-13","广东体育","广东卫视","大湾区卫视","浙江卫视","湖南卫视","翡翠台"] | List of favorite channel names (used only to distinguish from regular channels, custom page retrieval quantity) |
| open_online_search | False | Enable online search source feature |
| favorite_page_num | 5 | Page retrieval quantity for favorite channels |
| default_page_num | 3 | Page retrieval quantity for regular channels |
| urls_limit | 10 | Number of interfaces per channel |
| open_keep_all | False | Retain all search results, retain results with non-template channel names, recommended to be turned on when manually maintaining |
| open_sort | True | Enable the sorting function (response speed, date, resolution) |
| response_time_weight | 0.5 | Response time weight value (the sum of all weight values should be 1) |
| resolution_weight | 0.5 | Resolution weight value (the sum of all weight values should be 1) |
| recent_days | 30 | Retrieve interfaces updated within a recent time range (in days), reducing appropriately can avoid matching issues |
| ipv_type | "ipv4" | The type of interface in the generated result, optional values: "ipv4", "ipv6", "all" |
| domain_blacklist | ["epg.pw"] | Interface domain blacklist, used to filter out interfaces with low-quality, ad-inclusive domains |
| url_keywords_blacklist | [] | Interface keyword blacklist, used to filter out interfaces containing specific characters |
| open_subscribe | True | Enable subscription source feature |
| subscribe_urls | ["https://m3u.ibert.me/txt/fmml_dv6.txt",<br>"https://m3u.ibert.me/txt/o_cn.txt",<br>"https://m3u.ibert.me/txt/j_iptv.txt"] | Subscription source list |
| open_multicast | True | Enable multicast source function |
| region_list | ["all"] | Multicast source region list, [more regions](./fofa_map.py, "all" means all regions) |

@ -3,7 +3,7 @@ from utils.config import get_config
from utils.channel import (
get_channel_items,
append_data_to_info_data,
append_all_method_data,
append_total_data,
sort_channel_list,
write_channel_to_file,
)
@ -86,7 +86,7 @@ class UpdateSource:
self.total = len(channel_names)
await self.visit_page(channel_names)
self.tasks = []
self.channel_data = append_all_method_data(
self.channel_data = append_total_data(
self.channel_items.items(),
self.channel_data,
self.subscribe_result,

@ -24,11 +24,12 @@ class TkinterUI:
def __init__(self, root):
self.root = root
self.root.title("直播源接口更新工具")
self.version = "v1.3.3"
self.version = "v1.3.4"
self.update_source = UpdateSource()
self.update_running = False
self.config_entrys = [
"open_update_checkbutton",
"open_use_old_result_checkbutton",
"open_driver_checkbutton",
"open_proxy_checkbutton",
"source_file_entry",
@ -38,6 +39,7 @@ class TkinterUI:
"open_subscribe_checkbutton",
"open_multicast_checkbutton",
"open_online_search_checkbutton",
"open_keep_all_checkbutton",
"open_sort_checkbutton",
"favorite_list_text",
"favorite_page_num_entry",
@ -60,6 +62,9 @@ class TkinterUI:
def update_open_update(self):
config.open_update = self.open_update_var.get()
def update_open_use_old_result(self):
config.open_use_old_result = self.open_use_old_result_var.get()
def select_source_file(self):
filepath = filedialog.askopenfilename(
initialdir=os.getcwd(), title="选择模板文件", filetypes=[("txt", "*.txt")]
@ -93,6 +98,9 @@ class TkinterUI:
def update_open_proxy(self):
config.open_proxy = self.open_proxy_var.get()
def update_open_keep_all(self):
config.open_keep_all = self.open_keep_all_var.get()
def update_open_sort(self):
config.open_sort = self.open_sort_var.get()
@ -151,6 +159,7 @@ class TkinterUI:
def save_config(self):
config_values = {
"open_update": self.open_update_var.get(),
"open_use_old_result": self.open_use_old_result_var.get(),
"source_file": f'"{self.source_file_entry.get()}"',
"final_file": f'"{self.final_file_entry.get()}"',
"favorite_list": self.format_list(self.favorite_list_text.get(1.0, tk.END)),
@ -160,6 +169,7 @@ class TkinterUI:
"urls_limit": self.urls_limit_entry.get(),
"open_driver": self.open_driver_var.get(),
"open_proxy": self.open_proxy_var.get(),
"open_keep_all": self.open_keep_all_var.get(),
"open_sort": self.open_sort_var.get(),
"response_time_weight": self.response_time_weight_entry.get(),
"resolution_weight": self.resolution_weight_entry.get(),
@ -255,12 +265,18 @@ class TkinterUI:
frame1_open_update = tk.Frame(frame1)
frame1_open_update.pack(fill=tk.X)
frame1_open_update_column1 = tk.Frame(frame1_open_update)
frame1_open_update_column1.pack(side=tk.LEFT, fill=tk.Y)
frame1_open_update_column2 = tk.Frame(frame1_open_update)
frame1_open_update_column2.pack(side=tk.RIGHT, fill=tk.Y)
self.open_update_label = tk.Label(frame1_open_update, text="开启更新:", width=8)
self.open_update_label = tk.Label(
frame1_open_update_column1, text="开启更新:", width=8
)
self.open_update_label.pack(side=tk.LEFT, padx=4, pady=8)
self.open_update_var = tk.BooleanVar(value=config.open_update)
self.open_update_checkbutton = ttk.Checkbutton(
frame1_open_update,
frame1_open_update_column1,
variable=self.open_update_var,
onvalue=True,
offvalue=False,
@ -269,6 +285,21 @@ class TkinterUI:
)
self.open_update_checkbutton.pack(side=tk.LEFT, padx=4, pady=8)
self.open_use_old_result_label = tk.Label(
frame1_open_update_column2, text="使用历史结果:", width=12
)
self.open_use_old_result_label.pack(side=tk.LEFT, padx=4, pady=8)
self.open_use_old_result_var = tk.BooleanVar(value=config.open_use_old_result)
self.open_use_old_result_checkbutton = ttk.Checkbutton(
frame1_open_update_column2,
variable=self.open_use_old_result_var,
onvalue=True,
offvalue=False,
command=self.update_open_use_old_result,
text="(保留上次更新可用结果)",
)
self.open_use_old_result_checkbutton.pack(side=tk.LEFT, padx=4, pady=8)
frame1_source_file = tk.Frame(frame1)
frame1_source_file.pack(fill=tk.X)
@ -336,7 +367,7 @@ class TkinterUI:
onvalue=True,
offvalue=False,
command=self.update_open_proxy,
text="(自动获取免费代理)",
text="(通过代理获取更新结果)",
)
self.open_proxy_checkbutton.pack(side=tk.LEFT, padx=4, pady=8)
@ -368,12 +399,33 @@ class TkinterUI:
frame1_sort = tk.Frame(frame1)
frame1_sort.pack(fill=tk.X)
frame1_sort_column1 = tk.Frame(frame1_sort)
frame1_sort_column1.pack(side=tk.LEFT, fill=tk.Y)
frame1_sort_column2 = tk.Frame(frame1_sort)
frame1_sort_column2.pack(side=tk.RIGHT, fill=tk.Y)
self.open_sort_label = tk.Label(frame1_sort, text="开启测速排序:", width=12)
self.open_keep_all_label = tk.Label(
frame1_sort_column1, text="保留模式:", width=12
)
self.open_keep_all_label.pack(side=tk.LEFT, padx=4, pady=8)
self.open_keep_all_var = tk.BooleanVar(value=config.open_keep_all)
self.open_keep_all_checkbutton = ttk.Checkbutton(
frame1_sort_column1,
variable=self.open_keep_all_var,
onvalue=True,
offvalue=False,
command=self.update_open_keep_all,
text="(保留所有检索结果,建议手动维护时开启)",
)
self.open_keep_all_checkbutton.pack(side=tk.LEFT, padx=4, pady=8)
self.open_sort_label = tk.Label(
frame1_sort_column2, text="开启测速排序:", width=12
)
self.open_sort_label.pack(side=tk.LEFT, padx=4, pady=8)
self.open_sort_var = tk.BooleanVar(value=config.open_sort)
self.open_sort_checkbutton = ttk.Checkbutton(
frame1_sort,
frame1_sort_column2,
variable=self.open_sort_var,
onvalue=True,
offvalue=False,
@ -642,7 +694,7 @@ if __name__ == "__main__":
tkinter_ui.init_UI()
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
width = 500
width = 550
height = 700
x = (screen_width / 2) - (width / 2)
y = (screen_height / 2) - (height / 2)

@ -63,12 +63,13 @@ def get_channel_items():
# Create a dictionary to store the channels.
channels = defaultdict(lambda: defaultdict(list))
with open(resource_path(user_source_file), "r", encoding="utf-8") as file:
get_channel_data_from_file(channels, file)
if os.path.exists(resource_path(user_source_file)):
with open(resource_path(user_source_file), "r", encoding="utf-8") as file:
channels = get_channel_data_from_file(channels, file)
if config.open_use_old_result:
if config.open_use_old_result and os.path.exists(resource_path(user_final_file)):
with open(resource_path(user_final_file), "r", encoding="utf-8") as file:
get_channel_data_from_file(channels, file)
channels = get_channel_data_from_file(channels, file)
return channels
@ -77,6 +78,8 @@ def format_channel_name(name):
"""
Format the channel name with sub and replace and lower
"""
if config.open_keep_all:
return name
sub_pattern = (
r"-|_|\((.*?)\)|\[(.*?)\]| |频道|标清|高清|HD|hd|超清|超高|超高清|中央|央视|台"
)
@ -119,6 +122,8 @@ def channel_name_is_equal(name1, name2):
"""
Check if the channel name is equal
"""
if config.open_keep_all:
return True
cc = OpenCC("t2s")
name1_converted = cc.convert(format_channel_name(name1))
name2_converted = cc.convert(format_channel_name(name2))
@ -278,6 +283,16 @@ def append_data_to_info_data(info_data, cate, name, data, check=True):
return info_data
def append_total_data(*args, **kwargs):
"""
Append total channel data
"""
if config.open_keep_all:
return append_all_method_data_keep_all(*args, **kwargs)
else:
return append_all_method_data(*args, **kwargs)
def append_all_method_data(
items, data, subscribe_result=None, multicast_result=None, online_search_result=None
):
@ -286,44 +301,25 @@ def append_all_method_data(
"""
for cate, channel_obj in items:
for name, old_urls in channel_obj.items():
if config.open_subscribe:
data = append_data_to_info_data(
data,
cate,
name,
get_channel_results_by_name(name, subscribe_result),
)
print(
name,
"subscribe num:",
len(get_channel_results_by_name(name, subscribe_result)),
)
if config.open_multicast:
data = append_data_to_info_data(
data,
cate,
name,
get_channel_results_by_name(name, multicast_result),
)
print(
name,
"multicast num:",
len(get_channel_results_by_name(name, multicast_result)),
)
if config.open_online_search:
data = append_data_to_info_data(
data,
cate,
name,
get_channel_results_by_name(name, online_search_result),
)
print(
name,
"online search num:",
len(get_channel_results_by_name(name, online_search_result)),
)
for method, result in [
("subscribe", subscribe_result),
("multicast", multicast_result),
("online_search", online_search_result),
]:
if getattr(config, f"open_{method}"):
data = append_data_to_info_data(
data,
cate,
name,
get_channel_results_by_name(name, result),
)
print(
name,
f"{method.capitalize()} num:",
len(get_channel_results_by_name(name, result)),
)
total_channel_data_len = len(data.get(cate, {}).get(name, []))
if total_channel_data_len == 0:
if total_channel_data_len == 0 or config.open_use_old_result:
data = append_data_to_info_data(
data,
cate,
@ -338,6 +334,34 @@ def append_all_method_data(
return data
def append_all_method_data_keep_all(
items, data, subscribe_result=None, multicast_result=None, online_search_result=None
):
"""
Append all method data to total info data, keep all channel name and urls
"""
for cate, channel_obj in items:
for result_name, result in [
("subscribe", subscribe_result),
("multicast", multicast_result),
("online_search", online_search_result),
]:
if result and getattr(config, f"open_{result_name}"):
for name, urls in result.items():
data = append_data_to_info_data(data, cate, name, urls)
print(name, f"{result_name.capitalize()} num:", len(urls))
if config.open_use_old_result:
old_urls = channel_obj.get(name, [])
data = append_data_to_info_data(
data,
cate,
name,
[(url, None, None) for url in old_urls],
)
return data
async def sort_channel_list(semaphore, cate, name, info_list, callback):
"""
Sort the channel list