Ethscriptions commited on
Commit
ae5d853
·
verified ·
1 Parent(s): b5f63aa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -134
app.py CHANGED
@@ -1,158 +1,103 @@
1
  import streamlit as st
2
- import aria2p # 改用更稳定的 aria2p 库
3
- import time
4
- import threading
5
  import os
6
- from pathlib import Path
 
7
 
8
- # Aria2 配置
9
- ARIA2_RPC_HOST = "http://localhost"
10
- ARIA2_RPC_PORT = 6800
11
- ARIA2_SECRET = "SECRET_KEY"
 
 
 
 
 
12
 
13
- # 初始化 aria2 连接
14
- def init_aria2():
15
  try:
16
- # 自动启动 aria2 后台进程
17
- if not os.popen("pgrep aria2c").read():
18
- download_dir = os.path.abspath("./downloads")
19
- os.makedirs(download_dir, exist_ok=True)
20
-
21
- cmd = [
22
- "aria2c",
23
- "--enable-rpc",
24
- f"--rpc-listen-port={ARIA2_RPC_PORT}",
25
- f"--rpc-secret={ARIA2_SECRET}",
26
- f"--dir={download_dir}",
27
- "--daemon=true",
28
- "--max-concurrent-downloads=5",
29
- "--split=16",
30
- "--max-connection-per-server=16",
31
- "--file-allocation=prealloc"
32
- ]
33
- threading.Thread(target=lambda: os.system(" ".join(cmd))).start()
34
- time.sleep(2)
35
 
36
- # 初始化 API 客户端
37
- return aria2p.Client(
38
- host=ARIA2_RPC_HOST,
39
- port=ARIA2_RPC_PORT,
40
- secret=ARIA2_SECRET
41
- )
42
- except Exception as e:
43
- st.error(f"初始化失败: {str(e)}")
44
- raise
45
-
46
- # Session 状态初始化
47
- if 'aria_client' not in st.session_state:
48
- st.session_state.aria_client = init_aria2()
49
- if 'aria_api' not in st.session_state:
50
- st.session_state.aria_api = aria2p.API(st.session_state.aria_client)
51
- if 'download_progress' not in st.session_state:
52
- st.session_state.download_progress = 0
53
- if 'downloading' not in st.session_state:
54
- st.session_state.downloading = False
55
- if 'download_complete' not in st.session_state:
56
- st.session_state.download_complete = False
57
- if 'download_filename' not in st.session_state:
58
- st.session_state.download_filename = None
59
- if 'error_message' not in st.session_state:
60
- st.session_state.error_message = None
61
-
62
- def download_torrent(magnet_link):
63
- try:
64
- # 添加下载任务
65
- download = st.session_state.aria_api.add_magnet(
66
- magnet_link,
67
- options={
68
- "max-download-limit": "0",
69
- "seed-time": "0",
70
- "bt-detach-seed-only": "true"
71
- }
72
- )
73
 
74
- st.session_state.error_message = None
75
- st.session_state.downloading = True
 
 
 
76
 
77
- # 进度监控
78
- while download.is_active:
79
- download.update()
80
- st.session_state.download_progress = download.progress * 100
81
-
82
- # 自动刷新间隔
 
 
83
  time.sleep(1)
84
-
85
- if download.is_complete:
86
- st.session_state.download_complete = True
87
- st.session_state.download_filename = download.files[0].path
88
- else:
89
- raise Exception(download.error_message)
90
-
91
  except Exception as e:
92
- st.session_state.error_message = f"下载失败: {str(e)}"
93
- finally:
94
- st.session_state.downloading = False
95
-
96
 
97
  # 界面布局
98
- st.title("磁力链接下载器 🧲 (Aria2版)")
 
99
 
100
- with st.form("magnet_form"):
101
- magnet_link = st.text_input("输入磁力链接:", placeholder="magnet:?xt=urn:btih:...")
102
- submitted = st.form_submit_button("开始下载")
103
 
104
- if submitted and magnet_link:
105
- if st.session_state.downloading:
106
- st.warning("当前已有下载任务在进行中")
 
107
  else:
108
- # 重置状态
109
- st.session_state.download_progress = 0
110
- st.session_state.download_complete = False
111
- st.session_state.download_filename = None
112
- st.session_state.error_message = None
113
- st.session_state.downloading = True
114
- start_download_thread(magnet_link)
 
 
 
 
 
 
115
 
116
- if st.session_state.downloading:
117
- st.info("下载状态")
118
- progress_col, control_col = st.columns([4, 1])
119
 
120
- with progress_col:
121
- progress_bar = st.progress(int(st.session_state.download_progress))
122
- st.write(f"当前进度:{st.session_state.download_progress:.1f}%")
123
 
124
- with control_col:
125
- if st.button("取消下载"):
126
- st.session_state.downloading = False
127
- st.session_state.download_complete = False
128
- st.session_state.error_message = "下载已取消"
129
- st.experimental_rerun()
130
-
131
- if st.session_state.error_message:
132
- st.error(st.session_state.error_message)
133
-
134
- if st.session_state.download_complete:
135
- st.success("下载完成!✅")
136
- if st.session_state.download_filename and Path(st.session_state.download_filename).exists():
137
- file_path = Path(st.session_state.download_filename)
138
- file_size = file_path.stat().st_size
139
- st.write(f"文件大小:{file_size/1024/1024:.2f} MB")
140
 
141
  with open(file_path, "rb") as f:
142
  st.download_button(
143
- label="下载文件",
144
- data=f,
145
- file_name=file_path.name,
146
  mime="application/octet-stream"
147
  )
148
  else:
149
- st.error("文件不存在,可能下载失败")
150
-
151
- # 注意事项
152
- st.markdown("---")
153
- st.info("""
154
- **使用说明:**
155
- 1. 确保已安装 aria2:`brew install aria2` (macOS) 或 `sudo apt install aria2` (Linux)
156
- 2. 首次运行会自动启动 aria2 后台服务
157
- 3. 下载文件将保存到当前目录的 downloads 文件夹
158
- """)
 
1
  import streamlit as st
2
+ import libtorrent as lt
 
 
3
  import os
4
+ import threading
5
+ import time
6
 
7
+ # Session状态初始化
8
+ if 'download' not in st.session_state:
9
+ st.session_state.download = {
10
+ 'progress': 0,
11
+ 'is_downloading': False,
12
+ 'complete': False,
13
+ 'file_path': None,
14
+ 'status': ""
15
+ }
16
 
17
+ def download_torrent(magnet_link, save_path):
 
18
  try:
19
+ ses = lt.session()
20
+ params = {
21
+ 'save_path': save_path,
22
+ 'storage_mode': lt.storage_mode_t(2)
23
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
+ handle = lt.add_magnet_uri(ses, magnet_link, params)
26
+
27
+ # 获取元数据
28
+ st.session_state.download['status'] = "正在获取元数据..."
29
+ while not handle.has_metadata():
30
+ time.sleep(1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
+ # 获取文件信息
33
+ torrent_info = handle.get_torrent_info()
34
+ files = []
35
+ for i in range(torrent_info.num_files()):
36
+ files.append(torrent_info.file_at(i).path)
37
 
38
+ # 开始下载
39
+ st.session_state.download['status'] = "开始下载..."
40
+ st.session_state.download['is_downloading'] = True
41
+
42
+ while handle.status().state != lt.torrent_status.seeding:
43
+ status = handle.status()
44
+ progress = status.progress * 100
45
+ st.session_state.download['progress'] = progress
46
  time.sleep(1)
47
+
48
+ # 下载完成
49
+ st.session_state.download['is_downloading'] = False
50
+ st.session_state.download['complete'] = True
51
+ st.session_state.download['file_path'] = save_path
52
+ st.session_state.download['status'] = f"下载完成!保存路径:{save_path}"
53
+
54
  except Exception as e:
55
+ st.session_state.download['status'] = f"错误:{str(e)}"
56
+ st.session_state.download['is_downloading'] = False
 
 
57
 
58
  # 界面布局
59
+ st.title("🎯 磁力链接下载器")
60
+ st.write("输入磁力链接开始下载(仅支持单个文件)")
61
 
62
+ magnet_link = st.text_input("磁力链接:", placeholder="magnet:?xt=urn:btih:...")
63
+ col1, col2 = st.columns([1, 3])
 
64
 
65
+ with col1:
66
+ if st.button("🚀 开始下载", disabled=st.session_state.download['is_downloading']):
67
+ if not magnet_link.startswith("magnet:"):
68
+ st.error("请输入有效的磁力链接!")
69
  else:
70
+ save_dir = "./downloads"
71
+ os.makedirs(save_dir, exist_ok=True)
72
+ threading.Thread(
73
+ target=download_torrent,
74
+ args=(magnet_link, save_dir),
75
+ daemon=True
76
+ ).start()
77
+
78
+ # 下载状态显示
79
+ if st.session_state.download['is_downloading']:
80
+ st.progress(int(st.session_state.download['progress']))
81
+ st.write(f"🔍 进度:{st.session_state.download['progress']:.1f}%")
82
+ st.info(st.session_state.download['status'])
83
 
84
+ if st.session_state.download['complete']:
85
+ st.success("✅ 下载完成!")
 
86
 
87
+ # 显示下载文件
88
+ download_dir = st.session_state.download['file_path']
89
+ files = [f for f in os.listdir(download_dir) if os.path.isfile(os.path.join(download_dir, f))]
90
 
91
+ if files:
92
+ selected_file = st.selectbox("选择要下载的文件:", files)
93
+ file_path = os.path.join(download_dir, selected_file)
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
  with open(file_path, "rb") as f:
96
  st.download_button(
97
+ "⬇️ 下载文件",
98
+ f,
99
+ file_name=selected_file,
100
  mime="application/octet-stream"
101
  )
102
  else:
103
+ st.warning("未找到下载文件")