fix: fix decode token problem, decoupling rename and notifi, rss parser and database

This commit is contained in:
EstrellaXD
2023-05-30 18:31:20 +08:00
parent 39dbf09d18
commit 1a15f29442
16 changed files with 202 additions and 183 deletions

View File

@@ -4,6 +4,7 @@ from .status import ProgramStatus
from module.rss import analyser, add_rules
from module.manager import Renamer, eps_complete
from module.network import PostNotification
from module.conf import settings
@@ -48,7 +49,7 @@ class RenameThread(ProgramStatus):
def rename_loop(self):
while not self.stop_event.is_set():
with Renamer() as renamer:
renamer.rename()
renamed_info = renamer.rename()
self.stop_event.wait(settings.program.rename_time)
def rename_start(self):

View File

@@ -47,7 +47,6 @@ class TorrentPath:
def _file_depth(path):
return len(path.split(path.sep))
@staticmethod
def is_ep(self, path):
return self._file_depth(path) <= 2

View File

@@ -3,10 +3,10 @@ import logging
from module.downloader import DownloadClient
from module.parser import TitleParser
from module.network import PostNotification
# from module.network import PostNotification
from module.models import SubtitleFile, EpisodeFile, Notification
from module.conf import settings
from module.database import BangumiDatabase
# from module.database import BangumiDatabase
logger = logging.getLogger(__name__)
@@ -47,23 +47,23 @@ class Renamer(DownloadClient):
logger.error(f"[Renamer] Unknown rename method: {method}")
return file_info.media_path
@staticmethod
def send_notification(bangumi_name, ep: EpisodeFile):
with BangumiDatabase() as db:
poster_path = db.match_poster(bangumi_name)
poster_link = "https://mikanani.me" + poster_path
n = Notification(
official_title=bangumi_name,
season=ep.season,
episode=ep.episode,
poster_link=poster_link,
)
with PostNotification() as notificator:
status = notificator.send_msg(n)
if status:
logger.info(f"[Renamer] Notification sent: {ep.title} S{ep.season}E{ep.episode}")
else:
logger.warning(f"[Renamer] Notification failed: {ep.title} S{ep.season}E{ep.episode}")
# @staticmethod
# def send_notification(bangumi_name, ep: EpisodeFile):
# with BangumiDatabase() as db:
# poster_path = db.match_poster(bangumi_name)
# poster_link = "https://mikanani.me" + poster_path
# n = Notification(
# official_title=bangumi_name,
# season=ep.season,
# episode=ep.episode,
# poster_link=poster_link,
# )
# with PostNotification() as notificator:
# status = notificator.send_msg(n)
# if status:
# logger.info(f"[Renamer] Notification sent: {ep.title} S{ep.season}E{ep.episode}")
# else:
# logger.warning(f"[Renamer] Notification failed: {ep.title} S{ep.season}E{ep.episode}")
def rename_file(
self,
@@ -87,12 +87,14 @@ class Renamer(DownloadClient):
_hash=_hash, old_path=media_path, new_path=new_path
)
if renamed:
if settings.notification.enable:
self.send_notification(bangumi_name, ep)
return True
logger.warning(f"[Renamer] {media_path} parse failed")
if settings.bangumi_manage.remove_bad_torrent:
self.delete_torrent(hashes=_hash)
# if settings.notification.enable:
# self.send_notification(bangumi_name, ep)
return ep
else:
logger.warning(f"[Renamer] {media_path} parse failed")
if settings.bangumi_manage.remove_bad_torrent:
self.delete_torrent(hashes=_hash)
return None
def rename_collection(
self,
@@ -154,6 +156,7 @@ class Renamer(DownloadClient):
logger.debug("[Renamer] Start rename process.")
rename_method = settings.bangumi_manage.rename_method
torrents_info = self.get_torrent_info()
renamed_info = []
for info in torrents_info:
media_list, subtitle_list = self.check_files(info)
bangumi_name, season = self._path_to_bangumi(info.save_path)
@@ -166,7 +169,9 @@ class Renamer(DownloadClient):
}
# Rename single media file
if len(media_list) == 1:
self.rename_file(media_path=media_list[0], **kwargs)
ep_info = self.rename_file(media_path=media_list[0], **kwargs)
if ep_info:
renamed_info.append(ep_info)
# Rename subtitle file
if len(subtitle_list) > 0:
self.rename_subtitles(subtitle_list=subtitle_list, **kwargs)
@@ -180,11 +185,11 @@ class Renamer(DownloadClient):
else:
logger.warning(f"[Renamer] {info.name} has no media file")
logger.debug("[Renamer] Rename process finished.")
return renamed_info
if __name__ == "__main__":
from module.conf import setup_logger
settings.log.debug_enable = True
setup_logger()
with Renamer() as renamer:

View File

@@ -13,62 +13,77 @@ class TorrentManager(BangumiDatabase):
def __match_torrents_list(data: BangumiData) -> list:
with DownloadClient() as client:
torrents = client.get_torrent_info()
matched_list = []
for torrent in torrents:
if data.save_path == torrent.save_path:
matched_list.append(torrent.hash)
return matched_list
return [torrent.hash for torrent in torrents if torrent.save_path == data.save_path]
def delete_torrents(self, _id: int | str):
data = self.search_one(int(_id))
if isinstance(data, BangumiData):
hash_list = self.__match_torrents_list(data)
with DownloadClient() as client:
client.delete_torrent(hash_list)
def delete_torrents(self, data: BangumiData, client: DownloadClient):
hash_list = self.__match_torrents_list(data)
if hash_list:
client.delete_torrent(hash_list)
logger.info(f"Delete rule and torrents for {data.official_title}")
return {
"status": "success",
"msg": f"Delete torrents for {data.official_title}",
}
else:
return data
return {
"status": "error",
"msg": f"Can't find torrents for {data.official_title}",
}
def delete_rule(self, _id: int | str, file: bool = False):
data = self.search_id(int(_id))
if isinstance(data, BangumiData):
self.delete_one(int(_id))
if file:
self.delete_torrents(data.id)
logger.info(f"Delete {data.official_title} and torrents.")
with DownloadClient() as client:
client.remove_rule(data.rule_name)
self.delete_one(int(_id))
if file:
self.delete_torrents(data, client)
return {
"status": "success",
"msg": f"Delete rule and torrents for {data.official_title}",
}
logger.info(f"Delete rule for {data.official_title}")
return {
"status": "success",
"msg": f"Delete {data.official_title} and torrents.",
"msg": f"Delete rule for {data.official_title}",
}
logger.info(f"Delete {data.official_title}")
return {"status": "success", "msg": f"Delete {data.official_title}"}
else:
return data
return {"status": "error", "msg": f"Can't find id {_id}"}
# data = self.search_id(int(_id))
# if isinstance(data, BangumiData):
# self.delete_one(int(_id))
# if file:
# self.delete_torrents(data)
# logger.info(f"Delete {data.official_title} and torrents.")
# return {
# "status": "success",
# "msg": f"Delete {data.official_title} and torrents.",
# }
# logger.info(f"Delete {data.official_title}")
# return {"status": "success", "msg": f"Delete {data.official_title}"}
# else:
# return data
def disable_rule(self, _id: str | int, file: bool = False):
data = self.search_id(int(_id))
if isinstance(data, BangumiData):
with DownloadClient() as client:
client.remove_rule(data.rule_name)
data.deleted = True
self.update_one(data)
if file:
self.delete_torrents(data.id)
logger.info(f"Delete rule and torrents for {data.official_title}")
data.deleted = True
self.update_one(data)
if file:
self.delete_torrents(data, client)
return {
"status": "success",
"msg": f"Disable rule and delete torrents for {data.official_title}",
}
logger.info(f"Disable rule for {data.official_title}")
return {
"status": "success",
"msg": f"Disable rule and delete torrents for {data.official_title}",
"msg": f"Disable rule for {data.official_title}",
}
logger.info(f"Disable rule for {data.official_title}")
return {
"status": "success",
"msg": f"Disable rule for {data.official_title}",
}
else:
return data
return {"status": "error", "msg": f"Can't find data with id {_id}"}
def enable_rule(self, _id: str | int):
data = self.search_id(int(_id))

View File

@@ -1,2 +1 @@
from .request_contents import RequestContent, TorrentInfo
from .notification import PostNotification

View File

@@ -1,96 +0,0 @@
import logging
from module.network.request_contents import RequestContent
from module.models import Notification
from module.conf import settings
logger = logging.getLogger(__name__)
type = settings.notification.type
token = settings.notification.token
chat_id = settings.notification.chat_id
class TelegramNotification(RequestContent):
def __init__(self):
super().__init__()
self.notification_url = f"https://api.telegram.org/bot{token}/sendMessage"
self.chat_id = chat_id
def post_msg(self, text: str) -> bool:
data = {
"chat_id": self.chat_id,
"text": text,
"disable_notification": True,
}
resp = self.post_data(self.notification_url, data)
logger.debug(f"Telegram notification: {resp.status_code}")
return resp.status_code == 200
class ServerChanNotification(RequestContent):
"""Server酱推送"""
def __init__(self):
super().__init__()
self.notification_url = f"https://sctapi.ftqq.com/{token}.send"
def post_msg(self, text: str) -> bool:
data = {
"title": "AutoBangumi 番剧更新",
"desp": text,
}
resp = self.post_data(self.notification_url, data)
logger.debug(f"ServerChan notification: {resp.status_code}")
return resp.status_code == 200
class BarkNotification(RequestContent):
def __init__(self):
super().__init__()
self.token = token
self.notification_url = "https://api.day.app/push"
def post_msg(self, text) -> bool:
data = {"title": "AutoBangumi 番剧更新", "body": text, "device_key": self.token}
resp = self.post_data(self.notification_url, data)
logger.debug(f"Bark notification: {resp.status_code}")
return resp.status_code == 200
def getClient():
if type.lower() == "telegram":
return TelegramNotification
elif type.lower() == "server-chan":
return ServerChanNotification
elif type.lower() == "bark":
return BarkNotification
else:
return None
class PostNotification(getClient()):
def send_msg(self, info: Notification) -> bool:
text = (
f"番剧名称:{info.official_title}\n"
f"季度: 第{info.season}\n"
f"更新集数: 第{info.episode}\n"
f"{info.poster_link}\n"
)
try:
return self.post_msg(text)
except Exception as e:
logger.warning(f"Failed to send notification: {e}")
return False
if __name__ == "__main__":
info = Notification(
official_title="魔法纪录 魔法少女小圆外传",
season=2,
episode=1,
poster_link="https://mikanani.me/images/Bangumi/202107/3788b33f.jpg",
)
with PostNotification() as client:
client.send_msg(info)

View File

View File

@@ -0,0 +1,50 @@
import logging
from .plugin import *
from module.models import Notification
from module.conf import settings
logger = logging.getLogger(__name__)
type = settings.notification.type
token = settings.notification.token
chat_id = settings.notification.chat_id
def getClient():
if type.lower() == "telegram":
return TelegramNotification
elif type.lower() == "server-chan":
return ServerChanNotification
elif type.lower() == "bark":
return BarkNotification
else:
return None
class PostNotification(getClient()):
def send_msg(self, info: Notification) -> bool:
text = (
f"番剧名称:{info.official_title}\n"
f"季度: 第{info.season}\n"
f"更新集数: 第{info.episode}\n"
f"{info.poster_link}\n"
)
try:
return self.post_msg(text)
except Exception as e:
logger.warning(f"Failed to send notification: {e}")
return False
if __name__ == "__main__":
info = Notification(
official_title="魔法纪录 魔法少女小圆外传",
season=2,
episode=1,
poster_link="https://mikanani.me/images/Bangumi/202107/3788b33f.jpg",
)
with PostNotification() as client:
client.send_msg(info)

View File

@@ -0,0 +1,3 @@
from .bark import BarkNotification
from .server_chan import ServerChanNotification
from .telegram import TelegramNotification

View File

@@ -0,0 +1,11 @@
class BarkNotification(RequestContent):
def __init__(self):
super().__init__()
self.token = token
self.notification_url = "https://api.day.app/push"
def post_msg(self, text) -> bool:
data = {"title": "AutoBangumi 番剧更新", "body": text, "device_key": self.token}
resp = self.post_data(self.notification_url, data)
logger.debug(f"Bark notification: {resp.status_code}")
return resp.status_code == 200

View File

@@ -0,0 +1,15 @@
class ServerChanNotification(RequestContent):
"""Server酱推送"""
def __init__(self):
super().__init__()
self.notification_url = f"https://sctapi.ftqq.com/{token}.send"
def post_msg(self, text: str) -> bool:
data = {
"title": "AutoBangumi 番剧更新",
"desp": text,
}
resp = self.post_data(self.notification_url, data)
logger.debug(f"ServerChan notification: {resp.status_code}")
return resp.status_code == 200

View File

@@ -0,0 +1,11 @@
class BarkNotification(RequestContent):
def __init__(self):
super().__init__()
self.token = token
self.notification_url = "https://api.day.app/push"
def post_msg(self, text) -> bool:
data = {"title": "AutoBangumi 番剧更新", "body": text, "device_key": self.token}
resp = self.post_data(self.notification_url, data)
logger.debug(f"Bark notification: {resp.status_code}")
return resp.status_code == 200

View File

@@ -0,0 +1,17 @@
from module.network.request_contents import RequestContent
class TelegramNotification(RequestContent):
def __init__(self):
super().__init__()
self.notification_url = f"https://api.telegram.org/bot{token}/sendMessage"
self.chat_id = chat_id
def post_msg(self, text: str) -> bool:
data = {
"chat_id": self.chat_id,
"text": text,
"disable_notification": True,
}
resp = self.post_data(self.notification_url, data)
logger.debug(f"Telegram notification: {resp.status_code}")
return resp.status_code == 200

View File

@@ -75,24 +75,13 @@ class RSSAnalyser:
self.official_title_parser(data, mikan_title)
return data
def rss_to_data(self, rss_link: str, full_parse: bool = True) -> list[BangumiData]:
def rss_to_data(self, rss_link: str, database: BangumiDatabase, full_parse: bool = True) -> list[BangumiData]:
rss_torrents = self.get_rss_torrents(rss_link, full_parse)
with BangumiDatabase() as database:
torrents_to_add = database.match_list(rss_torrents, rss_link)
if not torrents_to_add:
logger.debug("[RSS] No new title has been found.")
return []
# New List
new_data = self.torrents_to_data(torrents_to_add, rss_link, full_parse)
if new_data:
if full_parse:
database.insert_list(new_data)
return new_data
def run(self, rss_link: str = settings.rss_link):
logger.info("[RSS] Start collecting RSS info.")
try:
self.rss_to_data(rss_link)
except Exception as e:
logger.debug(f"[RSS] {e}")
logger.error("[RSS] Failed to collect RSS info.")
torrents_to_add = database.match_list(rss_torrents, rss_link)
if not torrents_to_add:
logger.debug("[RSS] No new title has been found.")
return []
# New List
new_data = self.torrents_to_data(torrents_to_add, rss_link, full_parse)
if new_data:
return new_data

View File

@@ -1,7 +1,7 @@
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from .jwt import decode_token
from .jwt import verify_token
from module.database.user import AuthDB
from module.models.user import User
@@ -15,7 +15,7 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
payload = decode_token(token)
payload = verify_token(token)
if not payload:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
@@ -31,7 +31,7 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
async def get_token_data(token: str = Depends(oauth2_scheme)):
payload = decode_token(token)
payload = verify_token(token)
if not payload:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"

View File

@@ -30,8 +30,8 @@ def decode_token(token: str):
if username is None:
return None
return payload
except JWTError as e:
raise e
except JWTError:
return None
def verify_token(token: str):