torrload4 / app /utils.py
clove1002's picture
Create app/utils.py
5678c39 verified
Raw
History Blame Contribute Delete
5.57 kB
import os
import uuid
import requests
import traceback
import subprocess
from pathlib import Path
TMP_DIR = "/tmp"
def download_and_convert(torrent_url: str) -> str:
session_id = str(uuid.uuid4())
download_dir = f"{TMP_DIR}/{session_id}"
os.makedirs(download_dir, exist_ok=True)
print("[INFO] Starting download...")
print("[INFO] Connecting to peers...")
print("[INFO] Downloading metadata...")
# Run aria2c as subprocess
aria2_cmd = [
"aria2c", "--dir", download_dir, "--seed-time=0",
"--bt-save-metadata=true", torrent_url
]
try:
proc = subprocess.Popen(
aria2_cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True
)
for line in proc.stdout:
line = line.strip()
if "Downloading" in line:
print("[INFO] Downloading... ", line)
elif "Piece" in line:
print("[INFO] Piece ", line)
elif "%" in line:
print("[INFO] %%% ", line)
proc.wait()
print("[INFO] Download complete. Starting conversion...")
except Exception as e:
raise RuntimeError(f"Download failed: {str(e)}")
# Find video file
video_path = None
for root, _, files in os.walk(download_dir):
for file in files:
if file.lower().endswith(('.mp4', '.mkv', '.avi', '.mov')):
video_path = os.path.join(root, file)
break
if video_path:
break
if not video_path:
raise Exception("No video file found in the torrent.")
# Convert if not MP4
if not video_path.endswith(".mp4"):
output_path = os.path.join(download_dir, "converted.mp4")
print("[INFO] Converting to MP4...")
try:
ffmpeg_cmd = [
"ffmpeg", "-i", video_path,
"-c:v", "libx264", "-preset", "fast",
"-c:a", "aac", "-b:a", "128k",
"-y", output_path,
"-progress", "pipe:1", "-nostats"
]
proc = subprocess.Popen(
ffmpeg_cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True
)
last_percent = 0.0
while True:
line = proc.stdout.readline()
if not line:
break
line = line.strip()
if line.startswith("out_time_ms="):
out_time_ms = int(line.split('=')[1])
duration_seconds = get_video_duration(video_path)
if duration_seconds > 0:
percent = min(out_time_ms / (duration_seconds * 1000000) * 100, 100.0)
if percent - last_percent >= 5 or percent == 100:
print(f"[INFO] Converting... {percent:.1f}%")
last_percent = percent
elif "progress=end" in line:
break
proc.wait()
print(f"[INFO] Conversion complete. Saved to {output_path}")
return output_path
except Exception as e:
raise RuntimeError(f"Conversion failed: {str(e)}")
print(f"[INFO] No conversion needed. Saved to {video_path}")
return video_path
def get_video_duration(video_path: str) -> float:
try:
result = subprocess.run(
[
"ffprobe", "-v", "error",
"-show_entries", "format=duration",
"-of", "default=noprint_wrappers=1:nokey=1",
video_path
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True
)
return float(result.stdout.strip())
except Exception:
return 0.0
def get_tmp_directory_size():
total_size = 0
for dirpath, dirnames, filenames in os.walk("/tmp"):
for f in filenames:
fp = os.path.join(dirpath, f)
if os.path.isfile(fp):
total_size += os.path.getsize(fp)
return total_size
#def download_task(torrent_url: str, webhook_url: str):
# try:
# output_path = download_and_convert(torrent_url)
# payload = {
# "status": "success",
# "file_path": output_path
# }
# requests.post(webhook_url, json=payload)
# except Exception as e:
# payload = {
# "status": "error",
# "detail": str(e)
# }
# try:
# requests.post(webhook_url, json=payload)
# except:
# pass
def download_task(torrent_url: str, webhook_url: str):
try:
output_path = download_and_convert(torrent_url)
payload = {
"status": "success",
"file_path": output_path
}
r = requests.post(webhook_url, json=payload)
r.raise_for_status()
print(f"[INFO] Webhook sent successfully: {r.status_code}")
except Exception as e:
print(f"[ERROR] Download task failed: {e}")
print(traceback.format_exc())
payload = {
"status": "error",
"detail": str(e)
}
try:
r = requests.post(webhook_url, json=payload)
r.raise_for_status()
print(f"[INFO] Error webhook sent successfully: {r.status_code}")
except Exception as e2:
print(f"[ERROR] Failed to send error webhook: {e2}")
print(traceback.format_exc())