Compare commits

...

33 Commits
v1.9.11 ... v1

Author SHA1 Message Date
jxxghp
1336b2136d Merge pull request #4340 from jtcymc/main 2025-05-25 07:59:41 +08:00
shaw
b20e21e700 fix(SearchChain): with 关闭线程池
- 使用 with 语句管理 ThreadPoolExecutor,确保线程池正确关闭
2025-05-25 00:50:34 +08:00
jxxghp
c27ab4a4c7 v1.9.19
- 默认关闭自动升级
2025-05-12 16:41:57 +08:00
jxxghp
d9e6532325 更新 version.py 2025-04-10 14:55:24 +08:00
jxxghp
049f16ba01 Merge pull request #4130 from cddjr/fix_v1_mteam 2025-04-10 14:36:21 +08:00
景大侠
6541458326 backport: 适配馒头API变动 2025-04-10 14:18:04 +08:00
jxxghp
9f2912426b Merge pull request #2833 from wikrin/main 2024-10-10 22:49:12 +08:00
Attente
fde33d267a fix: 修正重复的特殊字符
将重复的特殊字符 `—`[U+2014](https://symbl.cc/cn/2014/) 修改为 `―`[U+2015](https://symbl.cc/cn/2015/)
2024-10-10 22:23:43 +08:00
jxxghp
ef7f0afa37 v1.9.17
- 修复115扫码登录问题
- 索引站点新增支持 `PTLGS`
2024-09-18 17:52:40 +08:00
jxxghp
bea77a8243 fix 115 2024-09-18 13:39:39 +08:00
jxxghp
b984b83870 v1.9.16
- 修复了有些情况下新增目录类型为全部时不生效的问题
2024-09-08 13:11:59 +08:00
jxxghp
2153ad48db v1.9.15
- 修复部分通知消息查看详细链接错误的问题
- 修复了麒麟无法索引综艺的问题
- 修复了插件无升级提示图标的问题
2024-08-28 15:01:46 +08:00
jxxghp
c9c43fde74 Merge pull request #2638 from Linvery/main 2024-08-13 12:41:51 +08:00
Linvery
e2c9742f64 fix: 解决推送消息错误的url路径 2024-08-13 12:40:33 +08:00
jxxghp
3d459a40f7 - 仅调整了插件页面的UI 2024-08-13 11:46:01 +08:00
jxxghp
5675cd5b11 v1.9.13
- 修复已知问题
2024-07-30 06:36:30 +08:00
jxxghp
74a4d0bd66 Merge pull request #2614 from InfinityPacer/main 2024-07-30 06:33:00 +08:00
InfinityPacer
2b8c313019 refactor(event): 事件处理调整为深复制,避免多线程环境下数据异常 2024-07-29 23:18:58 +08:00
jxxghp
62fb6b80a3 Merge pull request #2612 from audichuang/main 2024-07-28 18:48:06 +08:00
audichuang
eea86528d8 Modifying the Bilingual Subtitle Matching Specification 2024-07-28 18:07:28 +08:00
jxxghp
84e6abb659 Merge pull request #2600 from InfinityPacer/main 2024-07-23 19:45:18 +08:00
InfinityPacer
da2c755b6d fix(Plugin): 重置插件时初始化调整为reload,以保留默认配置 2024-07-23 19:41:29 +08:00
jxxghp
51f39be9bc Merge pull request #2590 from Akimio521/main 2024-07-20 20:15:04 +08:00
Akimio521
21b762e75c perfect(releasegroup):完善anime字幕组 2024-07-20 20:05:05 +08:00
jxxghp
54095074b6 v1.9.12
- 新增认证站点:`ROUSI`
- 修复Telegram部分消息格式异常问题
2024-07-16 08:07:24 +08:00
jxxghp
33525730b5 fix #2515 2024-07-16 08:04:48 +08:00
jxxghp
71260f04b5 Merge pull request #2560 from InfinityPacer/main 2024-07-12 17:03:55 +08:00
InfinityPacer
e2acec321d fix tips 2024-07-12 16:48:44 +08:00
InfinityPacer
74a462a09f fix SitesHelper import tips 2024-07-12 16:30:06 +08:00
jxxghp
ad9e1a5da6 Merge pull request #2552 from BrettDean/main 2024-07-11 21:26:04 +08:00
Dean
d90e3c29a5 优化微信文本消息发送:支持长文本分块发送 2024-07-11 20:30:09 +08:00
jxxghp
19165eff75 Merge pull request #2537 from InfinityPacer/main 2024-07-09 11:01:53 +08:00
InfinityPacer
1431a5e82a fix #2518 移除不必要的debug日志 2024-07-09 01:40:37 +08:00
19 changed files with 114 additions and 84 deletions

3
.gitignore vendored
View File

@@ -16,4 +16,5 @@ config/sites/**
*.pyc
*.log
.vscode
venv
venv
.DS_Store

View File

@@ -11,7 +11,7 @@ ENV LANG="C.UTF-8" \
PORT=3001 \
NGINX_PORT=3000 \
PROXY_HOST="" \
MOVIEPILOT_AUTO_UPDATE=release \
MOVIEPILOT_AUTO_UPDATE=false \
AUTH_SITE="iyuu" \
IYUU_SIGN=""
WORKDIR "/app"

View File

@@ -192,10 +192,7 @@ def reset_plugin(plugin_id: str, _: schemas.TokenPayload = Depends(verify_token)
# 删除插件所有数据
PluginManager().delete_plugin_data(plugin_id)
# 重新生效插件
PluginManager().init_plugin(plugin_id, {
"enabled": False,
"enable": False
})
PluginManager().reload_plugin(plugin_id)
# 注册插件服务
Scheduler().update_plugin_job(plugin_id)
# 注册插件API

View File

@@ -316,34 +316,34 @@ class SearchChain(ChainBase):
self.progress.update(value=0,
text=f"开始搜索,共 {total_num} 个站点 ...",
key=ProgressKey.Search)
# 多线程
executor = ThreadPoolExecutor(max_workers=len(indexer_sites))
all_task = []
for site in indexer_sites:
if area == "imdbid":
# 搜索IMDBID
task = executor.submit(self.search_torrents, site=site,
keywords=[mediainfo.imdb_id] if mediainfo else None,
mtype=mediainfo.type if mediainfo else None,
page=page)
else:
# 搜索标题
task = executor.submit(self.search_torrents, site=site,
keywords=keywords,
mtype=mediainfo.type if mediainfo else None,
page=page)
all_task.append(task)
# 结果集
results = []
for future in as_completed(all_task):
finish_count += 1
result = future.result()
if result:
results.extend(result)
logger.info(f"站点搜索进度:{finish_count} / {total_num}")
self.progress.update(value=finish_count / total_num * 100,
text=f"正在搜索{keywords or ''},已完成 {finish_count} / {total_num} 个站点 ...",
key=ProgressKey.Search)
# 多线程
with ThreadPoolExecutor(max_workers=len(indexer_sites)) as executor:
all_task = []
for site in indexer_sites:
if area == "imdbid":
# 搜索IMDBID
task = executor.submit(self.search_torrents, site=site,
keywords=[mediainfo.imdb_id] if mediainfo else None,
mtype=mediainfo.type if mediainfo else None,
page=page)
else:
# 搜索标题
task = executor.submit(self.search_torrents, site=site,
keywords=keywords,
mtype=mediainfo.type if mediainfo else None,
page=page)
all_task.append(task)
for future in as_completed(all_task):
finish_count += 1
result = future.result()
if result:
results.extend(result)
logger.info(f"站点搜索进度:{finish_count} / {total_num}")
self.progress.update(value=finish_count / total_num * 100,
text=f"正在搜索{keywords or ''},已完成 {finish_count} / {total_num} 个站点 ...",
key=ProgressKey.Search)
# 计算耗时
end_time = datetime.now()
# 更新进度

View File

@@ -110,30 +110,24 @@ class SiteChain(ChainBase):
domain = StringUtils.get_url_domain(site.url)
url = f"https://api.{domain}/api/member/profile"
headers = {
"Content-Type": "application/json",
"User-Agent": user_agent,
"Accept": "application/json, text/plain, */*",
"Authorization": site.token
"x-api-key": site.apikey,
}
res = RequestUtils(
headers=headers,
proxies=settings.PROXY if site.proxy else None,
timeout=site.timeout or 15
).post_res(url=url)
if res and res.status_code == 200:
user_info = res.json()
if user_info and user_info.get("data"):
# 更新最后访问时间
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, "鉴权已过期或无效"
if res is None:
return False, "无法打开网站!"
if res.status_code == 200:
user_info = res.json() or {}
if user_info.get("data"):
return True, "连接成功"
return False, user_info.get("message", "鉴权已过期或无效")
else:
return False, f"错误:{res.status_code} {res.reason}"
@staticmethod
def __yema_test(site: Site) -> Tuple[bool, str]:

View File

@@ -179,9 +179,9 @@ class SubscribeChain(ChainBase):
text = f"评分:{mediainfo.vote_average}"
# 群发
if mediainfo.type == MediaType.TV:
link = settings.MP_DOMAIN('#/subscribe-tv?tab=mysub')
link = settings.MP_DOMAIN('#/subscribe/tv?tab=mysub')
else:
link = settings.MP_DOMAIN('#/subscribe-movie?tab=mysub')
link = settings.MP_DOMAIN('#/subscribe/movie?tab=mysub')
self.post_message(Notification(mtype=NotificationType.Subscribe,
title=f"{mediainfo.title_year} {metainfo.season} 已添加订阅",
text=text,
@@ -922,9 +922,9 @@ class SubscribeChain(ChainBase):
self.subscribeoper.delete(subscribe.id)
# 发送通知
if mediainfo.type == MediaType.TV:
link = settings.MP_DOMAIN('#/subscribe-tv?tab=mysub')
link = settings.MP_DOMAIN('#/subscribe/tv?tab=mysub')
else:
link = settings.MP_DOMAIN('#/subscribe-movie?tab=mysub')
link = settings.MP_DOMAIN('#/subscribe/movie?tab=mysub')
self.post_message(Notification(mtype=NotificationType.Subscribe,
title=f'{mediainfo.title_year} {meta.season} 已完成{msgstr}',
image=mediainfo.get_message_image(),

View File

@@ -1,3 +1,4 @@
import copy
import importlib
import threading
import traceback
@@ -11,8 +12,7 @@ from app.chain.subscribe import SubscribeChain
from app.chain.system import SystemChain
from app.chain.transfer import TransferChain
from app.core.config import settings
from app.core.event import Event as ManagerEvent
from app.core.event import eventmanager, EventManager
from app.core.event import Event as ManagerEvent, eventmanager, EventManager
from app.core.plugin import PluginManager
from app.helper.message import MessageHelper
from app.helper.thread import ThreadHelper
@@ -194,7 +194,7 @@ class Command(metaclass=Singleton):
# 插件事件
self.threader.submit(
self.pluginmanager.run_plugin_method,
class_name, method_name, event
class_name, method_name, copy.deepcopy(event)
)
else:
@@ -217,7 +217,7 @@ class Command(metaclass=Singleton):
if hasattr(class_obj, method_name):
self.threader.submit(
getattr(class_obj, method_name),
event
copy.deepcopy(event)
)
except Exception as e:
logger.error(f"事件处理出错:{str(e)} - {traceback.format_exc()}")

View File

@@ -229,7 +229,7 @@ class Settings(BaseSettings):
# Github代理服务器格式https://mirror.ghproxy.com/
GITHUB_PROXY: Optional[str] = ''
# 自动检查和更新站点资源包(站点索引、认证等)
AUTO_UPDATE_RESOURCE: bool = True
AUTO_UPDATE_RESOURCE: bool = False
# 元数据识别缓存过期时间(小时)
META_CACHE_EXPIRE: int = 0
# 是否启用DOH解析域名

View File

@@ -71,7 +71,10 @@ class ReleaseGroupsMatcher(metaclass=Singleton):
"ultrahd": [],
"others": ['B(?:MDru|eyondHD|TN)', 'C(?:fandora|trlhd|MRG)', 'DON', 'EVO', 'FLUX', 'HONE(?:|yG)',
'N(?:oGroup|T(?:b|G))', 'PandaMoon', 'SMURF', 'T(?:EPES|aengoo|rollHD )'],
"anime": ['ANi', 'HYSUB', 'KTXP', 'LoliHouse', 'MCE', 'Nekomoe kissaten', '(?:Lilith|NC)-Raws', '织梦字幕组']
"anime": ['ANi', 'HYSUB', 'KTXP', 'LoliHouse', 'MCE', 'Nekomoe kissaten', 'SweetSub', 'MingY',
'(?:Lilith|NC)-Raws', '织梦字幕组', '枫叶字幕组', '猎户手抄部', '喵萌奶茶屋', '漫猫字幕社',
'霜庭云花Sub', '北宇治字幕组', '氢气烤肉架', '云歌字幕组', '萌樱字幕组','极影字幕社','悠哈璃羽字幕社',
'❀拨雪寻春❀', '沸羊羊(?:制作|字幕组)', '(?:桜|樱)都字幕组',]
}
def __init__(self):

View File

@@ -815,8 +815,6 @@ class PluginManager(metaclass=Singleton):
# 将插件标识转换为大写并构建环境变量名称
env_var_name = f"PLUGIN_{plugin_id.upper()}_PRIVATE_KEY"
private_key = os.environ.get(env_var_name)
if private_key is None:
logger.debug(f"环境变量 {env_var_name} 未找到。")
return private_key
except Exception as e:
logger.debug(f"获取插件 {plugin_id} 的私钥时发生错误:{e}")

View File

@@ -20,12 +20,20 @@ if SystemUtils.is_frozen():
from app.core.config import settings, global_vars
from app.core.module import ModuleManager
# SitesHelper涉及资源包拉取提前引入并容错提示
try:
from app.helper.sites import SitesHelper
except ImportError as e:
error_message = f"错误: {str(e)}\n站点认证及索引相关资源导入失败,请尝试重建容器或手动拉取资源"
print(error_message, file=sys.stderr)
sys.exit(1)
from app.core.plugin import PluginManager
from app.db.init import init_db, update_db, init_super_user
from app.helper.thread import ThreadHelper
from app.helper.display import DisplayHelper
from app.helper.resource import ResourceHelper
from app.helper.sites import SitesHelper
from app.helper.message import MessageHelper
from app.scheduler import Scheduler
from app.command import Command, CommandChian

View File

@@ -219,12 +219,13 @@ class FileTransferModule(_ModuleBase):
"""
# 字幕正则式
_zhcn_sub_re = r"([.\[(](((zh[-_])?(cn|ch[si]|sg|sc))|zho?" \
r"|chinese|(cn|ch[si]|sg|zho?|eng)[-_&](cn|ch[si]|sg|zho?|eng)" \
r"|chinese|(cn|ch[si]|sg|zho?|eng)[-_&]?(cn|ch[si]|sg|zho?|eng)" \
r"|简[体中]?)[.\])])" \
r"|([\u4e00-\u9fa5]{0,3}[中双][\u4e00-\u9fa5]{0,2}[字文语][\u4e00-\u9fa5]{0,3})" \
r"|简体|简中|JPSC" \
r"|(?<![a-z0-9])gb(?![a-z0-9])"
_zhtw_sub_re = r"([.\[(](((zh[-_])?(hk|tw|cht|tc))" \
r"|(cht|eng)[-_&]?(cht|eng)" \
r"|繁[体中]?)[.\])])" \
r"|繁体中[文字]|中[文字]繁体|繁体|JPTC" \
r"|(?<![a-z0-9])big5(?![a-z0-9])"

View File

@@ -193,7 +193,6 @@ class MTorrentSpider:
'id': torrent_id
},
'header': {
'Content-Type': 'application/json',
'User-Agent': f'{self._ua}',
'Accept': 'application/json, text/plain, */*',
'x-api-key': self._apikey

View File

@@ -88,6 +88,8 @@ class Telegram:
try:
if text:
# 对text进行Markdown特殊字符转义
text = re.sub(r"([_`])", r"\\\1", text)
caption = f"*{title}*\n{text}"
else:
caption = f"*{title}*"
@@ -208,8 +210,6 @@ class Telegram:
image_file = Path(settings.TEMP_PATH) / str(uuid.uuid4())
image_file.write_bytes(res.content)
photo = InputFile(image_file)
# 对caption进行Markdown特殊字符转义
caption = re.sub(r"([_`])", r"\\\1", caption)
# 发送图片到Telegram
ret = self._bot.send_photo(chat_id=userid or self._telegram_chat_id,
photo=photo,

View File

@@ -100,28 +100,57 @@ class WeChat:
"""
message_url = self._send_msg_url % self.__get_access_token()
if text:
conent = "%s\n%s" % (title, text.replace("\n\n", "\n"))
content = "%s\n%s" % (title, text.replace("\n\n", "\n"))
else:
conent = title
content = title
if link:
conent = f"{conent}\n点击查看:{link}"
content = f"{content}\n点击查看:{link}"
if not userid:
userid = "@all"
req_json = {
"touser": userid,
"msgtype": "text",
"agentid": self._appid,
"text": {
"content": conent
},
"safe": 0,
"enable_id_trans": 0,
"enable_duplicate_check": 0
}
return self.__post_request(message_url, req_json)
# Check if content exceeds 2048 bytes and split if necessary
if len(content.encode('utf-8')) > 2048:
content_chunks = []
current_chunk = ""
for line in content.splitlines():
if len(current_chunk.encode('utf-8')) + len(line.encode('utf-8')) > 2048:
content_chunks.append(current_chunk.strip())
current_chunk = ""
current_chunk += line + "\n"
if current_chunk:
content_chunks.append(current_chunk.strip())
# Send each chunk as a separate message
for chunk in content_chunks:
req_json = {
"touser": userid,
"msgtype": "text",
"agentid": self._appid,
"text": {
"content": chunk
},
"safe": 0,
"enable_id_trans": 0,
"enable_duplicate_check": 0
}
result = self.__post_request(message_url, req_json)
else:
req_json = {
"touser": userid,
"msgtype": "text",
"agentid": self._appid,
"text": {
"content": content
},
"safe": 0,
"enable_id_trans": 0,
"enable_duplicate_check": 0
}
return self.__post_request(message_url, req_json)
return result
def __send_image_message(self, title: str, text: str, image_url: str,
userid: str = None, link: str = None) -> Optional[bool]:

View File

@@ -186,7 +186,7 @@ class StringUtils:
忽略特殊字符
"""
# 需要忽略的特殊字符
CONVERT_EMPTY_CHARS = r"[、.。,,·:;!'\"“”()\[\]【】「」\-—\+\|\\_/&#~]"
CONVERT_EMPTY_CHARS = r"[、.。,,·:;!'\"“”()\[\]【】「」\-—\+\|\\_/&#~]"
if not text:
return text
if not isinstance(text, list):

View File

@@ -20,7 +20,7 @@ DOH_RESOLVERS=1.0.0.1,1.1.1.1,9.9.9.9,149.112.112.112
# 元数据识别缓存过期时间数字型单位小时0为系统默认大内存模式为7天滞则为3天调大该值可减少themoviedb的访问次数
META_CACHE_EXPIRE=0
# 自动检查和更新站点资源包(索引、认证等)
AUTO_UPDATE_RESOURCE=true
AUTO_UPDATE_RESOURCE=false
# 【*】API密钥建议更换复杂字符串有Jellyseerr/Overseerr、媒体服务器Webhook等配置以及部分支持API_TOKEN的API中使用
API_TOKEN=moviepilot
# 登录页面电影海报tmdb/bingtmdb要求能正常连接api.themoviedb.org

View File

@@ -58,5 +58,5 @@ pystray~=0.19.5
pyotp~=2.9.0
Pinyin2Hanzi~=0.1.1
pywebpush~=2.0.0
py115~=0.0.4
py115j~=0.0.6
oss2~=2.18.6

View File

@@ -1 +1 @@
APP_VERSION = 'v1.9.11'
APP_VERSION = 'v1.9.19'