Skip to content

Commit

Permalink
Merge pull request #558 from Guovin/dev
Browse files Browse the repository at this point in the history
Release:v1.5.2
  • Loading branch information
Guovin authored Nov 15, 2024
2 parents ec23752 + 288b8d9 commit 0664ac8
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 98 deletions.
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
# 更新日志(Changelog)

## v1.5.2

### 2024/11/15

- ✨ 新增各省份地方台
- ✨ 新增控制显示无结果频道分类配置(open_empty_category)(#551
- ✨ 调整接口源(#526
- 🪄 优化频道数据插入速度
- 🪄 优化 IPv6 测速逻辑,解决无结果问题
- 🪄 优化页面服务启动与 docker 定时任务日志输出
- 🪄 调整默认配置:接口数量 urls_limit=10 等数量配置,增加订阅源
- 🐛 修复运行停止问题(#527
- 🐛 修复 Win7 GUI 启动问题(#536
- 🗑️ 移除部分无效订阅源
- 🗑️ 移除域名黑名单配置(domain_blacklist),请使用接口关键字黑名单(url_keywords_blacklist)替代

<details>
<summary>English</summary>

- ✨ Added local channels for each province.
- ✨ Added configuration to control the display of the No Results Channel Category (open_empty_category) (#551).
- ✨ Adjusted interface sources (#526).
- 🪄 Optimized the speed of channel data insertion.
- 🪄 Optimized IPv6 speed test logic to resolve no results issues.
- 🪄 Optimized page service startup and Docker scheduled task log output.
- 🪄 Adjusted default configurations: number of interfaces urls_limit=10, etc., and added subscription sources.
- 🐛 Fixed the issue of the program stopping (#527).
- 🐛 Fixed the issue of Win7 GUI startup (#536).
- 🗑️ Removed some invalid subscription sources.
- 🗑️ Removed the domain blacklist configuration (domain_blacklist). Please use the interface keyword blacklist (url_keywords_blacklist) instead.

</details>

## v1.5.1

### 2024/11/5
Expand Down
3 changes: 1 addition & 2 deletions config/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ ipv_type = 全部
ipv_type_prefer = 自动
ipv4_num = 5
ipv6_num = 5
domain_blacklist = epg.pw,skype.serv00.net,iptv.yjxfz.com,live-hls-web-ajb.getaj.net,live.goodiptv.club,hc73k3dhwo5gfkt.wcetv.com,stream1.freetv.fun,zw9999.cnstream.top
open_m3u_result = True
url_keywords_blacklist =
url_keywords_blacklist = epg.pw,skype.serv00.net,iptv.yjxfz.com,live-hls-web-ajb.getaj.net,live.goodiptv.club,hc73k3dhwo5gfkt.wcetv.com,stream1.freetv.fun,zw9999.cnstream.top
open_subscribe = True
subscribe_urls = https://live.fanmingming.com/tv/m3u/ipv6.m3u,https://ghp.ci/https://raw.githubusercontent.com/joevess/IPTV/main/home.m3u8,https://aktv.top/live.txt,http://175.178.251.183:6689/live.txt,https://ghproxy.net/https://raw.githubusercontent.com/kimwang1978/collect-tv-txt/main/merged_output.txt,https://m3u.ibert.me/txt/fmml_dv6.txt,https://m3u.ibert.me/txt/o_cn.txt,https://m3u.ibert.me/txt/j_iptv.txt,https://github.moeyy.xyz/https://raw.githubusercontent.com/PizazzGY/TVBox/main/live.txt,https://ghproxy.net/https://raw.githubusercontent.com/xzw832/cmys/main/S_CCTV.txt,https://ghproxy.net/https://raw.githubusercontent.com/xzw832/cmys/main/S_weishi.txt,http://itv.22m.top/ITVBox/tv/tvonline.txt
open_multicast = True
Expand Down
1 change: 0 additions & 1 deletion docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
| ipv_type_prefer | 自动 | 接口协议类型偏好,优先将该类型的接口排在结果前面,可选值:IPv4、IPv6、自动、auto |
| ipv4_num | 5 | 结果中偏好的 IPv4 接口数量 |
| ipv6_num | 5 | 结果中偏好的 IPv6 接口数量 |
| domain_blacklist | epg.pw | 接口域名黑名单,用于过滤低质量含广告类域名的接口 |
| url_keywords_blacklist | | 接口关键字黑名单,用于过滤含特定字符的接口 |
| open_subscribe | False | 开启订阅源功能 |
| subscribe_urls | | 订阅源,请输入订阅链接(支持 txt 与 m3u 链接),多个链接以逗号分隔 |
Expand Down
1 change: 0 additions & 1 deletion docs/config_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
| ipv_type_prefer | auto | Interface protocol type preference, prioritize interfaces of this type in the results, optional values: IPv4, IPv6, auto |
| ipv4_num | 5 | The preferred number of IPv4 interfaces in the result |
| ipv6_num | 5 | The preferred number of IPv6 interfaces in the result |
| domain_blacklist | | 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 | | Subscription source, please enter the subscription link (supports txt and m3u links), multiple links should be separated by commas |
Expand Down
27 changes: 17 additions & 10 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,6 @@ async def main(self):
True,
url=f"{get_ip_address()}" if open_service else None,
)
if open_service:
run_service()
except asyncio.exceptions.CancelledError:
print("Update cancelled!")

Expand Down Expand Up @@ -253,14 +251,23 @@ def scheduled_task():


def run_service():
if not os.environ.get("GITHUB_ACTIONS"):
ip_address = get_ip_address()
print(f"📄 Result detail: {ip_address}/result")
print(f"📄 Log detail: {ip_address}/log")
print(f"✅ You can use this url to watch IPTV 📺: {ip_address}")
app.run(host="0.0.0.0", port=8000)
try:
if not os.environ.get("GITHUB_ACTIONS"):
ip_address = get_ip_address()
print(f"📄 Result detail: {ip_address}/result")
print(f"📄 Log detail: {ip_address}/log")
print(f"✅ You can use this url to watch IPTV 📺: {ip_address}")
app.run(host="0.0.0.0", port=8000)
except Exception as e:
print(f"❌ Service start failed: {e}")


if __name__ == "__main__":
if len(sys.argv) == 1 or (len(sys.argv) > 1 and sys.argv[1] == "scheduled_task"):
scheduled_task()
if len(sys.argv) == 1 and config.open_service:
loop = asyncio.new_event_loop()

async def run_service_async():
loop.run_in_executor(None, run_service)

asyncio.run(run_service_async())
scheduled_task()
76 changes: 29 additions & 47 deletions tkinter_ui/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def init_ui(self, root):
frame_default_channel_column1, text="频道接口数量:", width=12
)
self.urls_limit_label.pack(side=tk.LEFT, padx=4, pady=8)
self.urls_limit_entry = tk.Entry(frame_default_channel_column1)
self.urls_limit_entry = tk.Entry(frame_default_channel_column1, width=8)
self.urls_limit_entry.pack(side=tk.LEFT, padx=4, pady=8)
self.urls_limit_entry.insert(0, config.urls_limit)
self.urls_limit_entry.bind("<KeyRelease>", self.update_urls_limit)
Expand All @@ -150,7 +150,7 @@ def init_ui(self, root):
frame_default_channel_column2, text="接口协议类型:", width=12
)
self.ipv_type_label.pack(side=tk.LEFT, padx=4, pady=8)
self.ipv_type_combo = ttk.Combobox(frame_default_channel_column2)
self.ipv_type_combo = ttk.Combobox(frame_default_channel_column2, width=5)
self.ipv_type_combo.pack(side=tk.LEFT, padx=4, pady=8)
self.ipv_type_combo["values"] = ("IPv4", "IPv6", "全部")
if config.ipv_type == "ipv4":
Expand All @@ -161,22 +161,16 @@ def init_ui(self, root):
self.ipv_type_combo.current(2)
self.ipv_type_combo.bind("<<ComboboxSelected>>", self.update_ipv_type)

frame_default_sort = tk.Frame(root)
frame_default_sort.pack(fill=tk.X)
frame_default_sort_column1 = tk.Frame(frame_default_sort)
frame_default_sort_column1.pack(side=tk.LEFT, fill=tk.Y)
frame_default_sort_column2 = tk.Frame(frame_default_sort)
frame_default_sort_column2.pack(side=tk.LEFT, fill=tk.Y)
frame_default_sort_column3 = tk.Frame(frame_default_sort)
frame_default_sort_column3.pack(side=tk.RIGHT, fill=tk.Y)
frame_default_open_keep_all = tk.Frame(root)
frame_default_open_keep_all.pack(fill=tk.X)

self.open_keep_all_label = tk.Label(
frame_default_sort_column1, text="保留模式:", width=12
frame_default_open_keep_all, 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(
frame_default_sort_column1,
frame_default_open_keep_all,
variable=self.open_keep_all_var,
onvalue=True,
offvalue=False,
Expand All @@ -185,13 +179,20 @@ def init_ui(self, root):
)
self.open_keep_all_checkbutton.pack(side=tk.LEFT, padx=4, pady=8)

frame_default_sort = tk.Frame(root)
frame_default_sort.pack(fill=tk.X)
frame_default_sort_column1 = tk.Frame(frame_default_sort)
frame_default_sort_column1.pack(side=tk.LEFT, fill=tk.Y)
frame_default_sort_column2 = tk.Frame(frame_default_sort)
frame_default_sort_column2.pack(side=tk.RIGHT, fill=tk.Y)

self.open_sort_label = tk.Label(
frame_default_sort_column2, text="测速排序:", width=12
frame_default_sort_column1, 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(
frame_default_sort_column2,
frame_default_sort_column1,
variable=self.open_sort_var,
onvalue=True,
offvalue=False,
Expand All @@ -200,10 +201,10 @@ def init_ui(self, root):
self.open_sort_checkbutton.pack(side=tk.LEFT, padx=4, pady=8)

self.sort_timeout_label = tk.Label(
frame_default_sort_column3, text="测速超时:", width=12
frame_default_sort_column2, text="测速超时:", width=12
)
self.sort_timeout_label.pack(side=tk.LEFT, padx=4, pady=8)
self.sort_timeout_entry = tk.Entry(frame_default_sort_column3)
self.sort_timeout_entry = tk.Entry(frame_default_sort_column2, width=8)
self.sort_timeout_entry.pack(side=tk.LEFT, padx=4, pady=8)
self.sort_timeout_entry.insert(0, config.sort_timeout)
self.sort_timeout_entry.bind("<KeyRelease>", self.update_sort_timeout)
Expand Down Expand Up @@ -241,7 +242,7 @@ def init_ui(self, root):
onvalue=True,
offvalue=False,
command=self.update_open_m3u_result,
text="(支持频道图标)",
text="(开启频道图标)",
)
self.open_m3u_result_checkbutton.pack(side=tk.LEFT, padx=4, pady=8)

Expand Down Expand Up @@ -277,7 +278,9 @@ def init_ui(self, root):
frame_default_resolution_params_column2, text="最小分辨率:", width=12
)
self.min_resolution_label.pack(side=tk.LEFT, padx=4, pady=8)
self.min_resolution_entry = tk.Entry(frame_default_resolution_params_column2)
self.min_resolution_entry = tk.Entry(
frame_default_resolution_params_column2, width=10
)
self.min_resolution_entry.pack(side=tk.LEFT, padx=4, pady=8)
self.min_resolution_entry.insert(0, config.min_resolution)
self.min_resolution_entry.bind("<KeyRelease>", self.update_min_resolution)
Expand Down Expand Up @@ -345,49 +348,36 @@ def init_ui(self, root):
self.open_update_time_checkbutton.pack(side=tk.LEFT, padx=4, pady=8)

self.open_url_info_label = tk.Label(
frame_default_open_update_info_column1, text="显示接口信息:", width=12
frame_default_open_update_info_column2, text="显示接口信息:", width=12
)
self.open_url_info_label.pack(side=tk.LEFT, padx=4, pady=8)
self.open_url_info_var = tk.BooleanVar(value=config.open_url_info)
self.open_url_info_checkbutton = ttk.Checkbutton(
frame_default_open_update_info_column1,
frame_default_open_update_info_column2,
variable=self.open_url_info_var,
onvalue=True,
offvalue=False,
command=self.update_open_url_info,
)
self.open_url_info_checkbutton.pack(side=tk.LEFT, padx=4, pady=8)

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

self.open_empty_category_label = tk.Label(
frame_default_open_update_info_column2, text="无结果频道分类:", width=12
frame_default_open_empty_category, text="显示无结果分类:", width=12
)
self.open_empty_category_label.pack(side=tk.LEFT, padx=4, pady=8)
self.open_empty_category_var = tk.BooleanVar(value=config.open_empty_category)
self.open_empty_category_checkbutton = ttk.Checkbutton(
frame_default_open_update_info_column2,
frame_default_open_empty_category,
variable=self.open_empty_category_var,
onvalue=True,
offvalue=False,
command=self.update_open_empty_category,
)
self.open_empty_category_checkbutton.pack(side=tk.LEFT, padx=4, pady=8)

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

self.domain_blacklist_label = tk.Label(
frame_default_domain_blacklist, text="域名黑名单:", width=12
)
self.domain_blacklist_label.pack(side=tk.LEFT, padx=4, pady=8)
self.domain_blacklist_text = scrolledtext.ScrolledText(
frame_default_domain_blacklist, height=2
)
self.domain_blacklist_text.pack(
side=tk.LEFT, padx=4, pady=8, expand=True, fill=tk.BOTH
)
self.domain_blacklist_text.insert(tk.END, ",".join(config.domain_blacklist))
self.domain_blacklist_text.bind("<KeyRelease>", self.update_domain_blacklist)

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

Expand All @@ -396,7 +386,7 @@ def init_ui(self, root):
)
self.url_keywords_blacklist_label.pack(side=tk.LEFT, padx=4, pady=8)
self.url_keywords_blacklist_text = scrolledtext.ScrolledText(
frame_default_url_keywords_blacklist, height=2
frame_default_url_keywords_blacklist, height=5
)
self.url_keywords_blacklist_text.pack(
side=tk.LEFT, padx=4, pady=8, expand=True, fill=tk.BOTH
Expand Down Expand Up @@ -503,13 +493,6 @@ def update_url_keywords_blacklist(self, event):
self.url_keywords_blacklist_text.get(1.0, tk.END),
)

def update_domain_blacklist(self, event):
config.set(
"Settings",
"domain_blacklist",
self.domain_blacklist_text.get(1.0, tk.END),
)

def update_url_keywords_blacklist(self, event):
config.set(
"Settings",
Expand Down Expand Up @@ -541,7 +524,6 @@ def change_entry_state(self, state):
"open_url_info_checkbutton",
"open_empty_category_checkbutton",
"ipv_type_combo",
"domain_blacklist_text",
"url_keywords_blacklist_text",
]:
getattr(self, entry).config(state=state)
11 changes: 8 additions & 3 deletions tkinter_ui/tkinter_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from PIL import Image, ImageTk
from utils.config import config
from utils.tools import resource_path
from main import UpdateSource
from main import UpdateSource, run_service
import asyncio
import threading
import webbrowser
Expand Down Expand Up @@ -58,7 +58,6 @@ def save_config(self):
"response_time_weight": self.default_ui.response_time_weight_scale.get(),
"resolution_weight": self.default_ui.resolution_weight_scale.get(),
"ipv_type": self.default_ui.ipv_type_combo.get(),
"domain_blacklist": self.default_ui.domain_blacklist_text.get(1.0, tk.END),
"url_keywords_blacklist": self.default_ui.url_keywords_blacklist_text.get(
1.0, tk.END
),
Expand Down Expand Up @@ -113,11 +112,17 @@ async def run_update(self):
self.progress_label.pack_forget()

def on_run_update(self):
loop = asyncio.new_event_loop()

async def run_service_async():
loop.run_in_executor(None, run_service)

def run_loop():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(self.run_update())

if config.open_service:
asyncio.run(run_service_async())
self.thread = threading.Thread(target=run_loop, daemon=True)
self.thread.start()

Expand Down
Loading

0 comments on commit 0664ac8

Please sign in to comment.