Compare commits

...

12 Commits

Author SHA1 Message Date
jxxghp
397a8a9536 v2.2.1
- 订阅分享支持搜索词,修复了订阅复用人数显示
- 新增`VCronField`前端组件供插件使用,以简化cron表达式的输入
2025-01-13 12:52:58 +08:00
jxxghp
1da0a706a3 fix 订阅匹配缓存问题 2025-01-13 12:41:25 +08:00
jxxghp
4f2a110b5f fix 订阅匹配缓存问题 2025-01-13 12:11:56 +08:00
jxxghp
bb356ffcee Merge pull request #3721 from InfinityPacer/feature/site 2025-01-13 11:41:19 +08:00
jxxghp
6c986416ca fix 订阅分享显示复用人数 2025-01-13 08:55:06 +08:00
jxxghp
951ec138ef Merge pull request #3720 from InfinityPacer/feature/site 2025-01-13 07:09:23 +08:00
InfinityPacer
23e779ed94 fix(site): handle NoneType for userdata.user_level in regex search 2025-01-13 02:02:08 +08:00
InfinityPacer
29fccd3887 fix(site): update regex for unread message matching 2025-01-13 01:30:59 +08:00
jxxghp
1bef723332 Merge pull request #3717 from cddjr/fix_mteam_test 2025-01-12 21:25:16 +08:00
景大侠
3c41fed0ef fix 馒头连通性测试失败 2025-01-12 20:14:30 +08:00
jxxghp
5947d0e6d0 fix transfer 2025-01-09 22:24:01 +08:00
jxxghp
0e4fa86372 更新 transfer.py 2025-01-09 21:34:37 +08:00
6 changed files with 73 additions and 66 deletions

View File

@@ -1,6 +1,7 @@
import base64
import re
from datetime import datetime
from time import time
from typing import Optional, Tuple, Union, Dict
from urllib.parse import urljoin
@@ -88,7 +89,7 @@ class SiteChain(ChainBase):
))
# 低分享率警告
if userdata.ratio and float(userdata.ratio) < 1 and not bool(
re.search(r"(贵宾|VIP?)", userdata.user_level, re.IGNORECASE)):
re.search(r"(贵宾|VIP?)", userdata.user_level or "", re.IGNORECASE)):
self.post_message(Notification(
mtype=NotificationType.SiteMessage,
title=f"【站点分享率低预警】",
@@ -172,27 +173,37 @@ class SiteChain(ChainBase):
"Content-Type": "application/json",
"User-Agent": user_agent,
"Accept": "application/json, text/plain, */*",
"Authorization": site.token
"Authorization": site.token,
"x-api-key": site.apikey,
"ts": str(int(time()))
}
res = RequestUtils(
headers=headers,
proxies=settings.PROXY if site.proxy else None,
timeout=site.timeout or 15
).post_res(url=url)
state = False
message = "鉴权已过期或无效"
if res and res.status_code == 200:
user_info = res.json()
if user_info and user_info.get("data"):
user_info = res.json() or {}
if user_info.get("data"):
# 更新最后访问时间
del headers["x-api-key"]
res = RequestUtils(headers=headers,
timeout=site.timeout or 15,
proxies=settings.PROXY if site.proxy else None,
referer=f"{site.url}index"
).post_res(url=f"https://api.{domain}/api/member/updateLastBrowse")
if res:
return True, "连接成功"
else:
return True, f"连接成功,但更新状态失败"
return False, "鉴权已过期或无效"
state = True
message = "连接成功,但更新状态失败"
if res and res.status_code == 200:
update_info = res.json() or {}
if "code" in update_info and int(update_info["code"]) == 0:
message = "连接成功"
elif user_info.get("message"):
# 使用馒头的错误提示
message = user_info.get("message")
return state, message
@staticmethod
def __yema_test(site: Site) -> Tuple[bool, str]:

View File

@@ -6,8 +6,6 @@ import time
from datetime import datetime
from typing import Dict, List, Optional, Union, Tuple
from cachetools import TTLCache
from app.chain import ChainBase
from app.chain.download import DownloadChain
from app.chain.media import MediaChain
@@ -509,9 +507,6 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
logger.warn('没有缓存资源,无法匹配订阅')
return
# 记录重新识别过的种子
_recognize_cached = TTLCache(maxsize=1024, ttl=6 * 3600)
with self._rlock:
logger.debug(f"match lock acquired at {datetime.now()}")
# 所有订阅
@@ -552,6 +547,12 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
if exist_flag:
continue
# 订阅识别词
if subscribe.custom_words:
custom_words_list = subscribe.custom_words.split("\n")
else:
custom_words_list = None
# 遍历缓存种子
_match_context = []
for domain, contexts in torrents.items():
@@ -573,8 +574,8 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
continue
# 有自定义识别词时,需要判断是否需要重新识别
if subscribe.custom_words:
custom_words_list = subscribe.custom_words.split("\n")
apply_words = None
if custom_words_list:
_, apply_words = WordsMatcher().prepare(torrent_info.title,
custom_words=custom_words_list)
if apply_words:
@@ -589,30 +590,28 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
# 先判断是否有没识别的种子,否则重新识别
if not torrent_mediainfo \
or (not torrent_mediainfo.tmdb_id and not torrent_mediainfo.douban_id):
# 避免重复处理
_cache_key = f"{torrent_meta.org_string}_{torrent_info.description}"
if not _recognize_cached.get(_cache_key):
_recognize_cached[_cache_key] = True
# 重新识别媒体信息
torrent_mediainfo = self.recognize_media(meta=torrent_meta)
if torrent_mediainfo:
# 更新种子缓存
# 重新识别媒体信息
torrent_mediainfo = self.recognize_media(meta=torrent_meta)
if torrent_mediainfo:
# 更新种子缓存
if not apply_words:
context.media_info = torrent_mediainfo
if not torrent_mediainfo:
# 通过标题匹配兜底
logger.warn(
f'{torrent_info.site_name} - {torrent_info.title} 重新识别失败,尝试通过标题匹配...')
if self.torrenthelper.match_torrent(mediainfo=mediainfo,
torrent_meta=torrent_meta,
torrent=torrent_info):
# 匹配成功
logger.info(
f'{mediainfo.title_year} 通过标题匹配到可选资源:{torrent_info.site_name} - {torrent_info.title}')
# 更新种子缓存
torrent_mediainfo = mediainfo
else:
# 通过标题匹配兜底
logger.warn(
f'{torrent_info.site_name} - {torrent_info.title} 重新识别失败,尝试通过标题匹配...')
if self.torrenthelper.match_torrent(mediainfo=mediainfo,
torrent_meta=torrent_meta,
torrent=torrent_info):
# 匹配成功
logger.info(
f'{mediainfo.title_year} 通过标题匹配到可选资源:{torrent_info.site_name} - {torrent_info.title}')
torrent_mediainfo = mediainfo
# 更新种子缓存
if not apply_words:
context.media_info = mediainfo
else:
continue
else:
continue
# 直接比对媒体信息
if torrent_mediainfo and (torrent_mediainfo.tmdb_id or torrent_mediainfo.douban_id):

View File

@@ -545,8 +545,6 @@ class TransferChain(ChainBase, metaclass=Singleton):
task = item.task
if not task:
continue
# 正在处理
self.jobview.running_task(task)
# 文件信息
fileitem = task.fileitem
# 开始新队列
@@ -692,6 +690,9 @@ class TransferChain(ChainBase, metaclass=Singleton):
src_path=Path(task.fileitem.path),
target_storage=task.target_storage)
# 正在处理
self.jobview.running_task(task)
# 执行整理
transferinfo: TransferInfo = self.transfer(fileitem=task.fileitem,
meta=task.meta,
@@ -983,23 +984,7 @@ class TransferChain(ChainBase, metaclass=Singleton):
logger.warn(f"{fileitem.path} 没有找到可整理的媒体文件")
return False, f"{fileitem.name} 没有找到可整理的媒体文件"
# 总数量
total_num = len(file_items)
# 已处理数量
processed_num = 0
# 失败数量
fail_num = 0
logger.info(f"正在计划整理 {total_num} 个文件...")
# 启动进度
if not background:
self.progress.start(ProgressKey.FileTransfer)
__process_msg = f"开始整理,共 {total_num} 个文件 ..."
logger.info(__process_msg)
self.progress.update(value=0,
text=__process_msg,
key=ProgressKey.FileTransfer)
logger.info(f"正在计划整理 {len(file_items)} 个文件...")
# 整理所有文件
transfer_tasks: List[TransferTask] = []
@@ -1013,7 +998,6 @@ class TransferChain(ChainBase, metaclass=Singleton):
or file_item.path.find('/.') != -1 \
or file_item.path.find('/@eaDir') != -1:
logger.debug(f"{file_item.path} 是回收站或隐藏的文件")
fail_num += 1
continue
# 整理屏蔽词不处理
@@ -1027,7 +1011,6 @@ class TransferChain(ChainBase, metaclass=Singleton):
is_blocked = True
break
if is_blocked:
fail_num += 1
continue
# 整理成功的不再处理
@@ -1038,7 +1021,6 @@ class TransferChain(ChainBase, metaclass=Singleton):
all_success = False
logger.info(f"{file_item.path} 已整理过,如需重新处理,请删除整理记录。")
err_msgs.append(f"{file_item.name} 已整理过")
fail_num += 1
continue
if not meta:
@@ -1055,7 +1037,6 @@ class TransferChain(ChainBase, metaclass=Singleton):
all_success = False
logger.error(f"{file_path.name} 无法识别有效信息")
err_msgs.append(f"{file_path.name} 无法识别有效信息")
fail_num += 1
continue
# 自定义识别
@@ -1105,14 +1086,28 @@ class TransferChain(ChainBase, metaclass=Singleton):
if background:
self.put_to_queue(task=transfer_task)
logger.info(f"{file_path.name} 已添加到整理队列")
processed_num += 1
else:
# 加入列表
self.__put_to_jobview(transfer_task)
transfer_tasks.append(transfer_task)
# 实时整理
if not background:
if transfer_tasks:
# 总数量
total_num = len(transfer_tasks)
# 已处理数量
processed_num = 0
# 失败数量
fail_num = 0
# 启动进度
self.progress.start(ProgressKey.FileTransfer)
__process_msg = f"开始整理,共 {total_num} 个文件 ..."
logger.info(__process_msg)
self.progress.update(value=0,
text=__process_msg,
key=ProgressKey.FileTransfer)
for transfer_task in transfer_tasks:
if global_vars.is_system_stopped:
break

View File

@@ -43,7 +43,7 @@ class NexusPhpSiteUserInfo(SiteParserBase):
message_text = message_labels[0].xpath("string(.)")
logger.debug(f"{self._site_name} 消息原始信息 {message_text}")
message_unread_match = re.findall(r"[^Date](信息箱\s*|\(|你有\xa0)(\d+)", message_text)
message_unread_match = re.findall(r"[^Date](信息箱\s*|\((?![^)]*:)|你有\xa0)(\d+)", message_text)
if message_unread_match and len(message_unread_match[-1]) == 2:
self.message_unread = StringUtils.str_int(message_unread_match[-1][1])

View File

@@ -127,6 +127,8 @@ class SubscribeShare(BaseModel):
custom_words: Optional[str] = None
# 自定义媒体类别
media_category: Optional[str] = None
# 复用人次
count: Optional[int] = 0
class SubscribeDownloadFileInfo(BaseModel):

View File

@@ -1,2 +1,2 @@
APP_VERSION = 'v2.2.0'
FRONTEND_VERSION = 'v2.2.0'
APP_VERSION = 'v2.2.1'
FRONTEND_VERSION = 'v2.2.1'