MyanmarSwe commited on
Commit
2a4580d
·
verified ·
1 Parent(s): fdfcbc0

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +70 -66
main.py CHANGED
@@ -25,7 +25,7 @@ ua = UserAgent(fallback='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/5
25
 
26
  # Global Async Client
27
  client = httpx.AsyncClient(
28
- timeout=httpx.Timeout(30.0, read=None),
29
  follow_redirects=True,
30
  limits=httpx.Limits(max_connections=100, max_keepalive_connections=20)
31
  )
@@ -60,73 +60,74 @@ async def download_proxy(request: Request, url: str, key: str = None):
60
  if key != ACCESS_KEY:
61
  raise HTTPException(status_code=403, detail="Access Denied")
62
 
63
- # Double encoded ဖြစ်နေသော URL များကို ရှင်းလင်းရန်
64
  url = urllib.parse.unquote(url)
65
-
66
  range_header = request.headers.get('range')
67
 
68
- # --- MediaFire & Others ---
69
- if "drive.google.com" not in url:
70
  target_link = None
71
- headers = {'User-Agent': ua.random, 'Accept-Language': 'en-US,en;q=0.9'}
72
-
73
- if "mediafire.com" in url:
74
- try:
75
- headers['Referer'] = 'https://www.mediafire.com/'
76
- r = await client.get(url, headers=headers)
77
-
78
- # Regex ဖြင့် Direct Link ကို ရှာဖွေခြင်း
79
- match = re.search(r'href="(https?://[a-zA-Z0-9-]+\.mediafire\.com/download/[^"]+)"', r.text)
80
- if match:
81
- target_link = match.group(1)
82
- else:
83
- soup = BeautifulSoup(r.text, 'html.parser')
84
- btn = soup.find('a', {'id': 'downloadButton'})
85
- if btn and btn.get('href'):
86
- # ပေးလာတဲ့ href မှာ https:// မပါရင် မူလ URL နဲ့ ပေါင်းပြီး အပြည့်အစုံဖြစ်အောင် ပြုလုပ်ခြင်း
87
- target_link = urllib.parse.urljoin(url, btn.get('href'))
88
- except Exception as e:
89
- print(f"MediaFire Error: {e}")
90
-
91
- elif "dropbox.com" in url:
92
- target_link = url.replace("?dl=0", "").split("?")[0] + "?dl=1"
93
 
94
- elif "1drv.ms" in url or "onedrive.live.com" in url:
95
- encoded_url = base64.b64encode(bytes(url, 'utf-8')).decode('utf-8').replace('=', '').replace('/', '_').replace('+', '-')
96
- target_link = f"https://api.onedrive.com/v1.0/shares/u!{encoded_url}/root/content"
 
 
 
97
 
98
- if not target_link:
99
- raise HTTPException(status_code=400, detail="Could not resolve direct link")
100
-
 
 
 
 
 
 
101
  return await stream_file(target_link, range_header)
102
 
103
  # --- Google Drive ---
104
- file_id = get_google_file_id(url)
105
- if not file_id:
106
- raise HTTPException(status_code=400, detail="Invalid Google Drive Link")
 
107
 
108
- accounts = get_all_service_accounts()
109
- random.shuffle(accounts)
110
 
111
- for account in accounts:
112
- token = await get_token_for_account(account)
113
- if not token: continue
114
 
115
- api_link = f"https://www.googleapis.com/drive/v3/files/{file_id}?alt=media"
116
- headers = {"Authorization": f"Bearer {token}"}
117
- if range_header: headers['Range'] = range_header
118
 
119
- try:
120
- req = client.build_request("GET", api_link, headers=headers)
121
- r = await client.send(req, stream=True)
122
- if r.status_code in [200, 206]:
123
- return await process_response(r)
124
- await r.aclose()
125
- except: continue
 
 
 
126
 
127
- # Public Fallback
128
- public_url = f"https://drive.google.com/uc?export=download&id={file_id}"
129
- return await stream_file(public_url, range_header)
130
 
131
  async def stream_file(target_url, range_header):
132
  headers = {'User-Agent': ua.random}
@@ -137,24 +138,27 @@ async def stream_file(target_url, range_header):
137
  r = await client.send(req, stream=True)
138
  return await process_response(r)
139
  except Exception as e:
140
- print(f"Stream Error for {target_url}: {e}")
141
  raise HTTPException(status_code=500, detail=str(e))
142
 
143
  async def process_response(r):
144
- excluded = ['content-encoding', 'content-length', 'transfer-encoding', 'connection', 'content-disposition']
145
- response_headers = {n: v for n, v in r.headers.items() if n.lower() not in excluded}
 
 
 
146
 
147
- response_headers['Accept-Ranges'] = 'bytes'
148
- if 'Content-Length' in r.headers:
149
- response_headers['Content-Length'] = r.headers['Content-Length']
150
- if 'Content-Range' in r.headers:
151
- response_headers['Content-Range'] = r.headers['Content-Range']
152
-
153
- response_headers['Content-Disposition'] = 'attachment'
 
154
 
155
  async def stream_generator():
156
  try:
157
- async for chunk in r.aiter_bytes(chunk_size=131072):
158
  yield chunk
159
  finally:
160
  await r.aclose()
@@ -163,7 +167,7 @@ async def process_response(r):
163
  stream_generator(),
164
  status_code=r.status_code,
165
  headers=response_headers,
166
- media_type='application/octet-stream'
167
  )
168
 
169
  if __name__ == "__main__":
 
25
 
26
  # Global Async Client
27
  client = httpx.AsyncClient(
28
+ timeout=httpx.Timeout(60.0, read=None),
29
  follow_redirects=True,
30
  limits=httpx.Limits(max_connections=100, max_keepalive_connections=20)
31
  )
 
60
  if key != ACCESS_KEY:
61
  raise HTTPException(status_code=403, detail="Access Denied")
62
 
 
63
  url = urllib.parse.unquote(url)
 
64
  range_header = request.headers.get('range')
65
 
66
+ # --- MediaFire ---
67
+ if "mediafire.com" in url:
68
  target_link = None
69
+ headers = {'User-Agent': ua.random}
70
+ try:
71
+ r = await client.get(url, headers=headers)
72
+ # ပိုမိုတိကျသော Regex ဖြင့် Direct Link ရှာခြင်း
73
+ match = re.search(r'https?://download[0-9]+\.mediafire\.com/[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+/[^"]+', r.text)
74
+ if match:
75
+ target_link = match.group(0)
76
+ else:
77
+ soup = BeautifulSoup(r.text, 'html.parser')
78
+ btn = soup.find('a', {'id': 'downloadButton'})
79
+ if btn and btn.get('href'):
80
+ target_link = btn.get('href')
 
 
 
 
 
 
 
 
 
 
81
 
82
+ if not target_link:
83
+ raise HTTPException(status_code=404, detail="MediaFire direct link not found")
84
+
85
+ return await stream_file(target_link, range_header)
86
+ except Exception as e:
87
+ raise HTTPException(status_code=500, detail=f"MediaFire Error: {str(e)}")
88
 
89
+ # --- Dropbox ---
90
+ elif "dropbox.com" in url:
91
+ target_link = url.replace("?dl=0", "").split("?")[0] + "?dl=1"
92
+ return await stream_file(target_link, range_header)
93
+
94
+ # --- OneDrive ---
95
+ elif "1drv.ms" in url or "onedrive.live.com" in url:
96
+ encoded_url = base64.b64encode(bytes(url, 'utf-8')).decode('utf-8').replace('=', '').replace('/', '_').replace('+', '-')
97
+ target_link = f"https://api.onedrive.com/v1.0/shares/u!{encoded_url}/root/content"
98
  return await stream_file(target_link, range_header)
99
 
100
  # --- Google Drive ---
101
+ elif "drive.google.com" in url:
102
+ file_id = get_google_file_id(url)
103
+ if not file_id:
104
+ raise HTTPException(status_code=400, detail="Invalid Google Drive Link")
105
 
106
+ accounts = get_all_service_accounts()
107
+ random.shuffle(accounts)
108
 
109
+ for account in accounts:
110
+ token = await get_token_for_account(account)
111
+ if not token: continue
112
 
113
+ api_link = f"https://www.googleapis.com/drive/v3/files/{file_id}?alt=media"
114
+ headers = {"Authorization": f"Bearer {token}"}
115
+ if range_header: headers['Range'] = range_header
116
 
117
+ try:
118
+ req = client.build_request("GET", api_link, headers=headers)
119
+ r = await client.send(req, stream=True)
120
+ if r.status_code in [200, 206]:
121
+ return await process_response(r)
122
+ await r.aclose()
123
+ except: continue
124
+
125
+ public_url = f"https://drive.google.com/uc?export=download&id={file_id}"
126
+ return await stream_file(public_url, range_header)
127
 
128
+ else:
129
+ # Generic fallback for other direct links
130
+ return await stream_file(url, range_header)
131
 
132
  async def stream_file(target_url, range_header):
133
  headers = {'User-Agent': ua.random}
 
138
  r = await client.send(req, stream=True)
139
  return await process_response(r)
140
  except Exception as e:
 
141
  raise HTTPException(status_code=500, detail=str(e))
142
 
143
  async def process_response(r):
144
+ # Pass-through critical headers for streaming
145
+ safe_headers = [
146
+ 'content-type', 'content-length', 'content-range',
147
+ 'accept-ranges', 'content-disposition', 'cache-control'
148
+ ]
149
 
150
+ response_headers = {n: v for n, v in r.headers.items() if n.lower() in safe_headers}
151
+
152
+ # Force basic streaming headers if missing
153
+ if 'accept-ranges' not in [k.lower() for k in response_headers.keys()]:
154
+ response_headers['Accept-Ranges'] = 'bytes'
155
+
156
+ # nPlayer/VLC အတွက် Content-Type သည် အရေးကြီးပါသည်
157
+ media_type = r.headers.get('content-type', 'application/octet-stream')
158
 
159
  async def stream_generator():
160
  try:
161
+ async for chunk in r.aiter_bytes(chunk_size=262144): # Chunk size ကို 256KB သို့ တိုးမြှင့်ထားသည်
162
  yield chunk
163
  finally:
164
  await r.aclose()
 
167
  stream_generator(),
168
  status_code=r.status_code,
169
  headers=response_headers,
170
+ media_type=media_type
171
  )
172
 
173
  if __name__ == "__main__":