diff --git a/info.yaml b/info.yaml
index 5c43c9c..5846fad 100644
--- a/info.yaml
+++ b/info.yaml
@@ -1,5 +1,5 @@
title: "애니 다운로더"
-version: "0.5.35"
+version: "0.5.36"
package_name: "anime_downloader"
developer: "projectdx"
description: "anime downloader"
diff --git a/lib/ffmpeg_queue_v1.py b/lib/ffmpeg_queue_v1.py
index 0ca4d35..2e2c5a9 100644
--- a/lib/ffmpeg_queue_v1.py
+++ b/lib/ffmpeg_queue_v1.py
@@ -9,10 +9,10 @@ from datetime import datetime
import requests
# from flaskfarm.lib.plugin import get_model_setting
-from flaskfarm.lib.support.expand.ffmpeg import SupportFfmpeg
+from support.expand.ffmpeg import SupportFfmpeg
# from flaskfarm.lib.system.setup import SystemModelSetting
-from flaskfarm.lib.tool import ToolUtil
+from tool import ToolUtil
# from flaskfarm.lib.system.setup import P as SM
# from flaskfarm.lib.system.mod_setting import ModuleSetting as SM
diff --git a/mod_anilife.py b/mod_anilife.py
index 0017885..04b1762 100644
--- a/mod_anilife.py
+++ b/mod_anilife.py
@@ -690,7 +690,7 @@ class LogicAniLife(AnimeModuleBase):
"msg": "%s 개의 에피소드를 큐에 추가 하였습니다." % count,
}
socketio.emit(
- "notify", notify, namespace="/framework", broadcast=True
+ "notify", notify, namespace="/framework"
)
thread = threading.Thread(target=func, args=())
thread.daemon = True
diff --git a/mod_base.py b/mod_base.py
index 5697d85..9e84fbf 100644
--- a/mod_base.py
+++ b/mod_base.py
@@ -1,5 +1,5 @@
from flask import render_template, request, jsonify
-from flaskfarm.lib.plugin import PluginModuleBase
+from plugin import PluginModuleBase
import framework
import os, traceback, time, json
from datetime import datetime
@@ -177,7 +177,7 @@ class AnimeModuleBase(PluginModuleBase):
namespace = f"/{self.P.package_name}/{self.name}/queue"
# 큐 페이지 소켓에 직접 emit
- socketio.emit(refresh_type, data, namespace=namespace, broadcast=True)
+ socketio.emit(refresh_type, data, namespace=namespace)
except Exception as e:
self.P.logger.error(f"socketio_callback error: {e}")
diff --git a/mod_linkkf.py b/mod_linkkf.py
index 9bd49c8..ebed5f6 100644
--- a/mod_linkkf.py
+++ b/mod_linkkf.py
@@ -22,7 +22,7 @@ from bs4 import BeautifulSoup
# third-party
from flask import jsonify, render_template, request
-from flaskfarm.lib.support.expand.ffmpeg import SupportFfmpeg
+from support.expand.ffmpeg import SupportFfmpeg
# sjva 공용
from framework import db, path_data, scheduler
@@ -479,7 +479,7 @@ class LogicLinkkf(AnimeModuleBase):
"""
logger.info(f">>> socketio_callback called: {refresh_type}, {data.get('percent', 'N/A')}%")
try:
- from flaskfarm.lib.framework.init_main import socketio
+ from framework import socketio
# FlaskFarm의 기존 패턴: /framework namespace로 emit
# queue 페이지의 소켓이 이 메시지를 받아서 처리
diff --git a/mod_ohli24.py b/mod_ohli24.py
index 134efbd..dad24e3 100644
--- a/mod_ohli24.py
+++ b/mod_ohli24.py
@@ -530,7 +530,7 @@ class LogicOhli24(AnimeModuleBase):
"type": "success",
"msg": "%s 개의 에피소드를 큐에 추가 하였습니다." % count,
}
- socketio.emit("notify", notify, namespace="/framework", broadcast=True)
+ socketio.emit("notify", notify, namespace="/framework")
thread = threading.Thread(target=func, args=())
thread.daemon = True
@@ -2091,7 +2091,7 @@ class LogicOhli24(AnimeModuleBase):
+ args["data"]["save_fullpath"],
"url": "/ffmpeg/download/list",
}
- # socketio.emit("notify", data, namespace='/framework', broadcast=True)
+ # socketio.emit("notify", data, namespace='/framework')
refresh_type = "add"
elif args["type"] == "last":
entity = self.queue.get_entity_by_entity_id(args['data']['callback_id'])
@@ -2099,7 +2099,7 @@ class LogicOhli24(AnimeModuleBase):
if args["status"] == SupportFfmpeg.Status.WRONG_URL:
if entity: entity.download_failed("WRONG_URL")
data = {"type": "warning", "msg": "잘못된 URL입니다"}
- socketio.emit("notify", data, namespace="/framework", broadcast=True)
+ socketio.emit("notify", data, namespace="/framework")
refresh_type = "add"
elif args["status"] == SupportFfmpeg.Status.WRONG_DIRECTORY:
if entity: entity.download_failed("WRONG_DIRECTORY")
@@ -2107,7 +2107,7 @@ class LogicOhli24(AnimeModuleBase):
"type": "warning",
"msg": "잘못된 디렉토리입니다.
" + args["data"]["save_fullpath"],
}
- socketio.emit("notify", data, namespace="/framework", broadcast=True)
+ socketio.emit("notify", data, namespace="/framework")
refresh_type = "add"
elif args["status"] == SupportFfmpeg.Status.ERROR or args["status"] == SupportFfmpeg.Status.EXCEPTION:
if entity: entity.download_failed("ERROR/EXCEPTION")
@@ -2115,7 +2115,7 @@ class LogicOhli24(AnimeModuleBase):
"type": "warning",
"msg": "다운로드 시작 실패.
" + args["data"]["save_fullpath"],
}
- socketio.emit("notify", data, namespace="/framework", broadcast=True)
+ socketio.emit("notify", data, namespace="/framework")
refresh_type = "add"
elif args["status"] == SupportFfmpeg.Status.USER_STOP:
if entity: entity.download_failed("USER_STOP")
@@ -2124,7 +2124,7 @@ class LogicOhli24(AnimeModuleBase):
"msg": "다운로드가 중지 되었습니다.
" + args["data"]["save_fullpath"],
"url": "/ffmpeg/download/list",
}
- socketio.emit("notify", data, namespace="/framework", broadcast=True)
+ socketio.emit("notify", data, namespace="/framework")
refresh_type = "last"
elif args["status"] == SupportFfmpeg.Status.COMPLETED:
logger.debug("download completed........")
@@ -2134,7 +2134,7 @@ class LogicOhli24(AnimeModuleBase):
"url": "/ffmpeg/download/list",
}
- socketio.emit("notify", data, namespace="/framework", broadcast=True)
+ socketio.emit("notify", data, namespace="/framework")
refresh_type = "last"
elif args["status"] == SupportFfmpeg.Status.TIME_OVER:
@@ -2144,7 +2144,7 @@ class LogicOhli24(AnimeModuleBase):
"msg": "시간초과로 중단 되었습니다.
" + args["data"]["save_fullpath"],
"url": "/ffmpeg/download/list",
}
- socketio.emit("notify", data, namespace="/framework", broadcast=True)
+ socketio.emit("notify", data, namespace="/framework")
refresh_type = "last"
elif args["status"] == SupportFfmpeg.Status.PF_STOP:
if entity: entity.download_failed("PF_STOP")
@@ -2153,7 +2153,7 @@ class LogicOhli24(AnimeModuleBase):
"msg": "PF초과로 중단 되었습니다.
" + args["data"]["save_fullpath"],
"url": "/ffmpeg/download/list",
}
- socketio.emit("notify", data, namespace="/framework", broadcast=True)
+ socketio.emit("notify", data, namespace="/framework")
refresh_type = "last"
elif args["status"] == SupportFfmpeg.Status.FORCE_STOP:
if entity: entity.download_failed("FORCE_STOP")
@@ -2162,7 +2162,7 @@ class LogicOhli24(AnimeModuleBase):
"msg": "강제 중단 되었습니다.
" + args["data"]["save_fullpath"],
"url": "/ffmpeg/download/list",
}
- socketio.emit("notify", data, namespace="/framework", broadcast=True)
+ socketio.emit("notify", data, namespace="/framework")
refresh_type = "last"
elif args["status"] == SupportFfmpeg.Status.HTTP_FORBIDDEN:
if entity: entity.download_failed("HTTP_FORBIDDEN")
@@ -2171,7 +2171,7 @@ class LogicOhli24(AnimeModuleBase):
"msg": "403에러로 중단 되었습니다.
" + args["data"]["save_fullpath"],
"url": "/ffmpeg/download/list",
}
- socketio.emit("notify", data, namespace="/framework", broadcast=True)
+ socketio.emit("notify", data, namespace="/framework")
refresh_type = "last"
elif args["status"] == SupportFfmpeg.Status.ALREADY_DOWNLOADING:
# Already downloading usually means logic error or race condition, maybe not fail DB?
@@ -2181,7 +2181,7 @@ class LogicOhli24(AnimeModuleBase):
"msg": "임시파일폴더에 파일이 있습니다.
" + args["data"]["temp_fullpath"],
"url": "/ffmpeg/download/list",
}
- socketio.emit("notify", data, namespace="/framework", broadcast=True)
+ socketio.emit("notify", data, namespace="/framework")
refresh_type = "last"
elif args["type"] == "normal":
if args["status"] == SupportFfmpeg.Status.DOWNLOADING:
@@ -2791,25 +2791,25 @@ class Ohli24QueueEntity(AnimeQueueEntity):
# data = {'type': 'info',
# 'msg': '다운로드중 Duration(%s)' % args['data']['duration_str'] + '
' + args['data'][
# 'save_fullpath'], 'url': '/ffmpeg/download/list'}
- # socketio.emit("notify", data, namespace='/framework', broadcast=True)
+ # socketio.emit("notify", data, namespace='/framework')
# refresh_type = 'add'
# elif args['type'] == 'last':
# if args['status'] == SupportFfmpeg.Status.WRONG_URL:
# data = {'type': 'warning', 'msg': '잘못된 URL입니다'}
- # socketio.emit("notify", data, namespace='/framework', broadcast=True)
+ # socketio.emit("notify", data, namespace='/framework')
# refresh_type = 'add'
# elif args['status'] == SupportFfmpeg.Status.WRONG_DIRECTORY:
# data = {'type': 'warning', 'msg': '잘못된 디렉토리입니다.
' + args['data']['save_fullpath']}
- # socketio.emit("notify", data, namespace='/framework', broadcast=True)
+ # socketio.emit("notify", data, namespace='/framework')
# refresh_type = 'add'
# elif args['status'] == SupportFfmpeg.Status.ERROR or args['status'] == SupportFfmpeg.Status.EXCEPTION:
# data = {'type': 'warning', 'msg': '다운로드 시작 실패.
' + args['data']['save_fullpath']}
- # socketio.emit("notify", data, namespace='/framework', broadcast=True)
+ # socketio.emit("notify", data, namespace='/framework')
# refresh_type = 'add'
# elif args['status'] == SupportFfmpeg.Status.USER_STOP:
# data = {'type': 'warning', 'msg': '다운로드가 중지 되었습니다.
' + args['data']['save_fullpath'],
# 'url': '/ffmpeg/download/list'}
- # socketio.emit("notify", data, namespace='/framework', broadcast=True)
+ # socketio.emit("notify", data, namespace='/framework')
# refresh_type = 'last'
# elif args['status'] == SupportFfmpeg.Status.COMPLETED:
# logger.debug('ffmpeg download completed......')
@@ -2818,32 +2818,32 @@ class Ohli24QueueEntity(AnimeQueueEntity):
# 'url': '/ffmpeg/download/list'}
#
#
- # socketio.emit("notify", data, namespace='/framework', broadcast=True)
+ # socketio.emit("notify", data, namespace='/framework')
# refresh_type = 'last'
# elif args['status'] == SupportFfmpeg.Status.TIME_OVER:
# data = {'type': 'warning', 'msg': '시간초과로 중단 되었습니다.
' + args['data']['save_fullpath'],
# 'url': '/ffmpeg/download/list'}
- # socketio.emit("notify", data, namespace='/framework', broadcast=True)
+ # socketio.emit("notify", data, namespace='/framework')
# refresh_type = 'last'
# elif args['status'] == SupportFfmpeg.Status.PF_STOP:
# data = {'type': 'warning', 'msg': 'PF초과로 중단 되었습니다.
' + args['data']['save_fullpath'],
# 'url': '/ffmpeg/download/list'}
- # socketio.emit("notify", data, namespace='/framework', broadcast=True)
+ # socketio.emit("notify", data, namespace='/framework')
# refresh_type = 'last'
# elif args['status'] == SupportFfmpeg.Status.FORCE_STOP:
# data = {'type': 'warning', 'msg': '강제 중단 되었습니다.
' + args['data']['save_fullpath'],
# 'url': '/ffmpeg/download/list'}
- # socketio.emit("notify", data, namespace='/framework', broadcast=True)
+ # socketio.emit("notify", data, namespace='/framework')
# refresh_type = 'last'
# elif args['status'] == SupportFfmpeg.Status.HTTP_FORBIDDEN:
# data = {'type': 'warning', 'msg': '403에러로 중단 되었습니다.
' + args['data']['save_fullpath'],
# 'url': '/ffmpeg/download/list'}
- # socketio.emit("notify", data, namespace='/framework', broadcast=True)
+ # socketio.emit("notify", data, namespace='/framework')
# refresh_type = 'last'
# elif args['status'] == SupportFfmpeg.Status.ALREADY_DOWNLOADING:
# data = {'type': 'warning', 'msg': '임시파일폴더에 파일이 있습니다.
' + args['data']['temp_fullpath'],
# 'url': '/ffmpeg/download/list'}
- # socketio.emit("notify", data, namespace='/framework', broadcast=True)
+ # socketio.emit("notify", data, namespace='/framework')
# refresh_type = 'last'
# elif args['type'] == 'normal':
# if args['status'] == SupportFfmpeg.Status.DOWNLOADING:
diff --git a/plugin.py b/plugin.py
deleted file mode 100644
index 4065168..0000000
--- a/plugin.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# -*- coding: utf-8 -*-
-from flaskfarm.lib.plugin import *
diff --git a/static/css/mobile_custom.css b/static/css/mobile_custom.css
index f02354c..71cb468 100644
--- a/static/css/mobile_custom.css
+++ b/static/css/mobile_custom.css
@@ -73,8 +73,18 @@
flex-wrap: wrap; /* allow wrap on small screens */
justify-content: center;
width: auto !important; /* Prevent full width */
- margin-bottom: 20px;
- margin-top: 50px !important; /* Mobile spacing */
+ margin-bottom: 5px; /* Reduced for modularity */
+ margin-top: 50px !important; /* Mobile spacing - fallback for first menu */
+ }
+
+ /* Tighten spacing between 2nd and 3rd level menus */
+ #menu_module_div ul.nav.nav-pills.bg-light {
+ margin-bottom: 5px !important;
+ }
+
+ #menu_page_div ul.nav.nav-pills.bg-light {
+ margin-top: 0 !important;
+ margin-bottom: 20px !important;
}
ul.nav.nav-pills .nav-item {
diff --git a/static/css/ohli24.css b/static/css/ohli24.css
index 7798e0f..37e8e80 100644
--- a/static/css/ohli24.css
+++ b/static/css/ohli24.css
@@ -98,7 +98,7 @@ body {
color: #94a3b8;
}
-/* Nav Pills Customization */
+/* Nav Pills Customization (Shared styling, overrides in mobile_custom.css) */
ul.nav.nav-pills.bg-light {
background-color: rgba(30, 41, 59, 0.6) !important;
backdrop-filter: blur(10px);
@@ -110,7 +110,7 @@ ul.nav.nav-pills.bg-light {
flex-wrap: wrap;
justify-content: center;
width: auto !important;
- margin-bottom: 20px;
+ margin-bottom: 5px; /* Default for modular stacking */
}
ul.nav.nav-pills .nav-link {
@@ -155,6 +155,29 @@ ul.nav.nav-pills .nav-link.active {
border: none !important;
}
+/* Responsive Input Group for Search */
+.input-group-responsive {
+ height: 50px;
+}
+
+.input-group-responsive .form-control {
+ height: 100% !important;
+ font-size: 1.1rem;
+}
+
+.input-group-responsive .btn {
+ height: 100% !important;
+}
+
+@media (max-width: 768px) {
+ .input-group-responsive {
+ height: 42px;
+ }
+ .input-group-responsive .form-control {
+ font-size: 0.95rem;
+ }
+}
+
.btn-search { background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); color: white !important; }
.btn-reset { background: rgba(148, 163, 184, 0.1); color: #94a3b8 !important; }
diff --git a/templates/anime_downloader_ohli24_request.html b/templates/anime_downloader_ohli24_request.html
index e41dbc3..1f17e0b 100644
--- a/templates/anime_downloader_ohli24_request.html
+++ b/templates/anime_downloader_ohli24_request.html
@@ -1,6 +1,7 @@
{% extends "base.html" %} {% block content %}
+