diff --git a/info.yaml b/info.yaml index a76f5c9..ef9e8bf 100644 --- a/info.yaml +++ b/info.yaml @@ -1,6 +1,6 @@ title: "GDM" package_name: gommi_downloader_manager -version: '0.2.35' +version: '0.2.37' description: FlaskFarm 범용 다운로더 큐 - YouTube, 애니24, 링크애니, Anilife 지원 developer: projectdx home: https://gitea.yommi.duckdns.org/projectdx/gommi_downloader_manager diff --git a/mod_queue.py b/mod_queue.py index b5fc0a0..5c71d26 100644 --- a/mod_queue.py +++ b/mod_queue.py @@ -19,6 +19,7 @@ from framework import F, socketio class DownloadStatus(str, Enum): PENDING = "pending" EXTRACTING = "extracting" # 메타데이터 추출 중 + WAITING = "waiting" # 동시 다운로드 슬롯 대기 중 DOWNLOADING = "downloading" PAUSED = "paused" COMPLETED = "completed" @@ -203,6 +204,33 @@ class ModuleQueue(PluginModuleBase): self.P.logger.error(f'DB Delete Error: {e}') ret['msg'] = '항목이 삭제되었습니다.' + + elif command == 'delete_completed': + # 완료된 항목 일괄 삭제 (메모리 + DB) + removed_memory = 0 + with self._queue_lock: + remove_ids = [ + task_id + for task_id, task in self._downloads.items() + if task.status == DownloadStatus.COMPLETED + ] + for task_id in remove_ids: + del self._downloads[task_id] + removed_memory = len(remove_ids) + + removed_db = 0 + try: + from .model import ModelDownloadItem + with F.app.app_context(): + removed_db = F.db.session.query(ModelDownloadItem).filter( + ModelDownloadItem.status == DownloadStatus.COMPLETED + ).delete(synchronize_session=False) + F.db.session.commit() + except Exception as e: + self.P.logger.error(f'DB Delete Completed Error: {e}') + + ret['msg'] = f'완료 항목 삭제: 메모리 {removed_memory}개, DB {removed_db}개' + ret['data'] = {'memory': removed_memory, 'db': removed_db} # ===== YouTube API for Chrome Extension ===== @@ -747,6 +775,8 @@ class DownloadTask: ModuleQueue._ensure_concurrency_limit() sem = ModuleQueue._concurrency_sem if sem is not None: + self.status = DownloadStatus.WAITING + self._emit_status() while not self._cancelled: if sem.acquire(timeout=0.5): slot_acquired = True diff --git a/templates/gommi_downloader_manager_queue_list.html b/templates/gommi_downloader_manager_queue_list.html index f1b927a..8f462dc 100644 --- a/templates/gommi_downloader_manager_queue_list.html +++ b/templates/gommi_downloader_manager_queue_list.html @@ -323,6 +323,10 @@ background: linear-gradient(135deg, rgba(168, 85, 247, 0.1), rgba(30, 41, 59, 0.95)); border-color: rgba(168, 85, 247, 0.25); } + .dl-card.status-waiting { + background: linear-gradient(135deg, rgba(245, 158, 11, 0.1), rgba(30, 41, 59, 0.95)); + border-color: rgba(245, 158, 11, 0.28); + } /* ID & Meta Row */ .dl-meta { @@ -440,6 +444,9 @@ .status-downloading { color: var(--accent-primary); } .status-downloading .status-dot { background-color: var(--accent-primary); box-shadow: 0 0 8px var(--accent-primary); animation: pulse 1.5s infinite; } + + .status-waiting { color: var(--warning); } + .status-waiting .status-dot { background-color: var(--warning); box-shadow: 0 0 8px var(--warning); animation: pulse 1.5s infinite; } .status-completed { color: var(--success); } .status-completed .status-dot { background-color: var(--success); } @@ -658,6 +665,8 @@ .dl-status-pill.status-pending .status-dot { background: var(--text-muted); opacity: 0.5; } .dl-status-pill.status-extracting { background: rgba(168, 85, 247, 0.2); color: #c084fc; } .dl-status-pill.status-extracting .status-dot { background: #c084fc; animation: pulse 1s infinite; } + .dl-status-pill.status-waiting { background: rgba(240, 173, 78, 0.2); color: var(--warning); } + .dl-status-pill.status-waiting .status-dot { background: var(--warning); animation: pulse 1s infinite; } .dl-status-pill.status-error { background: rgba(217, 83, 79, 0.2); color: var(--danger); } .dl-status-pill.status-error .status-dot { background: var(--danger); } .dl-status-pill.status-cancelled { background: rgba(107, 114, 128, 0.2); color: #9ca3af; } @@ -882,6 +891,9 @@ + @@ -1168,7 +1180,7 @@ ${startTime !== '-' ? startTime.split(' ')[1] || startTime : '-'}
-