Spaces:
Sleeping
Sleeping
File size: 6,058 Bytes
31d1f71 ae5d853 31d1f71 ceae804 45da914 463f386 45da914 ac7717b 6e4f272 f7afc9d 6e4f272 f7afc9d 6e4f272 f7afc9d 6e4f272 ac7717b 45da914 ac7717b 45da914 6e4f272 45da914 6e4f272 45da914 6e4f272 45da914 6e4f272 f7afc9d 45da914 463f386 45da914 f7afc9d 45da914 f7afc9d 45da914 463f386 45da914 463f386 45da914 463f386 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
import streamlit as st
import libtorrent as lt
import os
import time
import threading
from pathlib import Path
# 下载状态类
class DownloadStatus:
def __init__(self):
self.progress = 0.0
self.download_rate = 0.0
self.remaining_time = 0.0
self.total_size = 0
self.downloaded_size = 0
self.status = "等待中"
self.file_path = None
def human_readable_size(size):
"""转换文件大小到易读格式"""
units = ['B', 'KB', 'MB', 'GB', 'TB']
index = 0
while size >= 1024 and index < 4:
size /= 1024
index += 1
return f"{size:.2f} {units[index]}"
def configure_session():
"""精确版本检测的会话配置"""
if hasattr(lt, 'settings_pack'):
# 新版本配置方式 (libtorrent 1.2.x+)
settings = lt.settings_pack()
settings.set_str(lt.settings_pack.listen_interfaces, '0.0.0.0:6881')
return lt.session(settings)
else:
# 旧版本配置方式 (libtorrent <1.2.x)
ses = lt.session()
if hasattr(ses, 'listen_on'):
ses.listen_on(6881, 6891)
return ses
def add_torrent_compat(ses, magnet_uri, download_path):
"""精确版本检测的种子添加方法"""
if hasattr(lt, 'parse_magnet_uri'):
# 新版本添加方式
params = lt.parse_magnet_uri(magnet_uri)
params.save_path = download_path
if hasattr(lt.storage_mode_t, 'storage_mode_sparse'):
params.storage_mode = lt.storage_mode_t.storage_mode_sparse
return ses.add_torrent(params)
else:
# 旧版本添加方式
return lt.add_magnet_uri(ses, magnet_uri, {
'save_path': download_path,
'storage_mode': lt.storage_mode_t(2)
})
def download_task(magnet_uri, download_path, status):
"""后台下载任务"""
try:
ses = configure_session()
status.status = "解析磁力链接..."
# 添加种子
handle = add_torrent_compat(ses, magnet_uri, download_path)
status.status = "获取元数据..."
# 等待元数据,带超时机制
timeout = 30
start = time.time()
while not handle.has_metadata():
if time.time() - start > timeout:
raise TimeoutError("获取元数据超时")
time.sleep(0.5)
if hasattr(ses, 'post_torrent_updates'):
ses.post_torrent_updates()
torrent_info = handle.get_torrent_info()
status.total_size = torrent_info.total_size()
status.status = "下载中..."
# 主下载循环
start_time = time.time()
last_downloaded = 0
while not handle.is_seed():
if hasattr(ses, 'post_torrent_updates'):
ses.post_torrent_updates()
s = handle.status()
# 计算下载速度
now = time.time()
dt = now - start_time
status.downloaded_size = s.total_done
status.download_rate = (s.total_done - last_downloaded) / dt if dt > 0 else 0
last_downloaded = s.total_done
start_time = now
# 计算进度和剩余时间
status.progress = s.progress
if status.download_rate > 0:
status.remaining_time = (status.total_size - s.total_done) / status.download_rate
else:
status.remaining_time = 0
time.sleep(1)
status.status = "下载完成"
status.file_path = os.path.join(download_path, handle.name())
except Exception as e:
status.status = f"错误: {str(e)}"
def main():
st.title("🕹️ 磁力链接下载器")
if 'download_status' not in st.session_state:
st.session_state.download_status = DownloadStatus()
with st.form("magnet_form"):
magnet_uri = st.text_input("磁力链接:", placeholder="magnet:?xt=urn:...")
submitted = st.form_submit_button("开始下载")
download_path = Path("downloads")
download_path.mkdir(exist_ok=True)
if submitted and magnet_uri:
if not magnet_uri.startswith("magnet:?"):
st.error("无效的磁力链接格式")
return
st.session_state.download_status = DownloadStatus()
thread = threading.Thread(
target=download_task,
args=(magnet_uri, download_path, st.session_state.download_status)
)
thread.start()
status = st.session_state.download_status
status_container = st.empty()
while status.status not in ["下载完成", "错误"] and status.status != "等待中":
with status_container.container():
st.progress(status.progress, text=f"进度: {status.progress*100:.1f}%")
cols = st.columns(4)
cols[0].metric("总大小", human_readable_size(status.total_size) if status.total_size > 0 else "--")
cols[1].metric("已下载", human_readable_size(status.downloaded_size))
speed_display = (f"{status.download_rate/1024:.2f} MB/s" if status.download_rate > 1024
else f"{status.download_rate:.2f} KB/s") if status.download_rate > 0 else "--"
cols[2].metric("速度", speed_display)
time_display = f"{status.remaining_time:.1f}秒" if status.remaining_time > 0 else "--"
cols[3].metric("剩余时间", time_display)
st.caption(f"状态: {status.status}")
time.sleep(0.5)
if status.status == "下载完成":
st.success("🎉 下载完成!")
with open(status.file_path, "rb") as f:
st.download_button(
label="保存文件",
data=f,
file_name=os.path.basename(status.file_path),
mime="application/octet-stream"
)
if __name__ == "__main__":
main() |