tvbs/main.py

212 lines
8 KiB
Python
Raw Permalink Normal View History

2024-02-26 11:35:35 +02:00
import asyncio
2024-11-04 12:00:15 +02:00
from utils.config import config
2024-11-28 08:29:46 +02:00
import utils.constants as constants
2024-11-27 10:57:12 +02:00
from service.app import run_service
2024-07-04 12:59:53 +03:00
from utils.channel import (
2024-06-04 12:52:16 +03:00
get_channel_items,
append_total_data,
2024-08-26 13:04:28 +03:00
process_sort_channel_list,
2024-07-07 09:47:08 +03:00
write_channel_to_file,
2024-09-24 06:31:26 +03:00
get_channel_data_cache_with_compare,
2024-10-10 05:51:43 +03:00
format_channel_url_info,
2024-07-04 12:59:53 +03:00
)
2024-07-07 10:39:55 +03:00
from utils.tools import (
2024-06-04 12:52:16 +03:00
update_file,
2024-06-16 13:53:04 +03:00
get_pbar_remaining,
2024-07-01 12:04:22 +03:00
get_ip_address,
2024-08-23 13:24:48 +03:00
convert_to_m3u,
2024-09-25 13:36:28 +03:00
process_nested_dict,
2024-10-10 10:50:31 +03:00
format_interval,
2024-10-25 10:16:35 +03:00
check_ipv6_support,
2024-11-04 08:01:49 +02:00
resource_path,
2024-03-15 05:08:46 +02:00
)
2024-08-12 05:01:04 +03:00
from updates.subscribe import get_channels_by_subscribe_urls
from updates.multicast import get_channels_by_multicast
2024-08-19 11:58:47 +03:00
from updates.hotel import get_channels_by_hotel
2024-08-19 12:30:09 +03:00
from updates.fofa import get_channels_by_fofa
2024-08-12 05:01:04 +03:00
from updates.online_search import get_channels_by_online_search
2024-06-04 12:52:16 +03:00
from tqdm import tqdm
2024-06-03 13:28:15 +03:00
from time import time
2024-09-23 13:06:35 +03:00
import pickle
2024-09-26 06:57:28 +03:00
import copy
2024-09-04 10:47:04 +03:00
2024-07-01 12:04:22 +03:00
2024-03-15 05:08:46 +02:00
class UpdateSource:
2024-02-06 09:19:09 +02:00
2024-03-15 05:08:46 +02:00
def __init__(self):
2024-06-05 05:36:13 +03:00
self.run_ui = False
2024-05-28 13:08:30 +03:00
self.tasks = []
2024-08-21 13:23:02 +03:00
self.channel_items = {}
2024-08-21 06:57:04 +03:00
self.hotel_fofa_result = {}
2024-11-12 10:31:56 +02:00
self.hotel_foodie_result = {}
2024-08-28 11:21:04 +03:00
self.multicast_result = {}
self.subscribe_result = {}
2024-07-03 06:45:26 +03:00
self.online_search_result = {}
2024-06-03 13:28:15 +03:00
self.channel_data = {}
2024-05-30 13:09:34 +03:00
self.pbar = None
self.total = 0
2024-06-03 13:28:15 +03:00
self.start_time = None
2024-05-31 13:24:33 +03:00
2024-06-16 13:53:04 +03:00
async def visit_page(self, channel_names=None):
2024-08-19 12:30:09 +03:00
tasks_config = [
2024-11-04 07:58:00 +02:00
("hotel_fofa", get_channels_by_fofa, "hotel_fofa_result"),
("multicast", get_channels_by_multicast, "multicast_result"),
2024-11-12 10:31:56 +02:00
("hotel_foodie", get_channels_by_hotel, "hotel_foodie_result"),
2024-11-04 07:58:00 +02:00
("subscribe", get_channels_by_subscribe_urls, "subscribe_result"),
2024-08-19 12:30:09 +03:00
(
2024-11-04 07:58:00 +02:00
"online_search",
2024-08-19 12:30:09 +03:00
get_channels_by_online_search,
"online_search_result",
),
]
for setting, task_func, result_attr in tasks_config:
2024-08-21 06:57:04 +03:00
if (
2024-11-12 10:31:56 +02:00
setting == "hotel_foodie" or setting == "hotel_fofa"
2024-11-04 12:00:15 +02:00
) and config.open_hotel == False:
2024-08-21 06:57:04 +03:00
continue
2024-11-04 12:00:15 +02:00
if config.open_method[setting]:
if setting == "subscribe":
subscribe_urls = config.subscribe_urls
2024-08-26 13:04:28 +03:00
task = asyncio.create_task(
2024-08-27 12:59:40 +03:00
task_func(subscribe_urls, callback=self.update_progress)
2024-08-26 13:04:28 +03:00
)
2024-11-12 10:31:56 +02:00
elif setting == "hotel_foodie" or setting == "hotel_fofa":
2024-09-03 12:18:36 +03:00
task = asyncio.create_task(task_func(callback=self.update_progress))
2024-08-26 13:04:28 +03:00
else:
task = asyncio.create_task(
2024-09-03 12:18:36 +03:00
task_func(channel_names, callback=self.update_progress)
2024-08-26 13:04:28 +03:00
)
2024-08-19 12:30:09 +03:00
self.tasks.append(task)
setattr(self, result_attr, await task)
2024-02-06 09:19:09 +02:00
2024-08-29 05:57:08 +03:00
def pbar_update(self, name=""):
2024-09-05 10:33:13 +03:00
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),
)
2024-07-07 09:47:08 +03:00
2024-09-05 05:35:12 +03:00
def get_urls_len(self, filter=False):
2024-09-26 06:57:28 +03:00
data = copy.deepcopy(self.channel_data)
if filter:
2024-11-01 11:46:20 +02:00
process_nested_dict(data, seen=set(), flag=r"cache:(.*)", force_str="!")
2024-09-04 12:32:25 +03:00
processed_urls = set(
2024-09-25 13:36:28 +03:00
url_info[0]
for channel_obj in data.values()
2024-09-04 12:32:25 +03:00
for url_info_list in channel_obj.values()
for url_info in url_info_list
2024-08-29 05:57:08 +03:00
)
2024-09-04 12:32:25 +03:00
return len(processed_urls)
2024-08-16 10:47:35 +03:00
2024-05-28 13:08:30 +03:00
async def main(self):
try:
2024-11-04 12:00:15 +02:00
if config.open_update:
2024-11-04 07:58:00 +02:00
main_start_time = time()
self.channel_items = get_channel_items()
channel_names = [
name
for channel_obj in self.channel_items.values()
for name in channel_obj.keys()
]
await self.visit_page(channel_names)
self.tasks = []
append_total_data(
self.channel_items.items(),
channel_names,
self.channel_data,
self.hotel_fofa_result,
self.multicast_result,
2024-11-12 10:31:56 +02:00
self.hotel_foodie_result,
2024-11-04 07:58:00 +02:00
self.subscribe_result,
self.online_search_result,
2024-06-03 13:28:15 +03:00
)
2024-11-04 07:58:00 +02:00
channel_data_cache = copy.deepcopy(self.channel_data)
ipv6_support = check_ipv6_support()
2024-11-04 12:00:15 +02:00
open_sort = config.open_sort
2024-11-04 07:58:00 +02:00
if open_sort:
urls_total = self.get_urls_len()
self.total = self.get_urls_len(filter=True)
print(f"Total urls: {urls_total}, need to sort: {self.total}")
sort_callback = lambda: self.pbar_update(name="测速")
self.update_progress(
f"正在测速排序, 共{urls_total}个接口, {self.total}个接口需要进行测速",
0,
)
self.start_time = time()
2024-11-19 12:28:17 +02:00
self.pbar = tqdm(total=self.total, desc="Sorting")
2024-11-28 08:29:46 +02:00
self.channel_data = await process_sort_channel_list(
2024-11-04 07:58:00 +02:00
self.channel_data,
ipv6=ipv6_support,
callback=sort_callback,
)
else:
format_channel_url_info(self.channel_data)
self.total = self.get_urls_len()
self.pbar = tqdm(total=self.total, desc="Writing")
2024-06-03 13:28:15 +03:00
self.start_time = time()
2024-11-04 07:58:00 +02:00
write_channel_to_file(
2024-08-29 05:57:08 +03:00
self.channel_data,
2024-10-25 10:16:35 +03:00
ipv6=ipv6_support,
2024-11-04 07:58:00 +02:00
callback=lambda: self.pbar_update(name="写入结果"),
2024-08-26 13:04:28 +03:00
)
2024-11-04 07:58:00 +02:00
self.pbar.close()
2024-11-04 12:00:15 +02:00
user_final_file = config.final_file
2024-11-28 08:29:46 +02:00
update_file(user_final_file, constants.result_path)
2024-11-04 12:00:15 +02:00
if config.open_use_old_result:
2024-11-04 07:58:00 +02:00
if open_sort:
get_channel_data_cache_with_compare(
channel_data_cache, self.channel_data
)
with open(
2024-11-28 08:29:46 +02:00
resource_path(constants.cache_path, persistent=True),
"wb",
2024-11-04 07:58:00 +02:00
) as file:
pickle.dump(channel_data_cache, file)
convert_to_m3u()
total_time = format_interval(time() - main_start_time)
print(
f"🥳 Update completed! Total time spent: {total_time}. Please check the {user_final_file} file!"
2024-06-19 15:31:06 +03:00
)
2024-11-04 12:00:15 +02:00
open_service = config.open_service
2024-06-19 15:31:06 +03:00
if self.run_ui:
2024-10-18 09:23:41 +03:00
service_tip = ", 可使用以下链接观看直播:" if open_service else ""
2024-09-05 10:33:13 +03:00
tip = (
2024-11-04 07:58:00 +02:00
f"✅ 服务启动成功{service_tip}"
2024-11-04 12:00:15 +02:00
if open_service and config.open_update == False
2024-11-04 07:58:00 +02:00
else f"🥳 更新完成, 耗时: {total_time}, 请检查{user_final_file}文件{service_tip}"
2024-09-05 10:33:13 +03:00
)
2024-06-19 15:31:06 +03:00
self.update_progress(
2024-09-05 10:33:13 +03:00
tip,
2024-07-01 12:04:22 +03:00
100,
True,
2024-10-18 09:23:41 +03:00
url=f"{get_ip_address()}" if open_service else None,
2024-06-19 15:31:06 +03:00
)
2024-11-27 10:57:12 +02:00
if open_service:
run_service()
2024-05-28 13:08:30 +03:00
except asyncio.exceptions.CancelledError:
print("Update cancelled!")
2024-02-26 11:35:35 +02:00
2024-06-14 12:55:27 +03:00
async def start(self, callback=None):
2024-06-05 05:36:13 +03:00
def default_callback(self, *args, **kwargs):
pass
self.update_progress = callback or default_callback
self.run_ui = True if callback else False
2024-11-04 07:58:00 +02:00
await self.main()
2024-02-06 09:19:09 +02:00
2024-05-28 13:08:30 +03:00
def stop(self):
for task in self.tasks:
task.cancel()
2024-05-31 13:24:33 +03:00
self.tasks = []
2024-06-16 13:53:04 +03:00
if self.pbar:
self.pbar.close()
2024-06-05 05:36:13 +03:00
2024-11-27 10:57:12 +02:00
if __name__ == "__main__":
2024-11-04 07:58:00 +02:00
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
update_source = UpdateSource()
loop.run_until_complete(update_source.start())