feat:open_use_old_result and open_keep_all
This commit is contained in:
parent
9289828af0
commit
7de4615181
@ -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) |
|
||||
|
4
main.py
4
main.py
@ -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)
|
||||
|
106
utils/channel.py
106
utils/channel.py
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user