Ethscriptions commited on
Commit
e4a61fc
·
verified ·
1 Parent(s): 6e4f272

Update app.py

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