From 15a81cc34406c35d7c9ee9f7ad5cf6191be15633 Mon Sep 17 00:00:00 2001 From: projectdx Date: Fri, 2 Jan 2026 17:48:58 +0900 Subject: [PATCH] Refactor: CSS theme consolidation & site-specific styles (v0.4.5) | Fix: mod_anilife get_series_info IndexError --- README.md | 13 +- info.yaml | 2 +- mod_anilife.py | 27 ++- static/css/anilife.css | 8 + static/css/linkkf.css | 37 ++++ static/css/mobile_custom.css | 88 +++++++++ static/css/ohli24.css | 39 ++++ .../anime_downloader_anilife_category.html | 19 +- templates/anime_downloader_anilife_list.html | 41 +--- templates/anime_downloader_anilife_queue.html | 24 +-- .../anime_downloader_anilife_request.html | 34 +--- .../anime_downloader_anilife_search.html | 64 +------ .../anime_downloader_anilife_setting.html | 19 +- .../anime_downloader_linkkf_category.html | 3 + templates/anime_downloader_linkkf_list.html | 144 +------------- templates/anime_downloader_linkkf_queue.html | 54 +----- .../anime_downloader_linkkf_request.html | 5 + templates/anime_downloader_linkkf_search.html | 4 + .../anime_downloader_linkkf_setting.html | 3 + templates/anime_downloader_ohli24_list.html | 175 +----------------- templates/anime_downloader_ohli24_queue.html | 76 +------- .../anime_downloader_ohli24_request.html | 15 +- templates/anime_downloader_ohli24_search.html | 17 +- .../anime_downloader_ohli24_setting.html | 3 + 24 files changed, 289 insertions(+), 625 deletions(-) create mode 100644 static/css/anilife.css create mode 100644 static/css/linkkf.css create mode 100644 static/css/mobile_custom.css create mode 100644 static/css/ohli24.css diff --git a/README.md b/README.md index 08bc916..b6ab44e 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,8 @@ * **스마트 다운로드 큐**: `ffmpeg` 및 `yt-dlp` 기반의 큐 시스템으로 안정적인 이어받기 및 재시도를 지원합니다. * **사용자 편의성**: * **Proxy 설정**: IP 차단 시 손쉽게 우회할 수 있도록 웹 설정 UI에서 프록시 서버를 지정할 수 있습니다. - * **반응형 UI**: 데스크탑과 모바일 모두에 최적화된 Glassmorphism 디자인. + * **모듈형 테마 시스템**: CSS 변수와 동적 로딩을 활용하여 데스크탑/모바일 모두에 최적화된 사이트별 테마(Anilife, Linkkf, Ohli24)를 제공합니다. + * **실시간 피드백**: 다운로드 상태, 중복 파일 감지 등을 사용자에게 실시간 알림으로 제공합니다. --- @@ -70,6 +71,16 @@ ## 📝 변경 이력 (Changelog) +### v0.4.5 (2026-01-02) +- **CSS 테마 아키텍처 전면 개편**: + - 사이트별 독립 테마 파일 분리 (`anilife.css`, `linkkf.css`, `ohli24.css`) + - 공통 모바일 로직 및 알림 스타일을 `mobile_custom.css`로 통합 (중복 코드 ~2,000줄 제거) + - Jinja2 템플릿을 활용한 테마 동적 로딩 시스템 구현 +- **백엔드 안정성 및 UX 강화**: + - **Anilife**: `get_series_info` 파싱 로직 개선으로 `IndexError` 방지 및 크롤링 안정성 확보 + - **중복 다운로드 알림**: 이미 파일이 존재하거나 DB에 기록이 있을 경우 사용자에게 명확한 알림 메시지 출력 + - **CSS 호환성**: `line-clamp` 속성 크로스 브라우저 호환성 패치 적용 + ### v0.4.3 (2026-01-02) - **모바일 UX 대폭 개선**: - 시스템 알림(bootstrap-notify) 커스텀 스타일링 (사이트별 테마 색상 적용) diff --git a/info.yaml b/info.yaml index 781e660..4e2b19b 100644 --- a/info.yaml +++ b/info.yaml @@ -1,5 +1,5 @@ title: "애니 다운로더" -version: "0.4.11" +version: "0.4.12" package_name: "anime_downloader" developer: "projectdx" description: "anime downloader" diff --git a/mod_anilife.py b/mod_anilife.py index 4387ea7..892dcb1 100644 --- a/mod_anilife.py +++ b/mod_anilife.py @@ -861,16 +861,23 @@ class LogicAniLife(AnimeModuleBase): # tree = html.fromstring(response_data) # logger.debug(response_data) - main_title = tree.xpath('//div[@class="infox"]/h1/text()')[0] - image = tree.xpath('//div[@class="thumb"]/img/@src')[0] - des_items = tree.xpath( - '//div[@class="info-content"]/div[@class="spe"]/span' - ) - des_items1 = ( - tree.xpath('//div[@class="info-content"]/div[@class="spe"]')[0] - .text_content() - .strip() - ) + try: + main_title_node = tree.xpath('//div[@class="infox"]/h1/text()') + main_title = main_title_node[0] if main_title_node else "Unknown Title" + + image_node = tree.xpath('//div[@class="thumb"]/img/@src') + image = image_node[0] if image_node else "" + + des_items = tree.xpath( + '//div[@class="info-content"]/div[@class="spe"]/span' + ) + + des_spe_node = tree.xpath('//div[@class="info-content"]/div[@class="spe"]') + des_items1 = des_spe_node[0].text_content().strip() if des_spe_node else "" + except Exception as e: + logger.error(f"Error parsing series info: {e}") + logger.debug(f"HTML Content: {response.text[:1000]}") # Log first 1000 chars + return {"ret": "error", "log": "HTML 파싱 중 오류가 발생했습니다."} des = {} des_key = [ diff --git a/static/css/anilife.css b/static/css/anilife.css new file mode 100644 index 0000000..311c148 --- /dev/null +++ b/static/css/anilife.css @@ -0,0 +1,8 @@ +/* Anilife Theme Variables */ +:root { + --notify-bg: rgba(30, 27, 75, 0.95); /* Cosmic Violet */ + --notify-border: rgba(139, 92, 246, 0.4); + --notify-success-bg: rgba(6, 78, 59, 0.95); + --notify-warning-bg: rgba(120, 53, 15, 0.95); + --notify-danger-bg: rgba(127, 29, 29, 0.95); +} diff --git a/static/css/linkkf.css b/static/css/linkkf.css new file mode 100644 index 0000000..02537ee --- /dev/null +++ b/static/css/linkkf.css @@ -0,0 +1,37 @@ +/* Linkkf Theme Variables & Overrides */ +:root { + --forest-950: #022c22; + --forest-900: #064e3b; + --forest-800: #065f46; + --forest-500: #10b981; + --forest-400: #34d399; + --forest-100: #d1fae5; + --accent-amber: #fbbf24; + + /* Shared Notify Variables */ + --notify-bg: rgba(2, 44, 34, 0.95); + --notify-border: rgba(16, 185, 129, 0.3); + --notify-success-bg: rgba(6, 78, 59, 0.95); + --notify-warning-bg: rgba(120, 53, 15, 0.95); + --notify-danger-bg: rgba(127, 29, 29, 0.95); +} + +body { + background-color: var(--forest-950) !important; + color: #ecfdf5; +} + +/* Linkkf Specific Nav-Pills Overrides */ +ul.nav.nav-pills.bg-light { + background-color: rgba(6, 78, 59, 0.4) !important; + border: 1px solid rgba(16, 185, 129, 0.1) !important; +} + +ul.nav.nav-pills .nav-link { + color: #d1fae5 !important; +} + +ul.nav.nav-pills .nav-link.active { + background: linear-gradient(135deg, #10b981 0%, #059669 100%) !important; + box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3) !important; +} diff --git a/static/css/mobile_custom.css b/static/css/mobile_custom.css new file mode 100644 index 0000000..c98e594 --- /dev/null +++ b/static/css/mobile_custom.css @@ -0,0 +1,88 @@ +/* Shared Mobile Custom CSS for Anime Downloader */ + +/* Custom Notify Styling for Mobile */ +.bootstrap-notify-container, +[data-notify="container"] { + max-width: 90vw !important; + width: auto !important; + right: 5vw !important; + left: 5vw !important; + padding: 12px 16px !important; + border-radius: 10px !important; + background: var(--notify-bg) !important; + backdrop-filter: blur(10px) !important; + border: 1px solid var(--notify-border) !important; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4) !important; + color: #e0e7ff !important; + font-size: 13px !important; + z-index: 10000 !important; +} + +[data-notify="container"].alert-success { + border-color: rgba(16, 185, 129, 0.4) !important; + background: var(--notify-success-bg, rgba(6, 78, 59, 0.95)) !important; +} + +[data-notify="container"].alert-warning { + border-color: rgba(245, 158, 11, 0.4) !important; + background: var(--notify-warning-bg, rgba(120, 53, 15, 0.95)) !important; +} + +[data-notify="container"].alert-danger { + border-color: rgba(239, 68, 68, 0.4) !important; + background: var(--notify-danger-bg, rgba(127, 29, 29, 0.95)) !important; +} + +[data-notify="message"] { + color: #e0e7ff !important; +} + +[data-notify="title"] { + color: #fff !important; + font-weight: 600 !important; +} + +/* Common Mobile Responsive Fixes */ +@media (max-width: 768px) { + body { + padding-top: 5px !important; + overflow-x: hidden !important; + } + + /* Global Navigation Pills Fix */ + ul.nav.nav-pills.bg-light { + margin-top: 50px !important; + margin-bottom: 10px !important; + width: 100% !important; + display: flex !important; + flex-wrap: wrap !important; + justify-content: center !important; + border-radius: 10px !important; + padding: 4px !important; + gap: 2px !important; + } + + ul.nav.nav-pills .nav-link { + padding: 5px 12px !important; + font-size: 13px !important; + } + + /* Layout Expansion on Mobile */ + .container, .container-fluid, .row, form, #main_container { + width: 100% !important; + max-width: 100% !important; + padding-left: 8px !important; + padding-right: 8px !important; + margin-left: 0 !important; + margin-right: 0 !important; + box-sizing: border-box !important; + } + + /* Card/Table Container Fix */ + .card, .table-responsive { + width: 100% !important; + margin-left: 0 !important; + margin-right: 0 !important; + border-radius: 12px !important; + } +} diff --git a/static/css/ohli24.css b/static/css/ohli24.css new file mode 100644 index 0000000..9c99c85 --- /dev/null +++ b/static/css/ohli24.css @@ -0,0 +1,39 @@ +/* Ohli24 Theme Variables & Overrides */ +:root { + --slate-950: #0f172a; + --slate-900: #0f172a; /* Same as 950 for deep background */ + --slate-800: #1e293b; + --slate-700: #334155; + --blue-500: #3b82f6; + --blue-600: #2563eb; + --amber-400: #facc15; + + /* Shared Notify Variables */ + --notify-bg: rgba(15, 23, 42, 0.95); + --notify-border: rgba(59, 130, 246, 0.3); + --notify-success-bg: rgba(6, 78, 59, 0.95); + --notify-warning-bg: rgba(120, 53, 15, 0.95); + --notify-danger-bg: rgba(127, 29, 29, 0.95); +} + +body { + background-color: var(--slate-950) !important; + color: #f1f5f9; + background-image: linear-gradient(135deg, #1f2937, #111827, #0f172a) !important; + background-attachment: fixed !important; +} + +/* Ohli24 Specific Nav-Pills Overrides */ +ul.nav.nav-pills.bg-light { + background-color: rgba(30, 41, 59, 0.6) !important; + border: 1px solid rgba(255, 255, 255, 0.08) !important; +} + +ul.nav.nav-pills .nav-link { + color: #94a3b8 !important; +} + +ul.nav.nav-pills .nav-link.active { + background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%) !important; + box-shadow: 0 4px 12px rgba(37, 99, 235, 0.4) !important; +} diff --git a/templates/anime_downloader_anilife_category.html b/templates/anime_downloader_anilife_category.html index 274e5ca..1d2e0ed 100644 --- a/templates/anime_downloader_anilife_category.html +++ b/templates/anime_downloader_anilife_category.html @@ -1,4 +1,7 @@ {% extends "base.html" %} {% block content %} + + +
@@ -917,20 +920,6 @@ opacity: 0.5; } - /* Mobile Responsive */ - @media (max-width: 768px) { - body { padding-top: 10px !important; } - ul.nav.nav-pills.bg-light { - margin-top: 50px !important; - margin-bottom: 10px !important; - width: 100% !important; - display: flex !important; - border-radius: 12px !important; - } - ul.nav.nav-pills .nav-link { - padding: 6px 12px !important; - font-size: 13px; - } - } + {% endblock %} diff --git a/templates/anime_downloader_anilife_list.html b/templates/anime_downloader_anilife_list.html index f8b4aca..2c5f550 100644 --- a/templates/anime_downloader_anilife_list.html +++ b/templates/anime_downloader_anilife_list.html @@ -2,6 +2,8 @@ {% block content %} + + + +