diff --git a/info.yaml b/info.yaml index d2943a7..0eff24b 100644 --- a/info.yaml +++ b/info.yaml @@ -1,5 +1,5 @@ title: "애니 다운로더" -version: "0.4.7" +version: "0.4.8" package_name: "anime_downloader" developer: "projectdx" description: "anime downloader" diff --git a/mod_anilife.py b/mod_anilife.py index a1ad5ed..e69177d 100644 --- a/mod_anilife.py +++ b/mod_anilife.py @@ -1238,29 +1238,93 @@ class LogicAniLife(AnimeModuleBase): ######################################################### def add(self, episode_info): + """Add episode to download queue with early skip checks.""" + # 1. Check if already in queue if self.is_exist(episode_info): return "queue_exist" + + # 2. Check DB for completion status FIRST (before expensive operations) + db_entity = ModelAniLifeItem.get_by_anilife_id(episode_info["_id"]) + logger.debug(f"db_entity():: => {db_entity}") + + if db_entity is not None and db_entity.status == "completed": + logger.info(f"[Skip] Already completed in DB: {episode_info.get('title')}") + return "db_completed" + + # 3. Early file existence check - predict filename from title before expensive Camoufox + predicted_filepath = self._predict_filepath(episode_info) + if predicted_filepath and os.path.exists(predicted_filepath): + logger.info(f"[Skip] File already exists: {predicted_filepath}") + # Update DB status to completed if not already + if db_entity is not None and db_entity.status != "completed": + db_entity.status = "completed" + db_entity.save() + return "file_exists" + + # 4. Proceed with queue addition + if db_entity is None: + logger.debug(f"episode_info:: {episode_info}") + entity = AniLifeQueueEntity(P, self, episode_info) + logger.debug("entity:::> %s", entity.as_dict()) + ModelAniLifeItem.append(entity.as_dict()) + self.queue.add_queue(entity) + return "enqueue_db_append" else: - db_entity = ModelAniLifeItem.get_by_anilife_id(episode_info["_id"]) - - logger.debug(f"db_entity():: => {db_entity}") - - if db_entity is None: - logger.debug(f"episode_info:: {episode_info}") - entity = AniLifeQueueEntity(P, self, episode_info) - logger.debug("entity:::> %s", entity.as_dict()) - ModelAniLifeItem.append(entity.as_dict()) - - self.queue.add_queue(entity) - - return "enqueue_db_append" - elif db_entity.status != "completed": - entity = AniLifeQueueEntity(P, self, episode_info) - - self.queue.add_queue(entity) - return "enqueue_db_exist" + # db_entity exists but status is not completed + entity = AniLifeQueueEntity(P, self, episode_info) + self.queue.add_queue(entity) + return "enqueue_db_exist" + + def _predict_filepath(self, episode_info): + """Predict the output filepath from episode info WITHOUT expensive site access.""" + try: + title = episode_info.get("title", "") + if not title: + return None + + # Parse title pattern: "제목 N기 M화" or "제목 M화" + match = re.compile( + r"(?P