Compare commits
27 Commits
master
...
9907d6b484
| Author | SHA1 | Date | |
|---|---|---|---|
| 9907d6b484 | |||
| cae6985aec | |||
| a9ea8f193f | |||
| ab346ccb19 | |||
| 7a529aa27b | |||
| 4527e54647 | |||
| d6aa3ff42b | |||
| 1ec1100f52 | |||
| dffddb7d28 | |||
| 21ef7c4bfc | |||
| af965a7ef9 | |||
| 09bb3e4a8a | |||
| 3ac8f3af8e | |||
| a3a6a84c97 | |||
| 1111d37074 | |||
| 48bb5dd489 | |||
| 6a309e0e11 | |||
| 7a82dc2fc7 | |||
| b4b567704c | |||
| 8a78d40c15 | |||
| 11afb7bf38 | |||
| 2af1e6d738 | |||
| 9f1de7aa8c | |||
| bfa64d4b8f | |||
| 027e41be46 | |||
| ce13a3e829 | |||
| 8e5c73c686 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,2 +1,7 @@
|
||||
*.pyo
|
||||
*.pyc
|
||||
*.pyc
|
||||
|
||||
.idea
|
||||
.vscode
|
||||
.gitignore
|
||||
test.ipynb
|
||||
|
||||
BIN
bin/.DS_Store
vendored
Normal file
BIN
bin/.DS_Store
vendored
Normal file
Binary file not shown.
25
lib/utils.py
Normal file
25
lib/utils.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import os
|
||||
import time
|
||||
from functools import wraps
|
||||
|
||||
try:
|
||||
from loguru import logger
|
||||
except:
|
||||
os.system(f"pip install loguru")
|
||||
from loguru import logger
|
||||
|
||||
|
||||
def yommi_timeit(func):
|
||||
@wraps(func)
|
||||
def timeit_wrapper(*args, **kwargs):
|
||||
start_time = time.perf_counter()
|
||||
result = func(*args, **kwargs)
|
||||
end_time = time.perf_counter()
|
||||
total_time = end_time - start_time
|
||||
# print(f"Function {func.__name__}{args} {kwargs} Took {total_time:.4f} secs")
|
||||
logger.debug(
|
||||
f"Function {func.__name__}{args} {kwargs} Took {total_time:.4f} secs"
|
||||
)
|
||||
return result
|
||||
|
||||
return timeit_wrapper
|
||||
73
linkey.py
Normal file
73
linkey.py
Normal file
@@ -0,0 +1,73 @@
|
||||
def get_html_selenium(url, referer):
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium import webdriver
|
||||
from selenium_stealth import stealth
|
||||
from webdriver_manager.chrome import ChromeDriverManager
|
||||
import time
|
||||
import platform
|
||||
import os
|
||||
|
||||
os_platform = platform.system()
|
||||
|
||||
options = webdriver.ChromeOptions()
|
||||
# 크롬드라이버 헤더 옵션추가 (리눅스에서 실행시 필수)
|
||||
options.add_argument("start-maximized")
|
||||
# options.add_argument("--headless")
|
||||
options.add_argument("--no-sandbox")
|
||||
options.add_experimental_option("excludeSwitches", ["enable-automation"])
|
||||
options.add_experimental_option("useAutomationExtension", False)
|
||||
|
||||
if os_platform == "Darwin":
|
||||
# 크롬드라이버 경로
|
||||
driver_path = "./bin/Darwin/chromedriver"
|
||||
# driver = webdriver.Chrome(executable_path=driver_path, chrome_options=options)
|
||||
driver = webdriver.Chrome(
|
||||
ChromeDriverManager().install(), chrome_options=options
|
||||
)
|
||||
else:
|
||||
driver_bin_path = os.path.join(
|
||||
os.path.dirname(__file__), "bin", f"{os_platform}"
|
||||
)
|
||||
driver_path = f"{driver_bin_path}/chromedriver"
|
||||
driver = webdriver.Chrome(executable_path=driver_path, chrome_options=options)
|
||||
|
||||
stealth(
|
||||
driver,
|
||||
languages=["en-US", "en"],
|
||||
vendor="Google Inc.",
|
||||
platform="Win32",
|
||||
webgl_vendor="Intel Inc.",
|
||||
renderer="Intel Iris OpenGL Engine",
|
||||
fix_hairline=True,
|
||||
)
|
||||
driver.get(url)
|
||||
|
||||
driver.refresh()
|
||||
print(f"current_url:: {driver.current_url}")
|
||||
# logger.debug(f"current_cookie:: {driver.get_cookies()}")
|
||||
cookies_list = driver.get_cookies()
|
||||
|
||||
cookies_dict = {}
|
||||
for cookie in cookies_list:
|
||||
cookies_dict[cookie["name"]] = cookie["value"]
|
||||
|
||||
print(cookies_dict)
|
||||
|
||||
# LogicAniLife.cookies = cookies_list
|
||||
# # LogicAniLife.headers["Cookie"] = driver.get_cookies()
|
||||
# LogicAniLife.episode_url = driver.current_url
|
||||
|
||||
time.sleep(1)
|
||||
elem = driver.find_element(By.XPATH, "//*")
|
||||
source_code = elem.get_attribute("outerHTML")
|
||||
|
||||
li_elem = driver.find_element(By.XPATH, "//li[@class='-qHwcFXhj0']//a")
|
||||
li_elem.click()
|
||||
|
||||
time.sleep(20.0)
|
||||
|
||||
return source_code.encode("utf-8")
|
||||
|
||||
|
||||
url = "https://smartstore.naver.com/flamingo_k"
|
||||
get_html_selenium(url=url, referer=None)
|
||||
116
logic_anilife.py
116
logic_anilife.py
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
import traceback
|
||||
@@ -17,12 +18,17 @@ from lxml import html
|
||||
from urllib import parse
|
||||
import urllib
|
||||
|
||||
# my
|
||||
from .lib.utils import yommi_timeit
|
||||
|
||||
packages = [
|
||||
"beautifulsoup4",
|
||||
"requests-cache",
|
||||
"cloudscraper",
|
||||
"selenium_stealth",
|
||||
"webdriver_manager",
|
||||
"html-to-json",
|
||||
"playwright-har-tracer",
|
||||
]
|
||||
for package in packages:
|
||||
try:
|
||||
@@ -577,12 +583,28 @@ class LogicAniLife(LogicModuleBase):
|
||||
return vod_url
|
||||
except Exception as e:
|
||||
logger.error("Exception:%s", e)
|
||||
result = subprocess.run(
|
||||
["playwright", "install"], stdout=subprocess.PIPE, text=True
|
||||
)
|
||||
print(result.stdout)
|
||||
|
||||
logger.error(traceback.format_exc())
|
||||
finally:
|
||||
await browser.close()
|
||||
|
||||
@staticmethod
|
||||
def get_html_selenium(url: str, referer: str) -> bytes:
|
||||
@yommi_timeit
|
||||
def get_html_selenium(
|
||||
url: str,
|
||||
referer: str,
|
||||
headless=True,
|
||||
linux=True,
|
||||
maximize=True,
|
||||
user_agent=False,
|
||||
lang_kr=False,
|
||||
secret_mode=False,
|
||||
download_path=None,
|
||||
) -> bytes:
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium import webdriver
|
||||
from selenium_stealth import stealth
|
||||
@@ -590,16 +612,44 @@ class LogicAniLife(LogicModuleBase):
|
||||
import time
|
||||
|
||||
options = webdriver.ChromeOptions()
|
||||
# options.add_experimental_option('excludeSwitches', ['enable-logging'])
|
||||
# 크롬드라이버 헤더 옵션추가 (리눅스에서 실행시 필수)
|
||||
options.add_argument("start-maximized")
|
||||
options.add_argument("--headless")
|
||||
|
||||
if headless:
|
||||
options.add_argument("--headless")
|
||||
options.add_argument("--no-sandbox")
|
||||
options.add_argument("window-size=1920x1080")
|
||||
options.add_argument("disable-gpu")
|
||||
# options.add_argument('--no-sandbox')
|
||||
options.add_argument("--disable-dev-shm-usage")
|
||||
options.add_experimental_option("excludeSwitches", ["enable-automation"])
|
||||
# 크롬 드라이버에 setuid를 하지 않음으로써 크롬의 충돌 막음
|
||||
options.add_argument("--disable-setuid-sandbox")
|
||||
|
||||
# disabling extensions
|
||||
options.add_argument("--disable-extensions")
|
||||
|
||||
if download_path:
|
||||
pass
|
||||
|
||||
if maximize:
|
||||
options.add_argument("start-maximized")
|
||||
|
||||
# 일단 좀 더 확인 필요
|
||||
options.add_experimental_option(
|
||||
"excludeSwitches", ["enable-automation", "enable-logging"]
|
||||
)
|
||||
options.add_experimental_option("useAutomationExtension", False)
|
||||
options.add_argument("--single-process")
|
||||
|
||||
if user_agent:
|
||||
options.add_argument(
|
||||
"user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 "
|
||||
"Safari/537.36"
|
||||
)
|
||||
if lang_kr:
|
||||
options.add_argument("--lang=ko_KR")
|
||||
if secret_mode:
|
||||
options.add_argument("--incognito")
|
||||
|
||||
if LogicAniLife.os_platform == "Darwin":
|
||||
# 크롬드라이버 경로
|
||||
@@ -608,15 +658,21 @@ class LogicAniLife(LogicModuleBase):
|
||||
driver = webdriver.Chrome(
|
||||
ChromeDriverManager().install(), chrome_options=options
|
||||
)
|
||||
|
||||
else:
|
||||
driver_bin_path = os.path.join(
|
||||
os.path.dirname(__file__), "bin", f"{LogicAniLife.os_platform}"
|
||||
)
|
||||
driver_path = f"{driver_bin_path}/chromedriver"
|
||||
# driver_bin_path = os.path.join(
|
||||
# os.path.dirname(__file__), "bin", f"{LogicAniLife.os_platform}"
|
||||
# )
|
||||
# driver_path = f"{driver_bin_path}/chromedriver"
|
||||
# driver = webdriver.Chrome(
|
||||
# executable_path=driver_path, chrome_options=options
|
||||
# )
|
||||
driver = webdriver.Chrome(
|
||||
executable_path=driver_path, chrome_options=options
|
||||
ChromeDriverManager().install(), chrome_options=options
|
||||
)
|
||||
|
||||
driver.implicitly_wait(5)
|
||||
|
||||
stealth(
|
||||
driver,
|
||||
languages=["ko-KR", "ko"],
|
||||
@@ -771,6 +827,7 @@ class LogicAniLife(LogicModuleBase):
|
||||
return render_template("sample.html", title="%s - %s" % (P.package_name, sub))
|
||||
|
||||
def process_ajax(self, sub, req):
|
||||
data = []
|
||||
try:
|
||||
if sub == "analysis":
|
||||
# code = req.form['code']
|
||||
@@ -779,7 +836,6 @@ class LogicAniLife(LogicModuleBase):
|
||||
|
||||
wr_id = request.form.get("wr_id", None)
|
||||
bo_table = request.form.get("bo_table", None)
|
||||
data = []
|
||||
|
||||
# logger.info("code::: %s", code)
|
||||
P.ModelSetting.set("anilife_current_code", code)
|
||||
@@ -787,7 +843,6 @@ class LogicAniLife(LogicModuleBase):
|
||||
self.current_data = data
|
||||
return jsonify({"ret": "success", "data": data, "code": code})
|
||||
elif sub == "anime_list":
|
||||
data = []
|
||||
cate = request.form["type"]
|
||||
page = request.form["page"]
|
||||
|
||||
@@ -797,7 +852,6 @@ class LogicAniLife(LogicModuleBase):
|
||||
{"ret": "success", "cate": cate, "page": page, "data": data}
|
||||
)
|
||||
elif sub == "complete_list":
|
||||
data = []
|
||||
|
||||
cate = request.form["type"]
|
||||
logger.debug("cate:: %s", cate)
|
||||
@@ -809,9 +863,7 @@ class LogicAniLife(LogicModuleBase):
|
||||
{"ret": "success", "cate": cate, "page": page, "data": data}
|
||||
)
|
||||
elif sub == "search":
|
||||
data = []
|
||||
# cate = request.form["type"]
|
||||
# page = request.form["page"]
|
||||
|
||||
cate = request.form["type"]
|
||||
query = request.form["query"]
|
||||
page = request.form["page"]
|
||||
@@ -1038,7 +1090,7 @@ class LogicAniLife(LogicModuleBase):
|
||||
"ep_num": ep_num,
|
||||
"title": f"{main_title} {ep_num}화 - {title}",
|
||||
"link": link,
|
||||
"thumbnail": image,
|
||||
"thumbnail": thumbnail,
|
||||
"date": date,
|
||||
"day": date,
|
||||
"_id": title,
|
||||
@@ -1049,21 +1101,6 @@ class LogicAniLife(LogicModuleBase):
|
||||
}
|
||||
)
|
||||
|
||||
# print(lxml.etree.tostring(des_items, method="text"))
|
||||
#
|
||||
# for idx, item in enumerate(des_items):
|
||||
# span = item.xpath(".//b/text()")
|
||||
# logger.info(f"0: {span[0]}")
|
||||
# key = description_dict[span[0].replace(":", "")]
|
||||
# logger.debug(f"key:: {key}")
|
||||
# try:
|
||||
# print(item.xpath(".//text()")[1].strip())
|
||||
# des[key] = item.xpath(".//text()")[1].strip()
|
||||
# except IndexError:
|
||||
# if item.xpath(".//a"):
|
||||
# des[key] = item.xpath(".//a")[0]
|
||||
# des[key] = ""
|
||||
|
||||
ser_description = "작품 설명 부분"
|
||||
des = ""
|
||||
des1 = ""
|
||||
@@ -1224,7 +1261,7 @@ class AniLifeQueueEntity(FfmpegQueueEntity):
|
||||
tmp["epi_queue"] = self.epi_queue
|
||||
return tmp
|
||||
|
||||
def donwload_completed(self):
|
||||
def download_completed(self):
|
||||
db_entity = ModelAniLifeItem.get_by_anilife_id(self.info["_id"])
|
||||
if db_entity is not None:
|
||||
db_entity.status = "completed"
|
||||
@@ -1244,13 +1281,11 @@ class AniLifeQueueEntity(FfmpegQueueEntity):
|
||||
ourls = parse.urlparse(url)
|
||||
|
||||
self.headers = {
|
||||
"Referer": f"{ourls.scheme}://{ourls.netloc}",
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Whale/3.12.129.46 Safari/537.36",
|
||||
"Referer": LogicAniLife.episode_url,
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/96.0.4664.110 Whale/3.12.129.46 Safari/537.36",
|
||||
}
|
||||
|
||||
headers["Referer"] = "https://anilife.live/detail/id/471"
|
||||
headers["Referer"] = LogicAniLife.episode_url
|
||||
|
||||
logger.debug("make_episode_info()::url==> %s", url)
|
||||
logger.info(f"self.info:::> {self.info}")
|
||||
|
||||
@@ -1276,13 +1311,9 @@ class AniLifeQueueEntity(FfmpegQueueEntity):
|
||||
)
|
||||
)
|
||||
|
||||
# vod_1080p_url = text
|
||||
|
||||
# logger.debug(text)
|
||||
soup = BeautifulSoup(text, "lxml")
|
||||
|
||||
all_scripts = soup.find_all("script")
|
||||
# print(all_scripts)
|
||||
|
||||
regex = r"(?P<jawcloud_url>http?s:\/\/.*=jawcloud)"
|
||||
match = re.compile(regex).search(text)
|
||||
@@ -1355,10 +1386,9 @@ class AniLifeQueueEntity(FfmpegQueueEntity):
|
||||
vod_1080p_url = asyncio.run(
|
||||
LogicAniLife.get_vod_url(jawcloud_url, headless=True)
|
||||
)
|
||||
print(f"vod_1080p_url:: {vod_1080p_url}")
|
||||
logger.debug(f"vod_1080p_url:: {vod_1080p_url}")
|
||||
self.url = vod_1080p_url
|
||||
|
||||
logger.info(self.url)
|
||||
except Exception as e:
|
||||
P.logger.error("Exception:%s", e)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
1201
logic_linkkf.py
1201
logic_linkkf.py
File diff suppressed because it is too large
Load Diff
571
logic_ohli24.py
571
logic_ohli24.py
@@ -61,25 +61,29 @@ logger = P.logger
|
||||
class LogicOhli24(LogicModuleBase):
|
||||
db_default = {
|
||||
"ohli24_db_version": "1",
|
||||
"ohli24_url": "https://ohli24.net",
|
||||
"ohli24_url": "https://ohli24.org",
|
||||
"ohli24_download_path": os.path.join(path_data, P.package_name, "ohli24"),
|
||||
"ohli24_auto_make_folder": "True",
|
||||
"ohli24_auto_make_season_folder": "True",
|
||||
"ohli24_finished_insert": "[완결]",
|
||||
"ohli24_max_ffmpeg_process_count": "1",
|
||||
"ohli24_order_desc": "False",
|
||||
"ohli24_order_desc": "True",
|
||||
"ohli24_auto_start": "False",
|
||||
"ohli24_interval": "* 5 * * *",
|
||||
"ohli24_auto_mode_all": "False",
|
||||
"ohli24_auto_code_list": "all",
|
||||
"ohli24_current_code": "",
|
||||
"ohli24_uncompleted_auto_enqueue": "False",
|
||||
"ohli24_image_url_prefix_series": "https://www.jetcloud.cc/series/",
|
||||
"ohli24_image_url_prefix_episode": "https://www.jetcloud-list.cc/thumbnail/",
|
||||
"ohli24_image_url_prefix_series": "",
|
||||
"ohli24_image_url_prefix_episode": "",
|
||||
"ohli24_discord_notify": "True",
|
||||
}
|
||||
current_headers = None
|
||||
current_data = None
|
||||
referer = None
|
||||
origin_url = None
|
||||
episode_url = None
|
||||
cookies = None
|
||||
|
||||
session = requests.Session()
|
||||
headers = {
|
||||
@@ -87,7 +91,8 @@ class LogicOhli24(LogicModuleBase):
|
||||
"Chrome/71.0.3578.98 Safari/537.36",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
|
||||
"Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
|
||||
"Referer": "",
|
||||
# "Referer": "",
|
||||
# "Cookie": "PHPSESSID=hhhnrora8o9omv1tljq4efv216; 2a0d2363701f23f8a75028924a3af643=NDkuMTYzLjExMS4xMDk=; e1192aefb64683cc97abb83c71057733=aW5n",
|
||||
}
|
||||
useragent = {
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, "
|
||||
@@ -100,6 +105,200 @@ class LogicOhli24(LogicModuleBase):
|
||||
self.queue = None
|
||||
default_route_socketio(P, self)
|
||||
|
||||
@staticmethod
|
||||
async def get_html_playwright(
|
||||
url: str,
|
||||
headless: bool = False,
|
||||
referer: str = "",
|
||||
engine: str = "chrome",
|
||||
stealth: bool = False,
|
||||
):
|
||||
try:
|
||||
from playwright.sync_api import sync_playwright
|
||||
from playwright.async_api import async_playwright
|
||||
from playwright_stealth import stealth_sync, stealth_async
|
||||
|
||||
import time
|
||||
|
||||
cookie = None
|
||||
# browser_args = [
|
||||
# "--window-size=1300,570",
|
||||
# "--window-position=000,000",
|
||||
# "--disable-dev-shm-usage",
|
||||
# "--no-sandbox",
|
||||
# "--disable-web-security",
|
||||
# "--disable-features=site-per-process",
|
||||
# "--disable-setuid-sandbox",
|
||||
# "--disable-accelerated-2d-canvas",
|
||||
# "--no-first-run",
|
||||
# "--no-zygote",
|
||||
# # '--single-process',
|
||||
# "--disable-gpu",
|
||||
# # "--use-gl=egl",
|
||||
# "--disable-blink-features=AutomationControlled",
|
||||
# # "--disable-background-networking",
|
||||
# # "--enable-features=NetworkService,NetworkServiceInProcess",
|
||||
# "--disable-background-timer-throttling",
|
||||
# "--disable-backgrounding-occluded-windows",
|
||||
# "--disable-breakpad",
|
||||
# "--disable-client-side-phishing-detection",
|
||||
# "--disable-component-extensions-with-background-pages",
|
||||
# "--disable-default-apps",
|
||||
# "--disable-extensions",
|
||||
# "--disable-features=Translate",
|
||||
# "--disable-hang-monitor",
|
||||
# "--disable-ipc-flooding-protection",
|
||||
# "--disable-popup-blocking",
|
||||
# "--disable-prompt-on-repost",
|
||||
# # "--disable-renderer-backgrounding",
|
||||
# "--disable-sync",
|
||||
# "--force-color-profile=srgb",
|
||||
# # "--metrics-recording-only",
|
||||
# # "--enable-automation",
|
||||
# "--password-store=basic",
|
||||
# # "--use-mock-keychain",
|
||||
# # "--hide-scrollbars",
|
||||
# "--mute-audio",
|
||||
# ]
|
||||
browser_args = [
|
||||
"--window-size=1300,570",
|
||||
"--window-position=0,0",
|
||||
# "--disable-dev-shm-usage",
|
||||
"--no-sandbox",
|
||||
# "--disable-web-security",
|
||||
# "--disable-features=site-per-process",
|
||||
# "--disable-setuid-sandbox",
|
||||
# "--disable-accelerated-2d-canvas",
|
||||
# "--no-first-run",
|
||||
# "--no-zygote",
|
||||
# "--single-process",
|
||||
"--disable-gpu",
|
||||
# "--use-gl=egl",
|
||||
"--mute-audio",
|
||||
]
|
||||
# scraper = cloudscraper.create_scraper(
|
||||
# browser={"browser": "chrome", "platform": "windows", "desktop": True},
|
||||
# debug=False,
|
||||
# # sess=LogicAniLife.session,
|
||||
# delay=10,
|
||||
# )
|
||||
#
|
||||
# cookie_value, user_agent = scraper.get_cookie_string(url)
|
||||
#
|
||||
# logger.debug(f"cookie_value:: {cookie_value}")
|
||||
|
||||
start = time.time()
|
||||
ua = (
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
|
||||
"AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/69.0.3497.100 Safari/537.36"
|
||||
)
|
||||
|
||||
# from playwright_stealth import stealth_sync
|
||||
|
||||
def set_cookie(req):
|
||||
nonlocal cookie
|
||||
if "cookie" in req.headers:
|
||||
cookie = req.headers["cookie"]
|
||||
|
||||
async with async_playwright() as p:
|
||||
try:
|
||||
if engine == "chrome":
|
||||
browser = await p.chromium.launch(
|
||||
channel="chrome", args=browser_args, headless=headless
|
||||
)
|
||||
elif engine == "webkit":
|
||||
browser = await p.webkit.launch(
|
||||
headless=headless,
|
||||
args=browser_args,
|
||||
)
|
||||
else:
|
||||
browser = await p.firefox.launch(
|
||||
headless=headless,
|
||||
args=browser_args,
|
||||
)
|
||||
# context = browser.new_context(
|
||||
# user_agent=ua,
|
||||
# )
|
||||
|
||||
LogicOhli24.headers[
|
||||
"Referer"
|
||||
] = "https://anilife.live/detail/id/471"
|
||||
# print(LogicAniLife.headers)
|
||||
|
||||
LogicOhli24.headers["Referer"] = LogicOhli24.episode_url
|
||||
|
||||
if referer is not None:
|
||||
LogicOhli24.headers["Referer"] = referer
|
||||
|
||||
# logger.debug(f"LogicAniLife.headers::: {LogicOhli24.headers}")
|
||||
context = await browser.new_context(
|
||||
extra_http_headers=LogicOhli24.headers, ignore_https_errors=True
|
||||
)
|
||||
# await context.add_cookies(LogicOhli24.cookies)
|
||||
|
||||
# LogicAniLife.headers["Cookie"] = cookie_value
|
||||
|
||||
# await context.set_extra_http_headers(LogicOhli24.headers)
|
||||
|
||||
page = await context.new_page()
|
||||
|
||||
# page.set_extra_http_headers(LogicAniLife.headers)
|
||||
|
||||
if stealth:
|
||||
await stealth_async(page)
|
||||
|
||||
# page.on("request", set_cookie)
|
||||
# stealth_sync(page)
|
||||
# print(LogicOhli24.headers["Referer"])
|
||||
|
||||
# page.on("request", set_cookie)
|
||||
|
||||
print(f'Referer:: {LogicOhli24.headers["Referer"]}')
|
||||
# await page.set_extra_http_headers(LogicAniLife.headers)
|
||||
|
||||
# domcontentloaded
|
||||
# load
|
||||
# networkidle
|
||||
await page.goto(
|
||||
url,
|
||||
wait_until="load",
|
||||
# referer=LogicOhli24.headers["Referer"],
|
||||
)
|
||||
# await page.wait_for_url(url, wait_until="domcontentloaded")
|
||||
# page.wait_for_timeout(10000)
|
||||
# await asyncio.sleep(2.9)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
# await page.reload()
|
||||
|
||||
# time.sleep(10)
|
||||
# cookies = context.cookies
|
||||
# print(cookies)
|
||||
|
||||
print(f"page.url:: {page.url}")
|
||||
LogicOhli24.origin_url = page.url
|
||||
|
||||
temp_content = await page.content()
|
||||
#
|
||||
# print(temp_content)
|
||||
|
||||
print(f"run at {time.time() - start} sec")
|
||||
|
||||
return temp_content
|
||||
except Exception as e:
|
||||
logger.error("Exception:%s", e)
|
||||
logger.error(traceback.format_exc())
|
||||
finally:
|
||||
await browser.close()
|
||||
|
||||
except Exception as e:
|
||||
logger.error("Exception:%s", e)
|
||||
logger.error(traceback.format_exc())
|
||||
finally:
|
||||
# browser.close()
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def db_init():
|
||||
pass
|
||||
@@ -188,6 +387,7 @@ class LogicOhli24(LogicModuleBase):
|
||||
}
|
||||
)
|
||||
elif sub == "add_queue":
|
||||
logger.debug(f"linkkf add_queue routine ===============")
|
||||
ret = {}
|
||||
info = json.loads(request.form["data"])
|
||||
logger.info(f"info:: {info}")
|
||||
@@ -244,9 +444,48 @@ class LogicOhli24(LogicModuleBase):
|
||||
logger.error("Exception:%s", e)
|
||||
logger.error(traceback.format_exc())
|
||||
except Exception as e:
|
||||
P.logger.error("Exception:%s", e)
|
||||
P.logger.error(f"Exception: {str(e)}")
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
def process_api(self, sub, req):
|
||||
logger.debug("here!")
|
||||
ret = {}
|
||||
try:
|
||||
if sub == "anime_list":
|
||||
logger.debug(f"anime_list =*==")
|
||||
logger.debug(req)
|
||||
data = []
|
||||
cate = req.form["type"]
|
||||
page = req.form["page"]
|
||||
|
||||
data = self.get_anime_info(cate, page)
|
||||
# self.current_data = data
|
||||
return jsonify(
|
||||
{"ret": "success", "cate": cate, "page": page, "data": data}
|
||||
)
|
||||
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
ret["ret"] = "exception"
|
||||
ret["data"] = str(exception)
|
||||
return jsonify(ret)
|
||||
|
||||
#########################################################
|
||||
# API
|
||||
#########################################################
|
||||
# @blueprint.route("/api/<sub>", methods=["GET", "POST"])
|
||||
# @check_api
|
||||
# def api(self, sub):
|
||||
# if sub == "ohli24":
|
||||
# try:
|
||||
# logger.debug("api ohli24")
|
||||
# data = {"aaaa"}
|
||||
# except Exception as e:
|
||||
# logger.error("Exception:%s", e)
|
||||
# logger.error(traceback.format_exc())
|
||||
# return data
|
||||
|
||||
@staticmethod
|
||||
def add_whitelist(*args):
|
||||
ret = {}
|
||||
@@ -486,7 +725,7 @@ class LogicOhli24(LogicModuleBase):
|
||||
+ li.xpath('.//a[@class="item-subject"]/@href')[0]
|
||||
)
|
||||
# logger.debug(f"link:: {link}")
|
||||
date = li.xpath('.//div[@class="wr-date"]/text()')[0]
|
||||
_date = li.xpath('.//div[@class="wr-date"]/text()')[0]
|
||||
m = hashlib.md5(title.encode("utf-8"))
|
||||
# _vi = hashlib.md5(title.encode('utf-8').hexdigest())
|
||||
# logger.info(m.hexdigest())
|
||||
@@ -496,8 +735,8 @@ class LogicOhli24(LogicModuleBase):
|
||||
"title": title,
|
||||
"link": link,
|
||||
"thumbnail": image,
|
||||
"date": date,
|
||||
"day": date,
|
||||
"date": _date,
|
||||
"day": _date,
|
||||
"_id": title,
|
||||
"va": link,
|
||||
"_vi": _vi,
|
||||
@@ -505,7 +744,12 @@ class LogicOhli24(LogicModuleBase):
|
||||
}
|
||||
)
|
||||
|
||||
logger.info("des_items length:: %s", len(des_items))
|
||||
logger.debug(P.ModelSetting.get("ohli24_order_desc"))
|
||||
# if P.ModelSetting.get("ohli24_order_desc") == "False":
|
||||
# print("Here....")
|
||||
# episodes.reverse()
|
||||
|
||||
# logger.info("des_items length:: %s", len(des_items))
|
||||
for idx, item in enumerate(des_items):
|
||||
# key = des_key[idx]
|
||||
span = item.xpath(".//span//text()")
|
||||
@@ -534,7 +778,7 @@ class LogicOhli24(LogicModuleBase):
|
||||
"episode": episodes,
|
||||
}
|
||||
|
||||
if P.ModelSetting.get_bool("ohli24_order_desc"):
|
||||
if not P.ModelSetting.get_bool("ohli24_order_desc"):
|
||||
data["episode"] = list(reversed(data["episode"]))
|
||||
data["list_order"] = "desc"
|
||||
|
||||
@@ -576,6 +820,16 @@ class LogicOhli24(LogicModuleBase):
|
||||
logger.info("url:::> %s", url)
|
||||
data = {}
|
||||
response_data = LogicOhli24.get_html(url, timeout=10)
|
||||
# response_data = asyncio.run(
|
||||
# LogicOhli24.get_html_playwright(
|
||||
# url,
|
||||
# headless=False,
|
||||
# # referer=referer_url,
|
||||
# engine="chrome",
|
||||
# # stealth=True,
|
||||
# )
|
||||
# )
|
||||
# print(response_data)
|
||||
tree = html.fromstring(response_data)
|
||||
tmp_items = tree.xpath('//div[@class="list-row"]')
|
||||
data["anime_count"] = len(tmp_items)
|
||||
@@ -704,23 +958,56 @@ class LogicOhli24(LogicModuleBase):
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def get_html(url, referer=None, stream=False, timeout=5):
|
||||
def get_html(
|
||||
url, headers=None, referer=None, stream=False, timeout=5, stealth=False
|
||||
):
|
||||
# global response_data
|
||||
data = ""
|
||||
# response_date = ""
|
||||
try:
|
||||
|
||||
print("cloudflare protection bypass ==================P")
|
||||
response_date = ""
|
||||
if headers is not None:
|
||||
LogicOhli24.headers = headers
|
||||
|
||||
logger.debug(f"headers: {LogicOhli24.headers}")
|
||||
# response_data = asyncio.run(
|
||||
# LogicOhli24.get_html_playwright(
|
||||
# url,
|
||||
# headless=True,
|
||||
# # referer=referer_url,
|
||||
# engine="chrome",
|
||||
# # stealth=True,
|
||||
# )
|
||||
# )
|
||||
# # print(response_data)
|
||||
#
|
||||
# logger.debug(len(response_data))
|
||||
|
||||
# return response_data
|
||||
|
||||
if LogicOhli24.session is None:
|
||||
LogicOhli24.session = requests.session()
|
||||
|
||||
# logger.debug('get_html :%s', url)
|
||||
headers["Referer"] = "" if referer is None else referer
|
||||
# LogicOhli24.headers["Referer"] = "" if referer is None else referer
|
||||
logger.debug(f"referer:: {referer}")
|
||||
if referer:
|
||||
LogicOhli24.headers["Referer"] = referer
|
||||
|
||||
# logger.info(headers)
|
||||
logger.debug(f"LogicOhli24.headers:: {LogicOhli24.headers}")
|
||||
page_content = LogicOhli24.session.get(
|
||||
url, headers=headers, timeout=timeout
|
||||
url, headers=LogicOhli24.headers, timeout=timeout
|
||||
)
|
||||
data = page_content.text
|
||||
response_data = page_content.text
|
||||
# logger.debug(response_data)
|
||||
return response_data
|
||||
except Exception as e:
|
||||
logger.error("Exception:%s", e)
|
||||
logger.error(traceback.format_exc())
|
||||
return data
|
||||
# return response_data
|
||||
|
||||
#########################################################
|
||||
def add(self, episode_info):
|
||||
@@ -792,25 +1079,29 @@ class Ohli24QueueEntity(FfmpegQueueEntity):
|
||||
db_entity.save()
|
||||
|
||||
# Get episode info from OHLI24 site
|
||||
def make_episode_info_old(self):
|
||||
def make_episode_info(self):
|
||||
try:
|
||||
# url = 'https://ohli24.net/e/' + self.info['va']
|
||||
base_url = "https://ohli24.net"
|
||||
base_url = "https://ohli24.org"
|
||||
iframe_url = ""
|
||||
|
||||
# https://ohli24.net/e/%EB%85%B9%EC%9D%84%20%EB%A8%B9%EB%8A%94%20%EB%B9%84%EC%8A%A4%EC%BD%94%206%ED%99%94
|
||||
# https://ohli24.org/e/%EB%85%B9%EC%9D%84%20%EB%A8%B9%EB%8A%94%20%EB%B9%84%EC%8A%A4%EC%BD%94%206%ED%99%94
|
||||
url = self.info["va"]
|
||||
|
||||
ourls = parse.urlparse(url)
|
||||
|
||||
headers = {
|
||||
"Referer": f"{ourls.scheme}://{ourls.netloc}",
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Whale/3.12.129.46 Safari/537.36",
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/96.0.4664.110 Whale/3.12.129.46 Safari/537.36",
|
||||
}
|
||||
logger.debug(headers)
|
||||
logger.debug("make_episode_info()::url==> %s", url)
|
||||
logger.info(f"self.info:::> {self.info}")
|
||||
|
||||
text = requests.get(url, headers=headers).text
|
||||
# text = requests.get(url, headers=headers).text
|
||||
text = LogicOhli24.get_html(
|
||||
url, headers=headers, referer=f"{ourls.scheme}://{ourls.netloc}"
|
||||
)
|
||||
# logger.debug(text)
|
||||
soup1 = BeautifulSoup(text, "lxml")
|
||||
pattern = re.compile(r"url : \"\.\.(.*)\"")
|
||||
@@ -822,221 +1113,15 @@ class Ohli24QueueEntity(FfmpegQueueEntity):
|
||||
iframe_url = match.group(1)
|
||||
logger.info("iframe_url::> %s", iframe_url)
|
||||
|
||||
resp = requests.get(base_url + iframe_url, headers=headers, timeout=20).text
|
||||
soup2 = BeautifulSoup(resp, "lxml")
|
||||
iframe_src = soup2.find("iframe")["src"]
|
||||
# print(resp1)
|
||||
|
||||
logger.debug(f"iframe_src:::> {iframe_src}")
|
||||
|
||||
resp1 = requests.get(iframe_src, headers=headers, timeout=600).text
|
||||
# logger.info('resp1::>> %s', resp1)
|
||||
soup3 = BeautifulSoup(resp1, "lxml")
|
||||
# packed_pattern = re.compile(r'\\{*(eval.+)*\\}', re.MULTILINE | re.DOTALL)
|
||||
s_pattern = re.compile(r"(eval.+)", re.MULTILINE | re.DOTALL)
|
||||
packed_pattern = re.compile(
|
||||
r"if?.([^{}]+)\{.*(eval.+)\}.+else?.{.(eval.+)\}", re.DOTALL
|
||||
)
|
||||
packed_script = soup3.find("script", text=s_pattern)
|
||||
# packed_script = soup3.find('script')
|
||||
# logger.info('packed_script>>> %s', packed_script.text)
|
||||
unpack_script = None
|
||||
if packed_script is not None:
|
||||
# logger.debug('zzzzzzzzzzzz')
|
||||
match = packed_pattern.search(packed_script.text)
|
||||
# match = re.search(packed_pattern, packed_script.text)
|
||||
# logger.debug("match::: %s", match.group())
|
||||
unpack_script = jsbeautifier.beautify(match.group(3))
|
||||
|
||||
# logger.info('match groups:: %s', match.groups())
|
||||
# logger.info('match group3:: %s', match.group(3))
|
||||
# print('packed_script==>', packed_script)
|
||||
# logger.debug(unpack_script)
|
||||
|
||||
p1 = re.compile(r"(\"tracks\".*\])\,\"captions\"", re.MULTILINE | re.DOTALL)
|
||||
m2 = re.search(
|
||||
r"(\"tracks\".*\]).*\"captions\"",
|
||||
unpack_script,
|
||||
flags=re.MULTILINE | re.DOTALL,
|
||||
)
|
||||
# print(m2.group(1))
|
||||
dict_string = "{" + m2.group(1) + "}"
|
||||
|
||||
logger.info(f"dict_string::> {dict_string}")
|
||||
tracks = json.loads(dict_string)
|
||||
self.srt_url = tracks["tracks"][0]["file"]
|
||||
|
||||
logger.debug(f'srt_url::: {tracks["tracks"][0]["file"]}')
|
||||
|
||||
video_hash = iframe_src.split("/")
|
||||
video_hashcode = re.sub(r"index\.php\?data=", "", video_hash[-1])
|
||||
self._vi = video_hashcode
|
||||
video_info_url = f"{video_hash[0]}//{video_hash[2]}/player/index.php?data={video_hashcode}&do=getVideo"
|
||||
# print('hash:::', video_hash)
|
||||
logger.debug(f"video_info_url::: {video_info_url}")
|
||||
|
||||
headers = {
|
||||
"referer": f"{iframe_src}",
|
||||
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/96.0.4664.110 Whale/3.12.129.46 Safari/537.36"
|
||||
"Mozilla/5.0 (Macintosh; Intel "
|
||||
"Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 "
|
||||
"Whale/3.12.129.46 Safari/537.36",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
}
|
||||
# print(headers)
|
||||
payload = {
|
||||
"hash": video_hash[-1],
|
||||
}
|
||||
resp2 = requests.post(
|
||||
video_info_url, headers=headers, data=payload, timeout=20
|
||||
).json()
|
||||
|
||||
logger.debug("resp2::> %s", resp2)
|
||||
|
||||
hls_url = resp2["videoSource"]
|
||||
logger.debug(f"video_url::> {hls_url}")
|
||||
|
||||
resp3 = requests.get(hls_url, headers=headers).text
|
||||
# logger.debug(resp3)
|
||||
|
||||
# stream_url = hls_url.split('\n')[-1].strip()
|
||||
stream_info = resp3.split("\n")[-2:]
|
||||
# logger.debug('stream_url:: %s', stream_url)
|
||||
logger.debug(f"stream_info:: {stream_info}")
|
||||
self.headers = {
|
||||
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/71.0.3554.0 Safari/537.36Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
|
||||
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3554.0 Safari/537.36",
|
||||
"Referer": "https://ndoodle.xyz/video/03a3655fff3e9bdea48de9f49e938e32",
|
||||
}
|
||||
|
||||
self.url = stream_info[1].strip()
|
||||
match = re.compile(r'NAME="(?P<quality>.*?)"').search(stream_info[0])
|
||||
self.quality = "720P"
|
||||
if match is not None:
|
||||
self.quality = match.group("quality")
|
||||
logger.info(self.quality)
|
||||
|
||||
match = re.compile(
|
||||
r"(?P<title>.*?)\s*((?P<season>\d+)%s)?\s*((?P<epi_no>\d+)%s)"
|
||||
% ("기", "화")
|
||||
).search(self.info["title"])
|
||||
|
||||
# epi_no 초기값
|
||||
epi_no = 1
|
||||
|
||||
if match:
|
||||
self.content_title = match.group("title").strip()
|
||||
if "season" in match.groupdict() and match.group("season") is not None:
|
||||
self.season = int(match.group("season"))
|
||||
|
||||
# epi_no = 1
|
||||
epi_no = int(match.group("epi_no"))
|
||||
ret = "%s.S%sE%s.%s-OHNI24.mp4" % (
|
||||
self.content_title,
|
||||
"0%s" % self.season if self.season < 10 else self.season,
|
||||
"0%s" % epi_no if epi_no < 10 else epi_no,
|
||||
self.quality,
|
||||
)
|
||||
else:
|
||||
self.content_title = self.info["title"]
|
||||
P.logger.debug("NOT MATCH")
|
||||
ret = "%s.720p-OHNI24.mp4" % self.info["title"]
|
||||
|
||||
# logger.info('self.content_title:: %s', self.content_title)
|
||||
self.epi_queue = epi_no
|
||||
self.filename = Util.change_text_for_use_filename(ret)
|
||||
logger.info(f"self.filename::> {self.filename}")
|
||||
self.savepath = P.ModelSetting.get("ohli24_download_path")
|
||||
logger.info(f"self.savepath::> {self.savepath}")
|
||||
|
||||
# TODO: 완결 처리
|
||||
|
||||
if P.ModelSetting.get_bool("ohli24_auto_make_folder"):
|
||||
if self.info["day"].find("완결") != -1:
|
||||
folder_name = "%s %s" % (
|
||||
P.ModelSetting.get("ohli24_finished_insert"),
|
||||
self.content_title,
|
||||
)
|
||||
else:
|
||||
folder_name = self.content_title
|
||||
folder_name = Util.change_text_for_use_filename(folder_name.strip())
|
||||
self.savepath = os.path.join(self.savepath, folder_name)
|
||||
if P.ModelSetting.get_bool("ohli24_auto_make_season_folder"):
|
||||
self.savepath = os.path.join(
|
||||
self.savepath, "Season %s" % int(self.season)
|
||||
)
|
||||
self.filepath = os.path.join(self.savepath, self.filename)
|
||||
if not os.path.exists(self.savepath):
|
||||
os.makedirs(self.savepath)
|
||||
|
||||
from framework.common.util import write_file, convert_vtt_to_srt
|
||||
|
||||
srt_filepath = os.path.join(
|
||||
self.savepath, self.filename.replace(".mp4", ".ko.srt")
|
||||
)
|
||||
|
||||
if self.srt_url is not None and not os.path.exists(srt_filepath):
|
||||
# vtt_data = requests.get(self.vtt, headers=headers).text
|
||||
# srt_data = convert_vtt_to_srt(vtt_data)
|
||||
|
||||
srt_data = requests.get(self.srt_url, headers=headers).text
|
||||
write_file(srt_data, srt_filepath)
|
||||
|
||||
except Exception as e:
|
||||
P.logger.error("Exception:%s", e)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
def make_episode_info(self):
|
||||
try:
|
||||
# url = 'https://ohli24.net/e/' + self.info['va']
|
||||
base_url = "https://ohli24.net"
|
||||
iframe_url = ""
|
||||
|
||||
# https://ohli24.net/e/%EB%85%B9%EC%9D%84%20%EB%A8%B9%EB%8A%94%20%EB%B9%84%EC%8A%A4%EC%BD%94%206%ED%99%94
|
||||
url = self.info["va"]
|
||||
|
||||
ourls = parse.urlparse(url)
|
||||
|
||||
headers = {
|
||||
"referer": f"{ourls.scheme}://{ourls.netloc}",
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Whale/3.12.129.46 Safari/537.36",
|
||||
}
|
||||
logger.debug("make_episode_info()::url==> %s", url)
|
||||
logger.info(f"self.info:::> {self.info}")
|
||||
|
||||
text = requests.get(url, headers=headers).text
|
||||
# logger.debug(text)
|
||||
soup1 = BeautifulSoup(text, "lxml")
|
||||
pattern = re.compile(r"url : \"\.\.(.*)\"")
|
||||
script = soup1.find("script", text=pattern)
|
||||
|
||||
if script:
|
||||
match = pattern.search(script.text)
|
||||
if match:
|
||||
iframe_url = match.group(1)
|
||||
logger.info("iframe_url::> %s", iframe_url)
|
||||
|
||||
logger.debug(soup1.find("iframe"))
|
||||
|
||||
iframe_url = soup1.find("iframe")["src"]
|
||||
logger.info("iframe_url::> %s", iframe_url)
|
||||
|
||||
print(base_url)
|
||||
print(iframe_url)
|
||||
# exit()
|
||||
|
||||
# resp = requests.get(iframe_url, headers=headers, timeout=20).text
|
||||
# soup2 = BeautifulSoup(resp, "lxml")
|
||||
# iframe_src = soup2.find("iframe")["src"]
|
||||
iframe_src = iframe_url
|
||||
# print(resp1)
|
||||
|
||||
logger.debug(f"iframe_src:::> {iframe_src}")
|
||||
|
||||
resp1 = requests.get(iframe_src, headers=headers, timeout=600).text
|
||||
# logger.info('resp1::>> %s', resp1)
|
||||
# resp1 = requests.get(iframe_src, headers=headers, timeout=600).text
|
||||
resp1 = LogicOhli24.get_html(iframe_src, headers=headers, timeout=600)
|
||||
logger.info("resp1::>> %s", resp1)
|
||||
soup3 = BeautifulSoup(resp1, "lxml")
|
||||
# packed_pattern = re.compile(r'\\{*(eval.+)*\\}', re.MULTILINE | re.DOTALL)
|
||||
s_pattern = re.compile(r"(eval.+)", re.MULTILINE | re.DOTALL)
|
||||
@@ -1045,19 +1130,17 @@ class Ohli24QueueEntity(FfmpegQueueEntity):
|
||||
)
|
||||
packed_script = soup3.find("script", text=s_pattern)
|
||||
# packed_script = soup3.find('script')
|
||||
# logger.info('packed_script>>> %s', packed_script.text)
|
||||
# logger.info("packed_script>>> %s", packed_script.text)
|
||||
unpack_script = None
|
||||
if packed_script is not None:
|
||||
# logger.debug('zzzzzzzzzzzz')
|
||||
match = packed_pattern.search(packed_script.text)
|
||||
# match = re.search(packed_pattern, packed_script.text)
|
||||
# logger.debug("match::: %s", match.group())
|
||||
unpack_script = jsbeautifier.beautify(match.group(3))
|
||||
# unpack_script = jsbeautifier.beautify(match.group(3))
|
||||
|
||||
# logger.info('match groups:: %s', match.groups())
|
||||
# logger.info('match group3:: %s', match.group(3))
|
||||
# print('packed_script==>', packed_script)
|
||||
# logger.debug(unpack_script)
|
||||
logger.debug(type(packed_script))
|
||||
unpack_script = jsbeautifier.beautify(str(packed_script))
|
||||
|
||||
p1 = re.compile(r"(\"tracks\".*\])\,\"captions\"", re.MULTILINE | re.DOTALL)
|
||||
m2 = re.search(
|
||||
@@ -1068,7 +1151,7 @@ class Ohli24QueueEntity(FfmpegQueueEntity):
|
||||
# print(m2.group(1))
|
||||
dict_string = "{" + m2.group(1) + "}"
|
||||
|
||||
logger.info(f"dict_string::> {dict_string}")
|
||||
# logger.info(f"dict_string::> {dict_string}")
|
||||
tracks = json.loads(dict_string)
|
||||
self.srt_url = tracks["tracks"][0]["file"]
|
||||
|
||||
@@ -1089,8 +1172,9 @@ class Ohli24QueueEntity(FfmpegQueueEntity):
|
||||
"Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 "
|
||||
"Whale/3.12.129.46 Safari/537.36",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
"Cookie": "PHPSESSID=hhhnrora8o9omv1tljq4efv216; 2a0d2363701f23f8a75028924a3af643=NDkuMTYzLjExMS4xMDk=; e1192aefb64683cc97abb83c71057733=aW5n",
|
||||
}
|
||||
# print(headers)
|
||||
|
||||
payload = {
|
||||
"hash": video_hash[-1],
|
||||
}
|
||||
@@ -1183,10 +1267,11 @@ class Ohli24QueueEntity(FfmpegQueueEntity):
|
||||
self.savepath, self.filename.replace(".mp4", ".ko.srt")
|
||||
)
|
||||
|
||||
if self.srt_url is not None and not os.path.exists(srt_filepath):
|
||||
# vtt_data = requests.get(self.vtt, headers=headers).text
|
||||
# srt_data = convert_vtt_to_srt(vtt_data)
|
||||
|
||||
if (
|
||||
self.srt_url is not None
|
||||
and not os.path.exists(srt_filepath)
|
||||
and not ("thumbnails.vtt" in self.srt_url)
|
||||
):
|
||||
srt_data = requests.get(self.srt_url, headers=headers).text
|
||||
write_file(srt_data, srt_filepath)
|
||||
|
||||
|
||||
@@ -89,9 +89,10 @@ def initialize():
|
||||
PluginUtil.make_info_json(P.plugin_info, __file__)
|
||||
from .logic_ohli24 import LogicOhli24
|
||||
from .logic_anilife import LogicAniLife
|
||||
from .logic_linkkf import LogicLinkkf
|
||||
|
||||
# P.module_list = [LogicOhli24(P), LogicLinkkf(P)]
|
||||
P.module_list = [LogicOhli24(P), LogicAniLife(P)]
|
||||
P.module_list = [LogicOhli24(P), LogicAniLife(P), LogicLinkkf(P)]
|
||||
P.logic = Logic(P)
|
||||
default_route(P)
|
||||
except Exception as e:
|
||||
|
||||
243
static/css/linkkf.css
Normal file
243
static/css/linkkf.css
Normal file
@@ -0,0 +1,243 @@
|
||||
button.code-button {
|
||||
min-width: 82px !important;
|
||||
}
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
|
||||
[data-tooltip-text]:hover {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
[data-tooltip-text]:after {
|
||||
-webkit-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
||||
-moz-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
||||
transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
||||
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
|
||||
-webkit-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
|
||||
-moz-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
|
||||
box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
|
||||
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
margin-bottom: 10px;
|
||||
padding: 7px 12px;
|
||||
position: absolute;
|
||||
width: auto;
|
||||
min-width: 50px;
|
||||
max-width: 300px;
|
||||
word-wrap: break-word;
|
||||
|
||||
z-index: 9999;
|
||||
|
||||
opacity: 0;
|
||||
left: -9999px;
|
||||
top: 90%;
|
||||
|
||||
content: attr(data-tooltip-text);
|
||||
}
|
||||
|
||||
[data-tooltip-text]:hover:after {
|
||||
top: 230%;
|
||||
left: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
[data-tooltip-text]:hover {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
[data-tooltip-text]:after {
|
||||
-webkit-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
||||
-moz-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
||||
transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
||||
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
|
||||
-webkit-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
|
||||
-moz-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
|
||||
box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
|
||||
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
margin-bottom: 10px;
|
||||
padding: 7px 12px;
|
||||
position: absolute;
|
||||
width: auto;
|
||||
min-width: 50px;
|
||||
max-width: 300px;
|
||||
word-wrap: break-word;
|
||||
|
||||
z-index: 9999;
|
||||
|
||||
opacity: 0;
|
||||
left: -9999px;
|
||||
top: -210% !important;
|
||||
|
||||
content: attr(data-tooltip-text);
|
||||
}
|
||||
|
||||
[data-tooltip-text]:hover:after {
|
||||
top: 130%;
|
||||
left: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#airing_list {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cut-text {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
.container {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
#yommi_wrapper {
|
||||
max-width: 80%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
#screen_movie_list {
|
||||
margin-top: 10px;
|
||||
}
|
||||
/* .spinner {*/
|
||||
/* width: 40px;*/
|
||||
/* height: 40px;*/
|
||||
/* background-color: #333;*/
|
||||
|
||||
/* margin: 100px auto;*/
|
||||
/* -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;*/
|
||||
/* animation: sk-rotateplane 1.2s infinite ease-in-out;*/
|
||||
/*}*/
|
||||
|
||||
/*@-webkit-keyframes sk-rotateplane {*/
|
||||
/* 0% { -webkit-transform: perspective(120px) }*/
|
||||
/* 50% { -webkit-transform: perspective(120px) rotateY(180deg) }*/
|
||||
/* 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) }*/
|
||||
/*}*/
|
||||
|
||||
/*@keyframes sk-rotateplane {*/
|
||||
/* 0% {*/
|
||||
/* transform: perspective(120px) rotateX(0deg) rotateY(0deg);*/
|
||||
/* -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)*/
|
||||
/* } 50% {*/
|
||||
/* transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);*/
|
||||
/* -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)*/
|
||||
/* } 100% {*/
|
||||
/* transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);*/
|
||||
/* -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);*/
|
||||
/* }*/
|
||||
|
||||
/*}*/
|
||||
.spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
position: relative;
|
||||
margin: 100px auto;
|
||||
}
|
||||
|
||||
.double-bounce1,
|
||||
.double-bounce2 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
background-color: #333;
|
||||
opacity: 0.6;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
-webkit-animation: sk-bounce 2s infinite ease-in-out;
|
||||
animation: sk-bounce 2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.double-bounce2 {
|
||||
-webkit-animation-delay: -1s;
|
||||
animation-delay: -1s;
|
||||
}
|
||||
|
||||
@-webkit-keyframes sk-bounce {
|
||||
0%,
|
||||
100% {
|
||||
-webkit-transform: scale(0);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sk-bounce {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(0);
|
||||
-webkit-transform: scale(0);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.badge-on-image {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
/*bottom: 2px; !* position where you want it *!*/
|
||||
right: 2px;
|
||||
padding: 5px 12px;
|
||||
}
|
||||
|
||||
#inner_screen_movie > div {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 0!important;
|
||||
}
|
||||
.new-anime {
|
||||
border-color: darksalmon;
|
||||
border-width: 4px;
|
||||
border-style: dashed;
|
||||
|
||||
}
|
||||
|
||||
.card-title {
|
||||
padding: 1rem!important;
|
||||
}
|
||||
|
||||
button#add_whitelist {
|
||||
float: right;
|
||||
}
|
||||
|
||||
button.btn-favorite {
|
||||
background-color: #e0ff42;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
font-family: NanumSquareNeo,system-ui,-apple-system,Segoe UI,Roboto,Helvetica Neue,Noto Sans,Liberation Sans,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;
|
||||
}
|
||||
body {
|
||||
background-image: linear-gradient(90deg, #233f48, #6c6fa2, #768dae);
|
||||
}
|
||||
|
||||
@@ -56,11 +56,6 @@
|
||||
<form id="screen_movie_list_form">
|
||||
<div id="screen_movie_list" class="container"></div>
|
||||
</form>
|
||||
<div class="text-center">
|
||||
<div id="spinner" class="spinner-border" role="status">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
<form id="program_auto_form">
|
||||
<div id="episode_list"></div>
|
||||
</form>
|
||||
|
||||
@@ -192,6 +192,7 @@
|
||||
} else {
|
||||
document.getElementById("code").value = params.code
|
||||
document.getElementById("analysis_btn").click();
|
||||
return;
|
||||
}
|
||||
|
||||
if ("{{arg['anilife_current_code']}}" !== "") {
|
||||
|
||||
@@ -1,49 +1,57 @@
|
||||
{% extends "base.html" %} {% block content %}
|
||||
|
||||
<div class="input-group mb-2">
|
||||
<input
|
||||
id="input_search"
|
||||
type="search"
|
||||
class="form-control rounded"
|
||||
placeholder="Search"
|
||||
aria-label="Search"
|
||||
aria-describedby="search-addon"
|
||||
/>
|
||||
<button id="btn_search" type="button" class="btn btn-outline-primary">
|
||||
search
|
||||
</button>
|
||||
<div id="preloader" class="loader">
|
||||
<div class="loader-inner">
|
||||
<div class="loader-line-wrap">
|
||||
<div class="loader-line"></div>
|
||||
</div>
|
||||
<div class="loader-line-wrap">
|
||||
<div class="loader-line"></div>
|
||||
</div>
|
||||
<div class="loader-line-wrap">
|
||||
<div class="loader-line"></div>
|
||||
</div>
|
||||
<div class="loader-line-wrap">
|
||||
<div class="loader-line"></div>
|
||||
</div>
|
||||
<div class="loader-line-wrap">
|
||||
<div class="loader-line"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="yommi_wrapper">
|
||||
<div class="input-group mb-2">
|
||||
<input
|
||||
id="input_search"
|
||||
type="search"
|
||||
class="form-control rounded"
|
||||
placeholder="Search"
|
||||
aria-label="Search"
|
||||
aria-describedby="search-addon"
|
||||
/>
|
||||
<button id="btn_search" type="button" class="btn btn-primary">search</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div
|
||||
id="anime_category"
|
||||
class="btn-group"
|
||||
role="group"
|
||||
aria-label="Basic example"
|
||||
>
|
||||
<button id="ing" type="button" class="btn btn-success">방영중</button>
|
||||
<button id="theater" type="button" class="btn btn-primary">극장판</button>
|
||||
<button id="complete_anilist" type="button" class="btn btn-dark">
|
||||
완결
|
||||
</button>
|
||||
<div>
|
||||
<div id="anime_category" class="btn-group" role="group" aria-label="Basic example">
|
||||
<button id="ing" type="button" class="btn btn-success">방영중</button>
|
||||
<button id="theater" type="button" class="btn btn-primary">극장판</button>
|
||||
<button id="complete_anilist" type="button" class="btn btn-dark">완결</button>
|
||||
</div>
|
||||
<form id="airing_list_form">
|
||||
<div id="airing_list"></div>
|
||||
<div id="airing_list"></div>
|
||||
</form>
|
||||
<form id="screen_movie_list_form">
|
||||
<div id="screen_movie_list" class="container"></div>
|
||||
<div id="screen_movie_list" class="container"></div>
|
||||
</form>
|
||||
<div class="text-center">
|
||||
<div id="spinner" class="spinner-border" role="status">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form id="program_auto_form">
|
||||
<div id="episode_list"></div>
|
||||
<div id="episode_list"></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<!--전체-->
|
||||
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"
|
||||
@@ -127,28 +135,30 @@
|
||||
}
|
||||
|
||||
function make_airing_list(data, page) {
|
||||
console.log("call make_airing_list()")
|
||||
let str = ''
|
||||
let tmp = ''
|
||||
//console.log(data)
|
||||
|
||||
str += '<div>';
|
||||
str += '<button type="button" class="btn btn-info">Page <span class="badge bg-warning">' + page + '</span></button>';
|
||||
str += '</div>';
|
||||
// str += '<div class="card-columns">'
|
||||
str += '<div id="inner_screen_movie" class="row infinite-scroll">';
|
||||
for (let i in data.anime_list) {
|
||||
for (let i in data.episode) {
|
||||
|
||||
tmp = '<div class="col-6 col-sm-4 col-md-3">';
|
||||
tmp += '<div class="card">';
|
||||
// tmp += '<img class="lozad" data-src="' + data.anime_list[i].image_link + '" />';
|
||||
tmp += '<img class="lazyload" src="../static/img_loader_x200.svg" data-original="' + data.anime_list[i].image_link + '" style="cursor: pointer" onclick="location.href=\'./request?code=' + data.anime_list[i].code + '\'"/>';
|
||||
// tmp += '<img class="lozad" data-src="' + data.episode[i].image_link + '" />';
|
||||
tmp += '<img class="lazyload" src="../static/img_loader_x200.svg" data-original="' + data.episode[i].image_link + '" style="cursor: pointer" onclick="location.href=\'./request?code=' + data.episode[i].code + '\'"/>';
|
||||
tmp += '<div class="card-body">'
|
||||
// {#tmp += '<button id="code_button" data-code="' + data.episode[i].code + '" type="button" class="btn btn-primary code-button bootstrap-tooltip" data-toggle="button" data-tooltip="true" aria-pressed="true" autocomplete="off" data-placement="top">' +#}
|
||||
// {# '<span data-tooltip-text="'+data.episode[i].title+'">' + data.episode[i].code + '</span></button></div>';#}
|
||||
tmp += '<h5 class="card-title">' + data.anime_list[i].title + '</h5>';
|
||||
tmp += '<p class="card-text">' + data.anime_list[i].code + '<button id="add_whitelist" name="add_whitelist" class="btn btn-sm btn-favorite mb-1" data-code="' +
|
||||
data.anime_list[i].code +
|
||||
'"><i class="bi bi-heart-fill"></i></button></p>';
|
||||
tmp += '<a href="./request?code=' + data.anime_list[i].code + '" class="btn btn-primary cut-text">' + data.anime_list[i].title + '</a>';
|
||||
tmp += '<h5 class="card-title">' + data.episode[i].title + '</h5>';
|
||||
tmp += '<p class="card-text">' + data.episode[i].code + '<button id="add_whitelist" name="add_whitelist" class="btn btn-sm btn-favorite mb-1" data-code="' +
|
||||
data.episode[i].code +
|
||||
'"><i class="bi bi-heart-fill"></i></button></p>';
|
||||
tmp += '<a href="./request?code=' + data.episode[i].code + '" class="btn btn-primary cut-text">' + data.episode[i].title + '</a>';
|
||||
// tmp +=
|
||||
// '<button id="add_whitelist" name="add_whitelist" class="btn btn-sm btn-favorite mb-1" data-code="' +
|
||||
// data.anime_list[i].code +
|
||||
@@ -406,7 +416,7 @@
|
||||
let data_code = $(this).attr("data-code");
|
||||
console.log(data_code);
|
||||
$.ajax({
|
||||
url: "/" + package_name + "/ajax/"+sub+"/add_whitelist",
|
||||
url: "/" + package_name + "/ajax/" + sub + "/add_whitelist",
|
||||
type: "POST",
|
||||
cache: false,
|
||||
data: JSON.stringify({data_code: data_code}),
|
||||
@@ -642,6 +652,14 @@
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.badge-on-image {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
/*bottom: 2px; !* position where you want it *!*/
|
||||
right: 2px;
|
||||
padding: 5px 12px;
|
||||
}
|
||||
|
||||
#airing_list {
|
||||
display: none;
|
||||
}
|
||||
@@ -672,6 +690,7 @@
|
||||
button.btn-favorite {
|
||||
background-color: #e0ff42;
|
||||
}
|
||||
|
||||
/*.card-columns {*/
|
||||
/* @include media-breakpoint-only(lg) {*/
|
||||
/* column-count: 4;*/
|
||||
@@ -684,10 +703,12 @@
|
||||
.container {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.card-columns {
|
||||
column-count: 2;
|
||||
column-gap: 1.25rem;
|
||||
}
|
||||
|
||||
.card-columns .card {
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -695,12 +716,16 @@
|
||||
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.card-columns {column-count: 3;}
|
||||
.card-columns {
|
||||
column-count: 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Large devices (desktops, 992px and up) */
|
||||
@media (min-width: 992px) {
|
||||
.card-columns {column-count: 3;}
|
||||
.card-columns {
|
||||
column-count: 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Extra large devices (large desktops, 1200px and up) */
|
||||
@@ -709,22 +734,28 @@
|
||||
column-count: 5;
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.card-columns .card {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.card-columns .card img{
|
||||
|
||||
.card-columns .card img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
button#add_whitelist {
|
||||
/*top: -70px;*/
|
||||
position: relative;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: NanumSquareNeo,system-ui,-apple-system,Segoe UI,Roboto,Helvetica Neue,Noto Sans,Liberation Sans,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;
|
||||
font-family: NanumSquareNeo, system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, Noto Sans, Liberation Sans, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
|
||||
}
|
||||
|
||||
body {
|
||||
background-image: linear-gradient(90deg, #233f48, #6c6fa2, #768dae);
|
||||
}
|
||||
|
||||
144
templates/anime_downloader_linkkf_list.html
Normal file
144
templates/anime_downloader_linkkf_list.html
Normal file
@@ -0,0 +1,144 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
|
||||
<div>
|
||||
<form id="form_search" class="form-inline" style="text-align:left">
|
||||
<div class="container-fluid">
|
||||
<div class="row show-grid">
|
||||
<span class="col-md-4">
|
||||
<select id="order" name="order" class="form-control form-control-sm">
|
||||
<option value="desc">최근순</option>
|
||||
<option value="asc">오래된순</option>
|
||||
</select>
|
||||
<select id="option" name="option" class="form-control form-control-sm">
|
||||
<option value="all">전체</option>
|
||||
<option value="completed">완료</option>
|
||||
</select>
|
||||
</span>
|
||||
<span class="col-md-8">
|
||||
<input id="search_word" name="search_word" class="form-control form-control-sm w-75" type="text" placeholder="" aria-label="Search">
|
||||
<button id="search" class="btn btn-sm btn-outline-success">검색</button>
|
||||
<button id="reset_btn" class="btn btn-sm btn-outline-success">리셋</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div id='page1'></div>
|
||||
{{ macros.m_hr_head_top() }}
|
||||
{{ macros.m_row_start('0') }}
|
||||
{{ macros.m_col(2, macros.m_strong('Poster')) }}
|
||||
{{ macros.m_col(10, macros.m_strong('Info')) }}
|
||||
{{ macros.m_row_end() }}
|
||||
{{ macros.m_hr_head_bottom() }}
|
||||
<div id="list_div"></div>
|
||||
<div id='page2'></div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var package_name = "{{arg['package_name']}}";
|
||||
var sub = "{{arg['sub']}}";
|
||||
var current_data = null;
|
||||
|
||||
$(document).ready(function(){
|
||||
global_sub_request_search('1');
|
||||
});
|
||||
|
||||
$("#search").click(function(e) {
|
||||
e.preventDefault();
|
||||
global_sub_request_search('1');
|
||||
});
|
||||
|
||||
$("body").on('click', '#page', function(e){
|
||||
e.preventDefault();
|
||||
global_sub_request_search($(this).data('page'));
|
||||
});
|
||||
|
||||
$("#reset_btn").click(function(e) {
|
||||
e.preventDefault();
|
||||
document.getElementById("order").value = 'desc';
|
||||
document.getElementById("option").value = 'all';
|
||||
document.getElementById("search_word").value = '';
|
||||
global_sub_request_search('1')
|
||||
});
|
||||
|
||||
|
||||
$("body").on('click', '#json_btn', function(e){
|
||||
e.preventDefault();
|
||||
var id = $(this).data('id');
|
||||
for (i in current_data.list) {
|
||||
if (current_data.list[i].id == id) {
|
||||
m_modal(current_data.list[i])
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$("body").on('click', '#self_search_btn', function(e){
|
||||
e.preventDefault();
|
||||
var search_word = $(this).data('title');
|
||||
document.getElementById("search_word").value = search_word;
|
||||
global_sub_request_search('1')
|
||||
});
|
||||
|
||||
$("body").on('click', '#remove_btn', function(e) {
|
||||
e.preventDefault();
|
||||
id = $(this).data('id');
|
||||
$.ajax({
|
||||
url: '/'+package_name+'/ajax/'+sub+ '/db_remove',
|
||||
type: "POST",
|
||||
cache: false,
|
||||
data: {id:id},
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data) {
|
||||
$.notify('<strong>삭제되었습니다.</strong>', {
|
||||
type: 'success'
|
||||
});
|
||||
global_sub_request_search(current_data.paging.current_page, false)
|
||||
} else {
|
||||
$.notify('<strong>삭제 실패</strong>', {
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("body").on('click', '#request_btn', function(e){
|
||||
e.preventDefault();
|
||||
var content_code = $(this).data('content_code');
|
||||
$(location).attr('href', '/' + package_name + '/' + sub + '/request?content_code=' + content_code)
|
||||
});
|
||||
|
||||
|
||||
|
||||
function make_list(data) {
|
||||
//console.log(data)
|
||||
str = '';
|
||||
for (i in data) {
|
||||
//console.log(data[i])
|
||||
str += m_row_start();
|
||||
str += m_col(1, data[i].id);
|
||||
tmp = (data[i].status == 'completed') ? '완료' : '미완료';
|
||||
str += m_col(1, tmp);
|
||||
tmp = data[i].created_time + '(추가)';
|
||||
if (data[i].completed_time != null)
|
||||
tmp += data[i].completed_time + '(완료)';
|
||||
str += m_col(3, tmp)
|
||||
tmp = data[i].savepath + '<br>' + data[i].filename + '<br><br>';
|
||||
tmp2 = m_button('json_btn', 'JSON', [{'key':'id', 'value':data[i].id}]);
|
||||
tmp2 += m_button('request_btn', '작품 검색', [{'key':'content_code', 'value':data[i].content_code}]);
|
||||
tmp2 += m_button('self_search_btn', '목록 검색', [{'key':'title', 'value':data[i].title}]);
|
||||
tmp2 += m_button('remove_btn', '삭제', [{'key':'id', 'value':data[i].id}]);
|
||||
tmp += m_button_group(tmp2)
|
||||
str += m_col(7, tmp)
|
||||
str += m_row_end();
|
||||
if (i != data.length -1) str += m_hr();
|
||||
}
|
||||
document.getElementById("list_div").innerHTML = str;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
131
templates/anime_downloader_linkkf_queue.html
Normal file
131
templates/anime_downloader_linkkf_queue.html
Normal file
@@ -0,0 +1,131 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
|
||||
<div>
|
||||
{{ macros.m_button_group([['reset_btn', '초기화'], ['delete_completed_btn', '완료 목록 삭제'], ['go_ffmpeg_btn', 'Go FFMPEG']])}}
|
||||
{{ macros.m_row_start('0') }}
|
||||
{{ macros.m_row_end() }}
|
||||
{{ macros.m_hr_head_top() }}
|
||||
{{ macros.m_row_start('0') }}
|
||||
{{ macros.m_col(1, macros.m_strong('Idx')) }}
|
||||
{{ macros.m_col(2, macros.m_strong('CreatedTime')) }}
|
||||
{{ macros.m_col(4, macros.m_strong('Filename')) }}
|
||||
{{ macros.m_col(3, macros.m_strong('Status')) }}
|
||||
{{ macros.m_col(2, macros.m_strong('Action')) }}
|
||||
{{ macros.m_row_end() }}
|
||||
{{ macros.m_hr_head_bottom() }}
|
||||
<div id="download_list_div"></div>
|
||||
</div> <!--전체-->
|
||||
|
||||
<script type="text/javascript">
|
||||
var package_name = "{{arg['package_name'] }}";
|
||||
var sub = "{{arg['sub'] }}";
|
||||
var current_data = null;
|
||||
socket = io.connect(window.location.protocol + "//" + document.domain + ":" + location.port + "/" + package_name + '/' + sub);
|
||||
|
||||
$(document).ready(function(){
|
||||
});
|
||||
|
||||
socket.on('start', function(data){
|
||||
on_start();
|
||||
});
|
||||
socket.on('list_refresh', function(data){
|
||||
on_start()
|
||||
});
|
||||
|
||||
socket.on('status', function(data){
|
||||
console.log(data);
|
||||
on_status(data)
|
||||
});
|
||||
|
||||
|
||||
function on_start() {
|
||||
$.ajax({
|
||||
url: '/' + package_name + '/ajax/' + sub + '/entity_list',
|
||||
type: "POST",
|
||||
cache: false,
|
||||
data: {},
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
make_download_list(data)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function on_status(data) {
|
||||
//console.log(data)
|
||||
tmp = document.getElementById("progress_"+data.entity_id)
|
||||
if (tmp != null) {
|
||||
document.getElementById("progress_"+data.entity_id).style.width = data.ffmpeg_percent+ '%';
|
||||
document.getElementById("progress_"+data.entity_id+"_label").innerHTML = data.ffmpeg_status_kor + "(" + data.ffmpeg_percent + "%)" + ' ' + ((data.ffmpeg_arg != null)?data.ffmpeg_arg.data.current_speed:'')
|
||||
}
|
||||
}
|
||||
|
||||
function make_download_list(data) {
|
||||
str = '';
|
||||
for (i in data) {
|
||||
str += m_row_start();
|
||||
str += m_col(1, data[i].entity_id);
|
||||
str += m_col(2, data[i].created_time);
|
||||
str += m_col(4, (data[i].filename != null) ? data[i].filename : '');
|
||||
|
||||
label = data[i].ffmpeg_status_kor
|
||||
if (data[i].ffmpeg_percent != 0) {
|
||||
label += '(' + data[i].ffmpeg_percent + '%)'
|
||||
}
|
||||
tmp = m_progress('progress_'+data[i].entity_id, data[i].ffmpeg_percent, label)
|
||||
str += m_col(3, tmp);
|
||||
tmp = m_button('program_cancel_btn', '취소', [{'key':'id', 'value':data[i].entity_id}]);
|
||||
tmp = m_button_group(tmp)
|
||||
str += m_col(2, tmp)
|
||||
str += m_row_end();
|
||||
if (i != data.length -1) str += m_hr(0);
|
||||
}
|
||||
document.getElementById("download_list_div").innerHTML = str;
|
||||
}
|
||||
|
||||
$("body").on('click', '#program_cancel_btn', function(e){
|
||||
e.preventDefault();
|
||||
entity_id = $(this).data('id')
|
||||
send_data = {'command':'cancel', 'entity_id':entity_id}
|
||||
queue_command(send_data)
|
||||
});
|
||||
|
||||
$("body").on('click', '#reset_btn', function(e){
|
||||
e.preventDefault();
|
||||
entity_id = $(this).data('id')
|
||||
send_data = {'command':'reset', 'entity_id':-1}
|
||||
queue_command(send_data)
|
||||
});
|
||||
|
||||
$("body").on('click', '#delete_completed_btn', function(e){
|
||||
e.preventDefault();
|
||||
entity_id = $(this).data('id')
|
||||
send_data = {'command':'delete_completed', 'entity_id':-1}
|
||||
queue_command(send_data)
|
||||
});
|
||||
|
||||
function queue_command(data) {
|
||||
$.ajax({
|
||||
url: '/' + package_name + '/ajax/' + sub + '/queue_command',
|
||||
type: "POST",
|
||||
cache: false,
|
||||
data: data,
|
||||
dataType: "json",
|
||||
success: function (ret) {
|
||||
if (ret.ret == 'notify') {
|
||||
$.notify('<strong>'+ ret.log +'</strong>', {type: 'warning'});
|
||||
}
|
||||
on_start();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$("body").on('click', '#go_ffmpeg_btn', function(e){
|
||||
e.preventDefault();
|
||||
$(location).attr('href', '/ffmpeg')
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
639
templates/anime_downloader_linkkf_request.html
Normal file
639
templates/anime_downloader_linkkf_request.html
Normal file
@@ -0,0 +1,639 @@
|
||||
{% extends "base.html" %} {% block content %}
|
||||
<div id="anime_downloader_wrapper">
|
||||
<div id="preloader">
|
||||
<div class='demo'>
|
||||
<!-- <div class="loader-inner">-->
|
||||
<div class='circle'>
|
||||
<div class='inner'></div>
|
||||
</div>
|
||||
<div class='circle'>
|
||||
<div class='inner'></div>
|
||||
</div>
|
||||
<div class='circle'>
|
||||
<div class='inner'></div>
|
||||
</div>
|
||||
<div class='circle'>
|
||||
<div class='inner'></div>
|
||||
</div>
|
||||
<div class='circle'>
|
||||
<div class='inner'></div>
|
||||
</div>
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<form id="program_list">
|
||||
{{ macros.setting_input_text_and_buttons('code', '작품 Code',
|
||||
[['analysis_btn', '분석'], ['go_ohli24_btn', 'Go OHLI24']], desc='예)
|
||||
"https://ohli24.net/c/녹을 먹는 비스코" 이나 "녹을 먹는 비스코"') }}
|
||||
</form>
|
||||
<form id="program_auto_form">
|
||||
<div id="episode_list"></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<!--전체-->
|
||||
<link
|
||||
href="{{ url_for('.static', filename='css/%s.css' % arg['sub'])
|
||||
}}"
|
||||
type="text/css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="{{ url_for('.static', filename='js/sjva_ui14.js') }}"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
const package_name = "{{arg['package_name'] }}";
|
||||
const sub = "{{arg['sub'] }}";
|
||||
const ohli24_url = "{{arg['ohli24_url']}}";
|
||||
|
||||
|
||||
const params = new Proxy(new URLSearchParams(window.location.search), {
|
||||
get: (searchParams, prop) => searchParams.get(prop),
|
||||
})
|
||||
|
||||
const loader = document.getElementById("preloader");
|
||||
|
||||
const dismissLoadingScreen = function () {
|
||||
loader.style.display = "none";
|
||||
$('.demo').css("display", "none")
|
||||
};
|
||||
|
||||
const wait3seconds = function () {
|
||||
// REFERENCE: https://www.w3schools.com/jsref/met_win_settimeout.asp
|
||||
const result = setTimeout(dismissLoadingScreen, 2000);
|
||||
};
|
||||
|
||||
window.addEventListener("load", wait3seconds);
|
||||
|
||||
|
||||
function findGetParameter(parameterName) {
|
||||
let result = null,
|
||||
tmp = [];
|
||||
const items = location.search.substr(1).split("&");
|
||||
for (let index = 0; index < items.length; index++) {
|
||||
tmp = items[index].split("=");
|
||||
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function analyze(wr_id, bo_table) {
|
||||
// e.preventDefault();
|
||||
const code = document.getElementById("code").value
|
||||
console.log(code)
|
||||
$.ajax({
|
||||
url: '/' + package_name + '/ajax/' + sub + '/analysis',
|
||||
type: "POST",
|
||||
cache: false,
|
||||
data: {code: code, wr_id: wr_id, bo_table: bo_table},
|
||||
dataType: "json",
|
||||
success: function (ret) {
|
||||
if (ret.ret === 'success' && ret.data != null) {
|
||||
// {#console.log(ret.code)#}
|
||||
console.log(ret.data)
|
||||
make_program(ret.data)
|
||||
} else {
|
||||
$.notify('<strong>분석 실패</strong><br>' + ret.log, {type: 'warning'});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function make_program(data) {
|
||||
current_data = data;
|
||||
|
||||
// $("body").css({"background": "url(" + data.poster_url + ")"})
|
||||
|
||||
// console.log('current_data:: ', data)
|
||||
str = "";
|
||||
tmp = '<div class="form-inline w-100">';
|
||||
tmp += m_button("check_download_btn", "선택 다운로드 추가", []);
|
||||
tmp += m_button("all_check_on_btn", "전체 선택", []);
|
||||
tmp += m_button("all_check_off_btn", "전체 해제", []);
|
||||
tmp += m_button("down_subtitle_btn", "자막만 전체 받기", [])
|
||||
tmp +=
|
||||
' <input id="new_title" name="new_title" class="form-control form-control-sm" value="' +
|
||||
data.title +
|
||||
'">';
|
||||
tmp += "</div>";
|
||||
tmp += '<div class="form-inline">';
|
||||
tmp += m_button("apply_new_title_btn", "저장폴더명 변경", []);
|
||||
tmp +=
|
||||
' <input id="new_season" name="new_season" class="form-control form-control-sm" value="' +
|
||||
data.season +
|
||||
'">';
|
||||
tmp += m_button("apply_new_season_btn", "시즌 변경 (숫자만 가능)", []);
|
||||
tmp += m_button("search_tvdb_btn", "TVDB", []);
|
||||
tmp += m_button("add_whitelist", "스케쥴링 추가", []);
|
||||
|
||||
tmp += "</div>";
|
||||
tmp = m_button_group(tmp);
|
||||
str += tmp;
|
||||
// program
|
||||
// str += m_hr_black();
|
||||
str += "<div class='card p-lg-5 mt-md-3 p-md-3 border-light'>"
|
||||
|
||||
str += m_row_start(0);
|
||||
tmp = "";
|
||||
if (data.poster_url != null)
|
||||
tmp = '<img src="' + data.poster_url + '" class="img-fluid">';
|
||||
str += m_col(3, tmp);
|
||||
tmp = "";
|
||||
tmp += m_row_start(0);
|
||||
tmp += m_col(3, "제목", "right");
|
||||
tmp += m_col(9, data.title);
|
||||
tmp += m_row_end();
|
||||
tmp += m_row_start(0);
|
||||
tmp += m_col(3, "시즌", "right");
|
||||
tmp += m_col(9, data.season);
|
||||
tmp += m_row_end();
|
||||
for (i in data.detail) {
|
||||
tmp += m_row_start(0);
|
||||
key = Object.keys(data.detail[i])[0];
|
||||
value = data.detail[i][key];
|
||||
tmp += m_col(3, key, "right");
|
||||
tmp += m_col(9, value);
|
||||
tmp += m_row_end();
|
||||
}
|
||||
|
||||
str += m_col(9, tmp);
|
||||
str += m_row_end();
|
||||
|
||||
// str += m_hr_black();
|
||||
str += "</div>"
|
||||
for (i in data.episode) {
|
||||
str += m_row_start();
|
||||
// tmp = '<img src="' + data.episode[i].image + '" class="img-fluid">'
|
||||
// str += m_col(3, tmp)
|
||||
tmp = "<strong>" + data.episode[i].title + "</strong><span>화. </span>";
|
||||
tmp += data.episode[i].filename + "<br><p></p>";
|
||||
|
||||
tmp += '<div class="form-inline">';
|
||||
tmp +=
|
||||
'<input id="checkbox_' +
|
||||
data.episode[i].code +
|
||||
'" name="checkbox_' +
|
||||
data.episode[i].code +
|
||||
'" type="checkbox" checked data-toggle="toggle" data-on="선 택" data-off="-" data-onstyle="success" data-offstyle="danger" data-size="small"> ';
|
||||
// tmp += m_button('add_queue_btn', '다운로드 추가', [{'key': 'code', 'value': data.episode[i].code}])
|
||||
tmp += m_button("add_queue_btn", "다운로드 추가", [
|
||||
{key: "idx", value: i},
|
||||
]);
|
||||
tmp += j_button('insert_download_btn', '다운로드 추가', {
|
||||
code: data.episode[i]._id,
|
||||
});
|
||||
tmp += j_button(
|
||||
'force_insert_download_btn',
|
||||
'다운로드 추가 (DB무시)',
|
||||
{code: data.episode[i]._id}
|
||||
);
|
||||
// tmp += '<button id="play_video" name="play_video" class="btn btn-sm btn-outline-primary" data-idx="'+i+'">바로보기</button>';
|
||||
tmp += "</div>";
|
||||
str += m_col(12, tmp);
|
||||
str += m_row_end();
|
||||
if (i != data.length - 1) str += m_hr(0);
|
||||
}
|
||||
document.getElementById("episode_list").innerHTML = str;
|
||||
$('input[id^="checkbox_"]').bootstrapToggle();
|
||||
}
|
||||
|
||||
$(function () {
|
||||
console.log(params.wr_id)
|
||||
console.log(findGetParameter('wr_id'))
|
||||
console.log(params.code)
|
||||
if (params.code === '') {
|
||||
|
||||
} else {
|
||||
document.getElementById("code").value = params.code
|
||||
// {#document.getElementById("analysis_btn").click();#}
|
||||
}
|
||||
|
||||
if ("{{arg['ohli24_current_code']}}" !== "") {
|
||||
if (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)
|
||||
document.getElementById("code").value = params.code
|
||||
|
||||
analyze(params.wr_id, params.bo_table)
|
||||
// document.getElementById("analysis_btn").click();
|
||||
// $('#analysis_btn').trigger('click')
|
||||
}
|
||||
// 값이 공백이 아니면 분석 버튼 계속 누름
|
||||
// {#document.getElementById("analysis_btn").click();#}
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
console.log('wr_id::', params.wr_id)
|
||||
|
||||
});
|
||||
|
||||
$("#analysis_btn").unbind("click").bind('click', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation()
|
||||
const code = document.getElementById("code").value
|
||||
console.log(code)
|
||||
$.ajax({
|
||||
url: '/' + package_name + '/ajax/' + sub + '/analysis',
|
||||
type: "POST",
|
||||
cache: false,
|
||||
data: {code: code},
|
||||
dataType: "json",
|
||||
success: function (ret) {
|
||||
if (ret.ret === 'success' && ret.data != null) {
|
||||
// {#console.log(ret.code)#}
|
||||
console.log(ret.data)
|
||||
make_program(ret.data)
|
||||
} else {
|
||||
$.notify('<strong>분석 실패</strong><br>' + ret.log, {type: 'warning'});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$("body").on('click', '#go_ohli24_btn', function (e) {
|
||||
e.preventDefault();
|
||||
window.open("{{arg['ohli24_url']}}", "_blank");
|
||||
});
|
||||
|
||||
$("body").on('click', '#all_check_on_btn', function (e) {
|
||||
e.preventDefault();
|
||||
$('input[id^="checkbox_"]').bootstrapToggle('on')
|
||||
});
|
||||
|
||||
$("body").on('click', '#all_check_off_btn', function (e) {
|
||||
e.preventDefault();
|
||||
$('input[id^="checkbox_"]').bootstrapToggle('off')
|
||||
});
|
||||
|
||||
$("body").on('click', '#add_queue_btn', function (e) {
|
||||
e.preventDefault();
|
||||
data = current_data.episode[$(this).data('idx')];
|
||||
console.log('data:::>', data)
|
||||
$.ajax({
|
||||
url: '/' + package_name + '/ajax/' + sub + '/add_queue',
|
||||
type: "POST",
|
||||
cache: false,
|
||||
data: {data: JSON.stringify(data)},
|
||||
dataType: "json",
|
||||
success: function (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') {
|
||||
$.notify('<strong>이미 큐에 있습니다. 삭제 후 추가하세요.</strong>', {type: 'warning'});
|
||||
} else if (data.ret == 'db_completed') {
|
||||
$.notify('<strong>DB에 완료 기록이 있습니다.</strong>', {type: 'warning'});
|
||||
} else {
|
||||
$.notify('<strong>추가 실패</strong><br>' + ret.log, {type: 'warning'});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$("body").on('click', '#check_download_btn', function (e) {
|
||||
e.preventDefault();
|
||||
all = $('input[id^="checkbox_"]');
|
||||
let data = [];
|
||||
let idx;
|
||||
for (let i in all) {
|
||||
if (all[i].checked) {
|
||||
idx = parseInt(all[i].id.split('_')[1])
|
||||
data.push(current_data.episode[idx]);
|
||||
}
|
||||
}
|
||||
if (data.length == 0) {
|
||||
$.notify('<strong>선택하세요.</strong>', {type: 'warning'});
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
url: '/' + package_name + '/ajax/' + sub + '/add_queue_checked_list',
|
||||
type: "POST",
|
||||
cache: false,
|
||||
data: {data: JSON.stringify(data)},
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
$.notify('<strong>백그라운드로 작업을 추가합니다.</strong>', {type: 'success'});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
#anime_downloader_wrapper {
|
||||
font-family: NanumSquareNeo, system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, Noto Sans, Liberation Sans, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
|
||||
}
|
||||
|
||||
body {
|
||||
background-image: linear-gradient(90deg, #33242c, #263341, #17273a);
|
||||
|
||||
}
|
||||
|
||||
#anime_downloader_wrapper {
|
||||
|
||||
color: #d6eaf8;
|
||||
}
|
||||
|
||||
button.code-button {
|
||||
min-width: 82px !important;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
|
||||
[data-tooltip-text]:hover {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
[data-tooltip-text]:after {
|
||||
-webkit-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
||||
-moz-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
||||
transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
||||
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
|
||||
-webkit-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
|
||||
-moz-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
|
||||
box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
|
||||
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
margin-bottom: 10px;
|
||||
padding: 7px 12px;
|
||||
position: absolute;
|
||||
width: auto;
|
||||
min-width: 50px;
|
||||
max-width: 300px;
|
||||
word-wrap: break-word;
|
||||
|
||||
z-index: 9999;
|
||||
|
||||
opacity: 0;
|
||||
left: -9999px;
|
||||
top: 90%;
|
||||
|
||||
content: attr(data-tooltip-text);
|
||||
}
|
||||
|
||||
[data-tooltip-text]:hover:after {
|
||||
top: 230%;
|
||||
left: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[data-tooltip-text]:hover {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
[data-tooltip-text]:after {
|
||||
-webkit-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
||||
-moz-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
||||
transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
||||
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
|
||||
-webkit-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
|
||||
-moz-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
|
||||
box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
|
||||
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
margin-bottom: 10px;
|
||||
padding: 7px 12px;
|
||||
position: absolute;
|
||||
width: auto;
|
||||
min-width: 50px;
|
||||
max-width: 300px;
|
||||
word-wrap: break-word;
|
||||
|
||||
z-index: 9999;
|
||||
|
||||
opacity: 0;
|
||||
left: -9999px;
|
||||
top: -210% !important;
|
||||
|
||||
content: attr(data-tooltip-text);
|
||||
}
|
||||
|
||||
[data-tooltip-text]:hover:after {
|
||||
top: 130%;
|
||||
left: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: none;
|
||||
box-shadow: inset 1px 1px hsl(0deg 0% 100% / 20%), inset -1px -1px hsl(0deg 0% 100% / 10%), 1px 3px 24px -1px rgb(0 0 0 / 15%);
|
||||
background-color: transparent;
|
||||
background-image: linear-gradient(125deg, hsla(0, 0%, 100%, .3), hsla(0, 0%, 100%, .2) 70%);
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
.card.border-light {
|
||||
border-radius: 30px 10px;
|
||||
--bs-border-opacity: 1;
|
||||
border-color: rgba(var(--bs-light-rgb), var(--bs-border-opacity)) !important;
|
||||
}
|
||||
|
||||
#airing_list {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cut-text {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#screen_movie_list {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/*@import url(https://fonts.googleapis.com/css?family=Lato);*/
|
||||
/*a {*/
|
||||
/* position: fixed;*/
|
||||
/* bottom: 2%;*/
|
||||
/* display: block;*/
|
||||
/* text-align: center;*/
|
||||
/* color: #0fa;*/
|
||||
/* font-family: "Lato", sans-serif;*/
|
||||
/* text-decoration: none !important;*/
|
||||
/* width: 100%;*/
|
||||
/*}*/
|
||||
|
||||
/*body, html {*/
|
||||
/* width: 100%;*/
|
||||
/* height: 100%;*/
|
||||
/* overflow: hidden;*/
|
||||
/*}*/
|
||||
|
||||
/*body {*/
|
||||
/* background: linear-gradient(90deg, #00b377, #00d68f);*/
|
||||
/* box-shadow: inset 0px 0px 90px rgba(0, 0, 0, 0.5);*/
|
||||
/* margin: 0px;*/
|
||||
/* padding: 0px;*/
|
||||
/*}*/
|
||||
|
||||
.demo {
|
||||
width: 100px;
|
||||
height: 102px;
|
||||
border-radius: 100%;
|
||||
position: absolute;
|
||||
top: 45%;
|
||||
left: calc(50% - 50px);
|
||||
}
|
||||
|
||||
.circle {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.circle .inner {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 100%;
|
||||
border: 5px solid rgba(0, 255, 170, 0.7);
|
||||
border-right: none;
|
||||
border-top: none;
|
||||
backgroudn-clip: padding;
|
||||
box-shadow: inset 0px 0px 10px rgba(0, 255, 170, 0.15);
|
||||
}
|
||||
|
||||
@-webkit-keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.circle:nth-of-type(0) {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
.circle:nth-of-type(0) .inner {
|
||||
-webkit-animation: spin 2s infinite linear;
|
||||
animation: spin 2s infinite linear;
|
||||
}
|
||||
|
||||
.circle:nth-of-type(1) {
|
||||
transform: rotate(70deg);
|
||||
}
|
||||
|
||||
.circle:nth-of-type(1) .inner {
|
||||
-webkit-animation: spin 2s infinite linear;
|
||||
animation: spin 2s infinite linear;
|
||||
}
|
||||
|
||||
.circle:nth-of-type(2) {
|
||||
transform: rotate(140deg);
|
||||
}
|
||||
|
||||
.circle:nth-of-type(2) .inner {
|
||||
-webkit-animation: spin 2s infinite linear;
|
||||
animation: spin 2s infinite linear;
|
||||
}
|
||||
|
||||
.demo {
|
||||
-webkit-animation: spin 5s infinite linear;
|
||||
animation: spin 5s infinite linear;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
background: radial-gradient(#222, #000);
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
/*position: fixed;*/
|
||||
right: 0;
|
||||
/*top: 0;*/
|
||||
z-index: 99999;
|
||||
opacity: 0.5;
|
||||
margin: 0 auto;
|
||||
transform: translate(-50%, -50%);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
|
||||
}
|
||||
|
||||
.circle {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.circle .inner {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 100%;
|
||||
border: 5px solid rgba(0, 255, 170, 0.7);
|
||||
border-right: none;
|
||||
border-top: none;
|
||||
backgroudn-clip: padding;
|
||||
box-shadow: inset 0px 0px 10px rgba(0, 255, 170, 0.15);
|
||||
}
|
||||
|
||||
.loader-inner {
|
||||
bottom: 0;
|
||||
height: 60px;
|
||||
left: 0;
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
#preloader {
|
||||
/*background-color: green;*/
|
||||
/*color: white;*/
|
||||
/*height: 100vh;*/
|
||||
/*width: 100%;*/
|
||||
/*position: fixed;*/
|
||||
/*z-index: 100;*/
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
background: radial-gradient(#222, #000);
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 99999;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
1183
templates/anime_downloader_linkkf_search.html
Normal file
1183
templates/anime_downloader_linkkf_search.html
Normal file
File diff suppressed because it is too large
Load Diff
68
templates/anime_downloader_linkkf_setting.html
Normal file
68
templates/anime_downloader_linkkf_setting.html
Normal file
@@ -0,0 +1,68 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div>
|
||||
{{ macros.m_button_group([['global_setting_save_btn', '설정 저장']])}}
|
||||
{{ macros.m_row_start('5') }}
|
||||
{{ macros.m_row_end() }}
|
||||
<nav>
|
||||
{{ macros.m_tab_head_start() }}
|
||||
{{ macros.m_tab_head2('normal', '일반', true) }}
|
||||
{{ macros.m_tab_head2('auto', '홈화면 자동', false) }}
|
||||
{{ macros.m_tab_head2('action', '기타', false) }}
|
||||
{{ macros.m_tab_head_end() }}
|
||||
</nav>
|
||||
<form id="setting">
|
||||
<div class="tab-content" id="nav-tabContent">
|
||||
{{ macros.m_tab_content_start('normal', true) }}
|
||||
{{ macros.setting_input_text_and_buttons('linkkf_url', 'linkkf URL', [['go_btn', 'GO']], value=arg['linkkf_url']) }}
|
||||
{{ macros.setting_input_text('linkkf_download_path', '저장 폴더', value=arg['linkkf_download_path'], desc='정상적으로 다운 완료 된 파일이 이동할 폴더 입니다. ') }}
|
||||
{{ macros.setting_input_int('linkkf_max_ffmpeg_process_count', '동시 다운로드 수', value=arg['linkkf_max_ffmpeg_process_count'], desc='동시에 다운로드 할 에피소드 갯수입니다.') }}
|
||||
{{ macros.setting_checkbox('linkkf_order_desc', '요청 화면 최신순 정렬', value=arg['linkkf_order_desc'], desc='On : 최신화부터, Off : 1화부터') }}
|
||||
{{ macros.setting_checkbox('linkkf_auto_make_folder', '제목 폴더 생성', value=arg['linkkf_auto_make_folder'], desc='제목으로 폴더를 생성하고 폴더 안에 다운로드합니다.') }}
|
||||
<div id="linkkf_auto_make_folder_div" class="collapse">
|
||||
{{ macros.setting_input_text('linkkf_finished_insert', '완결 표시', col='3', value=arg['linkkf_finished_insert'], desc=['완결된 컨텐츠 폴더명 앞에 넣을 문구입니다.']) }}
|
||||
{{ macros.setting_checkbox('linkkf_auto_make_season_folder', '시즌 폴더 생성', value=arg['linkkf_auto_make_season_folder'], desc=['On : Season 번호 폴더를 만듭니다.']) }}
|
||||
</div>
|
||||
{{ macros.setting_checkbox('linkkf_uncompleted_auto_enqueue', '자동으로 다시 받기', value=arg['linkkf_uncompleted_auto_enqueue'], desc=['On : 플러그인 로딩시 미완료인 항목은 자동으로 다시 받습니다.']) }}
|
||||
{{ macros.m_tab_content_end() }}
|
||||
|
||||
{{ macros.m_tab_content_start('auto', false) }}
|
||||
{{ macros.setting_global_scheduler_sub_button(arg['scheduler'], arg['is_running']) }}
|
||||
{{ macros.setting_input_text('linkkf_interval', '스케쥴링 실행 정보', value=arg['linkkf_interval'], col='3', desc=['Inverval(minute 단위)이나 Cron 설정']) }}
|
||||
{{ macros.setting_checkbox('linkkf_auto_start', '시작시 자동실행', value=arg['linkkf_auto_start'], desc='On : 시작시 자동으로 스케쥴러에 등록됩니다.') }}
|
||||
{{ macros.setting_input_textarea('linkkf_auto_code_list', '자동 다운로드할 작품 코드', desc=['all 입력시 모두 받기', '구분자 | 또는 엔터'], value=arg['linkkf_auto_code_list'], row='10') }}
|
||||
{{ macros.setting_checkbox('linkkf_auto_mode_all', '에피소드 모두 받기', value=arg['linkkf_auto_mode_all'], desc=['On : 이전 에피소드를 모두 받습니다.', 'Off : 최신 에피소드만 받습니다.']) }}
|
||||
{{ macros.m_tab_content_end() }}
|
||||
|
||||
{{ macros.m_tab_content_start('action', false) }}
|
||||
{{ macros.setting_button([['global_one_execute_sub_btn', '1회 실행']], left='1회 실행' ) }}
|
||||
{{ macros.setting_button([['global_reset_db_sub_btn', 'DB 초기화']], left='DB정리' ) }}
|
||||
{{ macros.m_tab_content_end() }}
|
||||
|
||||
</div><!--tab-content-->
|
||||
</form>
|
||||
</div> <!--전체-->
|
||||
|
||||
<script type="text/javascript">
|
||||
var package_name = "{{arg['package_name'] }}";
|
||||
var sub = "{{arg['sub'] }}";
|
||||
var current_data = null;
|
||||
|
||||
|
||||
$(document).ready(function(){
|
||||
use_collapse('linkkf_auto_make_folder');
|
||||
});
|
||||
|
||||
$('#ani365_auto_make_folder').change(function() {
|
||||
use_collapse('linkkf_auto_make_folder');
|
||||
});
|
||||
|
||||
|
||||
$("body").on('click', '#go_btn', function(e){
|
||||
e.preventDefault();
|
||||
let url = document.getElementById("linkkf_url").value
|
||||
window.open(url, "_blank");
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
File diff suppressed because it is too large
Load Diff
605
test.ipynb
Normal file
605
test.ipynb
Normal file
File diff suppressed because one or more lines are too long
94
test.py
Normal file
94
test.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from playwright.sync_api import sync_playwright
|
||||
from playwright.async_api import async_playwright
|
||||
|
||||
# from playwright_stealth import stealth_sync
|
||||
import asyncio
|
||||
import html_to_json
|
||||
|
||||
|
||||
async def run(playwright):
|
||||
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
|
||||
"Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
|
||||
"Referer": "https://anilife.live/",
|
||||
# "Cookie": "SPSI=ef307b8c976fac3363cdf420c9ca40a9; SPSE=+PhK0/uGUBMCZIgXplNjzqW3K2kXLybiElDTtOOiboHiBXO7Tp/9roMW7FplGZuGCUo3i4Fwx5VIUG57Zj6VVw==; anilife_csrf=b1eb92529839d7486169cd91e4e60cd2; UTGv2=h45f897818578a5664b31004b95a9992d273; _ga=GA1.1.281412913.1662803695; _ga_56VYJJ7FTM=GS1.1.1662803695.1.0.1662803707.0.0.0; DCST=pE9; DSR=w2XdPUpwLWDqkLpWXfs/5TiO4mtNv5O3hqNhEr7GP1kFoRBBzbFRpR+xsJd9A+E29M+we7qIvJxQmHQTjDNLuQ==; DCSS=696763EB4EA5A67C4E39CFA510FE36F19B0912C; DGCC=RgP; spcsrf=8a6b943005d711258f2f145a8404d873; sp_lit=F9PWLXyxvZbOyk3eVmtTlg==; PRLST=wW; adOtr=70fbCc39867"
|
||||
# "Cookie": ""
|
||||
# "Cookie": "_ga=GA1.1.578607927.1660813724; __gads=ID=10abb8b98b6828ae-2281c943a9d500fd:T=1660813741:RT=1660813741:S=ALNI_MYU_iB2lBgSrEQUBwhKpNsToaqQ8A; SL_G_WPT_TO=ko; SL_GWPT_Show_Hide_tmp=1; SL_wptGlobTipTmp=1; SPSI=944c237cdd8606d80e5e330a0f332d03; SPSE=itZcXMDuso0ktWnDkV2G0HVwWEctCgDjrcFMlEQ5C745wqvp1pEEddrsAsjPUBjl6/8+9Njpq1IG3wt/tVag7w==; sbtsck=jav9aILa6Ofn0dEQr5DhDq5rpbd1JUoNgKwxBpZrqYd+CM=; anilife_csrf=54ee9d15c87864ee5e2538a63d894ad6; UTGv2=h46b326af644f4ac5d0eb1502881136b3750; DCST=pE9; __gpi=UID=000008ba227e99e0:T=1660813741:RT=1661170429:S=ALNI_MaJHIVJIGpQ5nTE9lvypKQxJnn10A; DSR=GWyTLTvSMF/lQD77ojQkGyl+7JvTudkSwV1GKeNVUcWEBa/msln9zzsBj7lj+89ywSRBM34Ol73AKf+KHZ9bZA==; DCSS=9D44115EC4CE12CADB88A005DC65A3CD74A211E; DGCC=zdV; spcsrf=fba136251afc6b5283109fc920322c70; sp_lit=kw0Xkp66eQ7bV0f0tNClhg==; PRLST=gt; adOtr=2C4H9c4d78d; _ga_56VYJJ7FTM=GS1.1.1661168661.18.1.1661173389.0.0.0",
|
||||
}
|
||||
useragent = {
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, "
|
||||
"like Gecko) Chrome/96.0.4664.110 Whale/3.12.129.46 Safari/537.36"
|
||||
}
|
||||
|
||||
browser = await playwright.webkit.launch(headless=False)
|
||||
# context = browser.new_context(
|
||||
# user_agent=ua,
|
||||
# )
|
||||
|
||||
# url = "https://anilife.live/h/live?p=7ccd9e49-9f59-4976-b5d8-25725d6a6188&a=none&player=jawcloud"
|
||||
url = "https://api-svr-01.anilife.live/m3u8/st/MDk5NzUyNjY3NTkwZTc3ZmYwMGRmNGIyMzk3MGZiNzU1YjBkNjk2YTFiMzJiZTVhZWZjYjg3NGY4YmE3NTkyMDRkNTU1Y2RjMDhkZTkwNWZiMzZiMTI3ZjE5Zjk0YzQ3MjgzYmUxMTIzZTM2OTllMWZlMzZjM2I1OTIxMmNkNmZmODUxOWZhY2JiMzUxYmE4ZjVjOTMyNzFiYzA0YWI1OTNjZWU0NzMwOTJmYTA4NGU1ZDM1YTlkODA5NzljOTMxNTVhYjlmMmQwMWIwOGMyMTg1N2UyOWJjYjZjN2UwNzJkNjBiOGQzNzc4NTZlZjlkNTQwMDQ5MjgyOGQzYjQxN2M1YmIzYmZiYWYwNGQ0M2U5YmIwMjc4NjgyN2I4M2M1ZDFjOWUxMjM3MjViZDJlZDM3MGI0ZmJkNDE2MThhYTY2N2JlZDllNjQwNTg4MGIxZjBmYTYzMTU4ZTJlZmI1Zg==/dKtKWqgJFnmS-1XShKtsaJWn_OMY1F_HdGDxH2w38mQ/1662826054"
|
||||
#
|
||||
# if referer is not None:
|
||||
# LogicAniLife.headers["Referer"] = referer
|
||||
|
||||
# context = browser.new_context(extra_http_headers=LogicAniLife.headers)
|
||||
# context = await browser.new_context()
|
||||
context = await browser.new_context(extra_http_headers=headers)
|
||||
# LogicAniLife.headers["Cookie"] = cookie_value
|
||||
|
||||
# context.set_extra_http_headers(LogicAniLife.headers)
|
||||
|
||||
page = await context.new_page()
|
||||
|
||||
# page.on("request", set_cookie)
|
||||
# stealth_sync(page)
|
||||
await page.goto(url, wait_until="networkidle")
|
||||
await page.wait_for_timeout(2000)
|
||||
# time.sleep(1)
|
||||
# page.reload()
|
||||
|
||||
# time.sleep(10)
|
||||
cookies = context.cookies
|
||||
# print(cookies)
|
||||
|
||||
# print(page.content())
|
||||
# vod_url = await page.evaluate(
|
||||
# """() => {
|
||||
# return console.log(vodUrl_1080p) }"""
|
||||
# )
|
||||
# vod_url1 = await page.evaluate(
|
||||
# """async () =>{
|
||||
# return _0x55265f(0x99) + alJson[_0x55265f(0x91)]
|
||||
# }"""
|
||||
# )
|
||||
# print(vod_url)
|
||||
# print(vod_url1)
|
||||
html_content = await page.content()
|
||||
# print(await page.content())
|
||||
# print(f"html_content:: {html_content}")
|
||||
output_json = html_to_json.convert(html_content)
|
||||
print(output_json)
|
||||
print(f"output_json:: {output_json['html'][0]['body'][0]['_value']}")
|
||||
|
||||
|
||||
async def main():
|
||||
async with async_playwright() as p:
|
||||
await run(p)
|
||||
|
||||
|
||||
from loguru import logger
|
||||
import snoop
|
||||
|
||||
|
||||
class Calc:
|
||||
@staticmethod
|
||||
# @logger.catch()
|
||||
@snoop
|
||||
def add(a, b):
|
||||
return a + b
|
||||
|
||||
|
||||
cal = Calc()
|
||||
cal.add(1, 2) # return 3
|
||||
38
test_sir.py
Normal file
38
test_sir.py
Normal file
@@ -0,0 +1,38 @@
|
||||
import asyncio
|
||||
from playwright.async_api import Playwright, async_playwright
|
||||
|
||||
|
||||
async def run(playwright: Playwright) -> None:
|
||||
browser = await playwright.chromium.launch(headless=False)
|
||||
context = await browser.new_context()
|
||||
# Open new page
|
||||
page = await context.new_page()
|
||||
# Go to https://sir.kr/
|
||||
await page.goto("https://sir.kr/")
|
||||
await asyncio.sleep(1)
|
||||
# Click [placeholder="아이디"]
|
||||
await page.locator('[placeholder="아이디"]').click()
|
||||
# Fill [placeholder="아이디"]
|
||||
await page.locator('[placeholder="아이디"]').fill("tongki77")
|
||||
# Press Tab
|
||||
await page.locator('[placeholder="아이디"]').press("Tab")
|
||||
# Fill [placeholder="비밀번호"]
|
||||
await page.locator('[placeholder="비밀번호"]').fill("sir98766")
|
||||
# Click input:has-text("로그인")
|
||||
await page.locator('input:has-text("로그인")').click()
|
||||
# await expect(page).to_have_url("https://sir.kr/")
|
||||
# Click text=출석 2
|
||||
await asyncio.sleep(2)
|
||||
await page.locator("text=출석 2").click()
|
||||
await asyncio.sleep(2)
|
||||
# ---------------------
|
||||
await context.close()
|
||||
await browser.close()
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
async with async_playwright() as playwright:
|
||||
await run(playwright)
|
||||
|
||||
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user