MyanmarSwe commited on
Commit
fd9bdbb
·
verified ·
1 Parent(s): 1ddbe65

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +25 -63
main.py CHANGED
@@ -9,7 +9,7 @@ import urllib.parse
9
  import mimetypes
10
  from bs4 import BeautifulSoup
11
  from fastapi import FastAPI, HTTPException, Request
12
- from fastapi.responses import StreamingResponse
13
  from fake_useragent import UserAgent
14
  import uvicorn
15
 
@@ -24,9 +24,9 @@ ACCESS_KEY = os.getenv("ACCESS_KEY", "0000")
24
  SERVICE_ACCOUNT_JSON_STR = os.getenv("GOOGLE_SERVICE_ACCOUNT_JSON")
25
  ua = UserAgent(fallback='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36')
26
 
27
- # MediaFire အတွက် Cache Memory
28
  MEDIAFIRE_CACHE = {}
29
- CACHE_TTL = 1800 # Cache သက်တမ်း စက္ကန့် 1800 (မိနစ် 30)
30
 
31
  client = httpx.AsyncClient(
32
  timeout=httpx.Timeout(60.0, read=None),
@@ -74,39 +74,25 @@ async def download_proxy(request: Request, url: str, key: str = None):
74
  clean_url = urllib.parse.unquote(url)
75
  filename = get_clean_filename(clean_url)
76
  range_header = request.headers.get('range')
77
-
78
- req_ua = ua.random
79
  current_time = time.time()
80
 
81
- # --- MediaFire Section ---
82
  if "mediafire.com" in clean_url:
83
-
84
- # 1. Cache ထဲမှာရှိမရှိ အရင်စစ်ဆေးခြင်း (Player များ Seek လုပ်ရာတွင် လွယ်ကူစေရန်)
85
  cached_data = MEDIAFIRE_CACHE.get(clean_url)
 
 
86
  if cached_data and (current_time - cached_data['time']) < CACHE_TTL:
87
- try:
88
- return await stream_file(
89
- cached_data['link'], range_header, filename,
90
- referer=clean_url, req_ua=cached_data['ua'], cookies=cached_data['cookies']
91
- )
92
- except HTTPException as e:
93
- # အကယ်၍ Cached Link သည် သက်တမ်းကုန်သွား၍ 415 ပြန်လာပါက Cache ကိုဖျက်ပြီး အသစ်ပြန်ရှာမည်
94
- if e.status_code == 415:
95
- print(f"Cache expired for {clean_url}, refetching...")
96
- del MEDIAFIRE_CACHE[clean_url]
97
- else:
98
- raise
99
-
100
- # 2. Cache မရှိပါက သို့မဟုတ် Expire ဖြစ်သွားပါက အသစ်ပြန်ရှာခြင်း
101
  try:
 
102
  async with httpx.AsyncClient(headers={'User-Agent': req_ua}, follow_redirects=True) as temp_client:
103
  page_res = await temp_client.get(clean_url)
104
  if page_res.status_code != 200:
105
- raise HTTPException(status_code=page_res.status_code, detail="MediaFire page access failed")
106
 
107
  html_content = page_res.text
108
  target_link = None
109
- cookies = temp_client.cookies
110
 
111
  match = re.search(r"https?://download[0-9]+\.mediafire\.com/[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+/[^\s'\"]+", html_content)
112
  if match:
@@ -115,30 +101,25 @@ async def download_proxy(request: Request, url: str, key: str = None):
115
  if not target_link:
116
  soup = BeautifulSoup(html_content, 'html.parser')
117
  download_btn = soup.find('a', {'id': 'downloadButton'}) or soup.find('a', {'class': 'input_btn_p'})
118
- if download_btn and download_btn.get('href'):
119
- target_link = download_btn.get('href')
120
 
121
  if target_link:
122
  if target_link.startswith("//"): target_link = f"https:{target_link}"
123
  elif target_link.startswith("/"): target_link = f"https://www.mediafire.com{target_link}"
124
 
125
- # နောက်ထပ် Range Request ျာအတွက Memory ထဲတွင် မှတ်သာထားခြင်း
126
- MEDIAFIRE_CACHE[clean_url] = {
127
- 'link': target_link,
128
- 'ua': req_ua,
129
- 'cookies': dict(cookies),
130
- 'time': current_time
131
- }
132
 
133
- return await stream_file(target_link, range_header, filename, referer=clean_url, req_ua=req_ua, cookies=cookies)
 
134
  else:
135
- raise HTTPException(status_code=404, detail="Could not extract direct download link")
136
 
137
  except Exception as e:
138
- print(f"MediaFire Logic Error: {str(e)}")
139
  raise HTTPException(status_code=500, detail=str(e))
140
 
141
- # --- Google Drive Section ---
142
  elif "drive.google.com" in clean_url:
143
  file_id = get_google_file_id(clean_url)
144
  if not file_id: raise HTTPException(status_code=400, detail="Invalid GD Link")
@@ -161,42 +142,28 @@ async def download_proxy(request: Request, url: str, key: str = None):
161
  except: continue
162
 
163
  public_url = f"https://drive.google.com/uc?export=download&id={file_id}"
164
- return await stream_file(public_url, range_header, filename, req_ua=req_ua)
165
 
166
  else:
167
- return await stream_file(clean_url, range_header, filename, req_ua=req_ua)
168
 
169
- async def stream_file(target_url, range_header, filename, referer=None, req_ua=None, cookies=None):
170
- headers = {'User-Agent': req_ua if req_ua else ua.random}
171
  if range_header: headers['Range'] = range_header
172
- if referer: headers['Referer'] = referer
173
-
174
  try:
175
- req = client.build_request("GET", target_url, headers=headers, cookies=cookies)
176
  r = await client.send(req, stream=True)
177
-
178
- ctype = r.headers.get('content-type', '').lower()
179
- if 'text/html' in ctype:
180
- await r.aclose()
181
- raise HTTPException(status_code=415, detail="Invalid Media Type: HTML Received")
182
-
183
  return await process_response(r, filename)
184
- except HTTPException:
185
- raise
186
  except Exception as e:
187
- print(f"Stream Error: {e}")
188
  raise HTTPException(status_code=500, detail=str(e))
189
 
190
  async def process_response(r, filename):
191
  mime_type, _ = mimetypes.guess_type(filename)
192
  if not mime_type or 'application' in mime_type:
193
- if filename.lower().endswith('.mkv'): mime_type = 'video/x-matroska'
194
- elif filename.lower().endswith('.mp4'): mime_type = 'video/mp4'
195
- else: mime_type = 'video/mp4'
196
 
197
  safe_headers = ['content-length', 'content-range', 'accept-ranges', 'cache-control']
198
  res_headers = {n: v for n, v in r.headers.items() if n.lower() in safe_headers}
199
-
200
  res_headers['Content-Type'] = mime_type
201
  res_headers['Accept-Ranges'] = 'bytes'
202
 
@@ -210,12 +177,7 @@ async def process_response(r, filename):
210
  finally:
211
  await r.aclose()
212
 
213
- return StreamingResponse(
214
- stream_generator(),
215
- status_code=r.status_code,
216
- headers=res_headers,
217
- media_type=mime_type
218
- )
219
 
220
  if __name__ == "__main__":
221
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
9
  import mimetypes
10
  from bs4 import BeautifulSoup
11
  from fastapi import FastAPI, HTTPException, Request
12
+ from fastapi.responses import StreamingResponse, RedirectResponse
13
  from fake_useragent import UserAgent
14
  import uvicorn
15
 
 
24
  SERVICE_ACCOUNT_JSON_STR = os.getenv("GOOGLE_SERVICE_ACCOUNT_JSON")
25
  ua = UserAgent(fallback='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36')
26
 
27
+ # MediaFire Cache
28
  MEDIAFIRE_CACHE = {}
29
+ CACHE_TTL = 1800
30
 
31
  client = httpx.AsyncClient(
32
  timeout=httpx.Timeout(60.0, read=None),
 
74
  clean_url = urllib.parse.unquote(url)
75
  filename = get_clean_filename(clean_url)
76
  range_header = request.headers.get('range')
 
 
77
  current_time = time.time()
78
 
79
+ # --- MediaFire Section (Modified to use Redirect) ---
80
  if "mediafire.com" in clean_url:
 
 
81
  cached_data = MEDIAFIRE_CACHE.get(clean_url)
82
+
83
+ # Cache ရှိရင် တိုက်ရိုက် Redirect လုပ်မည်
84
  if cached_data and (current_time - cached_data['time']) < CACHE_TTL:
85
+ return RedirectResponse(url=cached_data['link'])
86
+
 
 
 
 
 
 
 
 
 
 
 
 
87
  try:
88
+ req_ua = ua.random
89
  async with httpx.AsyncClient(headers={'User-Agent': req_ua}, follow_redirects=True) as temp_client:
90
  page_res = await temp_client.get(clean_url)
91
  if page_res.status_code != 200:
92
+ raise HTTPException(status_code=page_res.status_code, detail="MediaFire access failed")
93
 
94
  html_content = page_res.text
95
  target_link = None
 
96
 
97
  match = re.search(r"https?://download[0-9]+\.mediafire\.com/[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+/[^\s'\"]+", html_content)
98
  if match:
 
101
  if not target_link:
102
  soup = BeautifulSoup(html_content, 'html.parser')
103
  download_btn = soup.find('a', {'id': 'downloadButton'}) or soup.find('a', {'class': 'input_btn_p'})
104
+ if download_btn: target_link = download_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
+ # သိဆည်းခြင်း
111
+ MEDIAFIRE_CACHE[clean_url] = {'link': target_link, 'time': current_time}
 
 
 
 
 
112
 
113
+ # Proxy အစား RedirectResponse ကိုသုံးပြီး Player ဆီ လွှဲပေးလိုက်ခြင်း
114
+ return RedirectResponse(url=target_link)
115
  else:
116
+ raise HTTPException(status_code=404, detail="Direct link extraction failed")
117
 
118
  except Exception as e:
119
+ print(f"MediaFire Error: {e}")
120
  raise HTTPException(status_code=500, detail=str(e))
121
 
122
+ # --- Google Drive Section (Stay as Proxy) ---
123
  elif "drive.google.com" in clean_url:
124
  file_id = get_google_file_id(clean_url)
125
  if not file_id: raise HTTPException(status_code=400, detail="Invalid GD Link")
 
142
  except: continue
143
 
144
  public_url = f"https://drive.google.com/uc?export=download&id={file_id}"
145
+ return await stream_file(public_url, range_header, filename)
146
 
147
  else:
148
+ return await stream_file(clean_url, range_header, filename)
149
 
150
+ async def stream_file(target_url, range_header, filename):
151
+ headers = {'User-Agent': ua.random}
152
  if range_header: headers['Range'] = range_header
 
 
153
  try:
154
+ req = client.build_request("GET", target_url, headers=headers)
155
  r = await client.send(req, stream=True)
 
 
 
 
 
 
156
  return await process_response(r, filename)
 
 
157
  except Exception as e:
 
158
  raise HTTPException(status_code=500, detail=str(e))
159
 
160
  async def process_response(r, filename):
161
  mime_type, _ = mimetypes.guess_type(filename)
162
  if not mime_type or 'application' in mime_type:
163
+ mime_type = 'video/x-matroska' if filename.endswith('.mkv') else 'video/mp4'
 
 
164
 
165
  safe_headers = ['content-length', 'content-range', 'accept-ranges', 'cache-control']
166
  res_headers = {n: v for n, v in r.headers.items() if n.lower() in safe_headers}
 
167
  res_headers['Content-Type'] = mime_type
168
  res_headers['Accept-Ranges'] = 'bytes'
169
 
 
177
  finally:
178
  await r.aclose()
179
 
180
+ return StreamingResponse(stream_generator(), status_code=r.status_code, headers=res_headers, media_type=mime_type)
 
 
 
 
 
181
 
182
  if __name__ == "__main__":
183
  uvicorn.run(app, host="0.0.0.0", port=7860)