torp / app.py
bigbossmonster's picture
Create app.py
623b0d9 verified
import gradio as gr
import os
import threading
import asyncio
from torrentp import TorrentDownloader
# --- Configuration ---
if os.path.exists("/data"):
SAVE_PATH = "/data/torrents"
else:
SAVE_PATH = "./torrents"
print("WARNING: /data directory not found. Using ephemeral storage.")
print("Files will be DELETED when the Space restarts.")
os.makedirs(SAVE_PATH, exist_ok=True)
print(f"File save location: {SAVE_PATH}")
# Global dictionary to track the status from our threads
# We will store: {magnet_link: "Status Message"}
download_status = {}
def run_download_in_thread(magnet_link):
"""
This function runs in a separate thread.
It's what allows the GUI to stay responsive.
"""
try:
# Set status to "Starting"
download_status[magnet_link] = "🔽 Starting download..."
print(f"Thread started for: {magnet_link}")
# Initialize the downloader
torrent_downloader = TorrentDownloader(magnet_link, SAVE_PATH)
# This is a blocking call.
# We must run it in a new event loop inside this thread.
asyncio.run(torrent_downloader.start_download())
# If the line above finishes, the download is done.
print(f"Thread finished for: {magnet_link}")
download_status[magnet_link] = "✅ Download Finished"
except Exception as e:
print(f"Error in download thread: {e}")
download_status[magnet_link] = f"Error: {e}"
def add_torrent(magnet_link):
"""
This is called by the Gradio button.
It *starts* the background thread but does not wait for it.
"""
if not magnet_link or not magnet_link.startswith("magnet:?"):
return "Error: Invalid magnet link."
if magnet_link in download_status and download_status[magnet_link] not in ["✅ Download Finished", "Error"]:
return "Download for this link is already in progress."
# Create and start the new thread
# target=run_download_in_thread is the function to run
# args=(magnet_link,) are the arguments to pass to that function
thread = threading.Thread(target=run_download_in_thread, args=(magnet_link,))
thread.start()
download_status[magnet_link] = "ℹ️ Queued. Starting thread..."
return "Download process started in background."
def get_status_report():
"""
Reads the global 'download_status' dictionary to show progress.
This is not real-time speed, but it shows "Starting" or "Finished".
"""
if not download_status:
return "No downloads started yet."
report_lines = []
for link, status in download_status.items():
# Show the first 50 chars of the magnet link as an ID
link_id = link[0:50] + "..."
report_lines.append(f"{status}\n ({link_id})\n")
return "\n".join(report_lines)
# --- Build the Gradio App ---
with gr.Blocks(title="Torrent Downloader") as demo:
gr.Markdown(
"# Hugging Face Torrent Downloader (using 'torrentp')\n"
f"Shows basic status. Files are saved in: `{SAVE_PATH}`"
)
with gr.Row():
magnet_input = gr.Textbox(
label="Magnet Link",
placeholder="magnet:?xt=urn:btih:...",
scale=4
)
add_button = gr.Button("Add Torrent", variant="primary", scale=1)
status_output = gr.Textbox(
label="Download Status (refreshes every 5s)",
lines=15,
interactive=False,
value=get_status_report,
every=5
)
add_result_output = gr.Textbox(label="System Message", interactive=False)
add_button.click(
fn=add_torrent,
inputs=magnet_input,
outputs=add_result_output
)
add_button.click(lambda: "", outputs=magnet_input)
# Launch the app
demo.launch()