Hana Celeste commited on
Update app/akasa_logic.py
Browse files- app/akasa_logic.py +31 -31
app/akasa_logic.py
CHANGED
|
@@ -10,12 +10,19 @@ class AkasaApp:
|
|
| 10 |
|
| 11 |
async def start(self):
|
| 12 |
self.playwright = await async_playwright().start()
|
|
|
|
| 13 |
self.browser = await self.playwright.chromium.launch(
|
| 14 |
headless=True,
|
| 15 |
-
args=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
)
|
| 17 |
asyncio.create_task(self._cleanup_cache())
|
| 18 |
-
print("🚀 [
|
| 19 |
|
| 20 |
async def _cleanup_cache(self):
|
| 21 |
while True:
|
|
@@ -25,11 +32,10 @@ class AkasaApp:
|
|
| 25 |
for uid in uids_to_remove:
|
| 26 |
item = self.cache.pop(uid)
|
| 27 |
await item["context"].close()
|
| 28 |
-
print(f"🧹 [Akasha] Closed expired tab for UID: {uid}")
|
| 29 |
|
| 30 |
async def get_page(self, uid: str):
|
| 31 |
if uid in self.cache:
|
| 32 |
-
self.cache[uid]["expires"] = time.time() +
|
| 33 |
return self.cache[uid]["page"], False
|
| 34 |
|
| 35 |
context = await self.browser.new_context(
|
|
@@ -37,52 +43,46 @@ class AkasaApp:
|
|
| 37 |
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
| 38 |
)
|
| 39 |
page = await context.new_page()
|
| 40 |
-
|
|
|
|
|
|
|
|
|
|
| 41 |
return page, True
|
| 42 |
|
| 43 |
-
|
| 44 |
start_time = time.time()
|
| 45 |
page, is_new = await self.get_page(uid)
|
| 46 |
-
url = f"https://akasha.cv/profile/{uid}"
|
| 47 |
|
| 48 |
try:
|
| 49 |
-
#
|
| 50 |
-
await page.goto(
|
| 51 |
-
|
| 52 |
-
# Selector dựa trên thuộc tính title bạn đã gửi
|
| 53 |
-
refresh_btn_selector = 'div[title="Refresh builds"]'
|
| 54 |
|
| 55 |
-
# Đợi nút xuất hiện
|
| 56 |
-
|
|
|
|
| 57 |
|
| 58 |
-
#
|
| 59 |
-
await
|
| 60 |
|
| 61 |
-
# Click
|
| 62 |
-
await
|
| 63 |
|
| 64 |
-
#
|
| 65 |
-
|
| 66 |
-
await asyncio.sleep(2)
|
| 67 |
|
| 68 |
return {
|
| 69 |
"status": "success",
|
| 70 |
-
"message": "Refresh command executed",
|
| 71 |
"uid": uid,
|
| 72 |
-
"
|
|
|
|
| 73 |
}
|
| 74 |
except Exception as e:
|
| 75 |
-
# Chụp ảnh màn hình lỗi để debug (tùy chọn, lưu trên HuggingFace)
|
| 76 |
-
# await page.screenshot(path="error_akasha.png")
|
| 77 |
return {
|
| 78 |
-
"status": "error",
|
| 79 |
-
"
|
| 80 |
-
"
|
| 81 |
-
"uid": uid
|
| 82 |
}
|
| 83 |
|
| 84 |
async def stop(self):
|
| 85 |
-
for item in self.cache.values():
|
| 86 |
-
await item["context"].close()
|
| 87 |
if self.browser: await self.browser.close()
|
| 88 |
if self.playwright: await self.playwright.stop()
|
|
|
|
| 10 |
|
| 11 |
async def start(self):
|
| 12 |
self.playwright = await async_playwright().start()
|
| 13 |
+
# Launch với các flags tối ưu nhất cho HuggingFace (Low RAM)
|
| 14 |
self.browser = await self.playwright.chromium.launch(
|
| 15 |
headless=True,
|
| 16 |
+
args=[
|
| 17 |
+
'--no-sandbox',
|
| 18 |
+
'--disable-setuid-sandbox',
|
| 19 |
+
'--disable-dev-shm-usage',
|
| 20 |
+
'--disable-blink-features=AutomationControlled', # Tránh bị check bot
|
| 21 |
+
'--disable-extensions'
|
| 22 |
+
]
|
| 23 |
)
|
| 24 |
asyncio.create_task(self._cleanup_cache())
|
| 25 |
+
print("🚀 [Akasha] Browser Ready")
|
| 26 |
|
| 27 |
async def _cleanup_cache(self):
|
| 28 |
while True:
|
|
|
|
| 32 |
for uid in uids_to_remove:
|
| 33 |
item = self.cache.pop(uid)
|
| 34 |
await item["context"].close()
|
|
|
|
| 35 |
|
| 36 |
async def get_page(self, uid: str):
|
| 37 |
if uid in self.cache:
|
| 38 |
+
self.cache[uid]["expires"] = time.time() + 300
|
| 39 |
return self.cache[uid]["page"], False
|
| 40 |
|
| 41 |
context = await self.browser.new_context(
|
|
|
|
| 43 |
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
| 44 |
)
|
| 45 |
page = await context.new_page()
|
| 46 |
+
# Chặn bớt ảnh và css thừa của Akasha để tải cực nhanh
|
| 47 |
+
await page.route("**/*.{png,jpg,jpeg,gif,webp,css}", lambda route: route.abort())
|
| 48 |
+
|
| 49 |
+
self.cache[uid] = {"page": page, "context": context, "expires": time.time() + 300}
|
| 50 |
return page, True
|
| 51 |
|
| 52 |
+
async def refresh_akasha(self, uid: str):
|
| 53 |
start_time = time.time()
|
| 54 |
page, is_new = await self.get_page(uid)
|
|
|
|
| 55 |
|
| 56 |
try:
|
| 57 |
+
# 1. Đi tới profile
|
| 58 |
+
await page.goto(f"https://akasha.cv/profile/{uid}", wait_until="commit", timeout=20000)
|
|
|
|
|
|
|
|
|
|
| 59 |
|
| 60 |
+
# 2. Đợi nút Refresh (title="Refresh builds") xuất hiện trong DOM
|
| 61 |
+
# Dùng selector chính xác từ mẫu HTML bạn đưa
|
| 62 |
+
refresh_btn = page.locator('div[title="Refresh builds"]')
|
| 63 |
|
| 64 |
+
# Chờ nút hiện ra (timeout 10s)
|
| 65 |
+
await refresh_btn.wait_for(state="attached", timeout=10000)
|
| 66 |
|
| 67 |
+
# 3. Click cưỡng ép (force=True) vì đôi khi nó bị che bởi overlay
|
| 68 |
+
await refresh_btn.click(force=True)
|
| 69 |
|
| 70 |
+
# 4. Đợi 1 giây để trigger gửi request lên server Akasha
|
| 71 |
+
await asyncio.sleep(1.5)
|
|
|
|
| 72 |
|
| 73 |
return {
|
| 74 |
"status": "success",
|
|
|
|
| 75 |
"uid": uid,
|
| 76 |
+
"msg": "Lệnh Refresh đã được gửi thành công",
|
| 77 |
+
"time": f"{round(time.time() - start_time, 2)}s"
|
| 78 |
}
|
| 79 |
except Exception as e:
|
|
|
|
|
|
|
| 80 |
return {
|
| 81 |
+
"status": "error",
|
| 82 |
+
"msg": "Không tìm thấy nút Refresh. Có thể UID sai hoặc Akasha đang lag.",
|
| 83 |
+
"error": str(e)
|
|
|
|
| 84 |
}
|
| 85 |
|
| 86 |
async def stop(self):
|
|
|
|
|
|
|
| 87 |
if self.browser: await self.browser.close()
|
| 88 |
if self.playwright: await self.playwright.stop()
|