understanding commited on
Commit
b0822c8
·
verified ·
1 Parent(s): 138515e

Update terabox_utils.py

Browse files
Files changed (1) hide show
  1. terabox_utils.py +70 -13
terabox_utils.py CHANGED
@@ -3,11 +3,12 @@
3
  import re
4
  import requests
5
  import asyncio
6
- from functools import partial
7
- import logging
8
  import os
9
  import time
10
  import math
 
 
 
11
 
12
  import config
13
 
@@ -24,7 +25,19 @@ def format_bytes(size_bytes: int) -> str:
24
  s = round(size_bytes / p, 2)
25
  return f"{s} {size_name[i]}"
26
 
27
- async def extract_terabox_short_id(full_url: str):
 
 
 
 
 
 
 
 
 
 
 
 
28
  patterns = [
29
  r'terabox\.com/s/([a-zA-Z0-9_-]+)',
30
  r'teraboxapp\.com/s/([a-zA-Z0-9_-]+)',
@@ -40,7 +53,8 @@ async def extract_terabox_short_id(full_url: str):
40
  return m.group(1)
41
  return None
42
 
43
- async def get_final_url_and_filename(original_link: str):
 
44
  payload = {"link": original_link}
45
  headers = {"User-Agent": "Mozilla/5.0"}
46
 
@@ -64,9 +78,10 @@ async def get_final_url_and_filename(original_link: str):
64
  except Exception as e:
65
  return None, None, str(e)
66
 
67
- async def download_terabox_file(url: str, filename: str):
 
68
  safe_fn = re.sub(r'[\\/*?:"<>|]', "_", filename)[:200]
69
- download_path = os.path.join("downloads", f"{time.time()}_{safe_fn}")
70
 
71
  try:
72
  loop = asyncio.get_event_loop()
@@ -86,6 +101,7 @@ async def download_terabox_file(url: str, filename: str):
86
  total_size = int(r.headers.get('content-length', 0))
87
  dl_size = 0
88
  last_update = time.time()
 
89
 
90
  with open(download_path, 'wb') as f:
91
  for chunk in r.iter_content(chunk_size=1024 * 1024):
@@ -93,17 +109,58 @@ async def download_terabox_file(url: str, filename: str):
93
  f.write(chunk)
94
  dl_size += len(chunk)
95
 
96
- # For debug:
 
 
 
 
 
 
 
 
 
 
97
  if time.time() - last_update > 2.5:
98
- pct = (dl_size / total_size * 100) if total_size > 0 else 0
99
- logger.info(
100
- f"Downloading: {safe_fn} → {format_bytes(dl_size)}/{format_bytes(total_size)} ({pct:.1f}%)"
101
- )
 
 
 
 
 
 
102
  last_update = time.time()
103
 
104
- return download_path, None
 
 
 
 
 
 
105
 
106
  except Exception as e:
107
  if os.path.exists(download_path):
108
  os.remove(download_path)
109
- return None, str(e)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  import re
4
  import requests
5
  import asyncio
 
 
6
  import os
7
  import time
8
  import math
9
+ import logging
10
+ from functools import partial
11
+ from typing import Optional, Tuple
12
 
13
  import config
14
 
 
25
  s = round(size_bytes / p, 2)
26
  return f"{s} {size_name[i]}"
27
 
28
+ def format_eta(seconds_left: float) -> str:
29
+ seconds_left = int(seconds_left)
30
+ h, remainder = divmod(seconds_left, 3600)
31
+ m, s = divmod(remainder, 60)
32
+ if h > 0:
33
+ return f"{h}h {m}m {s}s"
34
+ elif m > 0:
35
+ return f"{m}m {s}s"
36
+ else:
37
+ return f"{s}s"
38
+
39
+ # --- Short ID Extract ---
40
+ async def extract_terabox_short_id(full_url: str) -> Optional[str]:
41
  patterns = [
42
  r'terabox\.com/s/([a-zA-Z0-9_-]+)',
43
  r'teraboxapp\.com/s/([a-zA-Z0-9_-]+)',
 
53
  return m.group(1)
54
  return None
55
 
56
+ # --- Get Final URL and Filename ---
57
+ async def get_final_url_and_filename(original_link: str) -> Tuple[Optional[str], Optional[str], Optional[str]]:
58
  payload = {"link": original_link}
59
  headers = {"User-Agent": "Mozilla/5.0"}
60
 
 
78
  except Exception as e:
79
  return None, None, str(e)
80
 
81
+ # --- Download with Progress ---
82
+ async def download_terabox_file(bot_instance, chat_id, msg_id, url, filename) -> Tuple[Optional[str], Optional[str], Optional[str]]:
83
  safe_fn = re.sub(r'[\\/*?:"<>|]', "_", filename)[:200]
84
+ download_path = os.path.join("downloads", f"{chat_id}_{time.time()}_{safe_fn}")
85
 
86
  try:
87
  loop = asyncio.get_event_loop()
 
101
  total_size = int(r.headers.get('content-length', 0))
102
  dl_size = 0
103
  last_update = time.time()
104
+ start_time = time.time()
105
 
106
  with open(download_path, 'wb') as f:
107
  for chunk in r.iter_content(chunk_size=1024 * 1024):
 
109
  f.write(chunk)
110
  dl_size += len(chunk)
111
 
112
+ elapsed = time.time() - start_time
113
+ speed = dl_size / elapsed if elapsed > 0 else 0
114
+ eta = (total_size - dl_size) / speed if speed > 0 else 0
115
+
116
+ pct = (dl_size / total_size * 100) if total_size > 0 else 0
117
+ prog_text = (
118
+ f"📥 <b>Downloading:</b> <code>{filename}</code>\n"
119
+ f"Progress: {format_bytes(dl_size)}/{format_bytes(total_size)} ({pct:.1f}%)\n"
120
+ f"Speed: {format_bytes(speed)}/s\n"
121
+ f"ETA: {format_eta(eta)}"
122
+ )
123
  if time.time() - last_update > 2.5:
124
+ try:
125
+ await bot_instance.edit_message_text(
126
+ chat_id=chat_id,
127
+ message_id=msg_id,
128
+ text=prog_text,
129
+ parse_mode="HTML"
130
+ )
131
+ except Exception:
132
+ pass
133
+
134
  last_update = time.time()
135
 
136
+ # Optional thumbnail generation — skip if not a video
137
+ video_exts = ('.mp4', '.mkv', '.mov', '.avi', '.webm')
138
+ thumb_path = None
139
+ if safe_fn.lower().endswith(video_exts):
140
+ thumb_path = await generate_video_thumbnail(download_path, chat_id)
141
+
142
+ return download_path, thumb_path, None
143
 
144
  except Exception as e:
145
  if os.path.exists(download_path):
146
  os.remove(download_path)
147
+ return None, None, str(e)
148
+
149
+ # --- Generate Video Thumbnail (Optional) ---
150
+ async def generate_video_thumbnail(filepath: str, chat_id: int) -> Optional[str]:
151
+ try:
152
+ import subprocess
153
+ thumb_path = os.path.join("downloads", f"{chat_id}_{time.time()}_thumb.jpg")
154
+
155
+ ffmpeg_cmd = [
156
+ "ffmpeg", "-y", "-i", filepath,
157
+ "-ss", "00:00:01.000", "-vframes", "1", thumb_path
158
+ ]
159
+ subprocess.run(ffmpeg_cmd, check=True)
160
+
161
+ if os.path.exists(thumb_path):
162
+ return thumb_path
163
+ except Exception as e:
164
+ logger.warning(f"Thumbnail generation failed: {e}")
165
+
166
+ return None