diff --git a/info.yaml b/info.yaml
index a013d3b..1efffdb 100644
--- a/info.yaml
+++ b/info.yaml
@@ -1,5 +1,5 @@
title: "애니 다운로더"
-version: "0.3.7"
+version: "0.3.8"
package_name: "anime_downloader"
developer: "projectdx"
description: "anime downloader"
diff --git a/mod_anilife.py b/mod_anilife.py
index a53062d..f7c99df 100644
--- a/mod_anilife.py
+++ b/mod_anilife.py
@@ -47,7 +47,7 @@ from sqlalchemy import or_, and_, func, not_, desc
from framework import db, scheduler, path_data, socketio
from framework.util import Util
from framework import F
-from plugin import PluginModuleBase
+from .mod_base import AnimeModuleBase
from .lib.ffmpeg_queue_v1 import FfmpegQueueEntity, FfmpegQueue
from support.expand.ffmpeg import SupportFfmpeg
from .lib.crawler import Crawler
@@ -68,7 +68,7 @@ logger = P.logger
name = "anilife"
-class LogicAniLife(PluginModuleBase):
+class LogicAniLife(AnimeModuleBase):
db_default = {
"anilife_db_version": "1",
"anilife_url": "https://anilife.live",
@@ -162,8 +162,7 @@ class LogicAniLife(PluginModuleBase):
}
def __init__(self, P):
- super(LogicAniLife, self).__init__(P, "setting", scheduler_desc="애니라이프 자동 다운로드")
- self.name = "anilife"
+ super(LogicAniLife, self).__init__(P, setup_default=self.db_default, name=name, first_menu='setting', scheduler_desc="애니라이프 자동 다운로드")
self.queue = None
self.OS_PLATFORM = platform.system()
default_route_socketio_module(self, attach="/search")
@@ -486,51 +485,7 @@ class LogicAniLife(PluginModuleBase):
def db_init():
pass
- def process_menu(self, sub, req):
- arg = P.ModelSetting.to_dict()
- arg["sub"] = self.name
- if sub in ["setting", "queue", "list", "search", "request"]:
- if sub == "request" and req.args.get("content_code") is not None:
- arg["anilife_current_code"] = req.args.get("content_code")
- if sub == "setting":
- job_id = "%s_%s" % (self.P.package_name, self.name)
- arg["scheduler"] = str(scheduler.is_include(job_id))
- arg["is_running"] = str(scheduler.is_running(job_id))
- return render_template(
- "{package_name}_{module_name}_{sub}.html".format(
- package_name=P.package_name, module_name=self.name, sub=sub
- ),
- arg=arg,
- )
- return render_template("sample.html", title="%s - %s" % (P.package_name, sub))
- def socketio_callback(self, refresh_type, data):
- """
- socketio를 통해 클라이언트에 상태 업데이트 전송
- refresh_type: 'add', 'status', 'last', 'list_refresh' 등
- data: entity.as_dict() 데이터 또는 리스트 갱신용 빈 문자열
- """
- try:
- from flaskfarm.lib.framework.init_main import socketio
-
- # /package_name/module_name/queue 네임스페이스로 emit
- namespace = f"/{P.package_name}/{self.name}/queue"
-
- # 큐 페이지 소켓에 직접 emit
- socketio.emit(refresh_type, data, namespace=namespace, broadcast=True)
-
- # 진행 상태인 경우 /framework 네임스페이스로 전역 알림(옵션)
- if refresh_type == "status" and isinstance(data, dict):
- percent = data.get('percent', 0)
- if percent > 0 and percent % 10 == 0: # 10% 단위로 전역 알림
- notify_data = {
- "type": "info",
- "msg": f"[Anilife] 다운로드중 {percent}% - {data.get('filename', '')}",
- }
- socketio.emit("notify", notify_data, namespace="/framework", broadcast=True)
-
- except Exception as e:
- logger.error(f"socketio_callback error: {e}")
def process_ajax(self, sub, req):
try:
@@ -606,13 +561,6 @@ class LogicAniLife(PluginModuleBase):
if ret["ret"].startswith("enqueue"):
self.socketio_callback("list_refresh", "")
return jsonify(ret)
- elif sub == "entity_list":
- return jsonify(self.queue.get_entity_list())
- elif sub == "queue_command":
- ret = self.queue.command(
- req.form["command"], int(req.form["entity_id"])
- )
- return jsonify(ret)
elif sub == "add_queue_checked_list":
data = json.loads(request.form["data"])
diff --git a/mod_base.py b/mod_base.py
new file mode 100644
index 0000000..1e88671
--- /dev/null
+++ b/mod_base.py
@@ -0,0 +1,192 @@
+from flask import render_template, request, jsonify
+from flaskfarm.lib.plugin import PluginModuleBase
+import framework
+import os, traceback, time, json
+from datetime import datetime
+
+class AnimeModuleBase(PluginModuleBase):
+ def __init__(self, P, setup_default=None, **kwargs):
+ super(AnimeModuleBase, self).__init__(P, **kwargs)
+ self.P = P # Ensure P is available via self.P
+ if setup_default:
+ self.init_module_settings(setup_default)
+
+ def init_module_settings(self, setup_default):
+ try:
+ for key, value in setup_default.items():
+ if self.P.ModelSetting.get(key) is None:
+ self.P.ModelSetting.set(key, value)
+ except Exception as e:
+ self.P.logger.error(f"Settings Init Error: {e}")
+ self.P.logger.error(traceback.format_exc())
+
+ def process_menu(self, sub, req):
+ from framework import F
+ try:
+ # sub can be None from first_menu
+ if sub is None:
+ sub = self.first_menu
+
+ arg = self.P.ModelSetting.to_dict() if self.P.ModelSetting is not None else {}
+ arg["sub"] = self.name
+ arg["sub2"] = sub
+ arg["package_name"] = self.P.package_name
+ arg["module_name"] = self.name
+ arg['path_data'] = F.config['path_data']
+
+ # job_id for scheduler
+ job_id = f"{self.P.package_name}_{self.name}"
+ arg['is_include'] = F.scheduler.is_include(job_id)
+ arg['is_running'] = F.scheduler.is_running(job_id)
+ # Legacy compatibility for some templates
+ arg["scheduler"] = str(arg['is_include'])
+
+ code = req.args.get("content_code") or req.args.get("code")
+ if sub == "request" and code is not None:
+ arg[f"{self.name}_current_code"] = code
+
+ # Check template existence
+ template_name = f"{self.P.package_name}_{self.name}_{sub}.html"
+ return render_template(template_name, arg=arg)
+
+ except Exception as e:
+ self.P.logger.error(f"Menu Error: {e}")
+ self.P.logger.error(traceback.format_exc())
+ return render_template("sample.html", title=f"Error: {e}")
+
+ def process_ajax(self, sub, req):
+ try:
+ if sub == 'setting_save':
+ ret = self.P.ModelSetting.setting_save(req)
+ return jsonify(ret)
+
+ elif sub == 'scheduler':
+ go = req.form['scheduler']
+ job_id = f"{self.P.package_name}_{self.name}"
+ if go == 'true':
+ framework.scheduler.manage_process(job_id, 'sched', {'sub': self.name})
+ else:
+ framework.scheduler.manage_process(job_id, 'cancel', None)
+ return jsonify(go)
+
+ elif sub in ['immediately_execute', 'one_execute']:
+ job_id = f"{self.P.package_name}_{self.name}"
+ framework.scheduler.manage_process(job_id, 'execute', {'sub': self.name})
+ return jsonify({'ret': 'success', 'msg': '작업을 시작합니다.'})
+
+ elif sub == 'reset_db':
+ return jsonify(self.reset_db())
+
+ elif sub == 'browse_dir':
+ # Folder Browser Logic (Matches UI expectation)
+ path = req.form.get('path')
+ if not path:
+ path = '/'
+
+ current_path = os.path.abspath(path)
+ if not os.path.exists(current_path):
+ current_path = '/'
+
+ parent_path = os.path.dirname(current_path)
+ if parent_path == current_path:
+ parent_path = None
+
+ dirs = []
+ try:
+ for name in os.listdir(current_path):
+ full_path = os.path.join(current_path, name)
+ if os.path.isdir(full_path) and not name.startswith('.'):
+ dirs.append({'name': name, 'path': full_path})
+
+ dirs.sort(key=lambda x: x['name'])
+ return jsonify({'ret': 'success', 'directories': dirs, 'current_path': current_path, 'parent_path': parent_path})
+ except Exception as e:
+ return jsonify({'ret': 'fail', 'error': str(e)})
+
+ elif sub == 'queue_command':
+ cmd = req.form['command']
+ entity_id = int(req.form['entity_id'])
+ ret = self.queue.command(cmd, entity_id)
+ return jsonify(ret)
+
+ elif sub == 'entity_list':
+ return jsonify(self.queue.get_entity_list())
+
+ elif sub == 'add_whitelist':
+ # Common whitelist addition
+ data = req.get_json() if req.is_json else req.form
+ data_code = data.get('data_code')
+ if hasattr(self, 'add_whitelist'):
+ return self.add_whitelist(data_code)
+ else:
+ return jsonify({'ret': False, 'log': 'Not implemented'})
+
+ elif sub == 'command':
+ command = request.form.get('command')
+ arg1 = request.form.get('arg1')
+ arg2 = request.form.get('arg2')
+ arg3 = request.form.get('arg3')
+ return self.process_command(command, arg1, arg2, arg3, req)
+
+ except Exception as e:
+ self.P.logger.error(f"AJAX Error: {e}")
+ self.P.logger.error(traceback.format_exc())
+ return jsonify({'ret': 'fail', 'log': str(e)})
+
+ def process_command(self, command, arg1, arg2, arg3, req):
+ try:
+ if command == "list":
+ ret = self.queue.get_entity_list() if self.queue else []
+ return jsonify(ret)
+ elif command == "stop":
+ entity_id = int(arg1)
+ result = self.queue.command("cancel", entity_id) if self.queue else {"ret": "error"}
+ return jsonify(result)
+ elif command == "remove":
+ entity_id = int(arg1)
+ result = self.queue.command("remove", entity_id) if self.queue else {"ret": "error"}
+ return jsonify(result)
+ elif command in ["reset", "delete_completed"]:
+ result = self.queue.command(command, 0) if self.queue else {"ret": "error"}
+ return jsonify(result)
+
+ return jsonify({'ret': 'fail', 'log': f'Unknown command: {command}'})
+ except Exception as e:
+ self.P.logger.error(f"Command Error: {e}")
+ self.P.logger.error(traceback.format_exc())
+ return jsonify({'ret': 'fail', 'log': str(e)})
+
+ def socketio_callback(self, refresh_type, data):
+ """
+ socketio를 통해 클라이언트에 상태 업데이트 전송
+ refresh_type: 'add', 'status', 'last', 'list_refresh' 등
+ data: entity.as_dict() 데이터 또는 리스트 갱신용 빈 문자열
+ """
+ try:
+ from framework import socketio
+
+ # /package_name/module_name/queue 네임스페이스로 emit
+ namespace = f"/{self.P.package_name}/{self.name}/queue"
+
+ # 큐 페이지 소켓에 직접 emit
+ socketio.emit(refresh_type, data, namespace=namespace, broadcast=True)
+
+ except Exception as e:
+ self.P.logger.error(f"socketio_callback error: {e}")
+
+ def reset_db(self):
+ try:
+ # Drop tables logic or delete all rows
+ # This requires access to specific Models.
+ # Child class should implement or pass Models?
+ # Or use self.web_list_model if set
+ if self.web_list_model:
+ framework.db.session.query(self.web_list_model).delete()
+
+ # Delete queue items?
+ # ...
+ framework.db.session.commit()
+ return {'ret': 'success', 'msg': 'DB가 초기화되었습니다.'}
+ except Exception as e:
+ return {'ret': 'fail', 'msg': str(e)}
+
diff --git a/mod_linkkf.py b/mod_linkkf.py
index 2181dc3..662edb8 100644
--- a/mod_linkkf.py
+++ b/mod_linkkf.py
@@ -27,7 +27,7 @@ from flaskfarm.lib.support.expand.ffmpeg import SupportFfmpeg
# sjva 공용
from framework import db, path_data, scheduler
from lxml import html
-from plugin import PluginModuleBase
+from .mod_base import AnimeModuleBase
from requests_cache import CachedSession
# cloudscraper는 lazy import로 처리
@@ -51,7 +51,7 @@ logger = P.logger
name = "linkkf"
-class LogicLinkkf(PluginModuleBase):
+class LogicLinkkf(AnimeModuleBase):
current_headers = None
current_data = None
referer = None
@@ -76,11 +76,8 @@ class LogicLinkkf(PluginModuleBase):
}
def __init__(self, P):
- super(LogicLinkkf, self).__init__(
- P, "setting", scheduler_desc="linkkf 자동 다운로드"
- )
+ super(LogicLinkkf, self).__init__(P, setup_default=self.db_default, name=name, first_menu='setting', scheduler_desc="linkkf 자동 다운로드")
self.queue = None
- self.name = name
self.db_default = {
"linkkf_db_version": "1",
"linkkf_url": "https://linkkf.live",
@@ -111,23 +108,6 @@ class LogicLinkkf(PluginModuleBase):
default_route_socketio_module(self, attach="/setting")
self.current_data = None
- def process_menu(self, sub, req):
- arg = P.ModelSetting.to_dict()
- arg["sub"] = self.name
- if sub in ["setting", "queue", "category", "list", "request", "search"]:
- if sub == "request" and req.args.get("code") is not None:
- arg["linkkf_current_code"] = req.args.get("code")
- if sub == "setting":
- job_id = "%s_%s" % (self.P.package_name, self.name)
- arg["scheduler"] = str(scheduler.is_include(job_id))
- arg["is_running"] = str(scheduler.is_running(job_id))
- return render_template(
- "{package_name}_{module_name}_{sub}.html".format(
- package_name=P.package_name, module_name=self.name, sub=sub
- ),
- arg=arg,
- )
- return render_template("sample.html", title="%s - %s" % (P.package_name, sub))
def process_ajax(self, sub, req):
try:
@@ -205,17 +185,6 @@ class LogicLinkkf(PluginModuleBase):
ret["ret"] = "error"
ret["log"] = str(e)
return jsonify(ret)
- elif sub == "entity_list":
- ret = {"list": self.queue.get_entity_list() if self.queue else []}
- return jsonify(ret)
- elif sub == "queue_command":
- cmd = request.form.get("cmd", "")
- entity_id = request.form.get("entity_id", "")
- if self.queue:
- ret = self.queue.command(cmd, int(entity_id) if entity_id else 0)
- else:
- ret = {"ret": "error", "log": "Queue not initialized"}
- return jsonify(ret)
elif sub == "add_queue_checked_list":
# 선택된 에피소드 일괄 추가 (백그라운드 스레드로 처리)
import threading
@@ -429,64 +398,6 @@ class LogicLinkkf(PluginModuleBase):
P.logger.error(traceback.format_exc())
return jsonify({"ret": "error", "log": str(e)})
- def process_command(self, command, arg1, arg2, arg3, req):
- """
- FlaskFarm 프레임워크가 /command 엔드포인트에서 호출하는 함수
- queue 페이지에서 list, stop 등의 명령을 처리
- """
- ret = {"ret": "success"}
- # logger.debug(f"process_command - command: {command}, arg1: {arg1}")
-
- if command == "list":
- # 큐 목록 반환
- if self.queue:
- ret = [x for x in self.queue.get_entity_list()]
- else:
- ret = []
- return jsonify(ret)
-
- elif command == "stop":
- # 다운로드 중지 (cancel)
- if self.queue and arg1:
- try:
- entity_id = int(arg1)
- result = self.queue.command("cancel", entity_id)
- if result:
- ret = result
- except Exception as e:
- ret = {"ret": "error", "log": str(e)}
- return jsonify(ret)
-
- elif command == "remove":
- # 개별 항목 삭제
- if self.queue and arg1:
- try:
- entity_id = int(arg1)
- result = self.queue.command("remove", entity_id)
- if result:
- ret = result
- except Exception as e:
- ret = {"ret": "error", "log": str(e)}
- return jsonify(ret)
-
- elif command in ["reset", "delete_completed"]:
- # 전체 초기화 또는 완료 삭제
- if self.queue:
- result = self.queue.command(command, 0)
- if result:
- ret = result
- return jsonify(ret)
-
- elif command == "queue_list":
- # 대기 큐 목록
- if self.queue:
- ret = [x for x in self.queue.get_entity_list()]
- else:
- ret = []
- return jsonify(ret)
-
- # 기본 응답
- return jsonify(ret)
def socketio_callback(self, refresh_type, data):
"""
diff --git a/mod_ohli24.py b/mod_ohli24.py
index 5f44606..164497b 100644
--- a/mod_ohli24.py
+++ b/mod_ohli24.py
@@ -55,6 +55,8 @@ from .lib.util import Util
# from support_site import SupportKakaotv
from .setup import *
+from .mod_base import AnimeModuleBase
+from .model_base import AnimeQueueEntity
logger = P.logger
@@ -62,7 +64,7 @@ print("*=" * 50)
name = "ohli24"
-class LogicOhli24(PluginModuleBase):
+class LogicOhli24(AnimeModuleBase):
current_headers: Optional[Dict[str, str]] = None
current_data: Optional[Dict[str, Any]] = None
referer: Optional[str] = None
@@ -108,7 +110,6 @@ class LogicOhli24(PluginModuleBase):
current_download_count = 0
def __init__(self, P: Any) -> None:
- super(LogicOhli24, self).__init__(P, "setting", scheduler_desc="ohli24 자동 다운로드")
self.name: str = name
self.db_default = {
@@ -135,6 +136,7 @@ class LogicOhli24(PluginModuleBase):
"ohli24_image_url_prefix_episode": "https://www.jetcloud-list.cc/thumbnail/",
"ohli24_discord_notify": "True",
}
+ super(LogicOhli24, self).__init__(P, name=name, first_menu='setting', scheduler_desc="ohli24 자동 다운로드", setup_default=self.db_default)
self.queue = None
# default_route_socketio(P, self)
self.web_list_model = ModelOhli24Item
@@ -164,9 +166,7 @@ class LogicOhli24(PluginModuleBase):
except Exception as e:
logger.error(f"Error during stale temp cleanup: {e}")
- @staticmethod
- def db_init() -> None:
- pass
+
# try:
# for key, value in P.Logic.db_default.items():
# if db.session.query(ModelSetting).filter_by(key=key).count() == 0:
@@ -176,27 +176,14 @@ class LogicOhli24(PluginModuleBase):
# logger.error('Exception:%s', e)
# logger.error(traceback.format_exc())
- def process_menu(self, sub: str, req: Any) -> str:
- arg = P.ModelSetting.to_dict()
- arg["sub"] = self.name
- if sub in ["setting", "queue", "list", "category", "request", "search"]:
- if sub == "request" and req.args.get("content_code") is not None:
- arg["ohli24_current_code"] = req.args.get("content_code")
- elif sub == "setting":
- job_id = "%s_%s" % (self.P.package_name, self.name)
- arg["scheduler"] = str(scheduler.is_include(job_id))
- arg["is_running"] = str(scheduler.is_running(job_id))
- return render_template(
- "{package_name}_{module_name}_{sub}.html".format(
- package_name=P.package_name, module_name=self.name, sub=sub
- ),
- arg=arg,
- )
- return render_template("sample.html", title="%s - %s" % (P.package_name, sub))
+
# @staticmethod
def process_ajax(self, sub: str, req: Any) -> Any:
try:
+ ret = super().process_ajax(sub, req)
+ if ret: return ret
+
data = []
cate = request.form.get("type", None)
page = request.form.get("page", None)
@@ -523,13 +510,7 @@ class LogicOhli24(PluginModuleBase):
def process_command(self, command, arg1, arg2, arg3, req):
ret = {"ret": "success"}
- if command == "queue_list":
- logger.debug("queue_list")
- logger.debug(f"self.queue.get_entity_list():: {self.queue.get_entity_list()}")
- ret = [x for x in self.queue.get_entity_list()]
-
- return ret
- elif command == "download_program":
+ if command == "download_program":
_pass = arg2
db_item = ModelOhli24Program.get(arg1)
if _pass == "false" and db_item is not None:
@@ -549,26 +530,9 @@ class LogicOhli24(PluginModuleBase):
db_item.init_for_queue()
self.download_queue.put(db_item)
ret["msg"] = "다운로드를 추가 하였습니다."
+ return jsonify(ret)
- elif command == "list":
- ret = []
- for ins in SupportFfmpeg.get_list():
- ret.append(ins.get_data())
-
- elif command == "queue_command":
- if arg1 == "cancel":
- pass
- elif arg1 == "reset":
- logger.debug("reset")
- # if self.queue is not None:
- # with self.queue.mutex:
- # self.queue.queue.clear()
-
- if self.download_queue is not None:
- with self.download_queue.mutex:
- self.download_queue.queue.clear()
-
- return jsonify(ret)
+ return super().process_command(command, arg1, arg2, arg3, req)
@staticmethod
def add_whitelist(*args):
@@ -1567,7 +1531,7 @@ class LogicOhli24(PluginModuleBase):
logger.error(traceback.format_exc())
-class Ohli24QueueEntity(FfmpegQueueEntity):
+class Ohli24QueueEntity(AnimeQueueEntity):
def __init__(self, P: Any, module_logic: LogicOhli24, info: Dict[str, Any]) -> None:
super(Ohli24QueueEntity, self).__init__(P, module_logic, info)
self._vi: Optional[Any] = None
@@ -1590,6 +1554,7 @@ class Ohli24QueueEntity(FfmpegQueueEntity):
def refresh_status(self) -> None:
+ super().refresh_status()
# ffmpeg_queue_v1.py에서 실패 처리(-1)된 경우 DB 업데이트 트리거
if getattr(self, 'ffmpeg_status', 0) == -1:
reason = getattr(self, 'ffmpeg_status_kor', 'Unknown Error')
@@ -1630,6 +1595,7 @@ class Ohli24QueueEntity(FfmpegQueueEntity):
return tmp
def download_completed(self) -> None:
+ super().download_completed()
logger.debug("download completed.......!!")
logger.debug(f"[DB_COMPLETE] Looking up entity by ohli24_id: {self.info.get('_id')}")
db_entity = ModelOhli24Item.get_by_ohli24_id(self.info["_id"])
diff --git a/model_base.py b/model_base.py
new file mode 100644
index 0000000..6d4f2f7
--- /dev/null
+++ b/model_base.py
@@ -0,0 +1,76 @@
+from .lib.ffmpeg_queue_v1 import FfmpegQueueEntity
+from framework import db
+import os, shutil, re
+from datetime import datetime
+
+class AnimeQueueEntity(FfmpegQueueEntity):
+ def __init__(self, P, module_logic, info):
+ super(AnimeQueueEntity, self).__init__(P, module_logic, info)
+ self.P = P
+
+ def refresh_status(self):
+ """Common status refresh logic"""
+ if self.ffmpeg_status == -1:
+ self.ffmpeg_status_kor = "대기"
+ elif self.ffmpeg_status == 0:
+ self.ffmpeg_status_kor = "대기" # Waiting in queue
+ elif self.ffmpeg_status == 1:
+ self.ffmpeg_status_kor = "분석 중"
+ elif self.ffmpeg_status == 2:
+ self.ffmpeg_status_kor = "다운로드 중"
+ elif self.ffmpeg_status == 3:
+ self.ffmpeg_status_kor = "변환 중" # post-processing
+ elif self.ffmpeg_status == 4:
+ self.ffmpeg_status_kor = "실패"
+ elif self.ffmpeg_status == 5:
+ self.ffmpeg_status_kor = "다운로드 중" # downloading
+ elif self.ffmpeg_status == 6:
+ self.ffmpeg_status_kor = "취소"
+ elif self.ffmpeg_status == 7:
+ self.ffmpeg_status_kor = "완료"
+ elif self.ffmpeg_status == 8:
+ self.ffmpeg_status_kor = "완료(이미 있음)"
+ elif self.ffmpeg_status == 9:
+ self.ffmpeg_status_kor = "실패(파일 없음)"
+
+ def download_completed(self):
+ """Common file move logic"""
+ try:
+ # LogicCommon to move file
+ # Specific implementation might vary but usually:
+ # 1. Check self.savepath
+ # 2. Check self.filename
+ # 3. Move self.filepath to dest
+
+ if not self.savepath or not self.filename:
+ return
+
+ if not os.path.exists(self.savepath):
+ os.makedirs(self.savepath)
+
+ # Clean filename
+ # self.filename = Util.change_text_for_use_filename(self.filename)
+ # (Assuming Util available or do basic replace)
+ self.filename = re.sub(r'[\\/:*?"<>|]', '', self.filename)
+
+ dest_path = os.path.join(self.savepath, self.filename)
+ 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
+
+ shutil.move(self.filepath, dest_path)
+ self.filepath = dest_path # Update filepath to new location
+ self.ffmpeg_status = 7
+ self.ffmpeg_status_kor = "완료"
+ self.end_time = datetime.now()
+ except Exception as e:
+ self.P.logger.error(f"Download completed error: {e}")
+ self.ffmpeg_status = 4
+ self.ffmpeg_status_kor = "이동 실패"
+
+ def info_dict(self, tmp):
+ """Default valid implementation"""
+ return tmp
diff --git a/templates/anime_downloader_anilife_category.html b/templates/anime_downloader_anilife_category.html
index a56d7bb..78bd2e8 100644
--- a/templates/anime_downloader_anilife_category.html
+++ b/templates/anime_downloader_anilife_category.html
@@ -93,14 +93,14 @@
const loader = document.getElementById("preloader");
const dismissLoadingScreen = async function () {
- console.log("Before the delay")
+ // console.log("Before the delay")
// await delay(2.5);
loader.style.display = "none";
};
const get_anime_list = (type, page) => {
- console.log(`type: ${type}, page: ${page}`)
+ // console.log(`type: ${type}, page: ${page}`)
let url = ''
let data = {"page": page, "type": type}
@@ -137,7 +137,7 @@
dataType: "json",
success: (ret) => {
current_screen_movie_data = ret
- console.log('ret::>', ret)
+ // console.log('ret::>', ret)
if (current_screen_movie_data !== '') {
if (type === "ing") {
@@ -153,7 +153,7 @@
make_screen_movie_list(ret.data, page)
}
div_visible = true
- console.log(div_visible)
+ // console.log(div_visible)
}
dismissLoadingScreen()
next_page = page + 1
@@ -216,7 +216,7 @@
let str = ''
let tmp = ''
- console.log(data.anime_list, page)
+ // console.log(data.anime_list, page)
str += '
';
str += '
';
@@ -226,7 +226,7 @@
if (data.anime_list[i].wr_id !== '') {
const re = /bo_table=([^&]+)/
const bo_table = data.anime_list[i].link.match(re)
- // console.log(bo_table)
+ // // console.log(bo_table)
request_url = './request?code=' + data.anime_list[i].code + '&wr_id=' + data.anime_list[i].wr_id + '&bo_table=' + bo_table[1]
} else {
request_url = './request?code=' + data.anime_list[i].code
@@ -269,7 +269,7 @@
let str = ''
let tmp = ''
- console.log(data.anime_list, page)
+ // console.log(data.anime_list, page)
str += '
';
str += '
';
@@ -343,12 +343,12 @@
$("body").on("click", "#btn_search", function (e) {
e.preventDefault();
let query = $("#input_search").val();
- console.log(query);
+ // console.log(query);
current_cate = "search"
current_query = query
if ($("#input_search").val() === "") {
- console.log("search keyword nothing");
+ // console.log("search keyword nothing");
return false;
}
@@ -361,7 +361,7 @@
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
success: function (ret) {
if (ret.ret) {
- console.log('ret:::', ret)
+ // console.log('ret:::', ret)
make_search_result_list(ret.data, 1);
next_page = page + 1
} else {
@@ -374,28 +374,28 @@
});
$('#anime_category #ing').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("ing", 1)
})
$('#anime_category #complete_anilist').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("fin", 1)
})
$('#anime_category #theater').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("theater", 1)
})
$('#anime_category #top20').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("top20", 1)
@@ -405,7 +405,7 @@
$("body").on('click', '#analysis_btn', function (e) {
e.preventDefault();
const code = document.getElementById("code").value
- console.log(code)
+ // console.log(code)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/analysis',
type: "POST",
@@ -414,8 +414,8 @@
dataType: "json",
success: function (ret) {
if (ret.ret === 'success' && ret.data != null) {
- // console.log(ret.code)
- console.log(ret.data)
+ // // console.log(ret.code)
+ // console.log(ret.data)
make_program(ret.data)
} else {
$.notify('
분석 실패' + ret.log, {type: 'warning'});
@@ -443,7 +443,7 @@
$("body").on('click', '#add_queue_btn', function (e) {
e.preventDefault();
data = current_data.episode[$(this).data('idx')];
- console.log('data:::>', data)
+ // console.log('data:::>', data)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/add_queue',
type: "POST",
@@ -507,9 +507,9 @@
})
.then((res) => res.json())
.then((response) => {
- // console.log("Success:", JSON.stringify(response));
+ // // console.log("Success:", JSON.stringify(response));
// {#imagesContainer.appendChild()#}
- console.log("return page:::> ", String(response.page));
+ // console.log("return page:::> ", String(response.page));
// {#page = response.page#}
if (current_cate === 'search') {
make_search_result_list(response.data, response.page);
@@ -529,9 +529,9 @@
const {scrollTop, scrollHeight, clientHeight} = e.target.scrollingElement;
if (Math.round(scrollHeight - scrollTop) <= clientHeight) {
document.getElementById("spinner").style.display = "block";
- console.log("loading");
- console.log("now page::> ", page);
- console.log("next_page::> ", String(next_page));
+ // console.log("loading");
+ // console.log("now page::> ", page);
+ // console.log("next_page::> ", String(next_page));
loadNextAnimes(current_cate, next_page);
}
};
diff --git a/templates/anime_downloader_anilife_queue.html b/templates/anime_downloader_anilife_queue.html
index 865ee20..3b8be8f 100644
--- a/templates/anime_downloader_anilife_queue.html
+++ b/templates/anime_downloader_anilife_queue.html
@@ -61,16 +61,16 @@
$(document).ready(function () {
const socket_url = window.location.protocol + "//" + document.domain + ":" + location.port + "/anime_downloader/anilife/queue";
- console.log("Connecting to socket:", socket_url);
+ // console.log("Connecting to socket:", socket_url);
const socket = io.connect(socket_url);
socket.on('connect', function() {
- console.log('Socket connected to anilife queue!');
+ // console.log('Socket connected to anilife queue!');
});
// 모든 이벤트 모니터링 (디버깅용)
socket.onAny((event, ...args) => {
- console.log(`[Socket event: ${event}]`, args);
+ // console.log(`[Socket event: ${event}]`, args);
});
socket.on('start', function (data) {
@@ -87,7 +87,7 @@
}, 3000);
socket.on('status', function (data) {
- console.log("Status update received:", data);
+ // console.log("Status update received:", data);
status_html(data);
});
@@ -121,7 +121,7 @@
globalSendCommand('list', null, null, null, function (data) {
current_data = data;
$("#list").html('');
- console.log(data)
+ // console.log(data)
if (data.length == 0) {
str = "
작업이 없습니다. | |
";
} else {
diff --git a/templates/anime_downloader_anilife_request.html b/templates/anime_downloader_anilife_request.html
index bde18df..d2c2a17 100644
--- a/templates/anime_downloader_anilife_request.html
+++ b/templates/anime_downloader_anilife_request.html
@@ -61,7 +61,7 @@
const loader = document.getElementById("preloader");
const dismissLoadingScreen = async function () {
- console.log("Before the delay")
+ // console.log("Before the delay")
// await delay(2.5);
loader.style.display = "none";
};
@@ -69,7 +69,7 @@
const wait_seconds = function () {
// REFERENCE: https://www.w3schools.com/jsref/met_win_settimeout.asp
let result = setTimeout(dismissLoadingScreen, 2500);
- console.log(result)
+ // console.log(result)
};
const init = function () {
@@ -83,11 +83,11 @@
async function myAsyncFunction() {
//Do what you want here
- console.log("Before the delay")
+ // console.log("Before the delay")
await delay(2.5);
- console.log("After the delay")
+ // console.log("After the delay")
//Do what you want here too
}
@@ -102,7 +102,7 @@
// e.stopPropagation()
// e.preventDefault();
const code = document.getElementById("code").value
- console.log(code)
+ // console.log(code)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/analysis',
type: "POST",
@@ -111,8 +111,8 @@
dataType: "json",
success: function (ret) {
if (ret.ret === 'success' && ret.data != null) {
- // {#console.log(ret.code)#}
- console.log(ret.data)
+ // {#// console.log(ret.code)#}
+ // console.log(ret.data)
make_program(ret.data)
$("#loader").css("display", 'none')
} else {
@@ -124,7 +124,7 @@
function make_program(data) {
current_data = data;
- // console.log("current_data::", current_data)
+ // // console.log("current_data::", current_data)
// 에피소드 목록을 완전히 숨긴 상태로 시작 (visibility로 레이아웃 시프트 방지)
const episodeList = document.getElementById("episode_list");
@@ -255,9 +255,9 @@
}
$(function () {
- console.log(params.wr_id)
- console.log(findGetParameter('wr_id'))
- console.log(params.code)
+ // console.log(params.wr_id)
+ // console.log(findGetParameter('wr_id'))
+ // console.log(params.code)
if (params.code === '') {
} else {
@@ -267,15 +267,15 @@
if ("{{arg['anilife_current_code']}}" !== "") {
if (params.code === null) {
- console.log('params.code === null')
+ // console.log('params.code === null')
document.getElementById("code").value = "{{arg['anilife_current_code']}}";
} else if (params.code === '') {
document.getElementById("code").value = "{{arg['anilife_current_code']}}";
} else {
- console.log('params code exist')
- console.log(params.code)
+ // console.log('params code exist')
+ // console.log(params.code)
document.getElementById("code").value = params.code
analyze(params.wr_id, params.bo_table)
@@ -309,7 +309,7 @@
}, 100);
$("#loader").css("display", 'none');
- console.log({{ arg['code'] }})
+ // console.log({{ arg['code'] }})
});
$("#analysis_btn").unbind("click").bind('click', function (e) {
@@ -317,7 +317,7 @@
e.stopPropagation()
$("#loader").css("display", 'block')
const code = document.getElementById("code").value
- console.log(code)
+ // console.log(code)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/analysis',
type: "POST",
@@ -327,8 +327,8 @@
success: function (ret) {
$("#loader").css("display", 'none')
if (ret.ret === 'success' && ret.data != null) {
- // {#console.log(ret.code)#}
- console.log(ret.data)
+ // {#// console.log(ret.code)#}
+ // console.log(ret.data)
make_program(ret.data)
dismissLoadingScreen()
@@ -358,7 +358,7 @@
$("body").on('click', '#add_queue_btn', function (e) {
e.preventDefault();
data = current_data.episode[$(this).data('idx')];
- console.log('data:::>', data)
+ // console.log('data:::>', data)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/add_queue',
type: "POST",
@@ -366,7 +366,7 @@
data: {data: JSON.stringify(data)},
dataType: "json",
success: function (data) {
- console.log('#add_queue_btn::data >>', data)
+ // console.log('#add_queue_btn::data >>', data)
if (data.ret == 'enqueue_db_append' || data.ret == 'enqueue_db_exist') {
$.notify('다운로드 작업을 추가 하였습니다.', {type: 'success'});
} else if (data.ret == 'queue_exist') {
diff --git a/templates/anime_downloader_anilife_search.html b/templates/anime_downloader_anilife_search.html
index e810020..93a5aa4 100644
--- a/templates/anime_downloader_anilife_search.html
+++ b/templates/anime_downloader_anilife_search.html
@@ -91,14 +91,14 @@
const loader = document.getElementById("preloader");
const dismissLoadingScreen = async function () {
- console.log("Before the delay")
+ // console.log("Before the delay")
// await delay(2.5);
loader.style.display = "none";
};
const get_anime_list = (type, page) => {
- console.log(`type: ${type}, page: ${page}`)
+ // console.log(`type: ${type}, page: ${page}`)
let url = ''
let data = {"page": page, "type": type}
@@ -138,14 +138,14 @@
$.notify("분석 실패
" + ret.log, {
type: "warning",
});
- console.log("error")
+ // console.log("error")
dismissLoadingScreen()
return false;
}
current_screen_movie_data = ret
- console.log('ret::>', ret)
+ // console.log('ret::>', ret)
if (current_screen_movie_data !== '') {
if (type === "ing") {
@@ -161,7 +161,7 @@
make_screen_movie_list(ret.data, page)
}
div_visible = true
- console.log(div_visible)
+ // console.log(div_visible)
}
dismissLoadingScreen()
next_page = page + 1
@@ -230,7 +230,7 @@
let str = ''
let tmp = ''
- console.log(data.anime_list, page)
+ // console.log(data.anime_list, page)
str += '';
str += '
';
@@ -240,7 +240,7 @@
if (data.anime_list[i].wr_id !== '') {
const re = /bo_table=([^&]+)/
const bo_table = data.anime_list[i].link.match(re)
- // console.log(bo_table)
+ // // console.log(bo_table)
request_url = './request?code=' + data.anime_list[i].code + '&wr_id=' + data.anime_list[i].wr_id + '&bo_table=' + bo_table[1]
} else {
request_url = './request?code=' + data.anime_list[i].code
@@ -289,7 +289,7 @@
let str = ''
let tmp = ''
- console.log(data.anime_list, page)
+ // console.log(data.anime_list, page)
str += '
';
str += '
';
@@ -368,12 +368,12 @@
$("body").on("click", "#btn_search", function (e) {
e.preventDefault();
let query = $("#input_search").val();
- console.log(query);
+ // console.log(query);
current_cate = "search"
current_query = query
if ($("#input_search").val() === "") {
- console.log("search keyword nothing");
+ // console.log("search keyword nothing");
return false;
}
@@ -386,7 +386,7 @@
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
success: function (ret) {
if (ret.ret) {
- console.log('ret:::', ret)
+ // console.log('ret:::', ret)
make_search_result_list(ret.data, 1);
next_page = page + 1
} else {
@@ -400,28 +400,28 @@
});
$('#anime_category #ing').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("ing", 1)
})
$('#anime_category #complete_anilist').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("fin", 1)
})
$('#anime_category #theater').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("theater", 1)
})
$('#anime_category #top20').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("top20", 1)
@@ -431,7 +431,7 @@
$("body").on('click', '#analysis_btn', function (e) {
e.preventDefault();
const code = document.getElementById("code").value
- console.log(code)
+ // console.log(code)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/analysis',
type: "POST",
@@ -440,8 +440,8 @@
dataType: "json",
success: function (ret) {
if (ret.ret === 'success' && ret.data != null) {
- // console.log(ret.code)
- console.log(ret.data)
+ // // console.log(ret.code)
+ // console.log(ret.data)
make_program(ret.data)
} else {
$.notify('
분석 실패' + ret.log, {type: 'warning'});
@@ -470,7 +470,7 @@
$("body").on('click', '#add_queue_btn', function (e) {
e.preventDefault();
data = current_data.episode[$(this).data('idx')];
- console.log('data:::>', data)
+ // console.log('data:::>', data)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/add_queue',
type: "POST",
@@ -534,9 +534,9 @@
})
.then((res) => res.json())
.then((response) => {
- // console.log("Success:", JSON.stringify(response));
+ // // console.log("Success:", JSON.stringify(response));
// {#imagesContainer.appendChild()#}
- console.log("return page:::> ", String(response.page));
+ // console.log("return page:::> ", String(response.page));
// {#page = response.page#}
if (current_cate === 'search') {
make_search_result_list(response.data, response.page);
@@ -556,9 +556,9 @@
const {scrollTop, scrollHeight, clientHeight} = e.target.scrollingElement;
if (Math.round(scrollHeight - scrollTop) <= clientHeight) {
document.getElementById("spinner").style.display = "block";
- console.log("loading");
- console.log("now page::> ", page);
- console.log("next_page::> ", String(next_page));
+ // console.log("loading");
+ // console.log("now page::> ", page);
+ // console.log("next_page::> ", String(next_page));
loadNextAnimes(current_cate, next_page);
}
};
diff --git a/templates/anime_downloader_anilife_setting.html b/templates/anime_downloader_anilife_setting.html
index 81da086..e3939a9 100644
--- a/templates/anime_downloader_anilife_setting.html
+++ b/templates/anime_downloader_anilife_setting.html
@@ -281,8 +281,28 @@
}
/* Collapse Borders */
- .border-left {
- border-left: 3px solid rgba(255,255,255,0.1) !important;
+ /* Folder Browser Modal Styles */
+ .folder-item {
+ cursor: pointer;
+ transition: background 0.2s;
+ border-bottom: 1px solid rgba(255,255,255,0.05);
+ display: flex !important;
+ align-items: center;
+ width: 100%;
+ overflow: hidden;
+ }
+ .folder-item:hover {
+ background: rgba(255, 255, 255, 0.1);
+ }
+ .folder-item span {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ flex: 1;
+ min-width: 0;
+ }
+ .folder-item.selected {
+ background: rgba(59, 130, 246, 0.3) !important;
}
diff --git a/templates/anime_downloader_linkkf_category.html b/templates/anime_downloader_linkkf_category.html
index f279139..a6afed2 100644
--- a/templates/anime_downloader_linkkf_category.html
+++ b/templates/anime_downloader_linkkf_category.html
@@ -70,7 +70,7 @@
const get_anime_list = (type, page) => {
- console.log(`type: ${type}, page: ${page}`)
+ // console.log(`type: ${type}, page: ${page}`)
let url = ''
let data = {"page": page, "type": type}
@@ -103,7 +103,7 @@
dataType: "json",
success: (ret) => {
current_screen_movie_data = ret
- console.log('ret::>', ret)
+ // console.log('ret::>', ret)
if (current_screen_movie_data !== '') {
if (type === "ing") {
@@ -119,7 +119,7 @@
make_screen_movie_list(ret.data, page)
}
div_visible = true
- console.log(div_visible)
+ // console.log(div_visible)
}
next_page = page + 1
}
@@ -189,7 +189,7 @@
let str = ''
let tmp = ''
- console.log(data.anime_list, page)
+ // console.log(data.anime_list, page)
str += '
';
str += '
';
@@ -200,7 +200,7 @@
if (data.anime_list[i].wr_id !== '') {
const re = /bo_table=([^&]+)/
const bo_table = data.anime_list[i].link.match(re)
- console.log(bo_table)
+ // console.log(bo_table)
request_url = './request?code=' + data.anime_list[i].code + '&wr_id=' + data.anime_list[i].wr_id + '&bo_table=' + bo_table[1]
} else {
@@ -245,7 +245,7 @@
let str = ''
let tmp = ''
- console.log(data.anime_list, page)
+ // console.log(data.anime_list, page)
str += '
';
str += '';
@@ -321,12 +321,12 @@
$("body").on("click", "#btn_search", function (e) {
e.preventDefault();
let query = $("#input_search").val();
- console.log(query);
+ // console.log(query);
current_cate = "search"
current_query = query
if ($("#input_search").val() === "") {
- console.log("search keyword nothing");
+ // console.log("search keyword nothing");
return false;
}
@@ -339,7 +339,7 @@
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
success: function (ret) {
if (ret.ret) {
- console.log('ret:::', ret)
+ // console.log('ret:::', ret)
make_search_result_list(ret.data, 1);
next_page = page + 1
} else {
@@ -352,21 +352,21 @@
});
$('#anime_category #ing').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("ing", 1)
})
$('#anime_category #complete_anilist').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("fin", 1)
})
$('#anime_category #theater').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("theater", 1)
@@ -376,7 +376,7 @@
$("body").on('click', '#analysis_btn', function (e) {
e.preventDefault();
const code = document.getElementById("code").value
- console.log(code)
+ // console.log(code)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/analysis',
type: "POST",
@@ -385,8 +385,8 @@
dataType: "json",
success: function (ret) {
if (ret.ret === 'success' && ret.data != null) {
- // console.log(ret.code)
- console.log(ret.data)
+ // // console.log(ret.code)
+ // console.log(ret.data)
make_program(ret.data)
} else {
$.notify('분석 실패
' + ret.log, {type: 'warning'});
@@ -404,7 +404,7 @@
$("body").on("click", "#add_whitelist", function (e) {
e.preventDefault();
let data_code = $(this).attr("data-code");
- console.log(data_code);
+ // console.log(data_code);
$.ajax({
url: "/" + package_name + "/ajax/"+sub+"/add_whitelist",
type: "POST",
@@ -440,7 +440,7 @@
$("body").on('click', '#add_queue_btn', function (e) {
e.preventDefault();
data = current_data.episode[$(this).data('idx')];
- console.log('data:::>', data)
+ // console.log('data:::>', data)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/add_queue',
type: "POST",
@@ -504,9 +504,9 @@
})
.then((res) => res.json())
.then((response) => {
- // console.log("Success:", JSON.stringify(response));
+ // // console.log("Success:", JSON.stringify(response));
// {#imagesContainer.appendChild()#}
- console.log("return page:::> ", String(response.page));
+ // console.log("return page:::> ", String(response.page));
// {#page = response.page#}
if (current_cate === 'search') {
make_search_result_list(response.data, response.page);
@@ -526,9 +526,9 @@
const {scrollTop, scrollHeight, clientHeight} = e.target.scrollingElement;
if (Math.round(scrollHeight - scrollTop) <= clientHeight) {
document.getElementById("spinner").style.display = "block";
- console.log("loading");
- console.log("now page::> ", page);
- console.log("next_page::> ", String(next_page));
+ // console.log("loading");
+ // console.log("now page::> ", page);
+ // console.log("next_page::> ", String(next_page));
loadNextAnimes(current_cate, next_page);
}
};
diff --git a/templates/anime_downloader_linkkf_request.html b/templates/anime_downloader_linkkf_request.html
index 204f3cd..678513d 100644
--- a/templates/anime_downloader_linkkf_request.html
+++ b/templates/anime_downloader_linkkf_request.html
@@ -83,7 +83,7 @@
function analyze(wr_id, bo_table) {
// e.preventDefault();
const code = document.getElementById("code").value
- console.log(code)
+ // console.log(code)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/analysis',
type: "POST",
@@ -92,8 +92,8 @@
dataType: "json",
success: function (ret) {
if (ret.ret === 'success' && ret.data != null) {
- // {#console.log(ret.code)#}
- console.log(ret.data)
+ // {#// console.log(ret.code)#}
+ // console.log(ret.data)
make_program(ret.data)
} else {
$.notify('분석 실패
' + ret.log, {type: 'warning'});
@@ -192,9 +192,9 @@
}
$(function () {
- console.log(params.wr_id)
- console.log(findGetParameter('wr_id'))
- console.log(params.code)
+ // console.log(params.wr_id)
+ // console.log(findGetParameter('wr_id'))
+ // console.log(params.code)
if (params.code === '') {
} else {
@@ -204,15 +204,15 @@
if ("{{arg['linkkf_current_code']}}" !== "") {
if (params.code === null) {
- console.log('params.code === null')
+ // console.log('params.code === null')
document.getElementById("code").value = "{{arg['linkkf_current_code']}}";
} else if (params.code === '') {
document.getElementById("code").value = "{{arg['linkkf_current_code']}}";
} else {
- console.log('params code exist')
- console.log(params.code)
+ // console.log('params code exist')
+ // console.log(params.code)
document.getElementById("code").value = params.code
analyze(params.wr_id, params.bo_table)
@@ -229,7 +229,7 @@
$(document).ready(function () {
- console.log('wr_id::', params.wr_id)
+ // console.log('wr_id::', params.wr_id)
});
@@ -237,7 +237,7 @@
e.preventDefault();
e.stopPropagation()
const code = document.getElementById("code").value
- console.log(code)
+ // console.log(code)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/analysis',
type: "POST",
@@ -246,8 +246,8 @@
dataType: "json",
success: function (ret) {
if (ret.ret === 'success' && ret.data != null) {
- // {#console.log(ret.code)#}
- console.log(ret.data)
+ // {#// console.log(ret.code)#}
+ // console.log(ret.data)
make_program(ret.data)
} else {
$.notify('분석 실패
' + ret.log, {type: 'warning'});
@@ -302,7 +302,7 @@
$("body").on('click', '#add_queue_btn', function (e) {
e.preventDefault();
data = current_data.episode[$(this).data('idx')];
- console.log('data:::>', data)
+ // console.log('data:::>', data)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/add_queue',
type: "POST",
@@ -310,7 +310,7 @@
data: {data: JSON.stringify(data)},
dataType: "json",
success: function (data) {
- console.log('#add_queue_btn::data >>', data)
+ // console.log('#add_queue_btn::data >>', data)
if (data.ret == 'enqueue_db_append' || data.ret == 'enqueue_db_exist') {
$.notify('다운로드 작업을 추가 하였습니다.', {type: 'success'});
} else if (data.ret == 'queue_exist') {
diff --git a/templates/anime_downloader_linkkf_search.html b/templates/anime_downloader_linkkf_search.html
index 9268008..9438dcb 100644
--- a/templates/anime_downloader_linkkf_search.html
+++ b/templates/anime_downloader_linkkf_search.html
@@ -126,7 +126,7 @@
success: (ret) => {
current_screen_movie_data = ret;
total_page = ret.total_page;
- // console.log("ret::>", ret);
+ // // console.log("ret::>", ret);
if (current_screen_movie_data !== "") {
make_screen_movie_list(ret, page);
@@ -175,7 +175,7 @@
dataType: "json",
success: (ret) => {
current_screen_movie_data = ret
- // console.log('ret::>', ret)
+ // // console.log('ret::>', ret)
if (current_screen_movie_data !== '') {
if (type === "ing") {
@@ -192,7 +192,7 @@
make_screen_movie_list(ret.data, page)
}
div_visible = true
- // console.log(div_visible)
+ // // console.log(div_visible)
}
next_page = page + 1
}
@@ -321,9 +321,9 @@
let tmp = "";
let new_anime = true;
let new_style = ''
- // console.log('page a: ', page)
- // console.log(data)
- // console.log(data.data)
+ // // console.log('page a: ', page)
+ // // console.log(data)
+ // // console.log(data.data)
//console.log(data.episode)
let page_elem = "";
@@ -341,8 +341,8 @@
str += "
";
str += '
';
for (let i in data.data) {
- // console.log(i)
- // console.log(data.data[i])
+ // // console.log(i)
+ // // console.log(data.data[i])
if (data.data[i].postid === data.latest_anime_code) {
new_anime = false
}
@@ -438,12 +438,12 @@
$("body").on("click", "#btn_search", function (e) {
e.preventDefault();
let query = $("#input_search").val();
- // console.log(query);
+ // // console.log(query);
current_cate = "search"
current_query = query
if ($("#input_search").val() === "") {
- // console.log("search keyword nothing");
+ // // console.log("search keyword nothing");
return false;
}
@@ -456,7 +456,7 @@
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
success: function (ret) {
if (ret.ret) {
- // console.log('ret:::', ret)
+ // // console.log('ret:::', ret)
make_search_result_list(ret.data, 1);
next_page = page + 1
} else {
@@ -470,34 +470,34 @@
$("#anime_category").on("click", function (e) {
- // console.log($(this))
- // console.log(e)
+ // // console.log($(this))
+ // // console.log(e)
switch (e.target.id) {
case "ing":
- // console.log("ing.....")
+ // // console.log("ing.....")
// spinner_loading.style.display = "block";
current_cate = "ing";
get_anime_list("ing", 1);
break;
case "movie":
- // console.log("movie")
+ // // console.log("movie")
current_cate = "movie";
get_anime_list("movie", 1);
break;
case "complete_anilist":
- // console.log("complete")
+ // // console.log("complete")
current_cate = "complete";
get_anime_list("complete", 1);
break;
case "top_view":
- // console.log("top_view")
+ // // console.log("top_view")
current_cate = "top_view";
get_anime_list("top_view", 1);
break;
default:
- // console.log("default")
+ // // console.log("default")
spinner_loading.style.display = "block";
current_cate = "ing";
get_anime_list(1, "ing");
@@ -512,7 +512,7 @@
$("body").on('click', '#analysis_btn', function (e) {
e.preventDefault();
const code = document.getElementById("code").value
- // console.log(code)
+ // // console.log(code)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/analysis',
type: "POST",
@@ -521,8 +521,8 @@
dataType: "json",
success: function (ret) {
if (ret.ret === 'success' && ret.data != null) {
- // console.log(ret.code)
- // console.log(ret.data)
+ // // console.log(ret.code)
+ // // console.log(ret.data)
make_program(ret.data)
} else {
$.notify('
분석 실패' + ret.log, {type: 'warning'});
@@ -582,7 +582,7 @@
$("body").on('click', '#add_queue_btn', function (e) {
e.preventDefault();
data = current_data.episode[$(this).data('idx')];
- // console.log('data:::>', data)
+ // // console.log('data:::>', data)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/add_queue',
type: "POST",
@@ -606,7 +606,7 @@
// const el = document.querySelector('img');
// const observer = lozad(el); // passing a `NodeList` (e.g. `document.querySelectorAll()`) is also valid
// observer.observe();
- // console.log('scroll 세로크기:', document.body.scrollHeight)
+ // // console.log('scroll 세로크기:', document.body.scrollHeight)
const loadNextAnimes = (cate, page, ch) => {
// spinner.style.display = "block";
@@ -649,9 +649,9 @@
})
.then((res) => res.json())
.then((response) => {
- // console.log("Success:", JSON.stringify(response));
+ // // console.log("Success:", JSON.stringify(response));
// {#imagesContainer.appendChild()#}
- // console.log("return page:::> ", String(response.page));
+ // // console.log("return page:::> ", String(response.page));
// {#page = response.page#}
loader.style.display = "block";
if (current_cate === 'search') {
@@ -661,8 +661,8 @@
make_screen_movie_list(response.data, response.page);
}
- // console.log(document.body.scrollHeight)
- // console.log(ch)
+ // // console.log(document.body.scrollHeight)
+ // // console.log(ch)
window.scrollBy({
top: ch + 35,
left: 0,
@@ -682,9 +682,9 @@
const {scrollTop, scrollHeight, clientHeight} = e.target.scrollingElement;
if (Math.round(scrollHeight - scrollTop) <= clientHeight + 170) {
// document.getElementById("spinner").style.display = "block";
- // console.log("loading");
- // console.log("now page::> ", page);
- // console.log("next_page::> ", String(next_page));
+ // // console.log("loading");
+ // // console.log("now page::> ", page);
+ // // console.log("next_page::> ", String(next_page));
loadNextAnimes(current_cate, next_page, clientHeight);
/*window.scrollBy({
top: e.target.scrollingElement.scrollHeight + 200,
diff --git a/templates/anime_downloader_linkkf_setting.html b/templates/anime_downloader_linkkf_setting.html
index 10a2a9d..c4f1f16 100644
--- a/templates/anime_downloader_linkkf_setting.html
+++ b/templates/anime_downloader_linkkf_setting.html
@@ -293,8 +293,28 @@
}
/* Collapse Borders */
- .border-left {
- border-left: 3px solid rgba(255,255,255,0.1) !important;
+ /* Folder Browser Modal Styles */
+ .folder-item {
+ cursor: pointer;
+ transition: background 0.2s;
+ border-bottom: 1px solid rgba(255,255,255,0.05);
+ display: flex !important;
+ align-items: center;
+ width: 100%;
+ overflow: hidden;
+ }
+ .folder-item:hover {
+ background: rgba(255, 255, 255, 0.05);
+ }
+ .folder-item span {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ flex: 1;
+ min-width: 0;
+ }
+ .folder-item.selected {
+ background: rgba(16, 185, 129, 0.3) !important;
}
diff --git a/templates/anime_downloader_ohli24_category_old.html b/templates/anime_downloader_ohli24_category_old.html
index 066b753..b43fe82 100644
--- a/templates/anime_downloader_ohli24_category_old.html
+++ b/templates/anime_downloader_ohli24_category_old.html
@@ -106,7 +106,7 @@
const get_anime_list = (type, page) => {
- console.log(`type: ${type}, page: ${page}`)
+ // console.log(`type: ${type}, page: ${page}`)
let url = ''
let data = {"page": page, "type": type}
@@ -139,7 +139,7 @@
dataType: "json",
success: (ret) => {
current_screen_movie_data = ret
- console.log('ret::>', ret)
+ // console.log('ret::>', ret)
if (current_screen_movie_data !== '') {
if (type === "ing") {
@@ -155,7 +155,7 @@
make_screen_movie_list(ret.data, page)
}
div_visible = true
- console.log(div_visible)
+ // console.log(div_visible)
}
next_page = page + 1
}
@@ -225,7 +225,7 @@
let str = ''
let tmp = ''
- console.log(data.anime_list, page)
+ // console.log(data.anime_list, page)
str += '
';
str += '
';
@@ -236,7 +236,7 @@
if (data.anime_list[i].wr_id !== '') {
const re = /bo_table=([^&]+)/
const bo_table = data.anime_list[i].link.match(re)
- console.log(bo_table)
+ // console.log(bo_table)
if (bo_table != null) {
request_url = './request?code=' + data.anime_list[i].code + '&wr_id=' + data.anime_list[i].wr_id + '&bo_table=' + bo_table[1]
} else {
@@ -284,7 +284,7 @@
let str = ''
let tmp = ''
- console.log(data.anime_list, page)
+ // console.log(data.anime_list, page)
str += '
';
str += '';
@@ -360,12 +360,12 @@
$("body").on("click", "#btn_search", function (e) {
e.preventDefault();
let query = $("#input_search").val();
- console.log(query);
+ // console.log(query);
current_cate = "search"
current_query = query
if ($("#input_search").val() === "") {
- console.log("search keyword nothing");
+ // console.log("search keyword nothing");
return false;
}
@@ -378,7 +378,7 @@
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
success: function (ret) {
if (ret.ret) {
- console.log('ret:::', ret)
+ // console.log('ret:::', ret)
make_search_result_list(ret.data, 1);
next_page = page + 1
} else {
@@ -391,21 +391,21 @@
});
$('#anime_category #ing').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("ing", 1)
})
$('#anime_category #complete_anilist').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("fin", 1)
})
$('#anime_category #theater').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
let spinner = document.getElementById('spinner');
spinner.style.visibility = 'visible';
get_anime_list("theater", 1)
@@ -415,7 +415,7 @@
$("body").on('click', '#analysis_btn', function (e) {
e.preventDefault();
const code = document.getElementById("code").value
- console.log(code)
+ // console.log(code)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/analysis',
type: "POST",
@@ -424,8 +424,8 @@
dataType: "json",
success: function (ret) {
if (ret.ret === 'success' && ret.data != null) {
- // console.log(ret.code)
- console.log(ret.data)
+ // // console.log(ret.code)
+ // console.log(ret.data)
make_program(ret.data)
} else {
$.notify('분석 실패
' + ret.log, {type: 'warning'});
@@ -443,7 +443,7 @@
$("body").on("click", "#add_whitelist", function (e) {
e.preventDefault();
let data_code = $(this).attr("data-code");
- console.log(data_code);
+ // console.log(data_code);
$.ajax({
url: "/" + package_name + "/ajax/" + sub + "/add_whitelist",
type: "POST",
@@ -479,7 +479,7 @@
$("body").on('click', '#add_queue_btn', function (e) {
e.preventDefault();
data = current_data.episode[$(this).data('idx')];
- console.log('data:::>', data)
+ // console.log('data:::>', data)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/add_queue',
type: "POST",
@@ -543,9 +543,9 @@
})
.then((res) => res.json())
.then((response) => {
- // console.log("Success:", JSON.stringify(response));
+ // // console.log("Success:", JSON.stringify(response));
// {#imagesContainer.appendChild()#}
- console.log("return page:::> ", String(response.page));
+ // console.log("return page:::> ", String(response.page));
// {#page = response.page#}
if (current_cate === 'search') {
make_search_result_list(response.data, response.page);
@@ -565,9 +565,9 @@
const {scrollTop, scrollHeight, clientHeight} = e.target.scrollingElement;
if (Math.round(scrollHeight - scrollTop) <= clientHeight) {
document.getElementById("spinner").style.display = "block";
- console.log("loading");
- console.log("now page::> ", page);
- console.log("next_page::> ", String(next_page));
+ // console.log("loading");
+ // console.log("now page::> ", page);
+ // console.log("next_page::> ", String(next_page));
loadNextAnimes(current_cate, next_page);
}
};
diff --git a/templates/anime_downloader_ohli24_list.html b/templates/anime_downloader_ohli24_list.html
index c4ff8ef..faf9258 100644
--- a/templates/anime_downloader_ohli24_list.html
+++ b/templates/anime_downloader_ohli24_list.html
@@ -147,7 +147,7 @@
});
function global_sub_request_search(page, move_top = true) {
- console.log('........................')
+ // console.log('........................')
var formData = get_formdata('#form_search')
formData += '&page=' + page;
$.ajax({
@@ -157,7 +157,7 @@
data: formData,
dataType: "json",
success: function (data) {
- console.log(data)
+ // console.log(data)
current_data = data;
if (move_top) {
window.scrollTo(0,0);
diff --git a/templates/anime_downloader_ohli24_request.html b/templates/anime_downloader_ohli24_request.html
index 744f2c0..da922d1 100644
--- a/templates/anime_downloader_ohli24_request.html
+++ b/templates/anime_downloader_ohli24_request.html
@@ -91,7 +91,7 @@
{#e.preventDefault();#}
const code = document.getElementById("code").value
- console.log(code)
+ // // console.log(code)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/analysis',
type: "POST",
@@ -100,8 +100,8 @@
dataType: "json",
success: function (ret) {
if (ret.ret === 'success' && ret.data != null) {
- // {#console.log(ret.code)#}
- console.log(ret.data)
+ // {#// // console.log(ret.code)#}
+ // // console.log(ret.data)
var order_text = (ret.data.list_order === 'desc') ? '최신화부터 (역순)' : '1화부터 (정순)';
if (ret.data.list_order === undefined) {
// 로직상 list_order가 없을 수 있으므로 체크
@@ -118,7 +118,7 @@
function make_program(data) {
current_data = data;
- console.log(data);
+ // // console.log(data);
let str = "";
@@ -226,9 +226,9 @@
}
$(function () {
- console.log(params.wr_id)
- console.log(findGetParameter('wr_id'))
- console.log(params.code)
+ // // console.log(params.wr_id)
+ // // console.log(findGetParameter('wr_id'))
+ // // console.log(params.code)
if (params.code === '') {
} else {
@@ -238,15 +238,15 @@
if ("{{arg['ohli24_current_code']}}" !== "") {
if (params.code === null) {
- console.log('params.code === null')
+ // // console.log('params.code === null')
document.getElementById("code").value = "{{arg['ohli24_current_code']}}";
} else if (params.code === '') {
document.getElementById("code").value = "{{arg['ohli24_current_code']}}";
} else {
- console.log('params code exist')
- console.log(params.code)
+ // // console.log('params code exist')
+ // // console.log(params.code)
document.getElementById("code").value = params.code
analyze(params.wr_id, params.bo_table)
@@ -262,15 +262,15 @@
})
$(document).ready(function () {
- console.log("{{ arg['code'] }}")
- console.log('wr_id::', params.wr_id)
+ // // console.log("{{ arg['code'] }}")
+ // // console.log('wr_id::', params.wr_id)
if (document.getElementById("code").value !== "") {
{#document.getElementById("analysis_btn").click()#}
$('#analysis_btn').click();
}
- console.log(accessibleCount)
+ // // console.log(accessibleCount)
});
@@ -280,12 +280,12 @@
e.stopPropagation();
accessibleCount = accessibleCount - 1; //count부터 뺀다
- console.log(accessibleCount)
+ // // console.log(accessibleCount)
if (accessibleCount < 0) {
alert("이미 작업이 수행중 입니다.");
} else {
const code = document.getElementById("code").value
- console.log(code)
+ // // console.log(code)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/analysis',
type: "POST",
@@ -294,17 +294,17 @@
dataType: "json",
success: function (ret) {
if (ret.ret === 'success' && ret.data != null) {
- // {#console.log(ret.code)#}
- console.log(ret.data)
+ // {#// // console.log(ret.code)#}
+ // // console.log(ret.data)
make_program(ret.data)
} else {
$.notify('분석 실패
' + ret.log, {type: 'warning'});
}
}
});
- console.log(accessibleCount)
+ // // console.log(accessibleCount)
accessibleCount++
- console.log(accessibleCount)
+ // // console.log(accessibleCount)
}
@@ -356,7 +356,7 @@
$("body").on('click', '#add_queue_btn', function (e) {
e.preventDefault();
data = current_data.episode[$(this).data('idx')];
- console.log('data:::>', data)
+ // // console.log('data:::>', data)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/add_queue',
type: "POST",
@@ -364,7 +364,7 @@
data: {data: JSON.stringify(data)},
dataType: "json",
success: function (data) {
- console.log('#add_queue_btn::data >>', data)
+ // // console.log('#add_queue_btn::data >>', data)
if (data.ret == 'enqueue_db_append' || data.ret == 'enqueue_db_exist') {
$.notify('다운로드 작업을 추가 하였습니다.', {type: 'success'});
} else if (data.ret == 'queue_exist') {
diff --git a/templates/anime_downloader_ohli24_search.html b/templates/anime_downloader_ohli24_search.html
index 94c2b5d..96f9650 100644
--- a/templates/anime_downloader_ohli24_search.html
+++ b/templates/anime_downloader_ohli24_search.html
@@ -109,7 +109,7 @@
const get_anime_list = (type, page) => {
- console.log(`type: ${type}, page: ${page}`)
+ // console.log(`type: ${type}, page: ${page}`)
let url = ''
let data = {"page": page, "type": type}
@@ -142,7 +142,7 @@
dataType: "json",
success: (ret) => {
let current_screen_movie_data = ret
- console.log('ret::>', ret)
+ // console.log('ret::>', ret)
if (current_screen_movie_data !== '') {
if (type === "ing") {
@@ -158,7 +158,7 @@
make_screen_movie_list(ret.data, page)
}
{#div_visible = true#}
- {#console.log(div_visible)#}
+ {#// console.log(div_visible)#}
}
next_page = page + 1
}
@@ -339,12 +339,12 @@
$("body").on("click", "#btn_search", function (e) {
e.preventDefault();
let query = $("#input_search").val();
- console.log(query);
+ // console.log(query);
current_cate = "search"
current_query = query
if ($("#input_search").val() === "") {
- console.log("search keyword nothing");
+ // console.log("search keyword nothing");
return false;
}
@@ -357,7 +357,7 @@
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
success: function (ret) {
if (ret.ret) {
- console.log('ret:::', ret)
+ // console.log('ret:::', ret)
make_search_result_list(ret.data, 1);
next_page = page + 1
} else {
@@ -370,21 +370,21 @@
});
$('#anime_category #ing').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
// let spinner = document.getElementById('spinner');
// spinner.style.visibility = 'visible';
get_anime_list("ing", 1)
})
$('#anime_category #complete_anilist').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
// let spinner = document.getElementById('spinner');
// spinner.style.visibility = 'visible';
get_anime_list("fin", 1)
})
$('#anime_category #theater').on("click", function () {
- // {#console.log(this.id)#}
+ // {#// console.log(this.id)#}
// let spinner = document.getElementById('spinner');
// spinner.style.visibility = 'visible';
get_anime_list("theater", 1)
@@ -394,7 +394,7 @@
$("body").on('click', '#analysis_btn', function (e) {
e.preventDefault();
const code = document.getElementById("code").value
- console.log(code)
+ // console.log(code)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/analysis',
type: "POST",
@@ -403,8 +403,8 @@
dataType: "json",
success: function (ret) {
if (ret.ret === 'success' && ret.data != null) {
- // console.log(ret.code)
- console.log(ret.data)
+ // // console.log(ret.code)
+ // console.log(ret.data)
make_program(ret.data)
} else {
$.notify('분석 실패
' + ret.log, {type: 'warning'});
@@ -422,7 +422,7 @@
$("body").on("click", "#add_whitelist", function (e) {
e.preventDefault();
let data_code = $(this).attr("data-code");
- console.log(data_code);
+ // console.log(data_code);
$.ajax({
url: "/" + package_name + "/ajax/" + sub + "/add_whitelist",
type: "POST",
@@ -458,7 +458,7 @@
$("body").on('click', '#add_queue_btn', function (e) {
e.preventDefault();
data = current_data.episode[$(this).data('idx')];
- console.log('data:::>', data)
+ // console.log('data:::>', data)
$.ajax({
url: '/' + package_name + '/ajax/' + sub + '/add_queue',
type: "POST",
@@ -522,9 +522,9 @@
})
.then((res) => res.json())
.then((response) => {
- // console.log("Success:", JSON.stringify(response));
+ // // console.log("Success:", JSON.stringify(response));
// {#imagesContainer.appendChild()#}
- console.log("return page:::> ", String(response.page));
+ // console.log("return page:::> ", String(response.page));
// {#page = response.page#}
if (current_cate === 'search') {
make_search_result_list(response.data, response.page);
@@ -544,9 +544,9 @@
const {scrollTop, scrollHeight, clientHeight} = e.target.scrollingElement;
if (Math.round(scrollHeight - scrollTop) <= clientHeight) {
{#document.getElementById("spinner").style.display = "block";#}
- console.log("loading");
- console.log("now page::> ", page);
- console.log("next_page::> ", String(next_page));
+ // console.log("loading");
+ // console.log("now page::> ", page);
+ // console.log("next_page::> ", String(next_page));
loadNextAnimes(current_cate, next_page);
}
};
diff --git a/templates/anime_downloader_ohli24_setting.html b/templates/anime_downloader_ohli24_setting.html
index 9aec3cf..1e065f6 100644
--- a/templates/anime_downloader_ohli24_setting.html
+++ b/templates/anime_downloader_ohli24_setting.html
@@ -329,20 +329,33 @@
/* Folder Browser Modal Styles */
.folder-item {
- transition: background-color 0.15s ease;
+ cursor: pointer;
+ transition: background 0.2s;
+ border-bottom: 1px solid rgba(255,255,255,0.05);
+ display: flex !important;
+ align-items: center;
+ width: 100%;
+ overflow: hidden;
font-size: 0.95rem;
margin-bottom: 2px;
}
-
.folder-item:hover {
- background-color: rgba(59, 130, 246, 0.2) !important;
+ background: rgba(59, 130, 246, 0.2) !important;
+ }
+ .folder-item span {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ flex: 1;
+ min-width: 0;
+ }
+ .folder-item.selected {
+ background: rgba(59, 130, 246, 0.3) !important;
}
-
.folder-item.folder-parent,
.folder-item.folder-current {
font-weight: 600;
}
-
.folder-item i {
font-size: 1.1rem;
}