File size: 5,038 Bytes
31d1f71
 
 
0582fea
31d1f71
 
0582fea
 
 
 
 
 
 
 
 
 
 
 
 
31d1f71
 
0582fea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31d1f71
0582fea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31d1f71
 
0582fea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
import libtorrent as lt
import time
import threading
import os

# Session状态初始化
if 'download_progress' not in st.session_state:
    st.session_state.download_progress = 0
if 'downloading' not in st.session_state:
    st.session_state.downloading = False
if 'download_complete' not in st.session_state:
    st.session_state.download_complete = False
if 'download_filename' not in st.session_state:
    st.session_state.download_filename = None
if 'error_message' not in st.session_state:
    st.session_state.error_message = None

def download_torrent(magnet_link, save_path):
    try:
        ses = lt.session()
        ses.listen_on(6881, 6891)
        params = {
            'save_path': save_path,
            'storage_mode': lt.storage_mode_t(2)
        }
        
        handle = lt.add_magnet_uri(ses, magnet_link, params)
        ses.start_dht()
        ses.start_lsd()
        ses.start_upnp()
        ses.start_natpmp()

        # 等待元数据
        st.session_state.error_message = "正在获取元数据..."
        while not handle.has_metadata():
            time.sleep(1)
            if not st.session_state.downloading:
                return

        # 获取文件信息
        torinfo = handle.get_torrent_info()
        files = torinfo.files()
        if files.num_files() > 1:
            st.session_state.error_message = "暂不支持多文件种子"
            st.session_state.downloading = False
            return

        file_path = files.file_path(0)
        st.session_state.download_filename = os.path.join(save_path, file_path)

        st.session_state.error_message = None
        st.session_state.downloading = True

        # 更新下载进度
        while handle.status().state != lt.torrent_status.seeding:
            if not st.session_state.downloading:
                handle.pause()
                return
            s = handle.status()
            progress = s.progress * 100
            st.session_state.download_progress = progress
            time.sleep(0.5)

        st.session_state.download_progress = 100
        st.session_state.download_complete = True
        st.session_state.downloading = False

    except Exception as e:
        st.session_state.error_message = f"下载出错:{str(e)}"
        st.session_state.downloading = False
        st.session_state.download_complete = False

def start_download_thread(magnet_link):
    save_path = './downloads'
    if not os.path.exists(save_path):
        os.makedirs(save_path)
    
    thread = threading.Thread(target=download_torrent, args=(magnet_link, save_path))
    thread.start()

# 界面布局
st.title("磁力链接下载器 🧲")

with st.form("magnet_form"):
    magnet_link = st.text_input("输入磁力链接:", placeholder="magnet:?xt=urn:btih:...")
    submitted = st.form_submit_button("开始下载")

    if submitted and magnet_link:
        if st.session_state.downloading:
            st.warning("当前已有下载任务在进行中")
        else:
            # 重置状态
            st.session_state.download_progress = 0
            st.session_state.download_complete = False
            st.session_state.download_filename = None
            st.session_state.error_message = None
            st.session_state.downloading = True
            start_download_thread(magnet_link)

if st.session_state.downloading:
    st.info("下载状态")
    progress_col, control_col = st.columns([4, 1])
    
    with progress_col:
        progress_bar = st.progress(int(st.session_state.download_progress))
        st.write(f"当前进度:{st.session_state.download_progress:.1f}%")
    
    with control_col:
        if st.button("取消下载"):
            st.session_state.downloading = False
            st.session_state.download_complete = False
            st.session_state.error_message = "下载已取消"
            st.experimental_rerun()

if st.session_state.error_message:
    st.error(st.session_state.error_message)

if st.session_state.download_complete:
    st.success("下载完成!✅")
    if st.session_state.download_filename and os.path.exists(st.session_state.download_filename):
        file_size = os.path.getsize(st.session_state.download_filename)
        st.write(f"文件大小:{file_size/1024/1024:.2f} MB")
        
        with open(st.session_state.download_filename, "rb") as f:
            st.download_button(
                label="下载文件",
                data=f,
                file_name=os.path.basename(st.session_state.download_filename),
                mime="application/octet-stream"
            )
    else:
        st.error("文件不存在,可能下载失败")

# 注意事项提示
st.markdown("---")
st.info("""
**使用说明:**
1. 输入有效的磁力链接(必须以'magnet:?xt='开头)
2. 点击开始下载按钮
3. 下载完成后会出现文件下载按钮
4. 大文件下载可能需要较长时间,请保持页面开启

**注意:** 下载速度取决于种子可用性和网络环境
""")