add 站点图标缓存

This commit is contained in:
jxxghp 2023-06-12 11:16:37 +08:00
parent e10776cf1d
commit a111c1dea9
13 changed files with 110 additions and 65 deletions

View File

@ -6,6 +6,7 @@ from lxml import etree
from app.chain import ChainBase from app.chain import ChainBase
from app.core.config import settings from app.core.config import settings
from app.db.siteicons import SiteIcons
from app.db.sites import Sites from app.db.sites import Sites
from app.helper.cookiecloud import CookieCloudHelper from app.helper.cookiecloud import CookieCloudHelper
from app.helper.sites import SitesHelper from app.helper.sites import SitesHelper
@ -21,6 +22,7 @@ class CookieCloudChain(ChainBase):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.sites = Sites() self.sites = Sites()
self.siteicons = SiteIcons()
self.siteshelper = SitesHelper() self.siteshelper = SitesHelper()
self.cookiecloud = CookieCloudHelper( self.cookiecloud = CookieCloudHelper(
server=settings.COOKIECLOUD_HOST, server=settings.COOKIECLOUD_HOST,
@ -60,7 +62,7 @@ class CookieCloudChain(ChainBase):
cookie=cookie, cookie=cookie,
ua=settings.USER_AGENT) ua=settings.USER_AGENT)
if icon_url: if icon_url:
self.sites.update_icon(name=indexer.get("name"), self.siteicons.update_icon(name=indexer.get("name"),
domain=domain, domain=domain,
icon_url=icon_url, icon_url=icon_url,
icon_base64=icon_base64) icon_base64=icon_base64)

View File

@ -86,7 +86,7 @@ class UserMessageChain(ChainBase):
mediainfo=self._current_media) mediainfo=self._current_media)
if exist_flag: if exist_flag:
self.post_message(title=f"{self._current_media.get_title_string()}" self.post_message(title=f"{self._current_media.get_title_string()}"
f"{self._current_meta.get_season_string()} 媒体库中已存在", f"{self._current_meta.get_season()} 媒体库中已存在",
userid=userid) userid=userid)
return return
# 发送缺失的媒体信息 # 发送缺失的媒体信息
@ -106,7 +106,7 @@ class UserMessageChain(ChainBase):
if not contexts: if not contexts:
# 没有数据 # 没有数据
self.post_message(title=f"{mediainfo.title}" self.post_message(title=f"{mediainfo.title}"
f"{self._current_meta.get_season_string()} 未搜索到资源!", f"{self._current_meta.get_season()} 未搜索到资源!",
userid=userid) userid=userid)
return return
# 搜索结果排序 # 搜索结果排序
@ -142,7 +142,7 @@ class UserMessageChain(ChainBase):
mediainfo=self._current_media) mediainfo=self._current_media)
if exist_flag: if exist_flag:
self.post_message(title=f"{self._current_media.get_title_string()}" self.post_message(title=f"{self._current_media.get_title_string()}"
f"{self._current_meta.get_season_string()} 媒体库中已存在", f"{self._current_meta.get_season()} 媒体库中已存在",
userid=userid) userid=userid)
return return
# 批量下载 # 批量下载

View File

@ -1,4 +1,4 @@
from typing import Union, Optional from typing import Union, Optional, List
import cn2an import cn2an
import regex as re import regex as re
@ -66,7 +66,7 @@ class MetaBase(object):
self.subtitle = subtitle self.subtitle = subtitle
self.isfile = isfile self.isfile = isfile
def get_name(self): def get_name(self) -> str:
""" """
返回名称 返回名称
""" """
@ -181,7 +181,7 @@ class MetaBase(object):
self.type = MediaType.TV self.type = MediaType.TV
self._subtitle_flag = True self._subtitle_flag = True
def is_in_season(self, season: Union[list, int, str]): def is_in_season(self, season: Union[list, int, str]) -> bool:
""" """
是否包含季 是否包含季
""" """
@ -204,7 +204,7 @@ class MetaBase(object):
else: else:
return int(season) == 1 return int(season) == 1
def is_in_episode(self, episode: Union[list, int, str]): def is_in_episode(self, episode: Union[list, int, str]) -> bool:
""" """
是否包含集 是否包含集
""" """
@ -220,9 +220,9 @@ class MetaBase(object):
else: else:
return int(episode) == self.begin_episode return int(episode) == self.begin_episode
def get_season_string(self): def get_season_string(self) -> str:
""" """
返回季字符串 返回季字符串确定是剧集没有季的返回S01
""" """
if self.begin_season is not None: if self.begin_season is not None:
return "S%s" % str(self.begin_season).rjust(2, "0") \ return "S%s" % str(self.begin_season).rjust(2, "0") \
@ -236,7 +236,16 @@ class MetaBase(object):
else: else:
return "S01" return "S01"
def get_season_item(self): def get_season(self) -> str:
"""
返回季字符串确定是剧集没有季的返回空
"""
if self.begin_season is not None:
return self.get_season_string()
else:
return "S01"
def get_begin_season_string(self) -> str:
""" """
返回begin_season 的Sxx 返回begin_season 的Sxx
""" """
@ -248,9 +257,9 @@ class MetaBase(object):
else: else:
return "S01" return "S01"
def get_season_seq(self): def get_season_seq(self) -> str:
""" """
返回begin_season 的数字 返回begin_season 的数字电视剧没有季的返回1
""" """
if self.begin_season is not None: if self.begin_season is not None:
return str(self.begin_season) return str(self.begin_season)
@ -260,7 +269,7 @@ class MetaBase(object):
else: else:
return "1" return "1"
def get_season_list(self): def get_season_list(self) -> List[int]:
""" """
返回季的数组 返回季的数组
""" """
@ -309,7 +318,7 @@ class MetaBase(object):
self.end_episode = None self.end_episode = None
# #
def get_episode_string(self): def get_episode_string(self) -> str:
""" """
返回集字符串 返回集字符串
""" """
@ -323,7 +332,7 @@ class MetaBase(object):
else: else:
return "" return ""
def get_episode_list(self): def get_episode_list(self) -> List[int]:
""" """
返回集的数组 返回集的数组
""" """
@ -334,13 +343,13 @@ class MetaBase(object):
else: else:
return [self.begin_episode] return [self.begin_episode]
def get_episode_items(self): def get_episode_strings(self) -> str:
""" """
返回集的并列表达方式用于支持单文件多集 返回集的并列表达方式用于支持单文件多集
""" """
return "E%s" % "E".join(str(episode).rjust(2, '0') for episode in self.get_episode_list()) return "E%s" % "E".join(str(episode).rjust(2, '0') for episode in self.get_episode_list())
def get_episode_seqs(self): def get_episode_seqs(self) -> str:
""" """
返回单文件多集的集数表达方式用于支持单文件多集 返回单文件多集的集数表达方式用于支持单文件多集
""" """
@ -354,7 +363,7 @@ class MetaBase(object):
else: else:
return "" return ""
def get_episode_seq(self): def get_episode_seq(self) -> str:
""" """
返回begin_episode 的数字 返回begin_episode 的数字
""" """
@ -364,7 +373,7 @@ class MetaBase(object):
else: else:
return "" return ""
def get_season_episode_string(self): def get_season_episode_string(self) -> str:
""" """
返回季集字符串 返回季集字符串
""" """
@ -381,7 +390,7 @@ class MetaBase(object):
return "%s" % episode return "%s" % episode
return "" return ""
def get_resource_type_string(self): def get_resource_type_string(self) -> str:
""" """
返回资源类型字符串含分辨率 返回资源类型字符串含分辨率
""" """
@ -394,7 +403,7 @@ class MetaBase(object):
ret_string = f"{ret_string} {self.resource_pix}" ret_string = f"{ret_string} {self.resource_pix}"
return ret_string return ret_string
def get_edtion_string(self): def get_edtion_string(self) -> str:
""" """
返回资源类型字符串不含分辨率 返回资源类型字符串不含分辨率
""" """
@ -405,7 +414,7 @@ class MetaBase(object):
ret_string = f"{ret_string} {self.resource_effect}" ret_string = f"{ret_string} {self.resource_effect}"
return ret_string.strip() return ret_string.strip()
def get_resource_team_string(self): def get_resource_team_string(self) -> str:
""" """
返回发布组/字幕组字符串 返回发布组/字幕组字符串
""" """
@ -414,13 +423,13 @@ class MetaBase(object):
else: else:
return "" return ""
def get_video_encode_string(self): def get_video_encode_string(self) -> str:
""" """
返回视频编码 返回视频编码
""" """
return self.video_encode or "" return self.video_encode or ""
def get_audio_encode_string(self): def get_audio_encode_string(self) -> str:
""" """
返回音频编码 返回音频编码
""" """

View File

@ -46,4 +46,4 @@ def update_db():
alembic_cfg.set_main_option('sqlalchemy.url', f"sqlite:///{db_location}") alembic_cfg.set_main_option('sqlalchemy.url', f"sqlite:///{db_location}")
upgrade(alembic_cfg, 'head') upgrade(alembic_cfg, 'head')
except Exception as e: except Exception as e:
logger(f'数据库更新失败:{e}') logger.error(f'数据库更新失败:{e}')

View File

@ -23,7 +23,6 @@ class Base:
for key, value in payload.items(): for key, value in payload.items():
setattr(self, key, value) setattr(self, key, value)
db.commit() db.commit()
db.refresh(self)
@classmethod @classmethod
def delete(cls, db, rid): def delete(cls, db, rid):

View File

@ -35,18 +35,3 @@ class Site(Base):
@staticmethod @staticmethod
def get_actives(db: Session): def get_actives(db: Session):
return db.query(Site).filter(Site.is_active == 1).all() return db.query(Site).filter(Site.is_active == 1).all()
class SiteIcon(Base):
"""
站点图标表
"""
id = Column(Integer, Sequence('id'), primary_key=True, index=True)
name = Column(String, nullable=False)
domain = Column(String, index=True)
url = Column(String, nullable=False)
base64 = Column(String)
@staticmethod
def get_by_domain(db: Session, domain: str):
return db.query(SiteIcon).filter(SiteIcon.domain == domain).first()

19
app/db/models/siteicon.py Normal file
View File

@ -0,0 +1,19 @@
from sqlalchemy import Column, Integer, String, Sequence
from sqlalchemy.orm import Session
from app.db.models import Base
class SiteIcon(Base):
"""
站点图标表
"""
id = Column(Integer, Sequence('id'), primary_key=True, index=True)
name = Column(String, nullable=False)
domain = Column(String, index=True)
url = Column(String, nullable=False)
base64 = Column(String)
@staticmethod
def get_by_domain(db: Session, domain: str):
return db.query(SiteIcon).filter(SiteIcon.domain == domain).first()

42
app/db/siteicons.py Normal file
View File

@ -0,0 +1,42 @@
from typing import List
from sqlalchemy.orm import Session
from app.db import SessionLocal
from app.db.models.siteicon import SiteIcon
class SiteIcons:
"""
站点管理
"""
_db: Session = None
def __init__(self, _db=SessionLocal()):
self._db = _db
def list(self) -> List[SiteIcon]:
"""
获取站点图标列表
"""
return SiteIcon.list(self._db)
def get_by_domain(self, domain: str) -> SiteIcon:
"""
按域名获取站点图标
"""
return SiteIcon.get_by_domain(self._db, domain)
def update_icon(self, name: str, domain: str, icon_url: str, icon_base64: str) -> bool:
"""
更新站点图标
"""
siteicon = SiteIcon(name=name, domain=domain, url=icon_url, base64=icon_base64)
if not self.get_by_domain(domain):
siteicon.create(self._db)
elif icon_base64:
siteicon.update(self._db, {
"url": icon_url,
"base64": f"data:image/ico;base64,{icon_base64}"
})
return True

View File

@ -3,7 +3,7 @@ from typing import Tuple, List
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app.db import SessionLocal from app.db import SessionLocal
from app.db.models.site import Site, SiteIcon from app.db.models.site import Site
class Sites: class Sites:
@ -60,17 +60,3 @@ class Sites:
"cookie": cookies "cookie": cookies
}) })
return True, "更新站点Cookie成功" return True, "更新站点Cookie成功"
def update_icon(self, name: str, domain: str, icon_url: str, icon_base64: str) -> bool:
"""
更新站点图标
"""
siteicon = SiteIcon(name=name, domain=domain, url=icon_url, base64=icon_base64)
if not siteicon.get_by_domain(self._db, domain):
siteicon.create(self._db)
elif icon_base64:
siteicon.update(self._db, {
"url": icon_url,
"base64": f"data:image/ico;base64,{icon_base64}"
})
return True

View File

@ -471,7 +471,7 @@ class FileTransferModule(_ModuleBase):
# 集号 # 集号
"episode": meta.get_episode_seqs(), "episode": meta.get_episode_seqs(),
# 季集 SxxExx # 季集 SxxExx
"season_episode": "%s%s" % (meta.get_season_item(), meta.get_episode_items()), "season_episode": "%s%s" % (meta.get_begin_season_string(), meta.get_episode_strings()),
# 段/节 # 段/节
"part": meta.part, "part": meta.part,
# 文件后缀 # 文件后缀

View File

@ -104,7 +104,7 @@ class IndexerModule(_ModuleBase):
seconds = round((datetime.now() - start_time).seconds, 1) seconds = round((datetime.now() - start_time).seconds, 1)
# 返回结果 # 返回结果
if len(result_array) == 0: if not result_array or len(result_array) == 0:
logger.warn(f"{site.get('name')} 未搜索到数据,耗时 {seconds}") logger.warn(f"{site.get('name')} 未搜索到数据,耗时 {seconds}")
return [] return []
else: else:

View File

@ -138,6 +138,7 @@ class Slack:
# 发送 # 发送
result = self._client.chat_postMessage( result = self._client.chat_postMessage(
channel=channel, channel=channel,
text=f"*{title}*\n{text or ''}",
blocks=blocks blocks=blocks
) )
return True, result return True, result
@ -220,6 +221,7 @@ class Slack:
# 发送 # 发送
result = self._client.chat_postMessage( result = self._client.chat_postMessage(
channel=channel, channel=channel,
text=title,
blocks=blocks blocks=blocks
) )
return True if result else False return True if result else False
@ -299,6 +301,7 @@ class Slack:
# 发送 # 发送
result = self._client.chat_postMessage( result = self._client.chat_postMessage(
channel=channel, channel=channel,
text=title,
blocks=blocks blocks=blocks
) )
return True if result else False return True if result else False
@ -318,7 +321,7 @@ class Slack:
if conversation_id: if conversation_id:
break break
for channel in result["channels"]: for channel in result["channels"]:
if channel.get("name") == settings.SLACK_CHANNEL or "全体": if channel.get("name") == (settings.SLACK_CHANNEL or "全体"):
conversation_id = channel.get("id") conversation_id = channel.get("id")
break break
except Exception as e: except Exception as e:

View File

@ -13,9 +13,9 @@ if __name__ == '__main__':
# 测试过滤器 # 测试过滤器
# suite.addTest(FilterTest('test_filter')) # suite.addTest(FilterTest('test_filter'))
# 测试名称识别 # 测试名称识别
# suite.addTest(MetaInfoTest('test_metainfo')) suite.addTest(MetaInfoTest('test_metainfo'))
# 测试媒体识别 # 测试媒体识别
suite.addTest(RecognizeTest('test_recognize')) # suite.addTest(RecognizeTest('test_recognize'))
# 测试CookieCloud同步 # 测试CookieCloud同步
# suite.addTest(CookieCloudTest('test_cookiecloud')) # suite.addTest(CookieCloudTest('test_cookiecloud'))
# 测试文件转移 # 测试文件转移