This commit is contained in:
EstrellaXD
2022-06-17 23:38:59 +08:00
parent feb904ecc3
commit 5fcde6941b
14 changed files with 179 additions and 70 deletions

View File

@@ -13,4 +13,6 @@ ADD ./auto_bangumi /auto_bangumi
ADD ./config /config
ADD ./templates /templates
CMD ["python3", "app.py"]
RUN chmod a+x run.sh
CMD ["./run.sh"]

View File

@@ -7,7 +7,7 @@ import logging
from core import RSSAnalyser
from core import DownloadClient
from conf import settings
from conf import settings, parse
from utils import json_config
logger = logging.getLogger(__name__)
@@ -15,13 +15,13 @@ logger = logging.getLogger(__name__)
app = FastAPI()
templates = Jinja2Templates(directory="templates")
# templates = Jinja2Templates(directory="templates")
@app.get("/", response_class=HTMLResponse)
def index(request: Request):
context = {"request": request}
return templates.TemplateResponse("index.html", context)
# @app.get("/", response_class=HTMLResponse)
# def index(request: Request):
# context = {"request": request}
# return templates.TemplateResponse("index.html", context)
class Config(BaseModel):
@@ -65,13 +65,16 @@ class RSS(BaseModel):
@app.post("/api/v1/subscriptions")
async def receive(link: RSS):
data = RSSAnalyser().rss_to_data(link.link)
from conf.const_dev import DEV_SETTINGS
settings.init(DEV_SETTINGS)
client = DownloadClient()
client.add_collection_feed(link.link, item_path=data["title"])
client.set_rule(data, link.link)
return "Successes"
try:
data = RSSAnalyser().rss_to_data(link.link)
client.add_collection_feed(link.link, item_path=data["official_title"])
client.set_rule(data, link.link)
return data
except Exception as e:
logger.debug(e)
return "Error"
class Search(BaseModel):
@@ -85,5 +88,19 @@ async def search(input: Search):
return "Nothing Happened"
def run():
args = parse()
if args.debug:
try:
from conf.const_dev import DEV_SETTINGS
settings.init(DEV_SETTINGS)
except ModuleNotFoundError:
logger.debug("Please copy `const_dev.py` to `const_dev.py` to use custom settings")
else:
settings.init()
uvicorn.run(app, host="0.0.0.0", port=settings.webui_port)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=settings.webui_port)
run()

View File

@@ -1,13 +1,13 @@
import os
import time
import logging
from multiprocessing import Process
from conf import settings, parse
from conf.log import setup_logger
from utils import json_config
from core import RSSAnalyser, DownloadClient, Renamer
from core import RSSAnalyser, DownloadClient, Renamer, FullSeasonGet
logger = logging.getLogger(__name__)
@@ -20,12 +20,15 @@ def load_data_file():
"data_version": settings.data_version,
"bangumi_info": []
}
logger.info("Building data information...")
else:
bangumi_data = json_config.load(info_path)
if bangumi_data["data_version"] != settings.data_version or bangumi_data["rss_link"] != settings.rss_link:
bangumi_data["bangumi_info"] = []
bangumi_data["data_version"] = settings.data_version
bangumi_data["rss_link"] = settings.rss_link
bangumi_data = {
"rss_link": settings.rss_link,
"data_version": settings.data_version,
"bangumi_info": []
}
logger.info("Rebuilding data information...")
return bangumi_data
@@ -50,15 +53,22 @@ def show_info():
def main_process(bangumi_data, download_client: DownloadClient):
rss_analyser = RSSAnalyser()
rename = Renamer(download_client)
rss_analyser = RSSAnalyser()
first_run = True
while True:
rss_analyser.run(bangumi_data["bangumi_info"], download_client)
save_data_file(bangumi_data)
times = 0
if settings.enable_rss_collector:
rss_analyser.run(bangumi_data["bangumi_info"], download_client)
if settings.eps_complete and first_run:
FullSeasonGet().eps_complete(bangumi_data["bangumi_info"], download_client)
first_run = False
logger.info("Running....")
save_data_file(bangumi_data)
while times < settings.times:
rename.refresh()
rename.run()
if settings.enable_rename:
rename.refresh()
rename.run()
times += 1
time.sleep(settings.sleep_time/settings.times)
@@ -77,7 +87,7 @@ def run():
# 初始化
setup_logger()
show_info()
time.sleep(3)
time.sleep(1)
download_client = DownloadClient()
download_client.init_downloader()
if settings.rss_link is None:

View File

@@ -1,6 +1,6 @@
from .conf import settings, Settings
from .const import BCOLORS
from .const_dev import DEV_SETTINGS
# from .const_dev import DEV_SETTINGS
from .parse import parse
from .log import setup_logger

View File

@@ -1,11 +1,11 @@
# -*- encoding: utf-8 -*-
DEFAULT_SETTINGS = {
"version": "2.5.0-beta2",
"version": "2.5.0-beta10",
"data_version": 4.0,
"host_ip": "localhost:8080",
"sleep_time": 1800,
"times": 10,
"sleep_time": 7200,
"times": 20,
"user_name": "admin",
"password": "adminadmin",
"download_path": "/downloads/Bangumi",
@@ -21,6 +21,11 @@ DEFAULT_SETTINGS = {
"eps_complete": False,
"webui_port": 7892,
"title_language": "zh",
"tmdb_api": "",
"enable_tmdb": False,
"socks": None,
"enable_rss_collector": True,
"enable_rename": True
}
ENV_TO_ATTR = {
@@ -36,13 +41,17 @@ ENV_TO_ATTR = {
"AB_NOT_CONTAIN": "not_contain",
"AB_DEBUG_MODE": ("debug_mode", lambda e: e.lower() in ("true", "1", "t")),
"AB_EP_COMPLETE": (
"enable_eps_complete",
"eps_complete",
lambda e: e.lower() in ("true", "1", "t")
),
"AB_REMOVE_BAD_BT": ("remove_bad_torrent", lambda e: e.lower() in ("true", "1", "t")),
"AB_WEBUI_PORT": ("webui_port", lambda e: int(e)),
"AB_HTTP_PROXY": "http_proxy",
"AB_LANGUAGE": "title_language",
"AB_ENABLE_TMDB": ("enable_tmdb", lambda e: e.lower() in ("true", "1", "t")),
"AB_SOCKS": "socks",
"AB_RENAME": ("enable_rename", lambda e: e.lower() in ("true", "1", "t")),
"AB_RSS_COLLECTOR": ("enable_rss_collector", lambda e: e.lower() in ("true", "1", "t")),
}

View File

@@ -14,13 +14,17 @@ class FullSeasonGet:
self._get_rss = RequestContent()
def init_eps_complete_search_str(self, data: dict):
search_str = re.sub(r"[\W_]", "+",
f"{data['group']} {data['title_raw']} {data['season_raw']} {data['subtitle']} {data['source']} {data['dpi']}")
search_str_pre = ""
for i in [data['group'], data['title_raw'], data['season_raw'], data['subtitle'], data['source'], data['dpi']]:
if i is not None:
search_str_pre += f" {i}"
search_str = re.sub(r"[\W_ ]", "+",
search_str_pre.strip())
return search_str
def get_season_torrents(self, data: dict):
keyword = self.init_eps_complete_search_str(data)
torrents = self._get_rss.get_torrents(f"https://mikanani.me/RSS/Search?str={keyword}")
torrents = self._get_rss.get_torrents(f"https://mikanani.me/RSS/Search?searchstr={keyword}")
return torrents
def collect_season_torrents(self, data: dict):
@@ -28,7 +32,7 @@ class FullSeasonGet:
downloads = []
for torrent in torrents:
download_info = {
"url": torrent["url"],
"url": torrent,
"save_path": os.path.join(
settings.download_path,
data["official_title"],
@@ -39,12 +43,28 @@ class FullSeasonGet:
def eps_complete(self, bangumi_info, download_client: DownloadClient):
for data in bangumi_info:
if data["eps_complete"]:
if data["eps_collect"]:
logger.info(f"Start collecting past episodes of {data['official_title']} Season {data['season']}...")
downloads = self.collect_season_torrents(data)
for download in downloads:
download_client.add_torrent(download)
logger.info("Completed!")
data["eps_complete"] = False
data["eps_collect"] = False
if __name__ == "__main__":
a = FullSeasonGet()
data = {
"official_title": "指名!",
"title_raw": "CUE!",
"season": 1,
"season_raw": "",
"group": "喵萌Production",
"dpi": "1080p",
"source": None,
"subtitle": "简日双语",
"added": True,
"eps_collect": True
}
torrents = a.collect_season_torrents(data)
print(torrents)

View File

@@ -34,11 +34,14 @@ class Renamer:
if PurePath(info.content_path).name != info.content_path \
else PureWindowsPath(info.content_path).parts
path_name = path_parts[-1]
season = int(re.search(r"\d", path_parts[-2]).group())
try:
new_name = self._renamer.download_parser(name, season, settings.method)
logger.debug(f"Origin name: {path_name}")
logger.debug(f"New name: {new_name}")
season = int(re.search(r"\d", path_parts[-2]).group())
except Exception as e:
logger.debug(e)
season = 1
folder_name = path_parts[-3]
try:
new_name = self._renamer.download_parser(name, folder_name, season, settings.method)
if path_name != new_name:
self.client.rename_torrent_file(torrent_hash, path_name, new_name)
self.rename_count += 1
@@ -46,6 +49,7 @@ class Renamer:
continue
except:
logger.warning(f"{path_name} rename failed")
logger.debug(f"origin: {name}")
if settings.remove_bad_torrent:
self.client.delete_torrent(torrent_hash)
self.print_result()

View File

@@ -24,6 +24,7 @@ class RSSAnalyser:
extra_add = True
for d in bangumi_info:
if re.search(d["title_raw"], raw_title) is not None:
logger.debug(f"Had added {d['title_raw']} before")
extra_add = False
break
if extra_add:
@@ -38,8 +39,14 @@ class RSSAnalyser:
return data
def run(self, bangumi_info: list, download_client: DownloadClient):
self.rss_to_datas(bangumi_info)
download_client.add_rules(bangumi_info, rss_link=settings.rss_link)
logger.info("Start collecting RSS info.")
try:
self.rss_to_datas(bangumi_info)
download_client.add_rules(bangumi_info, rss_link=settings.rss_link)
except Exception as e:
logger.debug(e)
logger.info("Connection error.")
logger.info("Finished")
if __name__ == "__main__":

View File

@@ -1,6 +1,8 @@
import time
import requests
import socket
import socks
import logging
from bs4 import BeautifulSoup
@@ -14,13 +16,15 @@ class RequestURL:
def __init__(self):
self.session = requests.session()
if settings.http_proxy is not None:
self.proxy = {
self.session.proxies = {
"https": settings.http_proxy,
"http": settings.http_proxy,
"socks": settings.http_proxy
}
else:
self.proxy = None
elif settings.socks is not None:
socks_info = settings.socks.split(",")
socks.set_default_proxy(socks.SOCKS5, addr=socks_info[0], port=int(socks_info[1]), rdns=True,
username=socks_info[2], password=socks_info[3])
socket.socket = socks.socksocket
self.header = {
"user-agent": "Mozilla/5.0",
"Accept": "application/xml"
@@ -30,11 +34,11 @@ class RequestURL:
times = 0
while times < 5:
try:
req = self.session.get(url=url, headers=self.header, proxies=self.proxy)
req = self.session.get(url=url, headers=self.header)
return req
except Exception as e:
logger.debug(f"URL: {url}")
logger.error("ERROR with DNS/Connection.")
logger.warning("ERROR with DNS/Connection.")
time.sleep(settings.connect_retry_interval)
times += 1
@@ -48,3 +52,11 @@ class RequestURL:
self.session.close()
if __name__ == "__main__":
a = RequestURL()
socks.set_default_proxy(socks.SOCKS5, "192.168.30.2", 19990, True, username="abc", password="abc")
socket.socket = socks.socksocket
b = a.get_url('https://www.themoviedb.org').text
print(b)

View File

@@ -15,14 +15,15 @@ class DownloadParser:
r"(.*)\[第(\d*\.*\d*)話(?:END)?\](.*)",
r"(.*)第(\d*\.*\d*)话(?:END)?(.*)",
r"(.*)第(\d*\.*\d*)話(?:END)?(.*)",
r"(.*)- (\d{1,3}|\d{1,3}\.\d{1,2})(?:v\d{1,2})?(?:END)? (.*)",
r"(.*)- (\d{1,3}|\d{1,3}\.\d{1,2})(?:v\d{1,2})?(?:END)?(.*)",
]
def rename_normal(self, name, season):
for rule in self.rules:
matchObj = re.match(rule, name, re.I)
if matchObj is not None:
new_name = f"{matchObj.group(1).strip()} S{season}E{matchObj.group(2)}{matchObj.group(3)}"
match_obj = re.match(rule, name, re.I)
if match_obj is not None:
title = re.sub(r"([Ss]|Season )\d{1,3}", "", match_obj.group(1)).strip()
new_name = f"{title} S{season}E{match_obj.group(2)}{match_obj.group(3)}"
return new_name
def rename_pn(self, name, season):
@@ -31,26 +32,44 @@ class DownloadParser:
if season < 10:
season = f"0{season}"
for rule in self.rules:
matchObj = re.match(rule, file_name, re.I)
if matchObj is not None:
match_obj = re.match(rule, file_name, re.I)
if match_obj is not None:
title = re.sub(r"([Ss]|Season )\d{1,3}", "", match_obj.group(1)).strip()
new_name = re.sub(
r"[\[\]]",
"",
f"{matchObj.group(1).strip()} S{season}E{matchObj.group(2)}{path.splitext(name)[-1]}",
f"{title} S{season}E{match_obj.group(2)}{path.splitext(name)[-1]}",
)
return new_name
def download_rename(self, name, season, method):
def rename_advance(self, name, folder_name, season):
n = re.split(r"[\[\]()【】()]", name)
file_name = name.replace(f"[{n[1]}]", "")
if season < 10:
season = f"0{season}"
for rule in self.rules:
match_obj = re.match(rule, file_name, re.I)
if match_obj is not None:
new_name = re.sub(
r"[\[\]]",
"",
f"{folder_name} S{season}E{match_obj.group(2)}{path.splitext(name)[-1]}",
)
return new_name
def download_rename(self, name, folder_name, season, method):
if method.lower() == "pn":
return self.rename_pn(name, season)
elif method.lower() == "normal":
return self.rename_normal(name, season)
elif method.lower() == "none":
return name
elif method.lower() == "advance":
return self.rename_advance(name, folder_name, season)
if __name__ == "__main__":
name = "[NC-Raws]间谍过家家 - 09(B-Global 3840x2160 HEVC AAC MKV).mkv"
name = "[NC-Raws]Summer Time Rendering S02 - 09(B-Global 3840x2160 HEVC AAC MKV).mkv"
rename = DownloadParser()
new_name = rename.rename_pn(name, "pn")
new_name = rename.rename_pn(name, 1)
print(new_name)

View File

@@ -16,9 +16,9 @@ class TMDBInfo:
class TMDBMatcher:
def __init__(self):
self.search_url = lambda e: \
f"https://api.themoviedb.org/3/search/tv?api_key={settings.tdmb_api}&page=1&query={e}&include_adult=false"
f"https://api.themoviedb.org/3/search/tv?api_key={settings.tmdb_api}&page=1&query={e}&include_adult=false"
self.info_url = lambda e: \
f"https://api.themoviedb.org/3/tv/{e}?api_key={settings.tdmb_api}&language=zh-CN"
f"https://api.themoviedb.org/3/tv/{e}?api_key={settings.tmdb_api}&language=zh-CN"
self._request = RequestContent()
def is_animation(self, id):

View File

@@ -14,20 +14,24 @@ class TitleParser:
def raw_parser(self, raw):
return self._raw_parser.analyse(raw)
def download_parser(self, download_raw, season, method=settings.method):
return self._download_parser.download_rename(download_raw, season, method)
def download_parser(self, download_raw, folder_name, season, method=settings.method):
return self._download_parser.download_rename(download_raw, folder_name, season, method)
def return_dict(self, raw):
tmdb = TMDBMatcher()
try:
episode = self.raw_parser(raw)
try:
tmdb_info = tmdb.tmdb_search(episode.title)
official_title = tmdb_info.title_zh if settings.title_language == "zh" else tmdb_info.title_jp
season = tmdb_info.last_season
except Exception as e:
logger.debug(e)
logger.info("Not Match in TMDB")
if settings.enable_tmdb:
try:
tmdb_info = tmdb.tmdb_search(episode.title)
official_title = tmdb_info.title_zh if settings.title_language == "zh" else tmdb_info.title_jp
season = tmdb_info.last_season
except Exception as e:
logger.debug(e)
logger.info("Not Match in TMDB")
official_title = episode.title
season = episode.season_info.number
else:
official_title = episode.title
season = episode.season_info.number
data = {

4
auto_bangumi/run.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
exec python3 app.py &
exec python3 api.py

View File

@@ -1,6 +1,7 @@
qbittorrent-api
bs4
requests~=2.27.1
requests==2.28.0
pysocks
lxml
setuptools~=62.1.0