MyanmarSwe commited on
Commit
a3f8c77
·
verified ·
1 Parent(s): cf0cec8

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +38 -47
main.py CHANGED
@@ -24,14 +24,14 @@ 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 (RAM)
28
  MEDIAFIRE_CACHE = {}
29
- CACHE_TTL = 3600 # ၁ နာရီအထိ တိုးမြှင့်ထားသည်
30
 
31
  client = httpx.AsyncClient(
32
  timeout=httpx.Timeout(60.0, read=None),
33
  follow_redirects=True,
34
- limits=httpx.Limits(max_connections=200, max_keepalive_connections=50)
35
  )
36
 
37
  @app.get("/")
@@ -63,7 +63,7 @@ def get_clean_filename(url):
63
  decoded_url = urllib.parse.unquote(url)
64
  name = decoded_url.split('/')[-1].split('?')[0]
65
  if not name or '.' not in name:
66
- return "video.mp4"
67
  return name
68
 
69
  @app.get("/download")
@@ -81,35 +81,40 @@ async def download_proxy(request: Request, url: str, key: str = None):
81
  cached_data = MEDIAFIRE_CACHE.get(clean_url)
82
 
83
  target_link = None
84
- # Cache စစ်ဆေးခြင်း
85
  if cached_data and (current_time - cached_data['time']) < CACHE_TTL:
86
  target_link = cached_data['link']
87
  else:
88
  try:
89
- # User-Agent တစ်ခုတည်းကို Session တစ်ခုလုံးအတွက် သုံးရန်
90
  req_ua = ua.random
91
  async with httpx.AsyncClient(headers={'User-Agent': req_ua}, follow_redirects=True) as temp_client:
92
  page_res = await temp_client.get(clean_url)
93
- if page_res.status_code == 200:
94
- html_content = page_res.text
95
- match = re.search(r"https?://download[0-9]+\.mediafire\.com/[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+/[^\s'\"]+", html_content)
96
- if match:
97
- target_link = match.group(0).replace('"', '').replace("'", "")
98
-
99
- if not target_link:
100
- soup = BeautifulSoup(html_content, 'html.parser')
101
- download_btn = soup.find('a', {'id': 'downloadButton'}) or soup.find('a', {'class': 'input_btn_p'})
102
- if download_btn: target_link = download_btn.get('href')
103
-
104
- if target_link:
105
- if target_link.startswith("//"): target_link = f"https:{target_link}"
106
- elif target_link.startswith("/"): target_link = f"https://www.mediafire.com{target_link}"
107
- MEDIAFIRE_CACHE[clean_url] = {'link': target_link, 'time': current_time}
108
- except: pass
 
 
 
 
109
 
110
  if target_link:
111
- # MediaFire က Redirect လုပင် Player မှာ Resume/Seek ရအောင် Proxy နဲ့ပဲ ပြန်ပို့ပေးမည
112
- return await stream_file(target_link, range_header, filename)
 
 
 
113
  else:
114
  raise HTTPException(status_code=404, detail="Direct link extraction failed")
115
 
@@ -147,10 +152,6 @@ async def stream_file(target_url, range_header, filename):
147
  try:
148
  req = client.build_request("GET", target_url, headers=headers)
149
  r = await client.send(req, stream=True)
150
- # အကယ်၍ HTML ပြန်လာပါက Cache ကို ဖျက်ပြီး အသစ်ပြန်လုပ်ရန် error ပေးမည်
151
- if 'text/html' in r.headers.get('content-type', '').lower():
152
- await r.aclose()
153
- raise HTTPException(status_code=415, detail="Link Expired")
154
  return await process_response(r, filename)
155
  except Exception as e:
156
  raise HTTPException(status_code=500, detail=str(e))
@@ -158,20 +159,15 @@ async def stream_file(target_url, range_header, filename):
158
  async def process_response(r, filename):
159
  mime_type, _ = mimetypes.guess_type(filename)
160
  if not mime_type or 'application' in mime_type:
161
- mime_type = 'video/mp4' if filename.endswith('.mp4') else 'video/x-matroska'
162
-
163
- # Seek/Resume ရရှိစေရန် အဓိကကျသော Header များကို ထည့်သွင်းခြင်း
164
- res_headers = {
165
- 'Content-Type': mime_type,
166
- 'Accept-Ranges': 'bytes',
167
- 'Cache-Control': 'no-cache',
168
- 'Content-Disposition': f'inline; filename=\"{urllib.parse.quote(filename)}\"'
169
- }
170
 
171
- if 'content-length' in r.headers:
172
- res_headers['Content-Length'] = r.headers['content-length']
173
- if 'content-range' in r.headers:
174
- res_headers['Content-Range'] = r.headers['content-range']
175
 
176
  async def stream_generator():
177
  try:
@@ -180,12 +176,7 @@ async def process_response(r, filename):
180
  finally:
181
  await r.aclose()
182
 
183
- return StreamingResponse(
184
- stream_generator(),
185
- status_code=r.status_code,
186
- headers=res_headers,
187
- media_type=mime_type
188
- )
189
 
190
  if __name__ == "__main__":
191
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
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),
33
  follow_redirects=True,
34
+ limits=httpx.Limits(max_connections=100, max_keepalive_connections=20)
35
  )
36
 
37
  @app.get("/")
 
63
  decoded_url = urllib.parse.unquote(url)
64
  name = decoded_url.split('/')[-1].split('?')[0]
65
  if not name or '.' not in name:
66
+ name = "video.mp4"
67
  return name
68
 
69
  @app.get("/download")
 
81
  cached_data = MEDIAFIRE_CACHE.get(clean_url)
82
 
83
  target_link = None
 
84
  if cached_data and (current_time - cached_data['time']) < CACHE_TTL:
85
  target_link = cached_data['link']
86
  else:
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
+ match = re.search(r"https?://download[0-9]+\.mediafire\.com/[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+/[^\s'\"]+", html_content)
96
+ if match:
97
+ target_link = match.group(0).replace('"', '').replace("'", "")
98
+
99
+ if not target_link:
100
+ soup = BeautifulSoup(html_content, 'html.parser')
101
+ download_btn = soup.find('a', {'id': 'downloadButton'}) or soup.find('a', {'class': 'input_btn_p'})
102
+ if download_btn: target_link = download_btn.get('href')
103
+
104
+ if target_link:
105
+ if target_link.startswith("//"): target_link = f"https:{target_link}"
106
+ elif target_link.startswith("/"): target_link = f"https://www.mediafire.com{target_link}"
107
+ MEDIAFIRE_CACHE[clean_url] = {'link': target_link, 'time': current_time}
108
+ except Exception as e:
109
+ print(f"MediaFire Error: {e}")
110
+ raise HTTPException(status_code=500, detail=str(e))
111
 
112
  if target_link:
113
+ # FIX: Player က Video မှနးသိအောင် Link အဆုံးမှာ /filename.mkv ကို Hint ေနဲ့ ထည့်ပေးလိုကခြင်း
114
+ # ဒါဟာ MediaFire ဆီ Request ရောက်တဲ့အခါ query parameter အနေနဲ့ပဲ မြင်သွားမှာမို့ link မပျက်ပါဘူး
115
+ separator = "&" if "?" in target_link else "?"
116
+ hinted_link = f"{target_link}{separator}ext={filename}"
117
+ return RedirectResponse(url=hinted_link)
118
  else:
119
  raise HTTPException(status_code=404, detail="Direct link extraction failed")
120
 
 
152
  try:
153
  req = client.build_request("GET", target_url, headers=headers)
154
  r = await client.send(req, stream=True)
 
 
 
 
155
  return await process_response(r, filename)
156
  except Exception as e:
157
  raise HTTPException(status_code=500, detail=str(e))
 
159
  async def process_response(r, filename):
160
  mime_type, _ = mimetypes.guess_type(filename)
161
  if not mime_type or 'application' in mime_type:
162
+ mime_type = 'video/x-matroska' if filename.endswith('.mkv') else 'video/mp4'
163
+
164
+ safe_headers = ['content-length', 'content-range', 'accept-ranges', 'cache-control']
165
+ res_headers = {n: v for n, v in r.headers.items() if n.lower() in safe_headers}
166
+ res_headers['Content-Type'] = mime_type
167
+ res_headers['Accept-Ranges'] = 'bytes'
 
 
 
168
 
169
+ quoted_name = urllib.parse.quote(filename)
170
+ res_headers['Content-Disposition'] = f'inline; filename="{quoted_name}"'
 
 
171
 
172
  async def stream_generator():
173
  try:
 
176
  finally:
177
  await r.aclose()
178
 
179
+ return StreamingResponse(stream_generator(), status_code=r.status_code, headers=res_headers, media_type=mime_type)
 
 
 
 
 
180
 
181
  if __name__ == "__main__":
182
  uvicorn.run(app, host="0.0.0.0", port=7860)