Skip to content

Commit

Permalink
Merge pull request #297 from Guovin/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Guovin authored Sep 5, 2024
2 parents c86cf79 + 831bd4b commit 799de26
Show file tree
Hide file tree
Showing 112 changed files with 229 additions and 117 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# 更新日志(Changelog)

## v1.4.0

### 2024/9/5

- 注意:本次更新涉及配置变更,请以最新 config/config.ini 为准,工作流使用 user_config.ini 或 docker 挂载的用户请及时更新配置文件
- 新增组播源运行模式:FOFA、Tonkiang
- 新增支持组播源自定义维护频道 IP,目录位于 config/rtp,文件按“地区\_运营商”命名
- 优化测速方法,大幅提升组播源、酒店源的测速速度
- 优化频道名称匹配方法,支持模糊匹配,提高命中率
- 优化地区输入选择框
- 修复 driver 模式请求问题
- 修复组播地区选择全部时无法运行问题
- 修复工作流使用 user_config 时无法生成 m3u 结果问题

- Warning: This update involves configuration changes. Please refer to the latest config/config.ini. Users using user_config.ini or Docker-mounted configurations should update their configuration files promptly.
- Added multicast source operation modes: FOFA, Tonkiang.
- Added support for custom-maintained multicast source channel IPs, located in config/rtp, with files named by "region_operator".
- Optimized speed test method, significantly improving the speed test of multicast sources and hotel sources.
- Optimized channel name matching method to support fuzzy matching, increasing hit rate.
- Optimized region input selection box.
- Fixed an issue with driver mode requests.
- Fixed an issue where multicast would not run when all regions were selected.
- Fixed an issue where workflows using user_config could not generate m3u results.

## v1.3.9

### 2024/8/30
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ for file in /tv_config/*; do
filename=$(basename "$file")
target_file="$APP_WORKDIR/config/$filename"
if [ ! -e "$target_file" ]; then
cp "$file" "$target_file"
cp -r "$file" "$target_file"
fi
done

Expand Down
92 changes: 27 additions & 65 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import asyncio
from utils.config import config, copy_config
from utils.config import config
from utils.channel import (
get_channel_items,
append_total_data,
process_sort_channel_list,
write_channel_to_file,
setup_logging,
cleanup_logging,
)
from utils.tools import (
update_file,
Expand All @@ -25,11 +27,12 @@
from flask import Flask, render_template_string
import sys
import shutil

# from collections import defaultdict
import atexit

app = Flask(__name__)

atexit.register(cleanup_logging)


@app.route("/")
def show_index():
Expand Down Expand Up @@ -104,15 +107,16 @@ async def visit_page(self, channel_names=None):
setattr(self, result_attr, await task)

def pbar_update(self, name=""):
self.pbar.update()
self.update_progress(
f"正在进行{name}, 剩余{self.total - self.pbar.n}个接口, 预计剩余时间: {get_pbar_remaining(n=self.pbar.n, total=self.total, start_time=self.start_time)}",
int((self.pbar.n) / self.total) * 100,
)
if self.pbar.n < self.total:
self.pbar.update()
self.update_progress(
f"正在进行{name}, 剩余{self.total - self.pbar.n}个接口, 预计剩余时间: {get_pbar_remaining(n=self.pbar.n, total=self.total, start_time=self.start_time)}",
int((self.pbar.n / self.total) * 100),
)

def get_urls_len(self):
def get_urls_len(self, filter=False):
def process_cache_url(url):
if "$cache:" in url:
if filter and "$cache:" in url:
cache_part = url.split("$cache:", 1)[1]
return cache_part.split("?")[0]
return url
Expand All @@ -128,8 +132,6 @@ def process_cache_url(url):
async def main(self):
try:
self.channel_items = get_channel_items()
if self.run_ui:
copy_config()
channel_names = [
name
for channel_obj in self.channel_items.values()
Expand All @@ -147,7 +149,7 @@ async def main(self):
self.subscribe_result,
self.online_search_result,
)
self.total = self.get_urls_len()
self.total = self.get_urls_len(filter=True)
sort_callback = lambda: self.pbar_update(name="测速")
if config.getboolean("Settings", "open_sort"):
self.update_progress(
Expand All @@ -160,48 +162,7 @@ async def main(self):
self.channel_data,
callback=sort_callback,
)
# no_result_cate_names = [
# (cate, name)
# for cate, channel_obj in self.channel_data.items()
# for name, info_list in channel_obj.items()
# if len(info_list) < 3
# ]
# no_result_names = [name for (_, name) in no_result_cate_names]
# if no_result_names:
# print(
# f"Not enough url found for {', '.join(no_result_names)}, try a supplementary multicast search..."
# )
# sup_results = await get_channels_by_multicast(
# no_result_names, self.update_progress
# )
# sup_channel_items = defaultdict(lambda: defaultdict(list))
# for cate, name in no_result_cate_names:
# data = sup_results.get(name)
# if data:
# sup_channel_items[cate][name] = data
# self.total = len(
# [
# url
# for obj in sup_channel_items.values()
# for url_list in obj.values()
# for url in url_list
# ]
# )
# if self.total > 0 and config.getboolean("Settings", "open_sort"):
# self.update_progress(
# f"正在对补充频道测速排序, 共{len([name for obj in sup_channel_items.values() for name in obj.keys()])}个频道, 含{self.total}个接口",
# 0,
# )
# self.start_time = time()
# self.pbar = tqdm_asyncio(total=self.total, desc="Sorting")
# sup_channel_items = await process_sort_channel_list(
# sup_channel_items,
# callback=sort_callback,
# )
# self.channel_data = merge_objects(
# self.channel_data, sup_channel_items
# )
# self.total = self.get_urls_len()
self.total = self.get_urls_len()
self.pbar = tqdm(total=self.total, desc="Writing")
self.start_time = time()
write_channel_to_file(
Expand All @@ -225,18 +186,26 @@ async def main(self):
if os.path.exists("config/user_config.ini")
else "result.log"
)
update_file(user_log_file, "output/result_new.log")
update_file(user_log_file, "output/result_new.log", copy=True)
convert_to_m3u()
print(f"Update completed! Please check the {user_final_file} file!")
if self.run_ui:
tip = (
"服务启动成功, 可访问以下链接:"
if config.getboolean("Settings", "open_update") == False
else f"更新完成, 请检查{user_final_file}文件, 可访问以下链接:"
)
self.update_progress(
f"更新完成, 请检查{user_final_file}文件, 可访问以下链接:",
tip,
100,
True,
url=f"{get_ip_address()}",
)
run_app()
except asyncio.exceptions.CancelledError:
print("Update cancelled!")
finally:
cleanup_logging()

async def start(self, callback=None):
def default_callback(self, *args, **kwargs):
Expand All @@ -245,15 +214,8 @@ def default_callback(self, *args, **kwargs):
self.update_progress = callback or default_callback
self.run_ui = True if callback else False
if config.getboolean("Settings", "open_update"):
setup_logging()
await self.main()
if self.run_ui and config.getboolean("Settings", "open_update") == False:
self.update_progress(
f"服务启动成功, 可访问以下链接:",
100,
True,
url=f"{get_ip_address()}",
)
run_app()

def stop(self):
for task in self.tasks:
Expand Down
2 changes: 1 addition & 1 deletion tkinter_ui/hotel.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ def init_ui(self, root):
values=regions,
selected_values=region_selected_values,
height=10,
command=self.update_region_list,
)
self.region_list_combo.pack(
side=tk.LEFT, padx=4, pady=8, expand=True, fill=tk.BOTH
)
self.region_list_combo.bind("<KeyRelease>", self.update_region_list)

frame_hotel_page_num = tk.Frame(root)
frame_hotel_page_num.pack(fill=tk.X)
Expand Down
69 changes: 63 additions & 6 deletions tkinter_ui/multicast.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from utils.config import config, resource_path
import json
from select_combobox import SelectCombobox
import os


class MulticastUI:
Expand Down Expand Up @@ -30,18 +31,60 @@ def init_ui(self, root):
)
self.open_multicast_checkbutton.pack(side=tk.LEFT, padx=4, pady=8)

frame_multicast_mode = tk.Frame(root)
frame_multicast_mode.pack(fill=tk.X)

self.open_multicast_mode_label = tk.Label(
frame_multicast_mode, text="工作模式:", width=9
)
self.open_multicast_mode_label.pack(side=tk.LEFT, padx=4, pady=8)
self.open_multicast_tonkiang_var = tk.BooleanVar(
value=config.getboolean("Settings", "open_multicast_tonkiang")
)
self.open_multicast_tonkiang_checkbutton = ttk.Checkbutton(
frame_multicast_mode,
variable=self.open_multicast_tonkiang_var,
onvalue=True,
offvalue=False,
command=self.update_open_multicast_tonkiang,
text="Tonkiang",
)
self.open_multicast_tonkiang_checkbutton.pack(side=tk.LEFT, padx=4, pady=8)

self.open_multicast_fofa_var = tk.BooleanVar(
value=config.getboolean("Settings", "open_multicast_fofa")
)
self.open_multicast_fofa_checkbutton = ttk.Checkbutton(
frame_multicast_mode,
variable=self.open_multicast_fofa_var,
onvalue=True,
offvalue=False,
command=self.update_open_multicast_fofa,
text="FOFA",
)
self.open_multicast_fofa_checkbutton.pack(side=tk.LEFT, padx=4, pady=8)

frame_multicast_region_list = tk.Frame(root)
frame_multicast_region_list.pack(fill=tk.X)

frame_multicast_region_list = tk.Frame(root)
frame_multicast_region_list.pack(fill=tk.X)

self.region_list_label = tk.Label(
frame_multicast_region_list, text="组播地区:", width=9
)
self.region_list_label.pack(side=tk.LEFT, padx=4, pady=8)
with open(
resource_path("updates/multicast/multicast_map.json"), "r", encoding="utf-8"
) as f:
regions_obj = json.load(f)
regions = ["全部"] + list(regions_obj.keys())
rtp_path = resource_path("config/rtp")
regions = list(
{"全部"}.union(
filename.rsplit(".", 1)[0].split("_", 1)[0]
for filename in os.listdir(rtp_path)
if filename.endswith(".txt") and "_" in filename
)
)
if "全部" in regions:
regions.remove("全部")
regions.insert(0, "全部")
region_selected_values = [
value
for value in config.get("Settings", "multicast_region_list").split(",")
Expand All @@ -52,11 +95,11 @@ def init_ui(self, root):
values=regions,
selected_values=region_selected_values,
height=10,
command=self.update_region_list,
)
self.region_list_combo.pack(
side=tk.LEFT, padx=4, pady=8, expand=True, fill=tk.BOTH
)
self.region_list_combo.bind("<KeyRelease>", self.update_region_list)

frame_multicast_page_num = tk.Frame(root)
frame_multicast_page_num.pack(fill=tk.X)
Expand All @@ -73,6 +116,18 @@ def init_ui(self, root):
def update_open_multicast(self):
config.set("Settings", "open_multicast", str(self.open_multicast_var.get()))

def update_open_multicast_tonkiang(self):
config.set(
"Settings",
"open_multicast_tonkiang",
str(self.open_multicast_tonkiang_var.get()),
)

def update_open_multicast_fofa(self):
config.set(
"Settings", "open_multicast_fofa", str(self.open_multicast_fofa_var.get())
)

def update_region_list(self, event):
config.set(
"Settings",
Expand All @@ -86,6 +141,8 @@ def update_page_num(self, event):
def change_entry_state(self, state):
for entry in [
"open_multicast_checkbutton",
"open_multicast_tonkiang_checkbutton",
"open_multicast_fofa_checkbutton",
"region_list_combo",
"page_num_entry",
]:
Expand Down
29 changes: 25 additions & 4 deletions tkinter_ui/select_combobox.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,41 @@ class SelectCombobox(ttk.Combobox):
def __init__(self, master=None, **kwargs):
selected_values = kwargs.pop("selected_values", [])
values = kwargs.pop("values", [])
command = kwargs.pop("command", None)
super().__init__(master, **kwargs)
self.selected_values = selected_values
self.values = values
self.command = command
self["values"] = self.values
self.bind("<<ComboboxSelected>>", self.on_select)
self.bind("<FocusOut>", self.on_text_change)
self.update_values()

def on_select(self, event):
selected_value = self.get().strip()
if selected_value in self.selected_values:
self.selected_values.remove(selected_value)
else:
self.selected_values.append(selected_value)
self.update_selected_values(selected_value)
self.update_values()
if self.command:
self.command(event)

def on_text_change(self, event):
text_value = self.get().strip()
value_list = [value.strip() for value in text_value.split(",")]
self.selected_values = [
value for value in self.selected_values if value in value_list
]
for value in value_list:
if value in self.values and value not in self.selected_values:
self.selected_values.append(value)
self.update_values()
if self.command:
self.command(event)

def update_selected_values(self, value):
if value in self.selected_values:
self.selected_values.remove(value)
else:
self.selected_values.append(value)

def update_values(self):
display_text = ",".join(self.selected_values)
Expand Down
Loading

0 comments on commit 799de26

Please sign in to comment.