refactor: Implement common base module and model for anime downloader plugins and refactor existing modules to use them.

This commit is contained in:
2026-01-01 22:58:25 +09:00
parent 5dab969580
commit 88aeb888b3
20 changed files with 555 additions and 409 deletions

View File

@@ -1,5 +1,5 @@
title: "애니 다운로더"
version: "0.3.7"
version: "0.3.8"
package_name: "anime_downloader"
developer: "projectdx"
description: "anime downloader"

View File

@@ -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"])

192
mod_base.py Normal file
View File

@@ -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)}

View File

@@ -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):
"""

View File

@@ -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"])

76
model_base.py Normal file
View File

@@ -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

View File

@@ -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 += '<div>';
str += '<button type="button" class="btn btn-info">Page <span class="badge bg-warning">' + page + '</span></button>';
@@ -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 + '&amp;wr_id=' + data.anime_list[i].wr_id + '&amp;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 += '<div>';
str += '<button type="button" class="btn btn-info">Page <span class="badge bg-warning">' + page + '</span></button>';
@@ -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('<strong>분석 실패</strong><br>' + 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);
}
};

View File

@@ -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 = "<tr><td colspan='10'><h4>작업이 없습니다.</h4><td><tr>";
} else {

View File

@@ -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('<strong>다운로드 작업을 추가 하였습니다.</strong>', {type: 'success'});
} else if (data.ret == 'queue_exist') {

View File

@@ -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("<strong>분석 실패</strong><br>" + 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 += '<div>';
str += '<button type="button" class="btn btn-info">Page <span class="badge bg-warning">' + page + '</span></button>';
@@ -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 + '&amp;wr_id=' + data.anime_list[i].wr_id + '&amp;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 += '<div>';
str += '<button type="button" class="btn btn-info">Page <span class="badge bg-warning">' + page + '</span></button>';
@@ -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('<strong>분석 실패</strong><br>' + 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);
}
};

View File

@@ -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;
}
</style>

View File

@@ -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 += '<div>';
str += '<button type="button" class="btn btn-info">Page <span class="badge bg-warning">' + page + '</span></button>';
@@ -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 + '&amp;wr_id=' + data.anime_list[i].wr_id + '&amp;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 += '<div>';
str += '<button type="button" class="btn btn-info">Page <span class="badge bg-warning">' + page + '</span></button>';
@@ -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('<strong>분석 실패</strong><br>' + 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);
}
};

View File

@@ -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('<strong>분석 실패</strong><br>' + 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('<strong>분석 실패</strong><br>' + 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('<strong>다운로드 작업을 추가 하였습니다.</strong>', {type: 'success'});
} else if (data.ret == 'queue_exist') {

View File

@@ -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 += "</div>";
str += '<div id="inner_screen_movie" class="row infinite-scroll">';
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('<strong>분석 실패</strong><br>' + 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,

View File

@@ -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;
}
</style>

View File

@@ -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 += '<div>';
str += '<button type="button" class="btn btn-info">Page <span class="badge bg-warning">' + page + '</span></button>';
@@ -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 + '&amp;wr_id=' + data.anime_list[i].wr_id + '&amp;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 += '<div>';
str += '<button type="button" class="btn btn-info">Page <span class="badge bg-warning">' + page + '</span></button>';
@@ -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('<strong>분석 실패</strong><br>' + 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);
}
};

View File

@@ -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);

View File

@@ -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('<strong>분석 실패</strong><br>' + 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('<strong>다운로드 작업을 추가 하였습니다.</strong>', {type: 'success'});
} else if (data.ret == 'queue_exist') {

View File

@@ -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('<strong>분석 실패</strong><br>' + 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);
}
};

View File

@@ -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;
}