feat: Add subtitle download and VTT to SRT conversion, refactor Linkkf queue to class-level, improve video URL extraction, and introduce downloader factory.

This commit is contained in:
2026-01-02 00:02:35 +09:00
parent 88aeb888b3
commit 0c0ab8cd77
10 changed files with 506 additions and 325 deletions

View File

@@ -1,13 +1,67 @@
from .lib.ffmpeg_queue_v1 import FfmpegQueueEntity
from .lib.downloader_factory import DownloaderFactory
from framework import db
import os, shutil, re
import os, shutil, re, logging
from datetime import datetime
logger = logging.getLogger(__name__)
class AnimeQueueEntity(FfmpegQueueEntity):
def __init__(self, P, module_logic, info):
super(AnimeQueueEntity, self).__init__(P, module_logic, info)
self.P = P
def get_downloader(self, video_url, output_file, callback=None, **kwargs):
"""Returns the appropriate downloader using the factory."""
method = self.P.ModelSetting.get(f"{self.module_logic.name}_download_method")
threads = self.P.ModelSetting.get_int(f"{self.module_logic.name}_download_threads")
if threads is None:
threads = 16
# Prepare headers and proxy
headers = self.headers
if headers is None:
headers = getattr(self.module_logic, 'headers', None)
proxy = getattr(self, 'proxy', None)
if proxy is None:
proxy = getattr(self.module_logic, 'proxy', None)
# Build downloader arguments
args = {
'cookies_file': getattr(self, 'cookies_file', None),
'iframe_src': getattr(self, 'iframe_src', None),
'callback_id': self.entity_id,
'callback_function': kwargs.get('callback_function') or getattr(self, 'ffmpeg_listener', None)
}
# Site specific referer defaults
if self.module_logic.name == 'ohli24':
args['referer_url'] = "https://ani.ohli24.com/"
elif self.module_logic.name == 'anilife':
args['referer_url'] = self.P.ModelSetting.get("anilife_url", "https://anilife.live")
args.update(kwargs)
return DownloaderFactory.get_downloader(
method=method,
video_url=video_url,
output_file=output_file,
headers=headers,
callback=callback,
proxy=proxy,
threads=threads,
**args
)
def prepare_extra(self):
"""
[Lazy Extraction]
다운로드 직전에 호출되는 무거운 분석 로직 (URL 추출 등).
자식 클래스에서 오버라이드하여 구현합니다.
"""
pass
def refresh_status(self):
"""Common status refresh logic"""
if self.ffmpeg_status == -1:
@@ -54,12 +108,18 @@ class AnimeQueueEntity(FfmpegQueueEntity):
self.filename = re.sub(r'[\\/:*?"<>|]', '', self.filename)
dest_path = os.path.join(self.savepath, self.filename)
# If already at destination, just return
if self.filepath == dest_path:
self.ffmpeg_status = 7
self.ffmpeg_status_kor = "완료"
self.end_time = datetime.now()
return
if self.filepath and os.path.exists(self.filepath):
if os.path.exists(dest_path):
self.P.logger.info(f"File exists, removing source: {dest_path}")
# policy: overwrite or skip? usually overwrite or skip
# Here assume overwrite or just move
os.remove(dest_path) # overwrite
self.P.logger.info(f"Destination file exists, removing to overwrite: {dest_path}")
os.remove(dest_path)
shutil.move(self.filepath, dest_path)
self.filepath = dest_path # Update filepath to new location