From 4200f48ec0fae25b95bb1ee4e2a4f82ae35f1db0 Mon Sep 17 00:00:00 2001 From: projectdx Date: Mon, 19 Jan 2026 21:14:47 +0900 Subject: [PATCH] Fix zendriver daemon robustness and switch to FF_3.10 environment --- info.yaml | 2 +- lib/zendriver_daemon.py | 27 +- static/css/mobile_custom.css | 4 +- static/css/ohli24.css | 4 +- .../anime_downloader_anilife_request.html | 11 +- templates/anime_downloader_linkkf_list.html | 4 +- .../anime_downloader_linkkf_request.html | 22 +- templates/anime_downloader_log.html | 383 +++++++----------- 8 files changed, 200 insertions(+), 257 deletions(-) diff --git a/info.yaml b/info.yaml index 43578cf..33062bf 100644 --- a/info.yaml +++ b/info.yaml @@ -1,5 +1,5 @@ title: "애니 다운로더" -version: 0.7.7 +version: 0.7.8 package_name: "anime_downloader" developer: "projectdx" description: "anime downloader" diff --git a/lib/zendriver_daemon.py b/lib/zendriver_daemon.py index 4f0f60f..97e8db7 100644 --- a/lib/zendriver_daemon.py +++ b/lib/zendriver_daemon.py @@ -187,8 +187,11 @@ async def ensure_browser() -> Any: # 사용자 데이터 디렉토리 설정 (Mac/Root 권한 이슈 대응) import tempfile + import platform uid = os.getuid() if hasattr(os, 'getuid') else 'win' + log_debug(f"[ZendriverDaemon] Environment: Python {sys.version.split()[0]} on {platform.system()}") + browser_args = [ "--no-sandbox", "--disable-setuid-sandbox", @@ -284,8 +287,28 @@ async def fetch_with_browser(url: str, timeout: int = 30, headers: Optional[Dict # 페이지 로드 시도 try: - # 탭(페이지) 열기 (브라우저가 없으면 생성) - page = await browser.get("about:blank") # 새 탭 열기 대신 기존 탭 재활용 혹은 about:blank 이동 + # zendriver/core/browser.py:304 에서 self.targets가 비어있을 때 StopIteration 발생 가능 + # 이를 방지하기 위해 tabs가 생길 때까지 잠시 대기하거나 직접 생성 시도 + + # 탭(페이지) 확보 + page = None + for attempt in range(5): + try: + if browser.tabs: + page = browser.tabs[0] + log_debug(f"[ZendriverDaemon] Using existing tab (Attempt {attempt+1})") + break + else: + log_debug(f"[ZendriverDaemon] No tabs found, trying browser.get('about:blank') (Attempt {attempt+1})") + page = await browser.get("about:blank") + break + except (StopIteration, RuntimeError, Exception) as tab_e: + log_debug(f"[ZendriverDaemon] Tab acquisition failed: {tab_e}. Retrying...") + await asyncio.sleep(0.5) + + if not page: + result["error"] = "Failed to acquire browser tab" + return result # 헤더 설정 (CDP 사용) if headers: diff --git a/static/css/mobile_custom.css b/static/css/mobile_custom.css index 5492974..e485657 100644 --- a/static/css/mobile_custom.css +++ b/static/css/mobile_custom.css @@ -76,8 +76,8 @@ width: 100% !important; max-width: 100% !important; min-width: 0 !important; - padding-left: 6px !important; - padding-right: 6px !important; + padding-left: 5px !important; + padding-right: 5px !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; diff --git a/static/css/ohli24.css b/static/css/ohli24.css index cc13f5e..d613dd7 100644 --- a/static/css/ohli24.css +++ b/static/css/ohli24.css @@ -40,8 +40,8 @@ body { /* General Layout Fixes */ .container-fluid { - padding-left: 8px !important; - padding-right: 8px !important; + padding-left: 5px !important; + padding-right: 5px !important; max-width: 100%; } diff --git a/templates/anime_downloader_anilife_request.html b/templates/anime_downloader_anilife_request.html index f2092f8..177920e 100644 --- a/templates/anime_downloader_anilife_request.html +++ b/templates/anime_downloader_anilife_request.html @@ -40,14 +40,13 @@ body { placeholder="URL 또는 코드를 입력하세요" style="background: rgba(30, 27, 75, 0.8); color: #e0e7ff; box-shadow: inset 0 2px 4px rgba(0,0,0,0.3); border-radius: 12px 0 0 12px;">
- -
diff --git a/templates/anime_downloader_linkkf_list.html b/templates/anime_downloader_linkkf_list.html index 43df903..821b208 100644 --- a/templates/anime_downloader_linkkf_list.html +++ b/templates/anime_downloader_linkkf_list.html @@ -769,9 +769,9 @@ $(document).ready(function(){ str += ''; } - // [작품소개] 버튼 추가 - JSON 버튼 왼쪽에 배치 + // [보기] 버튼 추가 - JSON 버튼 왼쪽에 배치 if (item.content_code) { - str += ''; + str += ''; } str += ''; diff --git a/templates/anime_downloader_linkkf_request.html b/templates/anime_downloader_linkkf_request.html index 2c408e8..82057e7 100644 --- a/templates/anime_downloader_linkkf_request.html +++ b/templates/anime_downloader_linkkf_request.html @@ -316,15 +316,12 @@ $("body").on('click', '#check_download_btn', function (e) { e.preventDefault(); - all = $('input[id^="checkbox_"]'); - let data = []; - let idx; - for (let i in all) { - if (all[i].checked) { - idx = parseInt(all[i].id.split('_')[1]) + $('input[id^="checkbox_"]').each(function() { + if ($(this).prop('checked')) { + idx = parseInt($(this).attr('id').split('_')[1]) data.push(current_data.episode[idx]); } - } + }); if (data.length == 0) { $.notify('선택하세요.', {type: 'warning'}); return; @@ -343,15 +340,12 @@ $("body").on('click', '#down_subtitle_btn', function (e) { e.preventDefault(); - all = $('input[id^="checkbox_"]'); - let data = []; - let idx; - for (let i in all) { - if (all[i].checked) { - idx = parseInt(all[i].id.split('_')[1]) + $('input[id^="checkbox_"]').each(function() { + if ($(this).prop('checked')) { + idx = parseInt($(this).attr('id').split('_')[1]); data.push(current_data.episode[idx]); } - } + }); if (data.length == 0) { $.notify('선택하세요.', {type: 'warning'}); return; diff --git a/templates/anime_downloader_log.html b/templates/anime_downloader_log.html index 505c7fb..d8e9d1f 100644 --- a/templates/anime_downloader_log.html +++ b/templates/anime_downloader_log.html @@ -1,193 +1,159 @@ {% extends "base.html" %} {% block content %} + + + -
- -
-
-

System Logs

-

Real-time application logs and history.

-
-
- -
+
+
- - - - {% endblock %}