Hana Celeste commited on
Commit
e348ea9
·
verified ·
1 Parent(s): 60d5394

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +41 -22
main.py CHANGED
@@ -1,7 +1,6 @@
1
  import asyncio
2
  import requests
3
  import time
4
- import re
5
  from fastapi import FastAPI
6
  from playwright.async_api import async_playwright
7
 
@@ -19,13 +18,14 @@ async def get_page(uid: str, fast_mode=False):
19
  page = await context.new_page()
20
 
21
  if fast_mode:
22
- # Chỉ cho phép tải tài nguyên cần thiết cho Text, chặn ảnh/css nặng
23
  await page.route("**/*", lambda route: route.abort() if route.request.resource_type in ["image", "media", "font", "stylesheet"] else route.continue_())
24
 
25
  url = f"https://enka.network/u/{uid}/"
26
  await page.goto(url, wait_until="domcontentloaded", timeout=60000)
27
  return browser, page
28
 
 
 
29
  @app.get("/info")
30
  async def info(uid: str):
31
  start_time = time.time()
@@ -47,22 +47,16 @@ async def info(uid: str):
47
  wl = wlMatch ? wlMatch[1] : null;
48
  }
49
 
50
- // FETCH STATS CÙNG ICON URL
51
  const stats = Array.from(document.querySelectorAll('tr.stat')).map(tr => {
52
  const val = tr.querySelector('td:first-child')?.innerText.trim();
53
  const label = tr.querySelector('td:last-child')?.innerText.trim();
54
  const iconTd = tr.querySelector('td.icon');
55
  let iconUrl = null;
56
-
57
  if (iconTd) {
58
  const style = iconTd.getAttribute('style');
59
- // Regex bóc tách link từ --icon: url(...)
60
  const match = style.match(/url\\(["']?(.*?)["']?\\)/);
61
- if (match && match[1]) {
62
- iconUrl = "https://enka.network" + match[1].replace(/\\\\/g, "");
63
- }
64
  }
65
-
66
  return { value: val, label: label, icon: iconUrl };
67
  });
68
 
@@ -76,17 +70,46 @@ async def info(uid: str):
76
  return { name: charName, level, icon: "https://enka.network" + icon_path };
77
  }).filter(i => i !== null);
78
 
79
- return {
80
- player: { name, ar, wl, signature, avatar: avatar_img ? "https://enka.network" + avatar_img : null, stats },
81
- characters: characters
82
- };
83
  }
84
  """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  await browser.close()
86
  return {
87
  "execution_time": f"{round(time.time() - start_time, 2)}s",
88
  "uid": uid,
89
- **data
90
  }
91
  except Exception as e:
92
  await browser.close()
@@ -98,12 +121,12 @@ async def generate(uid: str, char: str = None):
98
  browser, page = await get_page(uid, fast_mode=False)
99
  try:
100
  if char:
101
- formatted_char = char.strip().capitalize();
102
  char_selector = f"//div[contains(@class, 'avatar')]//figure[contains(@style, '{formatted_char}')]"
103
  try:
104
  await page.wait_for_selector(char_selector, timeout=5000)
105
  await page.click(char_selector)
106
- await asyncio.sleep(1)
107
  except: pass
108
 
109
  await page.click('button[data-icon="image"]')
@@ -123,15 +146,11 @@ async def generate(uid: str, char: str = None):
123
  """)
124
  await browser.close()
125
  res = requests.post("https://api.imgbb.com/1/upload", data={"key": IMGBB_API_KEY, "image": img_base64})
126
- return {
127
- "execution_time": f"{round(time.time() - start_time, 2)}s",
128
- "uid": uid,
129
- "card_url": res.json().get('data', {}).get('url')
130
- }
131
  except Exception as e:
132
  await browser.close()
133
  return {"error": str(e)}
134
 
135
  @app.get("/")
136
  def home():
137
- return {"status": "Enka API Pro is Live"}
 
1
  import asyncio
2
  import requests
3
  import time
 
4
  from fastapi import FastAPI
5
  from playwright.async_api import async_playwright
6
 
 
18
  page = await context.new_page()
19
 
20
  if fast_mode:
 
21
  await page.route("**/*", lambda route: route.abort() if route.request.resource_type in ["image", "media", "font", "stylesheet"] else route.continue_())
22
 
23
  url = f"https://enka.network/u/{uid}/"
24
  await page.goto(url, wait_until="domcontentloaded", timeout=60000)
25
  return browser, page
26
 
27
+ # --- ENDPOINTS ---
28
+
29
  @app.get("/info")
30
  async def info(uid: str):
31
  start_time = time.time()
 
47
  wl = wlMatch ? wlMatch[1] : null;
48
  }
49
 
 
50
  const stats = Array.from(document.querySelectorAll('tr.stat')).map(tr => {
51
  const val = tr.querySelector('td:first-child')?.innerText.trim();
52
  const label = tr.querySelector('td:last-child')?.innerText.trim();
53
  const iconTd = tr.querySelector('td.icon');
54
  let iconUrl = null;
 
55
  if (iconTd) {
56
  const style = iconTd.getAttribute('style');
 
57
  const match = style.match(/url\\(["']?(.*?)["']?\\)/);
58
+ if (match && match[1]) iconUrl = "https://enka.network" + match[1].replace(/\\\\/g, "");
 
 
59
  }
 
60
  return { value: val, label: label, icon: iconUrl };
61
  });
62
 
 
70
  return { name: charName, level, icon: "https://enka.network" + icon_path };
71
  }).filter(i => i !== null);
72
 
73
+ return { player: { name, ar, wl, signature, avatar: avatar_img ? "https://enka.network" + avatar_img : null, stats }, characters };
 
 
 
74
  }
75
  """)
76
+ await browser.close()
77
+ return {"execution_time": f"{round(time.time() - start_time, 2)}s", "uid": uid, **data}
78
+ except Exception as e:
79
+ await browser.close()
80
+ return {"error": str(e)}
81
+
82
+ @app.get("/namecard")
83
+ async def namecard(uid: str):
84
+ """Lấy link ảnh Danh Thiếp hiện tại"""
85
+ start_time = time.time()
86
+ # Fast mode = False vì cần click và chờ hiện element
87
+ browser, page = await get_page(uid, fast_mode=False)
88
+ try:
89
+ # Click nút Danh Thiếp
90
+ btn_selector = 'button[data-icon="cards"]'
91
+ await page.wait_for_selector(btn_selector, timeout=15000)
92
+ await page.click(btn_selector)
93
+
94
+ # Đợi modal Danh Thiếp hiện ra và lấy background-image
95
+ img_selector = '.Loda .bg'
96
+ await page.wait_for_selector(img_selector, timeout=15000)
97
+
98
+ namecard_url = await page.evaluate("""
99
+ () => {
100
+ const el = document.querySelector('.Loda .bg');
101
+ if (!el) return null;
102
+ const style = el.getAttribute('style');
103
+ const match = style.match(/url\\(["']?(.*?)["']?\\)/);
104
+ return match ? "https://enka.network" + match[1] : null;
105
+ }
106
+ """)
107
+
108
  await browser.close()
109
  return {
110
  "execution_time": f"{round(time.time() - start_time, 2)}s",
111
  "uid": uid,
112
+ "namecard_url": namecard_url
113
  }
114
  except Exception as e:
115
  await browser.close()
 
121
  browser, page = await get_page(uid, fast_mode=False)
122
  try:
123
  if char:
124
+ formatted_char = char.strip().capitalize()
125
  char_selector = f"//div[contains(@class, 'avatar')]//figure[contains(@style, '{formatted_char}')]"
126
  try:
127
  await page.wait_for_selector(char_selector, timeout=5000)
128
  await page.click(char_selector)
129
+ await asyncio.sleep(1.5)
130
  except: pass
131
 
132
  await page.click('button[data-icon="image"]')
 
146
  """)
147
  await browser.close()
148
  res = requests.post("https://api.imgbb.com/1/upload", data={"key": IMGBB_API_KEY, "image": img_base64})
149
+ return {"execution_time": f"{round(time.time() - start_time, 2)}s", "uid": uid, "card_url": res.json().get('data', {}).get('url')}
 
 
 
 
150
  except Exception as e:
151
  await browser.close()
152
  return {"error": str(e)}
153
 
154
  @app.get("/")
155
  def home():
156
+ return {"status": "Enka API Ultimate Live", "endpoints": ["/info", "/gen", "/namecard"]}