From 4e88d99e1cae0e8d1cb0dbe9c89f02e42d3ccd50 Mon Sep 17 00:00:00 2001 From: "guorong.zheng" <360996299@qq.com> Date: Wed, 10 Jul 2024 12:00:31 +0800 Subject: [PATCH 1/4] Update:README --- README.md | 6 ++++-- README_en.md | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ac36383db3..2c7e81832e 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,10 @@ pipenv run ui ### 方式三:Docker 更新 -- requests:轻量级,性能要求低,更新速度快,稳定性不确定(只使用订阅源推荐此版本) -- driver:性能要求较高,更新速度较慢,稳定性、成功率高(使用在线搜索、组播源使用此版本) +- requests:轻量级,性能要求低,更新速度快,稳定性不确定(推荐订阅源使用此版本) +- driver:性能要求较高,更新速度较慢,稳定性、成功率高(在线搜索、组播源使用此版本) + +建议都试用一次,选择自己合适的版本,在线搜索和组播源使用 requests 能拿到结果的话,优先选择 requests 版本。 ```bash 1. 拉取镜像: diff --git a/README_en.md b/README_en.md index 026f26d8e2..a008a8a925 100644 --- a/README_en.md +++ b/README_en.md @@ -59,8 +59,10 @@ pipenv run ui ### Method 3: Docker Update -- requests: Lightweight, low performance requirements, fast update speed, stability uncertain (recommend this version only for subscription sources) -- driver: Higher performance requirements, slower update speed, high stability, high success rate (use this version for online search, multicast sources) +- requests: Lightweight, low performance requirements, fast update speed, stability uncertain (Recommend using this version for the subscription source) +- driver: Higher performance requirements, slower update speed, high stability, high success rate (Online search, multicast source use this version) + +It's recommended to try each one and choose the version that suits you. If you can get results with requests for online searches and multicast sources, prioritize choosing the version that uses requests. ```bash 1. Pull the image: From 262d01f9d61b561c62828089282f74b05f3157e9 Mon Sep 17 00:00:00 2001 From: "guorong.zheng" <360996299@qq.com> Date: Wed, 10 Jul 2024 15:42:18 +0800 Subject: [PATCH 2/4] fix:get url --- utils/channel.py | 56 ++++++++++++++++++++++++++++++++++-------------- utils/speed.py | 4 +--- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/utils/channel.py b/utils/channel.py index ee6f993afe..ab304d4677 100644 --- a/utils/channel.py +++ b/utils/channel.py @@ -94,6 +94,20 @@ def format_channel_name(name): return name.lower() +def get_element_child_text_list(element, child_name): + """ + Get the child text of the element + """ + text_list = [] + children = element.find_all(child_name) + if children: + for child in children: + text = child.get_text(strip=True) + if text: + text_list.append(text) + return text_list + + def get_results_from_soup(soup, name): """ Get the results from the soup @@ -101,7 +115,8 @@ def get_results_from_soup(soup, name): results = [] for element in soup.descendants: if isinstance(element, NavigableString): - url = get_channel_url(element) + text = element.get_text(strip=True) + url = get_channel_url(text) if url and not any(item[0] == url for item in results): url_element = soup.find(lambda tag: tag.get_text(strip=True) == url) if url_element: @@ -112,7 +127,9 @@ def get_results_from_soup(soup, name): channel_name ): info_element = url_element.find_next_sibling() - date, resolution = get_channel_info(info_element) + date, resolution = get_channel_info( + info_element.get_text(strip=True) + ) results.append((url, date, resolution)) return results @@ -128,9 +145,17 @@ def get_results_from_soup_requests(soup, name): if name_element: channel_name = name_element.get_text(strip=True) if format_channel_name(name) == format_channel_name(channel_name): - url = get_channel_url(element) - date, resolution = get_channel_info(element) - results.append((url, date, resolution)) + text_list = get_element_child_text_list(element, "div") + url = date = resolution = None + for text in text_list: + text_url = get_channel_url(text) + if text_url: + url = text_url + if " " in text: + text_info = get_channel_info(text) + date, resolution = text_info + if url: + results.append((url, date, resolution)) return results @@ -155,33 +180,32 @@ def update_channel_urls_txt(cate, name, urls): f.write(name + "," + url + "\n") -def get_channel_url(element): +def get_channel_url(text): """ - Get the url, date and resolution + Get the url from text """ url = None urlRegex = r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+" url_search = re.search( urlRegex, - element.get_text(strip=True), + text, ) if url_search: url = url_search.group() return url -def get_channel_info(element): +def get_channel_info(text): """ - Get the channel info + Get the channel info from text """ date, resolution = None, None - info_text = element.get_text(strip=True) - if info_text: + if text: date, resolution = ( - (info_text.partition(" ")[0] if info_text.partition(" ")[0] else None), + (text.partition(" ")[0] if text.partition(" ")[0] else None), ( - info_text.partition(" ")[2].partition("•")[2] - if info_text.partition(" ")[2].partition("•")[2] + text.partition(" ")[2].partition("•")[2] + if text.partition(" ")[2].partition("•")[2] else None ), ) @@ -287,7 +311,7 @@ async def sort_channel_list(semaphore, cate, name, info_list, callback): resolution, ), response_time in sorted_data: logging.info( - f"Name: {name}, URL: {url}, Date: {date}, Resolution: {resolution}, Response Time: {response_time}ms" + f"Name: {name}, URL: {url}, Date: {date}, Resolution: {resolution}, Response Time: {response_time} ms" ) data = [ (url, date, resolution) diff --git a/utils/speed.py b/utils/speed.py index ee8c47b2c2..62676991c1 100644 --- a/utils/speed.py +++ b/utils/speed.py @@ -35,9 +35,7 @@ async def sort_urls_by_speed_and_resolution(infoList): Sort by speed and resolution """ response_times = await gather(*(get_speed(url) for url, _, _ in infoList)) - valid_responses = [ - (info, rt) for info, rt in zip(infoList, response_times) if rt != float("inf") - ] + valid_responses = [(info, rt) for info, rt in zip(infoList, response_times)] def extract_resolution(resolution_str): numbers = re.findall(r"\d+x\d+", resolution_str) From c06a0386a8274ab94674e6213f14d6cb9a2a1535 Mon Sep 17 00:00:00 2001 From: "guorong.zheng" <360996299@qq.com> Date: Wed, 10 Jul 2024 16:16:53 +0800 Subject: [PATCH 3/4] feat:OpenCC --- Pipfile | 1 + Pipfile.lock | 54 +++++++++++++++++++++++++++--------------------- utils/channel.py | 45 ++++++++++++++++++++++++++++++---------- 3 files changed, 66 insertions(+), 34 deletions(-) diff --git a/Pipfile b/Pipfile index 93a7ab10a0..bd190c8dee 100644 --- a/Pipfile +++ b/Pipfile @@ -21,6 +21,7 @@ pyinstaller = "*" aiohttp = "*" flask = "*" gunicorn = "*" +opencc-python-reimplemented = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index ceb35c148c..aa265ddf04 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "f2e414a925be2ea62fcf7660090d518ea80826d1e510d62732a75b5894b58730" + "sha256": "24e1f3abe777aadad329cd8764b401113d292117c39ce7fd275b5f4248910c5f" }, "pipfile-spec": 6, "requires": { @@ -157,11 +157,11 @@ }, "certifi": { "hashes": [ - "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516", - "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56" + "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b", + "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90" ], "markers": "python_version >= '3.6'", - "version": "==2024.6.2" + "version": "==2024.7.4" }, "cffi": { "hashes": [ @@ -759,6 +759,14 @@ "markers": "python_version >= '3.7'", "version": "==6.0.5" }, + "opencc-python-reimplemented": { + "hashes": [ + "sha256:41b3b92943c7bed291f448e9c7fad4b577c8c2eae30fcfe5a74edf8818493aa6", + "sha256:4f777ea3461a25257a7b876112cfa90bb6acabc6dfb843bf4d11266e43579dee" + ], + "index": "aliyun", + "version": "==0.1.7" + }, "outcome": { "hashes": [ "sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8", @@ -793,22 +801,22 @@ }, "pyinstaller": { "hashes": [ - "sha256:000c36b13fe4cd8d0d8c2bc855b1ddcf39867b5adf389e6b5ca45b25fa3e619d", - "sha256:1c3060a263758cf7f0144ab4c016097b20451b2469d468763414665db1bb743d", - "sha256:2b71509468c811968c0b5decb5bbe85b6292ea52d7b1f26313d2aabb673fa9a5", - "sha256:355832a3acc7de90a255ecacd4b9f9e166a547a79c8905d49f14e3a75c1acdb9", - "sha256:39ac424d2ee2457d2ab11a5091436e75a0cccae207d460d180aa1fcbbafdd528", - "sha256:3f4b6520f4423fe19bcc2fd63ab7238851ae2bdcbc98f25bc5d2f97cc62012e9", - "sha256:5ff6bc2784c1026f8e2f04aa3760cbed41408e108a9d4cf1dd52ee8351a3f6e1", - "sha256:6303c7a009f47e6a96ef65aed49f41e36ece8d079b9193ca92fe807403e5fe80", - "sha256:81cccfa9b16699b457f4788c5cc119b50f3cd4d0db924955f15c33f2ad27a50d", - "sha256:d257f6645c7334cbd66f38a4fac62c3ad614cc46302b2b5d9f8cc48c563bce0e", - "sha256:fe0af018d7d5077180e3144ada89a4da5df8d07716eb7e9482834a56dc57a4e8", - "sha256:ff31c5b99e05a4384bbe2071df67ec8b2b347640a375eae9b40218be2f1754c6" + "sha256:2bf4de17a1c63c0b797b38e13bfb4d03b5ee7c0a68e28b915a7eaacf6b76087f", + "sha256:43709c70b1da8441a730327a8ed362bfcfdc3d42c1bf89f3e2b0a163cc4e7d33", + "sha256:4e3e50743c091a06e6d01c59bdd6d03967b453ee5384a9e790759be4129db4a4", + "sha256:5ced2e83acf222b936ea94abc5a5cc96588705654b39138af8fb321d9cf2b954", + "sha256:7bf0c13c5a8560c89540746ae742f4f4b82290e95a6b478374d9f34959fe25d6", + "sha256:a0f378f64ad0655d11ade9fde7877e7573fd3d5066231608ce7dfa9040faecdd", + "sha256:b041be2fe78da47a269604d62c940d68c62f9a3913bdf64af4123f7689d47099", + "sha256:da994aba14c5686db88796684de265a8665733b4df09b939f7ebdf097d18df72", + "sha256:f15c1ef11ed5ceb32447dfbdab687017d6adbef7fc32aa359d584369bfe56eda", + "sha256:f18a3d551834ef8fb7830d48d4cc1527004d0e6b51ded7181e78374ad6111846", + "sha256:f2fc568de3d6d2a176716a3fc9f20da06d351e8bea5ddd10ecb5659fce3a05b0", + "sha256:f4a75c552facc2e2a370f1e422b971b5e5cdb4058ff38cea0235aa21fc0b378f" ], "index": "aliyun", "markers": "python_version < '3.13' and python_version >= '3.8'", - "version": "==6.8.0" + "version": "==6.9.0" }, "pyinstaller-hooks-contrib": { "hashes": [ @@ -862,11 +870,11 @@ }, "setuptools": { "hashes": [ - "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650", - "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95" + "sha256:b8b8060bb426838fbe942479c90296ce976249451118ef566a5a0b7d8b78fb05", + "sha256:bd63e505105011b25c3c11f753f7e3b8465ea739efddaccef8f0efac2137bac1" ], "markers": "python_version >= '3.8'", - "version": "==70.1.1" + "version": "==70.2.0" }, "sgmllib3k": { "hashes": [ @@ -908,11 +916,11 @@ }, "trio": { "hashes": [ - "sha256:9f5314f014ea3af489e77b001861c535005c3858d38ec46b6b071ebfa339d7fb", - "sha256:e42617ba091e7b2e50c899052e83a3c403101841de925187f61e7b7eaebdf3fb" + "sha256:67c5ec3265dd4abc7b1d1ab9ca4fe4c25b896f9c93dac73713778adab487f9c4", + "sha256:bb9c1b259591af941fccfbabbdc65bc7ed764bd2db76428454c894cd5e3d2032" ], "markers": "python_version >= '3.8'", - "version": "==0.25.1" + "version": "==0.26.0" }, "trio-websocket": { "hashes": [ diff --git a/utils/channel.py b/utils/channel.py index ab304d4677..5512f1f2cd 100644 --- a/utils/channel.py +++ b/utils/channel.py @@ -7,6 +7,7 @@ from bs4 import NavigableString import logging from logging.handlers import RotatingFileHandler +from opencc import OpenCC config = get_config() @@ -94,6 +95,31 @@ def format_channel_name(name): return name.lower() +def channel_name_is_equal(name1, name2): + """ + Check if the channel name is equal + """ + cc = OpenCC("t2s") + name1_converted = cc.convert(format_channel_name(name1)) + name2_converted = cc.convert(format_channel_name(name2)) + return name1_converted == name2_converted + + +def get_channel_results_by_name(name, data): + """ + Get channel results from data by name + """ + format_name = format_channel_name(name) + cc1 = OpenCC("s2t") + converted1 = cc1.convert(format_name) + cc2 = OpenCC("t2s") + converted2 = cc2.convert(format_name) + result1 = data.get(converted1, []) + result2 = data.get(converted2, []) + results = list(dict.fromkeys(result1 + result2)) + return results + + def get_element_child_text_list(element, child_name): """ Get the child text of the element @@ -123,9 +149,7 @@ def get_results_from_soup(soup, name): name_element = url_element.find_previous_sibling() if name_element: channel_name = name_element.get_text(strip=True) - if format_channel_name(name) == format_channel_name( - channel_name - ): + if channel_name_is_equal(name, channel_name): info_element = url_element.find_next_sibling() date, resolution = get_channel_info( info_element.get_text(strip=True) @@ -144,7 +168,7 @@ def get_results_from_soup_requests(soup, name): name_element = element.find("div", class_="channel") if name_element: channel_name = name_element.get_text(strip=True) - if format_channel_name(name) == format_channel_name(channel_name): + if channel_name_is_equal(name, channel_name): text_list = get_element_child_text_list(element, "div") url = date = resolution = None for text in text_list: @@ -242,42 +266,41 @@ def append_all_method_data( """ for cate, channel_obj in items: for name, old_urls in channel_obj.items(): - formatName = format_channel_name(name) if config.open_subscribe: data = append_data_to_info_data( data, cate, name, - subscribe_result.get(formatName, []), + get_channel_results_by_name(name, subscribe_result), ) print( name, "subscribe num:", - len(subscribe_result.get(formatName, [])), + len(get_channel_results_by_name(name, subscribe_result)), ) if config.open_multicast: data = append_data_to_info_data( data, cate, name, - multicast_result.get(formatName, []), + get_channel_results_by_name(name, multicast_result), ) print( name, "multicast num:", - len(multicast_result.get(formatName, [])), + len(get_channel_results_by_name(name, multicast_result)), ) if config.open_online_search: data = append_data_to_info_data( data, cate, name, - online_search_result.get(formatName, []), + get_channel_results_by_name(name, online_search_result), ) print( name, "online search num:", - len(online_search_result.get(formatName, [])), + len(get_channel_results_by_name(name, online_search_result)), ) total_channel_data_len = len(data.get(cate, {}).get(name, [])) if total_channel_data_len == 0: From 81fee2679d0f7cf4879afbd2ef6ca8d953df976e Mon Sep 17 00:00:00 2001 From: "guorong.zheng" <360996299@qq.com> Date: Wed, 10 Jul 2024 16:26:26 +0800 Subject: [PATCH 4/4] release:v1.3.2 --- CHANGELOG.md | 8 ++++++++ tkinter_ui.py | 2 +- version.json | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98447de43d..20f1cee0bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # 更新日志(Changelog) +## v1.3.2 + +### 2024/7/10 + +- 新增支持频道名称简体繁体匹配(Added support for channel name Simplified and Traditional Chinese match) +- 新增 Docker 修改模板与配置教程(Added Docker modification template and configuration tutorial) +- 修复频道更新结果为空问题(Fixed the issue where channel update result is empty) + ## v1.3.1 ### 2024/7/9 diff --git a/tkinter_ui.py b/tkinter_ui.py index 9ebaa0a341..3a8b7a214c 100644 --- a/tkinter_ui.py +++ b/tkinter_ui.py @@ -24,7 +24,7 @@ class TkinterUI: def __init__(self, root): self.root = root self.root.title("直播源接口更新工具") - self.version = "v1.3.1" + self.version = "v1.3.2" self.update_source = UpdateSource() self.update_running = False self.config_entrys = [ diff --git a/version.json b/version.json index 89bd88a69d..dd0488dc4c 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "1.3.1" + "version": "1.3.2" } \ No newline at end of file