fix: 使 python 脚本支持从 github 获取文件长度并更新 (#13457)

This commit is contained in:
cibimo
2025-08-06 09:36:04 +08:00
committed by GitHub
parent 1176822d0e
commit ed81d609f6
2 changed files with 33 additions and 13 deletions

View File

@@ -5,22 +5,26 @@ from concurrent.futures import ThreadPoolExecutor
from threading import Lock
import requests
# 获取文件大小
def length(url_list):
def getlenhead(single_url):
response = requests.head(single_url)
while 'Location' in response.headers:
response = requests.head(response.headers.get('Location'))
file_size = response.headers.get('Content-Length')
if file_size is not None:
return int(file_size)
else:
return False
for url in url_list:
single_file_length = getlenhead(url)
if single_file_length:
return single_file_length
try:
single_file_length = getlenhead(url)
if single_file_length:
return single_file_length
except Exception as e:
print(f"{url} 无法连接")
print(e)
# 定义Download类在初始化时保存几个参数
class Downloader:
@@ -60,7 +64,7 @@ class Downloader:
self.failed_requests[url]['fail'] > 10:
# 如果某 URL 的失败率高于 50%,则跳过该 URL
return
except requests.RequestException as e:
except Exception as e:
if self.chunk_status[chunk_id] == 1:
self.chunk_status[chunk_id] = 0
@@ -72,10 +76,17 @@ class Downloader:
except:
pass
os.makedirs(f'temp/{self.listhash}', exist_ok=True)
with ThreadPoolExecutor(max_workers=self.max_conn * len(self.urlist)) as executor:
for url in self.urlist:
for chunk_id in range(num_chunks):
executor.submit(self.download_chunk, url, chunk_id, total_size)
max_retry = 3
while 0 in self.chunk_status:
if max_retry == 0:
print("下载出错。")
return
with ThreadPoolExecutor(max_workers=self.max_conn * len(self.urlist)) as executor:
for url in self.urlist:
for chunk_id in range(num_chunks):
executor.submit(self.download_chunk, url, chunk_id, total_size)
max_retry -= 1
# 合并所有临时文件到一个文件
with open(file_path, 'wb') as outfile:
@@ -90,16 +101,21 @@ class Downloader:
# 验证下载文件
if os.path.getsize(file_path) != total_size:
print("文件大小不一致,下载可能出错。")
return True
def file_download(download_url_list, download_path, request_proxies=None):
chunksize = 1024 * 1024 # 分片大小1MB
chunksize = 4 * 1024 * 1024 # 分片大小1MB
max_conn = 4 # 最大连接数
# 创建对象
downloader = Downloader(download_url_list, chunksize, max_conn, use_proxies=request_proxies)
# 下载文件
total_size = length(download_url_list)
if not total_size:
print("无法连接所有的下载服务器,更新失败")
return
print("文件大小已获取,开始下载")
return downloader.download_file(total_size, download_path)

View File

@@ -196,16 +196,20 @@ class Updater:
# 下载调用Downloader下载器使用url_list镜像url列表和file文件保存路径两个参数
# Proxy参数没加因为可能有问题也可能没问题反正我晚上Clash连不上
# 重试3次
download_finished = False
max_retry = 3
for retry_frequency in range(max_retry):
try:
Updater.custom_print("开始下载" + (f",第{retry_frequency}次尝试" if retry_frequency > 1 else ""))
# 调用downloader方法进行下载
downloader.file_download(download_url_list=url_list, download_path=file)
download_finished = downloader.file_download(download_url_list=url_list, download_path=file)
break # RNM怎么会有这么蠢的人忘了写break啊淦
except(HTTPError, URLError) as e:
Updater.custom_print(e)
if not download_finished:
Updater.custom_print('下载异常,更新失败')
return
# 解压下载的文件,
Updater.custom_print('开始安装更新,请不要关闭')
file_extension = os.path.splitext(filename)[1]