MyanmarSwe commited on
Commit
4aababc
·
verified ·
1 Parent(s): 26a26d7

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +67 -66
main.py CHANGED
@@ -1,7 +1,6 @@
1
  import os
2
  import re
3
  import json
4
- import base64
5
  import httpx
6
  import random
7
  import asyncio
@@ -55,15 +54,13 @@ def get_google_file_id(url):
55
  fid = re.search(r'/(?:d|file/d|open\?id=)/([a-zA-Z0-9_-]+)', url)
56
  return fid.group(1) if fid else None
57
 
58
- def get_mime_from_filename(filename):
59
- """ဖိုင်နာမည်ကိုကြည့်ပြီး Content-Type သတ်မှတ်ခြင်း"""
60
- mime, _ = mimetypes.guess_type(filename)
61
- if not mime:
62
- if filename.lower().endswith('.mkv'): return 'video/x-matroska'
63
- if filename.lower().endswith('.mp4'): return 'video/mp4'
64
- if filename.lower().endswith('.avi'): return 'video/x-msvideo'
65
- return 'video/mp4' # Default for players
66
- return mime
67
 
68
  @app.get("/download")
69
  async def download_proxy(request: Request, url: str, key: str = None):
@@ -71,54 +68,52 @@ async def download_proxy(request: Request, url: str, key: str = None):
71
  raise HTTPException(status_code=403, detail="Access Denied")
72
 
73
  clean_url = urllib.parse.unquote(url)
74
- while "%" in clean_url:
75
- prev_url = clean_url
76
- clean_url = urllib.parse.unquote(clean_url)
77
- if prev_url == clean_url: break
78
-
79
- # URL ထဲမှ ဖိုင်နာမည်ကို ထုတ်ယူခြင်း
80
- filename = "video.mp4"
81
- path_parts = clean_url.split('/')
82
- for part in reversed(path_parts):
83
- if '.' in part and len(part) > 4:
84
- filename = part.split('?')[0]
85
- break
86
-
87
  range_header = request.headers.get('range')
88
 
89
- # --- MediaFire ---
90
  if "mediafire.com" in clean_url:
91
  try:
92
- r = await client.get(clean_url, headers={'User-Agent': ua.random})
93
- if r.status_code != 200:
94
- raise HTTPException(status_code=r.status_code, detail="MediaFire page error")
95
-
96
- target_link = None
97
- match = re.search(r"https?://download[0-9]+\.mediafire\.com/[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+/[^\s'\"]+", r.text)
98
- if match:
99
- target_link = match.group(0).replace('"', '').replace("'", "")
100
-
101
- if not target_link:
102
- soup = BeautifulSoup(r.text, 'html.parser')
103
- btn = soup.find('a', {'id': 'downloadButton'})
104
- if btn: target_link = btn.get('href')
105
-
106
- if target_link:
107
- if target_link.startswith("//"): target_link = f"https:{target_link}"
108
- elif target_link.startswith("/"): target_link = f"https://www.mediafire.com{target_link}"
109
-
110
- if not target_link:
111
- raise HTTPException(status_code=404, detail="Direct link extraction failed")
112
-
113
- return await stream_file(target_link, range_header, filename, referer=clean_url)
 
 
 
 
 
 
 
 
 
 
114
  except Exception as e:
 
115
  raise HTTPException(status_code=500, detail=str(e))
116
 
117
- # --- Google Drive ---
118
  elif "drive.google.com" in clean_url:
119
  file_id = get_google_file_id(clean_url)
120
- if not file_id:
121
- raise HTTPException(status_code=400, detail="Invalid Google Drive Link")
122
 
123
  accounts = get_all_service_accounts()
124
  random.shuffle(accounts)
@@ -130,14 +125,15 @@ async def download_proxy(request: Request, url: str, key: str = None):
130
  headers = {"Authorization": f"Bearer {token}"}
131
  if range_header: headers['Range'] = range_header
132
  try:
 
133
  req = client.build_request("GET", api_link, headers=headers)
134
  r = await client.send(req, stream=True)
135
  if r.status_code in [200, 206]:
136
- # Google API က Content-Type အမှန်ပြန်ပေးလေ့ရှိသည်
137
  return await process_response(r, filename)
138
  await r.aclose()
139
  except: continue
140
 
 
141
  public_url = f"https://drive.google.com/uc?export=download&id={file_id}"
142
  return await stream_file(public_url, range_header, filename)
143
 
@@ -153,30 +149,35 @@ async def stream_file(target_url, range_header, filename, referer=None):
153
  req = client.build_request("GET", target_url, headers=headers)
154
  r = await client.send(req, stream=True)
155
 
156
- # အကယ်၍ HTML ပြန်လာပါက ဗီဒီယိုမဟုတ်ဟု ယူဆပြီး Error ပြရန်
157
- content_type = r.headers.get('content-type', '').lower()
158
- if 'text/html' in content_type:
159
  await r.aclose()
160
- raise HTTPException(status_code=415, detail="Invalid Media: Received HTML instead of Video")
161
 
162
  return await process_response(r, filename)
163
  except Exception as e:
 
164
  raise HTTPException(status_code=500, detail=str(e))
165
 
166
  async def process_response(r, filename):
167
- mime_type = get_mime_from_filename(filename)
168
-
169
- # Player အတွက် လိုအပ်သော Header များကို သန့်စင်ခြင်း
170
- safe_headers = ['content-length', 'content-range', 'accept-ranges']
171
- response_headers = {n: v for n, v in r.headers.items() if n.lower() in safe_headers}
 
 
 
 
 
172
 
173
- # အရေးကြီးသော Header များကို အတင်းအကျပ်သတ်မှတ်ခြင်း
174
- response_headers['Content-Type'] = mime_type
175
- response_headers['Accept-Ranges'] = 'bytes'
176
 
177
- # nPlayer အတွက် filename header
178
- quoted_filename = urllib.parse.quote(filename)
179
- response_headers['Content-Disposition'] = f'inline; filename="{quoted_filename}"'
180
 
181
  async def stream_generator():
182
  try:
@@ -188,7 +189,7 @@ async def process_response(r, filename):
188
  return StreamingResponse(
189
  stream_generator(),
190
  status_code=r.status_code,
191
- headers=response_headers,
192
  media_type=mime_type
193
  )
194
 
 
1
  import os
2
  import re
3
  import json
 
4
  import httpx
5
  import random
6
  import asyncio
 
54
  fid = re.search(r'/(?:d|file/d|open\?id=)/([a-zA-Z0-9_-]+)', url)
55
  return fid.group(1) if fid else None
56
 
57
+ def get_clean_filename(url):
58
+ """URL ထဲကနေ ဖိုင်နာမည်ကို သန့်စင်စွာထုတ်ယူခြင်း"""
59
+ decoded_url = urllib.parse.unquote(url)
60
+ name = decoded_url.split('/')[-1].split('?')[0]
61
+ if not name or '.' not in name:
62
+ name = "video.mp4"
63
+ return name
 
 
64
 
65
  @app.get("/download")
66
  async def download_proxy(request: Request, url: str, key: str = None):
 
68
  raise HTTPException(status_code=403, detail="Access Denied")
69
 
70
  clean_url = urllib.parse.unquote(url)
71
+ filename = get_clean_filename(clean_url)
 
 
 
 
 
 
 
 
 
 
 
 
72
  range_header = request.headers.get('range')
73
 
74
+ # --- MediaFire Section ---
75
  if "mediafire.com" in clean_url:
76
  try:
77
+ # Browser အသွင်ဖြင့် စာမျက်နှာကိုအရင်ဖတ်ခြင်း
78
+ async with httpx.AsyncClient(headers={'User-Agent': ua.random}, follow_redirects=True) as temp_client:
79
+ page_res = await temp_client.get(clean_url)
80
+ if page_res.status_code != 200:
81
+ raise HTTPException(status_code=page_res.status_code, detail="MediaFire page access failed")
82
+
83
+ html_content = page_res.text
84
+ target_link = None
85
+
86
+ # Method A: Direct Search via Regex (The most reliable way)
87
+ # MediaFire direct links usually look like: https://download...
88
+ regex_match = re.search(r"https?://download[0-9]+\.mediafire\.com/[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+/[^\s'\"]+", html_content)
89
+ if regex_match:
90
+ target_link = regex_match.group(0).replace('"', '').replace("'", "")
91
+
92
+ # Method B: BeautifulSoup parsing
93
+ if not target_link:
94
+ soup = BeautifulSoup(html_content, 'html.parser')
95
+ download_btn = soup.find('a', {'id': 'downloadButton'}) or soup.find('a', {'class': 'input_btn_p'})
96
+ if download_btn and download_btn.get('href'):
97
+ target_link = download_btn.get('href')
98
+
99
+ if target_link:
100
+ # Fix Relative URLs
101
+ if target_link.startswith("//"): target_link = f"https:{target_link}"
102
+ elif target_link.startswith("/"): target_link = f"https://www.mediafire.com{target_link}"
103
+
104
+ return await stream_file(target_link, range_header, filename, referer=clean_url)
105
+ else:
106
+ print(f"Extraction Failed for: {clean_url}")
107
+ raise HTTPException(status_code=404, detail="Could not extract direct download link")
108
+
109
  except Exception as e:
110
+ print(f"MediaFire Logic Error: {str(e)}")
111
  raise HTTPException(status_code=500, detail=str(e))
112
 
113
+ # --- Google Drive Section ---
114
  elif "drive.google.com" in clean_url:
115
  file_id = get_google_file_id(clean_url)
116
+ if not file_id: raise HTTPException(status_code=400, detail="Invalid GD Link")
 
117
 
118
  accounts = get_all_service_accounts()
119
  random.shuffle(accounts)
 
125
  headers = {"Authorization": f"Bearer {token}"}
126
  if range_header: headers['Range'] = range_header
127
  try:
128
+ # build_request ကိုသုံးပြီး stream လုပ်ခြင်း
129
  req = client.build_request("GET", api_link, headers=headers)
130
  r = await client.send(req, stream=True)
131
  if r.status_code in [200, 206]:
 
132
  return await process_response(r, filename)
133
  await r.aclose()
134
  except: continue
135
 
136
+ # Fallback to Public Link
137
  public_url = f"https://drive.google.com/uc?export=download&id={file_id}"
138
  return await stream_file(public_url, range_header, filename)
139
 
 
149
  req = client.build_request("GET", target_url, headers=headers)
150
  r = await client.send(req, stream=True)
151
 
152
+ # HTML ပြန်လာရင် ဗီဒီယိုမဟုတ်ကြောင်း သေချာစေရန်
153
+ ctype = r.headers.get('content-type', '').lower()
154
+ if 'text/html' in ctype:
155
  await r.aclose()
156
+ raise HTTPException(status_code=415, detail="Invalid Media Type: HTML Received")
157
 
158
  return await process_response(r, filename)
159
  except Exception as e:
160
+ print(f"Stream Error: {e}")
161
  raise HTTPException(status_code=500, detail=str(e))
162
 
163
  async def process_response(r, filename):
164
+ # MIME Type ကို အတင်းအကျပ် သတ်မှတ်ခြင်း
165
+ mime_type, _ = mimetypes.guess_type(filename)
166
+ if not mime_type or 'application' in mime_type:
167
+ if filename.lower().endswith('.mkv'): mime_type = 'video/x-matroska'
168
+ elif filename.lower().endswith('.mp4'): mime_type = 'video/mp4'
169
+ else: mime_type = 'video/mp4' # Player တွေအတွက် Safe အဖြစ်ဆုံး type
170
+
171
+ # nPlayer/VLC အတွက် လိုအပ်သော Header သန့်စင်မှု
172
+ safe_headers = ['content-length', 'content-range', 'accept-ranges', 'cache-control']
173
+ res_headers = {n: v for n, v in r.headers.items() if n.lower() in safe_headers}
174
 
175
+ res_headers['Content-Type'] = mime_type
176
+ res_headers['Accept-Ranges'] = 'bytes'
 
177
 
178
+ # Filename Header
179
+ quoted_name = urllib.parse.quote(filename)
180
+ res_headers['Content-Disposition'] = f'inline; filename="{quoted_name}"'
181
 
182
  async def stream_generator():
183
  try:
 
189
  return StreamingResponse(
190
  stream_generator(),
191
  status_code=r.status_code,
192
+ headers=res_headers,
193
  media_type=mime_type
194
  )
195