mirror of
https://github.com/jxxghp/MoviePilot-Plugins.git
synced 2026-06-13 23:16:49 +00:00
Compare commits
19 Commits
AutoSignIn
...
ClashRuleP
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2102a03740 | ||
|
|
0a9cadf7ab | ||
|
|
279efe8000 | ||
|
|
fd92e58f81 | ||
|
|
fe93e46e02 | ||
|
|
cbf541992f | ||
|
|
8e1d336250 | ||
|
|
12e0e2b9f5 | ||
|
|
ac914f70f3 | ||
|
|
a07b8a4f4a | ||
|
|
6960b3f7aa | ||
|
|
fe83ff1be8 | ||
|
|
6357dc8e4a | ||
|
|
f1d94d0aa3 | ||
|
|
53dd3bc796 | ||
|
|
a9d528fc05 | ||
|
|
0388c437b1 | ||
|
|
ac4b53e745 | ||
|
|
53297fccaf |
7
.github/workflows/release.yml
vendored
7
.github/workflows/release.yml
vendored
@@ -90,15 +90,18 @@ jobs:
|
||||
rm -f "$asset"
|
||||
(cd "$(dirname "$plugin_dir")" && zip -r "$GITHUB_WORKSPACE/$asset" "$(basename "$plugin_dir")" -x "*/__pycache__/*" -x "*.pyc") >/dev/null
|
||||
|
||||
# If same tag exists, delete release and remote tag first
|
||||
# If same tag exists, delete release and both remote/local tag first
|
||||
if gh release view "$tag" >/dev/null 2>&1; then
|
||||
echo "Release $tag exists, deleting..."
|
||||
gh release delete "$tag" -y
|
||||
git push origin :refs/tags/"$tag" || true
|
||||
fi
|
||||
|
||||
# Ensure no stale local tag remains
|
||||
git tag -d "$tag" >/dev/null 2>&1 || true
|
||||
|
||||
echo "Creating release $tag"
|
||||
gh release create "$tag" "$asset" --title "$tag" --notes "Automated release of $plugin_id $plugin_version" --latest
|
||||
gh release create "$tag" "$asset" --title "$tag" --notes "Automated release of $plugin_id $plugin_version" --latest --target "$GITHUB_SHA"
|
||||
|
||||
echo "$tag" >> processed_tags.txt
|
||||
done
|
||||
|
||||
185
README.md
185
README.md
@@ -23,6 +23,7 @@ MoviePilot官方插件市场:https://github.com/jxxghp/MoviePilot-Plugins
|
||||
- [12. 如何通过插件扩展支持的存储类型?](#12-如何通过插件扩展支持的存储类型)
|
||||
- [13. 如何将插件功能集成到工作流?](#13-如何将插件功能集成到工作流)
|
||||
- [14. 如何在插件中通过消息持续与用户交互?](#14-如何在插件中通过消息持续与用户交互)
|
||||
- [15. 如何在插件中使用系统级统一缓存?](#15-如何在插件中使用系统级统一缓存)
|
||||
- [版本发布](#版本发布)
|
||||
- [1. 如何发布插件版本?](#1-如何发布插件版本)
|
||||
- [2. 如何开发V2版本的插件以及实现插件多版本兼容?](#2-如何开发v2版本的插件以及实现插件多版本兼容)
|
||||
@@ -1167,6 +1168,190 @@ def get_actions(self) -> List[Dict[str, Any]]:
|
||||
- 建议在交互中保存用户状态数据,以支持复杂的多步骤操作
|
||||
- 可以结合插件数据存储功能保存用户的交互历史和偏好设置
|
||||
|
||||
### 15. 如何在插件中使用系统级统一缓存?
|
||||
**(仅支持 `v2.7.4+` 版本)**
|
||||
- MoviePilot提供了统一的缓存系统,支持内存缓存、文件系统缓存和Redis缓存自动管理,当有Redis时优先使用Redis,否则使用内存或文件系统。插件可以通过系统提供的缓存接口实现高效的缓存管理,无需关心系统设置。
|
||||
|
||||
- 1. 使用缓存装饰器:
|
||||
```python
|
||||
from app.core.cache import cached
|
||||
|
||||
class MyPlugin(_PluginBase):
|
||||
@cached(region="my_plugin", ttl=3600)
|
||||
def get_data(self, key: str):
|
||||
"""
|
||||
使用缓存装饰器,缓存结果1小时
|
||||
"""
|
||||
# 复杂的计算或网络请求
|
||||
return expensive_operation(key)
|
||||
|
||||
@cached(region="my_plugin_async", ttl=1800, skip_none=True)
|
||||
async def get_async_data(self, key: str):
|
||||
"""
|
||||
异步函数缓存,跳过None值
|
||||
"""
|
||||
return await async_expensive_operation(key)
|
||||
```
|
||||
|
||||
- 2. 使用TTLCache类:
|
||||
```python
|
||||
from app.core.cache import TTLCache
|
||||
|
||||
class MyPlugin(_PluginBase):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# 创建缓存实例,最大128项,TTL 30分钟
|
||||
self.cache = TTLCache(region="my_plugin", maxsize=128, ttl=1800)
|
||||
|
||||
def process_data(self, key: str):
|
||||
# 检查缓存
|
||||
if key in self.cache:
|
||||
return self.cache[key]
|
||||
|
||||
# 计算并缓存结果
|
||||
result = expensive_operation(key)
|
||||
self.cache[key] = result
|
||||
return result
|
||||
|
||||
def clear_cache(self):
|
||||
"""
|
||||
清理插件缓存
|
||||
"""
|
||||
self.cache.clear()
|
||||
```
|
||||
|
||||
- 3. 使用文件缓存后端(适用于大文件缓存):
|
||||
```python
|
||||
from app.core.cache import FileCache, AsyncFileCache
|
||||
from pathlib import Path
|
||||
|
||||
class MyPlugin(_PluginBase):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# 获取文件缓存后端,支持Redis和文件系统
|
||||
self.file_cache = FileCache(
|
||||
base=Path("/tmp/my_plugin_cache"),
|
||||
ttl=86400 # 24小时
|
||||
)
|
||||
|
||||
def cache_large_file(self, key: str, data: bytes):
|
||||
"""
|
||||
缓存大文件数据
|
||||
"""
|
||||
self.file_cache.set(key, data, region="large_files")
|
||||
|
||||
def get_cached_file(self, key: str) -> Optional[bytes]:
|
||||
"""
|
||||
获取缓存的文件数据
|
||||
"""
|
||||
return self.file_cache.get(key, region="large_files")
|
||||
|
||||
async def async_cache_operations(self):
|
||||
"""
|
||||
异步文件缓存操作
|
||||
"""
|
||||
async_cache = AsyncFileCache(
|
||||
base=Path("/tmp/my_plugin_async_cache"),
|
||||
ttl=3600
|
||||
)
|
||||
|
||||
# 异步设置缓存
|
||||
await async_cache.set("async_key", b"async_data", region="async_files")
|
||||
|
||||
# 异步获取缓存
|
||||
data = await async_cache.get("async_key", region="async_files")
|
||||
|
||||
await async_cache.close()
|
||||
```
|
||||
|
||||
- 4. 直接使用缓存后端(高级用法):
|
||||
```python
|
||||
from app.core.cache import Cache
|
||||
|
||||
class MyPlugin(_PluginBase):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# 直接获取缓存后端实例,系统自动选择Redis或内存缓存
|
||||
self.cache_backend = Cache(maxsize=256, ttl=3600)
|
||||
|
||||
def custom_cache_operation(self, key: str, value: Any):
|
||||
"""
|
||||
自定义缓存操作
|
||||
"""
|
||||
# 设置缓存
|
||||
self.cache_backend.set(key, value, region="custom_region")
|
||||
|
||||
# 检查缓存是否存在
|
||||
if self.cache_backend.exists(key, region="custom_region"):
|
||||
# 获取缓存
|
||||
cached_value = self.cache_backend.get(key, region="custom_region")
|
||||
return cached_value
|
||||
|
||||
return None
|
||||
|
||||
def iterate_cache_items(self):
|
||||
"""
|
||||
遍历缓存项
|
||||
"""
|
||||
for key, value in self.cache_backend.items(region="custom_region"):
|
||||
print(f"缓存键: {key}, 值: {value}")
|
||||
|
||||
def cleanup(self):
|
||||
"""
|
||||
清理缓存
|
||||
"""
|
||||
self.cache_backend.clear(region="custom_region")
|
||||
self.cache_backend.close()
|
||||
```
|
||||
|
||||
- 5. 缓存装饰器参数说明:
|
||||
```python
|
||||
@cached(
|
||||
region="my_plugin", # 缓存区域,用于隔离不同插件的缓存
|
||||
maxsize=512, # 最大缓存条目数(仅内存缓存有效)
|
||||
ttl=1800, # 缓存存活时间(秒)
|
||||
skip_none=True, # 是否跳过None值缓存
|
||||
skip_empty=False # 是否跳过空值缓存(空列表、空字典等)
|
||||
)
|
||||
def my_function(self, param):
|
||||
pass
|
||||
```
|
||||
|
||||
- 6. 缓存管理功能:
|
||||
```python
|
||||
class MyPlugin(_PluginBase):
|
||||
@cached(region="my_plugin")
|
||||
def cached_function(self, param):
|
||||
return expensive_operation(param)
|
||||
|
||||
def clear_my_cache(self):
|
||||
"""
|
||||
清理指定区域的缓存
|
||||
"""
|
||||
self.cached_function.cache_clear()
|
||||
|
||||
def get_cache_info(self):
|
||||
"""
|
||||
获取缓存信息
|
||||
"""
|
||||
cache_region = self.cached_function.cache_region
|
||||
return f"缓存区域: {cache_region}"
|
||||
```
|
||||
|
||||
- 7. 缓存后端自动选择:
|
||||
- 系统会根据配置自动选择缓存后端:
|
||||
- `CACHE_BACKEND_TYPE=redis`:使用Redis作为缓存后端
|
||||
- `CACHE_BACKEND_TYPE=memory`:使用内存缓存(cachetools)
|
||||
- 插件代码无需修改,系统会自动处理缓存后端的切换
|
||||
|
||||
- 8. 最佳实践:
|
||||
- 为每个插件使用独立的缓存区域(region),避免缓存键冲突
|
||||
- 合理设置TTL,避免缓存过期时间过长导致数据过期
|
||||
- 对于频繁访问的数据使用较长的TTL,对于实时性要求高的数据使用较短的TTL
|
||||
- 使用`skip_none=True`避免缓存无意义的None值
|
||||
- 大文件或二进制数据建议使用文件缓存后端
|
||||
- 在插件卸载时清理相关缓存,避免内存泄漏
|
||||
|
||||
|
||||
## 版本发布
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 35 KiB |
@@ -943,11 +943,14 @@
|
||||
"name": "钉钉机器人",
|
||||
"description": "支持使用钉钉机器人发送消息通知。",
|
||||
"labels": "消息通知,钉钉机器人",
|
||||
"version": "1.12",
|
||||
"version": "1.13",
|
||||
"icon": "Dingding_A.png",
|
||||
"author": "nnlegenda",
|
||||
"level": 1,
|
||||
"v2": true
|
||||
"v2": true,
|
||||
"history": {
|
||||
"v1.13": "优化钉钉消息换行"
|
||||
}
|
||||
},
|
||||
"DynamicWeChat": {
|
||||
"name": "动态企微可信IP",
|
||||
|
||||
@@ -42,12 +42,13 @@
|
||||
"name": "站点自动签到",
|
||||
"description": "自动模拟登录、签到站点。",
|
||||
"labels": "站点",
|
||||
"version": "2.6",
|
||||
"version": "2.7",
|
||||
"icon": "signin.png",
|
||||
"author": "thsrite",
|
||||
"level": 2,
|
||||
"release": true,
|
||||
"history": {
|
||||
"v2.7": "站点请求使用站点设置的超时时间",
|
||||
"v2.6": "感谢madrays佬提供的UI!",
|
||||
"v2.5.4": "增加保号风险提示",
|
||||
"v2.5.3": "优化执行周期输入,需要MoviePilot v2.2.1+",
|
||||
@@ -350,6 +351,18 @@
|
||||
"v2.0": "适配新的目录结构变化,短剧分类名称调整为配置目录路径,升级后需要重新调整设置后才能使用。"
|
||||
}
|
||||
},
|
||||
"MultiClass": {
|
||||
"name": "视频多级分类",
|
||||
"description": "支持视频多级分类",
|
||||
"labels": "文件整理",
|
||||
"version": "0.1",
|
||||
"icon": "Calibreweb_B.png",
|
||||
"author": "liuhangbin",
|
||||
"level": 1,
|
||||
"history": {
|
||||
"v0.1": "视频多级分类插件, 目前仅支持电影按评分,年代,系列分类。"
|
||||
}
|
||||
},
|
||||
"MoviePilotUpdateNotify": {
|
||||
"name": "MoviePilot更新推送",
|
||||
"description": "MoviePilot推送release更新通知、自动重启。",
|
||||
@@ -419,11 +432,12 @@
|
||||
"name": "绕过Trackers",
|
||||
"description": "提供tracker服务器IP地址列表,帮助IPv6连接绕过OpenClash。",
|
||||
"labels": "工具",
|
||||
"version": "1.4.2",
|
||||
"version": "1.4.3",
|
||||
"icon": "Clash_A.png",
|
||||
"author": "wumode",
|
||||
"level": 2,
|
||||
"history": {
|
||||
"v1.4.3": "修复 bug",
|
||||
"v1.4.2": "修复插件动作",
|
||||
"v1.4.1": "修复通知类型错误",
|
||||
"v1.4": "异步查询DNS",
|
||||
@@ -437,11 +451,13 @@
|
||||
"name": "IMDb源",
|
||||
"description": "让探索,推荐和媒体识别支持IMDb数据源。",
|
||||
"labels": "探索",
|
||||
"version": "1.5.6",
|
||||
"version": "1.5.8",
|
||||
"icon": "IMDb_IOS-OSX_App.png",
|
||||
"author": "wumode",
|
||||
"level": 1,
|
||||
"history": {
|
||||
"v1.5.8": "修改UA",
|
||||
"v1.5.7": "改进异常处理",
|
||||
"v1.5.6": "固定仪表盘组件海报比例; 修复 bug",
|
||||
"v1.5.5": "修复初始化错误",
|
||||
"v1.5.4": "改进媒体识别",
|
||||
@@ -467,12 +483,13 @@
|
||||
"name": "Clash Rule Provider",
|
||||
"description": "随时为Clash添加一些额外的规则。",
|
||||
"labels": "工具",
|
||||
"version": "1.3.2",
|
||||
"version": "1.3.3",
|
||||
"icon": "Mihomo_Meta_A.png",
|
||||
"author": "wumode",
|
||||
"level": 1,
|
||||
"release": true,
|
||||
"history": {
|
||||
"v1.3.3": "通过emoji识别国家; 按国家分组节点; mrs格式支持",
|
||||
"v1.3.2": "注册插件动作",
|
||||
"v1.3.1": "支持配置 Hosts",
|
||||
"v1.2.8": "改进导入界面",
|
||||
@@ -495,11 +512,13 @@
|
||||
"name": "美剧生词标注",
|
||||
"description": "根据CEFR等级,为英语影视剧标注高级词汇。",
|
||||
"labels": "英语",
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.1",
|
||||
"icon": "LexiAnnot.png",
|
||||
"author": "wumode",
|
||||
"level": 1,
|
||||
"history": {
|
||||
"v1.1.1": "添加任务页面; 改进 spaCy 模型加载逻辑",
|
||||
"v1.1.0": "支持考试词汇标注; 优化分词处理; 修复错误",
|
||||
"v1.0.1": "合并连字符词; 避免ARM平台依赖问题",
|
||||
"v1.0": "新增LexiAnnot"
|
||||
}
|
||||
|
||||
@@ -7,10 +7,6 @@ from typing import Any, List, Dict, Tuple, Optional
|
||||
from urllib.parse import urljoin
|
||||
|
||||
import pytz
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app import schemas
|
||||
from app.core.config import settings
|
||||
from app.core.event import eventmanager, Event
|
||||
@@ -26,6 +22,9 @@ from app.utils.http import RequestUtils
|
||||
from app.utils.site import SiteUtils
|
||||
from app.utils.string import StringUtils
|
||||
from app.utils.timer import TimerUtils
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
|
||||
class AutoSignIn(_PluginBase):
|
||||
@@ -36,7 +35,7 @@ class AutoSignIn(_PluginBase):
|
||||
# 插件图标
|
||||
plugin_icon = "signin.png"
|
||||
# 插件版本
|
||||
plugin_version = "2.6"
|
||||
plugin_version = "2.7"
|
||||
# 插件作者
|
||||
plugin_author = "thsrite"
|
||||
# 作者主页
|
||||
@@ -1545,6 +1544,7 @@ class AutoSignIn(_PluginBase):
|
||||
render = site_info.get("render")
|
||||
proxies = settings.PROXY if site_info.get("proxy") else None
|
||||
proxy_server = settings.PROXY_SERVER if site_info.get("proxy") else None
|
||||
timeout = site_info.get("timeout") or 60
|
||||
if not site_url or not site_cookie:
|
||||
logger.warn(f"未配置 {site} 的站点地址或Cookie,无法签到")
|
||||
return False, ""
|
||||
@@ -1560,7 +1560,8 @@ class AutoSignIn(_PluginBase):
|
||||
page_source = PlaywrightHelper().get_page_source(url=checkin_url,
|
||||
cookies=site_cookie,
|
||||
ua=ua,
|
||||
proxies=proxy_server)
|
||||
proxies=proxy_server,
|
||||
timeout=timeout)
|
||||
if not SiteUtils.is_logged_in(page_source):
|
||||
if under_challenge(page_source):
|
||||
return False, f"无法通过Cloudflare!"
|
||||
@@ -1574,13 +1575,15 @@ class AutoSignIn(_PluginBase):
|
||||
else:
|
||||
res = RequestUtils(cookies=site_cookie,
|
||||
ua=ua,
|
||||
proxies=proxies
|
||||
proxies=proxies,
|
||||
timeout=timeout
|
||||
).get_res(url=checkin_url)
|
||||
if not res and site_url != checkin_url:
|
||||
logger.info(f"开始站点模拟登录:{site},地址:{site_url}...")
|
||||
res = RequestUtils(cookies=site_cookie,
|
||||
ua=ua,
|
||||
proxies=proxies
|
||||
proxies=proxies,
|
||||
timeout=timeout
|
||||
).get_res(url=site_url)
|
||||
# 判断登录状态
|
||||
if res and res.status_code in [200, 500, 403]:
|
||||
@@ -1647,6 +1650,7 @@ class AutoSignIn(_PluginBase):
|
||||
render = site_info.get("render")
|
||||
proxies = settings.PROXY if site_info.get("proxy") else None
|
||||
proxy_server = settings.PROXY_SERVER if site_info.get("proxy") else None
|
||||
timeout = site_info.get("timeout") or 60
|
||||
if not site_url or not site_cookie:
|
||||
logger.warn(f"未配置 {site} 的站点地址或Cookie,无法签到")
|
||||
return False, ""
|
||||
@@ -1659,7 +1663,8 @@ class AutoSignIn(_PluginBase):
|
||||
page_source = PlaywrightHelper().get_page_source(url=site_url,
|
||||
cookies=site_cookie,
|
||||
ua=ua,
|
||||
proxies=proxy_server)
|
||||
proxies=proxy_server,
|
||||
timeout=timeout)
|
||||
if not SiteUtils.is_logged_in(page_source):
|
||||
if under_challenge(page_source):
|
||||
return False, f"无法通过Cloudflare!"
|
||||
@@ -1669,7 +1674,8 @@ class AutoSignIn(_PluginBase):
|
||||
else:
|
||||
res = RequestUtils(cookies=site_cookie,
|
||||
ua=ua,
|
||||
proxies=proxies
|
||||
proxies=proxies,
|
||||
timeout=timeout
|
||||
).get_res(url=site_url)
|
||||
# 判断登录状态
|
||||
if res and res.status_code in [200, 500, 403]:
|
||||
|
||||
@@ -2,13 +2,12 @@ import random
|
||||
import re
|
||||
from typing import Tuple
|
||||
|
||||
from lxml import etree
|
||||
|
||||
from app.core.config import settings
|
||||
from app.log import logger
|
||||
from app.plugins.autosignin.sites import _ISiteSigninHandler
|
||||
from app.utils.http import RequestUtils
|
||||
from app.utils.string import StringUtils
|
||||
from lxml import etree
|
||||
|
||||
|
||||
class Pt52(_ISiteSigninHandler):
|
||||
@@ -46,14 +45,16 @@ class Pt52(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
render = site_info.get("render")
|
||||
proxy = site_info.get("proxy")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 判断今日是否已签到
|
||||
html_text = self.get_page_source(url='https://52pt.site/bakatest.php',
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
return False, '签到失败,请检查站点连通性'
|
||||
@@ -97,14 +98,16 @@ class Pt52(_ISiteSigninHandler):
|
||||
site_cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
site=site)
|
||||
site=site,
|
||||
timeout=timeout)
|
||||
|
||||
def __signin(self, questionid: str,
|
||||
choice: list,
|
||||
site: str,
|
||||
site_cookie: str,
|
||||
ua: str,
|
||||
proxy: bool) -> Tuple[bool, str]:
|
||||
proxy: bool,
|
||||
timeout: int) -> Tuple[bool, str]:
|
||||
"""
|
||||
签到请求
|
||||
questionid: 450
|
||||
@@ -124,7 +127,8 @@ class Pt52(_ISiteSigninHandler):
|
||||
|
||||
sign_res = RequestUtils(cookies=site_cookie,
|
||||
ua=ua,
|
||||
proxies=settings.PROXY if proxy else None
|
||||
proxies=settings.PROXY if proxy else None,
|
||||
timeout=timeout
|
||||
).post_res(url='https://52pt.site/bakatest.php', data=data)
|
||||
if not sign_res or sign_res.status_code != 200:
|
||||
logger.error(f"{site} 签到失败,签到接口请求失败")
|
||||
|
||||
@@ -42,7 +42,8 @@ class _ISiteSigninHandler(metaclass=ABCMeta):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_page_source(url: str, cookie: str, ua: str, proxy: bool, render: bool, token: str = None) -> str:
|
||||
def get_page_source(url: str, cookie: str, ua: str, proxy: bool, render: bool,
|
||||
token: str = None, timeout: int = None) -> str:
|
||||
"""
|
||||
获取页面源码
|
||||
:param url: Url地址
|
||||
@@ -51,13 +52,15 @@ class _ISiteSigninHandler(metaclass=ABCMeta):
|
||||
:param proxy: 是否使用代理
|
||||
:param render: 是否渲染
|
||||
:param token: JWT Token
|
||||
:param timeout: 请求超时时间,单位秒
|
||||
:return: 页面源码,错误信息
|
||||
"""
|
||||
if render:
|
||||
return PlaywrightHelper().get_page_source(url=url,
|
||||
cookies=cookie,
|
||||
ua=ua,
|
||||
proxies=settings.PROXY_SERVER if proxy else None)
|
||||
proxies=settings.PROXY_SERVER if proxy else None,
|
||||
timeout=timeout or 60)
|
||||
else:
|
||||
if token:
|
||||
headers = {
|
||||
@@ -70,7 +73,8 @@ class _ISiteSigninHandler(metaclass=ABCMeta):
|
||||
"Cookie": cookie
|
||||
}
|
||||
res = RequestUtils(headers=headers,
|
||||
proxies=settings.PROXY if proxy else None).get_res(url=url)
|
||||
proxies=settings.PROXY if proxy else None,
|
||||
timeout=timeout or 20).get_res(url=url)
|
||||
if res is not None:
|
||||
# 使用chardet检测字符编码
|
||||
raw_data = res.content
|
||||
|
||||
@@ -37,6 +37,7 @@ class BTSchool(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
render = site_info.get("render")
|
||||
proxy = site_info.get("proxy")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
logger.info(f"{site} 开始签到")
|
||||
# 判断今日是否已签到
|
||||
@@ -44,7 +45,8 @@ class BTSchool(_ISiteSigninHandler):
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
@@ -63,7 +65,8 @@ class BTSchool(_ISiteSigninHandler):
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,签到接口请求失败")
|
||||
|
||||
@@ -47,13 +47,15 @@ class CHDBits(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
proxy = site_info.get("proxy")
|
||||
render = site_info.get("render")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 判断今日是否已签到
|
||||
html_text = self.get_page_source(url='https://ptchdbits.co/bakatest.php',
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
|
||||
@@ -37,21 +37,24 @@ class HaiDan(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
proxy = site_info.get("proxy")
|
||||
render = site_info.get("render")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 签到
|
||||
# 签到页会重定向到index.php,由于302重定向特性,导致index.php没有携带cookie
|
||||
self.get_page_source(url='https://www.haidan.video/signin.php',
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
|
||||
# 重新携带cookie获取index.php查看签到结果
|
||||
html_text = self.get_page_source(url='https://www.haidan.video/index.php',
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
return False, '签到失败,请检查站点连通性'
|
||||
|
||||
@@ -40,13 +40,15 @@ class Hares(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
proxy = site_info.get("proxy")
|
||||
render = site_info.get("render")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 获取页面html
|
||||
html_text = self.get_page_source(url='https://club.hares.top',
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
|
||||
if not html_text:
|
||||
logger.error(f"{site} 模拟访问失败,请检查站点连通性")
|
||||
@@ -66,7 +68,8 @@ class Hares(_ISiteSigninHandler):
|
||||
}
|
||||
sign_res = RequestUtils(cookies=site_cookie,
|
||||
headers=headers,
|
||||
proxies=settings.PROXY if proxy else None
|
||||
proxies=settings.PROXY if proxy else None,
|
||||
timeout=timeout
|
||||
).get_res(url="https://club.hares.top/attendance.php?action=sign")
|
||||
if not sign_res or sign_res.status_code != 200:
|
||||
logger.error(f"{site} 签到失败,签到接口请求失败")
|
||||
|
||||
@@ -40,6 +40,7 @@ class HDArea(_ISiteSigninHandler):
|
||||
site_cookie = site_info.get("cookie")
|
||||
ua = site_info.get("ua")
|
||||
proxies = settings.PROXY if site_info.get("proxy") else None
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 获取页面html
|
||||
data = {
|
||||
@@ -47,7 +48,8 @@ class HDArea(_ISiteSigninHandler):
|
||||
}
|
||||
html_res = RequestUtils(cookies=site_cookie,
|
||||
ua=ua,
|
||||
proxies=proxies
|
||||
proxies=proxies,
|
||||
timeout=timeout
|
||||
).post_res(url="https://hdarea.club/sign_in.php", data=data)
|
||||
if not html_res or html_res.status_code != 200:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
|
||||
@@ -40,6 +40,7 @@ class HDChina(_ISiteSigninHandler):
|
||||
site_cookie = site_info.get("cookie")
|
||||
ua = site_info.get("ua")
|
||||
proxies = settings.PROXY if site_info.get("proxy") else None
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 尝试解决瓷器cookie每天签到后过期,只保留hdchina=部分
|
||||
cookie = ""
|
||||
@@ -59,7 +60,8 @@ class HDChina(_ISiteSigninHandler):
|
||||
# 获取页面html
|
||||
html_res = RequestUtils(cookies=site_cookie,
|
||||
ua=ua,
|
||||
proxies=proxies
|
||||
proxies=proxies,
|
||||
timeout=timeout
|
||||
).get_res(url="https://hdchina.org/index.php")
|
||||
if not html_res or html_res.status_code != 200:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
@@ -99,7 +101,8 @@ class HDChina(_ISiteSigninHandler):
|
||||
}
|
||||
sign_res = RequestUtils(cookies=site_cookie,
|
||||
ua=ua,
|
||||
proxies=proxies
|
||||
proxies=proxies,
|
||||
timeout=timeout
|
||||
).post_res(url="https://hdchina.org/plugin_sign-in.php?cmd=signin", data=data)
|
||||
if not sign_res or sign_res.status_code != 200:
|
||||
logger.error(f"{site} 签到失败,签到接口请求失败")
|
||||
|
||||
@@ -39,13 +39,15 @@ class HDCity(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
proxy = site_info.get("proxy")
|
||||
render = site_info.get("render")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 获取页面html
|
||||
html_text = self.get_page_source(url='https://hdcity.city/sign',
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
return False, '签到失败,请检查站点连通性'
|
||||
|
||||
@@ -43,13 +43,15 @@ class HDSky(_ISiteSigninHandler):
|
||||
proxy = site_info.get("proxy")
|
||||
render = site_info.get("render")
|
||||
referer = site_info.get("url")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 判断今日是否已签到
|
||||
html_text = self.get_page_source(url='https://hdsky.me',
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
return False, '签到失败,请检查站点连通性'
|
||||
@@ -73,7 +75,8 @@ class HDSky(_ISiteSigninHandler):
|
||||
content_type='application/x-www-form-urlencoded; charset=UTF-8',
|
||||
referer="https://hdsky.me/index.php",
|
||||
accept_type="*/*",
|
||||
proxies=settings.PROXY if proxy else None
|
||||
proxies=settings.PROXY if proxy else None,
|
||||
timeout=timeout
|
||||
).post_res(url='https://hdsky.me/image_code_ajax.php',
|
||||
data={'action': 'new'})
|
||||
if image_res and image_res.status_code == 200:
|
||||
|
||||
@@ -41,13 +41,15 @@ class HDUpt(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
proxy = site_info.get("proxy")
|
||||
render = site_info.get("render")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 获取页面html
|
||||
html_text = self.get_page_source(url='https://pt.hdupt.com',
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
return False, '签到失败,请检查站点连通性'
|
||||
@@ -67,7 +69,8 @@ class HDUpt(_ISiteSigninHandler):
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
return False, '签到失败,请检查站点连通性'
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from typing import Tuple
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
@@ -38,10 +37,11 @@ class MTorrent(_ISiteSigninHandler):
|
||||
"Authorization": site_info.get("token")
|
||||
}
|
||||
url = site_info.get('url')
|
||||
timeout = site_info.get("timeout")
|
||||
domain = StringUtils.get_url_domain(url)
|
||||
# 更新最后访问时间
|
||||
res = RequestUtils(headers=headers,
|
||||
timeout=60,
|
||||
timeout=timeout,
|
||||
proxies=settings.PROXY if site_info.get("proxy") else None,
|
||||
referer=f"{url}index"
|
||||
).post_res(url=f"https://api.{domain}/api/member/updateLastBrowse")
|
||||
|
||||
@@ -40,6 +40,7 @@ class NexusHD(_ISiteSigninHandler):
|
||||
site_cookie = site_info.get("cookie")
|
||||
ua = site_info.get("ua")
|
||||
proxies = settings.PROXY if site_info.get("proxy") else None
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 获取页面html
|
||||
data = {
|
||||
@@ -48,7 +49,8 @@ class NexusHD(_ISiteSigninHandler):
|
||||
}
|
||||
html_res = RequestUtils(cookies=site_cookie,
|
||||
ua=ua,
|
||||
proxies=proxies
|
||||
proxies=proxies,
|
||||
timeout=timeout
|
||||
).post_res(url="https://v6.nexushd.org/signin.php", data=data)
|
||||
if not html_res or html_res.status_code != 200:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
|
||||
@@ -43,13 +43,15 @@ class Opencd(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
proxy = site_info.get("proxy")
|
||||
render = site_info.get("render")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 判断今日是否已签到
|
||||
html_text = self.get_page_source(url='https://www.open.cd',
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
return False, '签到失败,请检查站点连通性'
|
||||
|
||||
@@ -35,13 +35,15 @@ class PTerClub(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
proxy = site_info.get("proxy")
|
||||
render = site_info.get("render")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 签到
|
||||
html_text = self.get_page_source(url='https://pterclub.com/attendance-ajax.php',
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
return False, '签到失败,请检查站点连通性'
|
||||
|
||||
@@ -37,6 +37,7 @@ class PTTime(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
proxy = site_info.get("proxy")
|
||||
render = site_info.get("render")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 签到
|
||||
# 签到返回:<html><head></head><body>签到成功</body></html>
|
||||
@@ -44,7 +45,8 @@ class PTTime(_ISiteSigninHandler):
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
|
||||
@@ -57,6 +57,7 @@ class Tjupt(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
proxy = site_info.get("proxy")
|
||||
render = site_info.get("render")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 创建正确答案存储目录
|
||||
if not os.path.exists(os.path.dirname(self._answer_file)):
|
||||
@@ -67,7 +68,8 @@ class Tjupt(_ISiteSigninHandler):
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
|
||||
# 获取签到后返回html,判断是否签到成功
|
||||
if not html_text:
|
||||
|
||||
@@ -44,13 +44,15 @@ class TTG(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
proxy = site_info.get("proxy")
|
||||
render = site_info.get("render")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 获取页面html
|
||||
html_text = self.get_page_source(url="https://totheglory.im",
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
return False, '签到失败,请检查站点连通性'
|
||||
|
||||
@@ -50,6 +50,7 @@ class U2(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
proxy = site_info.get("proxy")
|
||||
render = site_info.get("render")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
now = datetime.datetime.now()
|
||||
# 判断当前时间是否小于9点
|
||||
@@ -62,7 +63,8 @@ class U2(_ISiteSigninHandler):
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
if not html_text:
|
||||
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||
return False, '签到失败,请检查站点连通性'
|
||||
|
||||
@@ -37,7 +37,7 @@ class YemaPT(_ISiteSigninHandler):
|
||||
}
|
||||
# 获取用户信息,更新最后访问时间
|
||||
res = (RequestUtils(headers=headers,
|
||||
timeout=15,
|
||||
timeout=site_info.get("timeout"),
|
||||
cookies=site_info.get("cookie"),
|
||||
proxies=settings.PROXY if site_info.get("proxy") else None,
|
||||
referer=site_info.get('url')
|
||||
@@ -64,7 +64,7 @@ class YemaPT(_ISiteSigninHandler):
|
||||
}
|
||||
# 获取用户信息,更新最后访问时间
|
||||
res = (RequestUtils(headers=headers,
|
||||
timeout=15,
|
||||
timeout=site_info.get("timeout"),
|
||||
cookies=site_info.get("cookie"),
|
||||
proxies=settings.PROXY if site_info.get("proxy") else None,
|
||||
referer=site_info.get('url')
|
||||
|
||||
@@ -38,13 +38,15 @@ class ZhuQue(_ISiteSigninHandler):
|
||||
ua = site_info.get("ua")
|
||||
proxy = site_info.get("proxy")
|
||||
render = site_info.get("render")
|
||||
timeout = site_info.get("timeout")
|
||||
|
||||
# 获取页面html
|
||||
html_text = self.get_page_source(url="https://zhuque.in",
|
||||
cookie=site_cookie,
|
||||
ua=ua,
|
||||
proxy=proxy,
|
||||
render=render)
|
||||
render=render,
|
||||
timeout=timeout)
|
||||
if not html_text:
|
||||
logger.error(f"{site} 模拟登录失败,请检查站点连通性")
|
||||
return False, '模拟登录失败,请检查站点连通性'
|
||||
@@ -73,7 +75,8 @@ class ZhuQue(_ISiteSigninHandler):
|
||||
}
|
||||
skill_res = RequestUtils(cookies=site_cookie,
|
||||
headers=headers,
|
||||
proxies=settings.PROXY if proxy else None
|
||||
proxies=settings.PROXY if proxy else None,
|
||||
timeout=timeout
|
||||
).post_res(url="https://zhuque.in/api/gaming/fireGenshinCharacterMagic", json=data)
|
||||
if not skill_res or skill_res.status_code != 200:
|
||||
logger.error(f"模拟登录失败,释放技能失败")
|
||||
|
||||
@@ -39,7 +39,7 @@ class ClashRuleProvider(_PluginBase):
|
||||
# 插件图标
|
||||
plugin_icon = "Mihomo_Meta_A.png"
|
||||
# 插件版本
|
||||
plugin_version = "1.3.2"
|
||||
plugin_version = "1.3.3"
|
||||
# 插件作者
|
||||
plugin_author = "wumode"
|
||||
# 作者主页
|
||||
@@ -71,8 +71,10 @@ class ClashRuleProvider(_PluginBase):
|
||||
_auto_update_subscriptions = True
|
||||
_ruleset_prefix: str = '📂<='
|
||||
_group_by_region: bool = False
|
||||
_group_by_country: bool = False
|
||||
_refresh_delay: int = 5
|
||||
_discard_rules: bool = False
|
||||
_discard_proxy_groups: bool = False
|
||||
_enable_acl4ssr: bool = False
|
||||
_dashboard_components: List[str] = []
|
||||
_clash_template_yaml: str = ''
|
||||
@@ -122,15 +124,15 @@ class ClashRuleProvider(_PluginBase):
|
||||
self._notify = config.get("notify"),
|
||||
self._sub_links = config.get("sub_links") or []
|
||||
self._clash_dashboard_url = config.get("clash_dashboard_url") or ''
|
||||
if self._clash_dashboard_url and self._clash_dashboard_url[-1] == '/':
|
||||
self._clash_dashboard_url = self._clash_dashboard_url[:-1]
|
||||
if self._clash_dashboard_url:
|
||||
self._clash_dashboard_url = self._clash_dashboard_url.rstrip("/")
|
||||
if not (self._clash_dashboard_url.startswith('http://') or
|
||||
self._clash_dashboard_url.startswith('https://')):
|
||||
self._clash_dashboard_url = 'http://' + self._clash_dashboard_url
|
||||
self._clash_dashboard_secret = config.get("clash_dashboard_secret")
|
||||
self._movie_pilot_url = config.get("movie_pilot_url")
|
||||
if self._movie_pilot_url and self._movie_pilot_url[-1] == '/':
|
||||
self._movie_pilot_url = self._movie_pilot_url[:-1]
|
||||
if self._movie_pilot_url:
|
||||
self._movie_pilot_url = self._movie_pilot_url.rstrip("/")
|
||||
self._cron = config.get("cron_string") or '30 12 * * *'
|
||||
self._timeout = config.get("timeout")
|
||||
self._retry_times = config.get("retry_times") or 3
|
||||
@@ -139,8 +141,10 @@ class ClashRuleProvider(_PluginBase):
|
||||
self._acl4ssr_prefix = config.get("acl4ssr_prefix", "🗂️=>")
|
||||
self._auto_update_subscriptions = config.get("auto_update_subscriptions")
|
||||
self._group_by_region = config.get("group_by_region")
|
||||
self._group_by_country = config.get("group_by_country") or False
|
||||
self._refresh_delay = config.get("refresh_delay") or 5
|
||||
self._discard_rules = config.get("discard_rules") or False
|
||||
self._discard_proxy_groups = config.get("discard_proxy_groups") or False
|
||||
self._enable_acl4ssr = config.get("enable_acl4ssr") or False
|
||||
self._dashboard_components = config.get("dashboard_components") or []
|
||||
self._clash_template_yaml = config.get("clash_template") or ''
|
||||
@@ -816,6 +820,8 @@ class ClashRuleProvider(_PluginBase):
|
||||
for key, value in new_value.items():
|
||||
if key == 'name' or value is None:
|
||||
continue
|
||||
if key == 'payload' and params.get('type') != 'inline':
|
||||
continue
|
||||
if value == '' or value is None:
|
||||
continue
|
||||
item[key] = value
|
||||
@@ -1119,8 +1125,6 @@ class ClashRuleProvider(_PluginBase):
|
||||
|
||||
def delete_rule_by_priority(self, priority: int, rule_parser: ClashRuleParser
|
||||
) -> Optional[Union[ClashRule, LogicRule, MatchRule]]:
|
||||
if not isinstance(priority, int):
|
||||
return None
|
||||
res = rule_parser.remove_rule_at_priority(priority)
|
||||
self.__save_data()
|
||||
return res
|
||||
@@ -1263,6 +1267,8 @@ class ClashRuleProvider(_PluginBase):
|
||||
logger.info(f"已更新: {url}. 节点数量: {len(rs['proxies'])}")
|
||||
if rs.get('rules') is None:
|
||||
rs['rules'] = []
|
||||
if self._discard_proxy_groups:
|
||||
rs['proxy-groups'] = []
|
||||
rs = self.__remove_nodes_by_keywords(rs)
|
||||
except Exception as e:
|
||||
logger.error(f"解析配置出错: {e}")
|
||||
@@ -1290,7 +1296,7 @@ class ClashRuleProvider(_PluginBase):
|
||||
).put(url)
|
||||
|
||||
def proxy_groups_by_region(self) -> List[Dict[str, Any]]:
|
||||
return ClashRuleProvider.__group_by_region(self._countries, self.all_proxies())
|
||||
return self.__group_by_region(self._countries, self.all_proxies())
|
||||
|
||||
@staticmethod
|
||||
def __load_countries(file_path: str) -> List:
|
||||
@@ -1301,40 +1307,71 @@ class ClashRuleProvider(_PluginBase):
|
||||
return []
|
||||
return countries
|
||||
|
||||
@staticmethod
|
||||
def __group_by_region(countries: List, proxies) -> List[Dict[str, Any]]:
|
||||
continents_nodes = {'Asia': [], 'Europe': [], 'SouthAmerica': [], 'NorthAmerica': [], 'Africa': [],
|
||||
'Oceania': [], 'AsiaExceptChina': []}
|
||||
def __group_by_region(self, countries: List, proxies) -> List[Dict[str, Any]]:
|
||||
continent_groups = {}
|
||||
country_groups = {}
|
||||
continent_map = {
|
||||
'欧洲': 'Europe',
|
||||
'亚洲': 'Asia',
|
||||
'大洋洲': 'Oceania',
|
||||
'非洲': 'Africa',
|
||||
'北美洲': 'NorthAmerica',
|
||||
'南美洲': 'SouthAmerica'
|
||||
}
|
||||
proxy_groups = []
|
||||
hk = next(filter(lambda c: c['abbr'] == 'HK', countries),
|
||||
{"abbr": "HK", "chinese": "中国香港特别行政区", "emoji": "🇭🇰"})
|
||||
tw = next(filter(lambda c: c['abbr'] == 'TW', countries),
|
||||
{"abbr": "TW", "chinese": "中国台湾", "emoji": "🇹🇼"})
|
||||
for proxy_node in proxies:
|
||||
continent = ClashRuleProvider.__continent_name_from_node(countries, proxy_node['name'])
|
||||
if not continent:
|
||||
country = ClashRuleProvider.__country_from_node(countries, proxy_node['name'])
|
||||
if not country:
|
||||
continue
|
||||
continents_nodes[continent].append(proxy_node['name'])
|
||||
for continent_nodes in continents_nodes:
|
||||
if len(continents_nodes[continent_nodes]):
|
||||
proxy_group = {'name': continent_nodes, 'type': 'select', 'proxies': continents_nodes[continent_nodes]}
|
||||
if country.get("abbr") == "CN":
|
||||
if any(key in proxy_node["name"] for key in ("🇭🇰", "HK", "香港")):
|
||||
country = hk
|
||||
if any(key in proxy_node["name"] for key in ("🇹🇼", "TW", "台湾")):
|
||||
country = tw
|
||||
continent = continent_map[country.get('continent')]
|
||||
if self._group_by_region:
|
||||
continent_groups.setdefault(continent, []).append(proxy_node['name'])
|
||||
if self._group_by_country:
|
||||
country_groups.setdefault(f"{country.get('emoji')} {country.get('chinese')}", []).append(
|
||||
proxy_node['name'])
|
||||
for continent, nodes in continent_groups.items():
|
||||
if len(nodes):
|
||||
proxy_group = {'name': continent, 'type': 'select', 'proxies': nodes}
|
||||
proxy_groups.append(proxy_group)
|
||||
for continent_node in continents_nodes['Asia']:
|
||||
if any(x in continent_node for x in ('中国', '香港', 'CN')):
|
||||
excluded = ('中国', '香港', 'CN', 'HK', '🇨🇳', '🇭🇰')
|
||||
for continent_node in continent_groups.get('Asia', []):
|
||||
if any(x in continent_node for x in excluded):
|
||||
continue
|
||||
continents_nodes['AsiaExceptChina'].append(continent_node)
|
||||
if continents_nodes['AsiaExceptChina']:
|
||||
proxy_group = {'name': 'AsiaExceptChina', 'type': 'select', 'proxies': continents_nodes['AsiaExceptChina']}
|
||||
continent_groups.setdefault('AsiaExceptChina', []).append(continent_node)
|
||||
if continent_groups.get('AsiaExceptChina'):
|
||||
proxy_group = {'name': 'AsiaExceptChina', 'type': 'select', 'proxies': continent_groups['AsiaExceptChina']}
|
||||
proxy_groups.append(proxy_group)
|
||||
for country, nodes in country_groups.items():
|
||||
if len(nodes):
|
||||
proxy_group = {'name': country, 'type': 'select', 'proxies': nodes}
|
||||
proxy_groups.append(proxy_group)
|
||||
country_group = list(country_groups.keys())
|
||||
if country_group:
|
||||
proxy_groups.append({'name': '🏴☠️国家分组', 'type': 'select', 'proxies': country_group})
|
||||
|
||||
return proxy_groups
|
||||
|
||||
@staticmethod
|
||||
def __continent_name_from_node(countries: List[Dict[str, str]], node_name: str) -> Optional[str]:
|
||||
continents_names = {'欧洲': 'Europe',
|
||||
'亚洲': 'Asia',
|
||||
'大洋洲': 'Oceania',
|
||||
'非洲': 'Africa',
|
||||
'北美洲': 'NorthAmerica',
|
||||
'南美洲': 'SouthAmerica'}
|
||||
def __country_from_node(countries: List[Dict[str, str]], node_name: str) -> Optional[Dict[str, str]]:
|
||||
node_name_lower = node_name.lower()
|
||||
for country in countries:
|
||||
if country['chinese'] in node_name or country['english'].lower() in node_name.lower():
|
||||
return continents_names[country['continent']]
|
||||
if country['emoji'] and country['emoji'] in node_name:
|
||||
return country
|
||||
elif (
|
||||
country['chinese'] in node_name
|
||||
or country['english'].lower() in node_name_lower
|
||||
):
|
||||
return country
|
||||
|
||||
return None
|
||||
|
||||
def __add_notification_job(self, ruleset_names: List[str]):
|
||||
@@ -1432,7 +1469,7 @@ class ClashRuleProvider(_PluginBase):
|
||||
clash_config['proxy-groups'] = ClashRuleProvider.extend_with_name_checking(clash_config['proxy-groups'],
|
||||
proxy_groups)
|
||||
# 添加按大洲代理组
|
||||
if self._group_by_region:
|
||||
if self._group_by_region or self._group_by_country:
|
||||
groups_by_region = self.proxy_groups_by_region()
|
||||
if groups_by_region:
|
||||
clash_config['proxy-groups'] = ClashRuleProvider.extend_with_name_checking(clash_config['proxy-groups'],
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +0,0 @@
|
||||
|
||||
.plugin-config[data-v-929102b8] {
|
||||
margin: 0 auto;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
4
plugins.v2/clashruleprovider/dist/assets/__federation_expose_Config-rtAetK-O.css
vendored
Normal file
4
plugins.v2/clashruleprovider/dist/assets/__federation_expose_Config-rtAetK-O.css
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
.plugin-config[data-v-c2db3dad] {
|
||||
margin: 0 auto;
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
|
||||
.plugin-page[data-v-d6db167c] {
|
||||
.plugin-page[data-v-6aba879d] {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* 使卡片等宽并适应移动端 */
|
||||
.d-flex.flex-wrap[data-v-d6db167c] {
|
||||
.d-flex.flex-wrap[data-v-6aba879d] {
|
||||
gap: 16px;
|
||||
}
|
||||
.url-display[data-v-d6db167c] {
|
||||
.url-display[data-v-6aba879d] {
|
||||
word-break: break-all;
|
||||
padding: 8px;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
@@ -16,19 +16,19 @@
|
||||
|
||||
/* 移动端堆叠布局 */
|
||||
@media (max-width: 768px) {
|
||||
.d-flex.flex-wrap[data-v-d6db167c] {
|
||||
.d-flex.flex-wrap[data-v-6aba879d] {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add visual distinction between sections */
|
||||
.ruleset-section[data-v-d6db167c] {
|
||||
.ruleset-section[data-v-6aba879d] {
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.top-section[data-v-d6db167c] {
|
||||
.top-section[data-v-6aba879d] {
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
@@ -36,15 +36,15 @@
|
||||
}
|
||||
|
||||
/* Optional: Add different border colors to further distinguish */
|
||||
.ruleset-section[data-v-d6db167c] {
|
||||
.ruleset-section[data-v-6aba879d] {
|
||||
border-left: 4px solid #2196F3; /* Blue accent */
|
||||
}
|
||||
.top-section[data-v-d6db167c] {
|
||||
.top-section[data-v-6aba879d] {
|
||||
border-left: 4px solid #4CAF50; /* Green accent */
|
||||
}
|
||||
.drag-handle[data-v-d6db167c] {
|
||||
.drag-handle[data-v-6aba879d] {
|
||||
cursor: move;
|
||||
}
|
||||
.gap-2[data-v-d6db167c] {
|
||||
.gap-2[data-v-6aba879d] {
|
||||
gap: 8px;
|
||||
}
|
||||
@@ -4733,7 +4733,7 @@ const importRuleTypes = ['YAML'];
|
||||
const importProxiesTypes = ['YAML', 'LINK'];
|
||||
const ruleProviderTypes = ['http', 'file', 'inline'];
|
||||
const ruleProviderBehaviorTypes = ['domain', 'ipcidr', 'classical'];
|
||||
const ruleProviderFormatTypes = ['yaml', 'text'];
|
||||
const ruleProviderFormatTypes = ['yaml', 'text', 'mrs'];
|
||||
// 修改actions为计算属性,合并内置动作和自定义出站
|
||||
const actions = computed(() => [
|
||||
'DIRECT', 'REJECT', 'REJECT-DROP', 'PASS', 'COMPATIBLE',
|
||||
@@ -5601,39 +5601,75 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_tab, null, {
|
||||
default: _withCtx(() => _cache[92] || (_cache[92] = [
|
||||
_createTextVNode("规则集规则")
|
||||
])),
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { start: "" }, {
|
||||
default: _withCtx(() => _cache[92] || (_cache[92] = [
|
||||
_createTextVNode("mdi-format-list-bulleted")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[93] || (_cache[93] = _createTextVNode(" 规则集规则 "))
|
||||
]),
|
||||
_: 1
|
||||
}),
|
||||
_createVNode(_component_v_tab, null, {
|
||||
default: _withCtx(() => _cache[93] || (_cache[93] = [
|
||||
_createTextVNode("置顶规则")
|
||||
])),
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { start: "" }, {
|
||||
default: _withCtx(() => _cache[94] || (_cache[94] = [
|
||||
_createTextVNode("mdi-pin")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[95] || (_cache[95] = _createTextVNode(" 置顶规则 "))
|
||||
]),
|
||||
_: 1
|
||||
}),
|
||||
_createVNode(_component_v_tab, null, {
|
||||
default: _withCtx(() => _cache[94] || (_cache[94] = [
|
||||
_createTextVNode("代理组")
|
||||
])),
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { start: "" }, {
|
||||
default: _withCtx(() => _cache[96] || (_cache[96] = [
|
||||
_createTextVNode("mdi-source-branch")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[97] || (_cache[97] = _createTextVNode(" 代理组 "))
|
||||
]),
|
||||
_: 1
|
||||
}),
|
||||
_createVNode(_component_v_tab, null, {
|
||||
default: _withCtx(() => _cache[95] || (_cache[95] = [
|
||||
_createTextVNode("出站代理")
|
||||
])),
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { start: "" }, {
|
||||
default: _withCtx(() => _cache[98] || (_cache[98] = [
|
||||
_createTextVNode("mdi-rocket-launch")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[99] || (_cache[99] = _createTextVNode(" 出站代理 "))
|
||||
]),
|
||||
_: 1
|
||||
}),
|
||||
_createVNode(_component_v_tab, null, {
|
||||
default: _withCtx(() => _cache[96] || (_cache[96] = [
|
||||
_createTextVNode("规则集合")
|
||||
])),
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { start: "" }, {
|
||||
default: _withCtx(() => _cache[100] || (_cache[100] = [
|
||||
_createTextVNode("mdi-folder-multiple")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[101] || (_cache[101] = _createTextVNode(" 规则集合 "))
|
||||
]),
|
||||
_: 1
|
||||
}),
|
||||
_createVNode(_component_v_tab, null, {
|
||||
default: _withCtx(() => _cache[97] || (_cache[97] = [
|
||||
_createTextVNode("Hosts")
|
||||
])),
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { start: "" }, {
|
||||
default: _withCtx(() => _cache[102] || (_cache[102] = [
|
||||
_createTextVNode("mdi-lan")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[103] || (_cache[103] = _createTextVNode(" Hosts "))
|
||||
]),
|
||||
_: 1
|
||||
})
|
||||
]),
|
||||
@@ -5649,7 +5685,7 @@ return (_ctx, _cache) => {
|
||||
_createElementVNode("div", _hoisted_3, [
|
||||
_createElementVNode("div", _hoisted_4, [
|
||||
_createElementVNode("div", _hoisted_5, [
|
||||
_cache[100] || (_cache[100] = _createElementVNode("div", { class: "text-h6" }, "规则集规则", -1)),
|
||||
_cache[106] || (_cache[106] = _createElementVNode("div", { class: "text-h6" }, "规则集规则", -1)),
|
||||
_createElementVNode("div", _hoisted_6, [
|
||||
_createVNode(_component_v_text_field, {
|
||||
modelValue: searchRulesetRule.value,
|
||||
@@ -5668,12 +5704,12 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { left: "" }, {
|
||||
default: _withCtx(() => _cache[98] || (_cache[98] = [
|
||||
default: _withCtx(() => _cache[104] || (_cache[104] = [
|
||||
_createTextVNode("mdi-plus")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[99] || (_cache[99] = _createTextVNode(" 添加规则 "))
|
||||
_cache[105] || (_cache[105] = _createTextVNode(" 添加规则 "))
|
||||
]),
|
||||
_: 1
|
||||
})
|
||||
@@ -5702,7 +5738,7 @@ return (_ctx, _cache) => {
|
||||
}, [
|
||||
_createElementVNode("td", null, [
|
||||
_createVNode(_component_v_icon, { class: "drag-handle" }, {
|
||||
default: _withCtx(() => _cache[101] || (_cache[101] = [
|
||||
default: _withCtx(() => _cache[107] || (_cache[107] = [
|
||||
_createTextVNode("mdi-drag")
|
||||
])),
|
||||
_: 1
|
||||
@@ -5733,7 +5769,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[102] || (_cache[102] = [
|
||||
default: _withCtx(() => _cache[108] || (_cache[108] = [
|
||||
_createTextVNode("mdi-pencil")
|
||||
])),
|
||||
_: 1
|
||||
@@ -5750,7 +5786,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[103] || (_cache[103] = [
|
||||
default: _withCtx(() => _cache[109] || (_cache[109] = [
|
||||
_createTextVNode("mdi-delete")
|
||||
])),
|
||||
_: 1
|
||||
@@ -5790,7 +5826,7 @@ return (_ctx, _cache) => {
|
||||
]),
|
||||
_: 1
|
||||
}, 8, ["headers", "items", "search", "page", "items-per-page", "items-per-page-options"]),
|
||||
_cache[104] || (_cache[104] = _createElementVNode("div", { class: "text-caption text-grey mt-2" }, " *对规则集中规则的修改可以在Clash中立即生效。 ", -1))
|
||||
_cache[110] || (_cache[110] = _createElementVNode("div", { class: "text-caption text-grey mt-2" }, " *对规则集中规则的修改可以在Clash中立即生效。 ", -1))
|
||||
])
|
||||
]),
|
||||
_: 1
|
||||
@@ -5800,7 +5836,7 @@ return (_ctx, _cache) => {
|
||||
_createElementVNode("div", _hoisted_11, [
|
||||
_createElementVNode("div", _hoisted_12, [
|
||||
_createElementVNode("div", _hoisted_13, [
|
||||
_cache[109] || (_cache[109] = _createElementVNode("div", { class: "text-h6" }, "置顶规则", -1)),
|
||||
_cache[115] || (_cache[115] = _createElementVNode("div", { class: "text-h6" }, "置顶规则", -1)),
|
||||
_createElementVNode("div", _hoisted_14, [
|
||||
_createVNode(_component_v_text_field, {
|
||||
modelValue: searchTopRule.value,
|
||||
@@ -5820,12 +5856,12 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { left: "" }, {
|
||||
default: _withCtx(() => _cache[105] || (_cache[105] = [
|
||||
default: _withCtx(() => _cache[111] || (_cache[111] = [
|
||||
_createTextVNode("mdi-import")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[106] || (_cache[106] = _createTextVNode(" 导入规则 "))
|
||||
_cache[112] || (_cache[112] = _createTextVNode(" 导入规则 "))
|
||||
]),
|
||||
_: 1
|
||||
}),
|
||||
@@ -5835,12 +5871,12 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { left: "" }, {
|
||||
default: _withCtx(() => _cache[107] || (_cache[107] = [
|
||||
default: _withCtx(() => _cache[113] || (_cache[113] = [
|
||||
_createTextVNode("mdi-plus")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[108] || (_cache[108] = _createTextVNode(" 添加规则 "))
|
||||
_cache[114] || (_cache[114] = _createTextVNode(" 添加规则 "))
|
||||
]),
|
||||
_: 1
|
||||
})
|
||||
@@ -5869,7 +5905,7 @@ return (_ctx, _cache) => {
|
||||
}, [
|
||||
_createElementVNode("td", null, [
|
||||
_createVNode(_component_v_icon, { class: "drag-handle" }, {
|
||||
default: _withCtx(() => _cache[110] || (_cache[110] = [
|
||||
default: _withCtx(() => _cache[116] || (_cache[116] = [
|
||||
_createTextVNode("mdi-drag")
|
||||
])),
|
||||
_: 1
|
||||
@@ -5900,7 +5936,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[111] || (_cache[111] = [
|
||||
default: _withCtx(() => _cache[117] || (_cache[117] = [
|
||||
_createTextVNode("mdi-pencil")
|
||||
])),
|
||||
_: 1
|
||||
@@ -5918,7 +5954,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[112] || (_cache[112] = [
|
||||
default: _withCtx(() => _cache[118] || (_cache[118] = [
|
||||
_createTextVNode("mdi-delete")
|
||||
])),
|
||||
_: 1
|
||||
@@ -5932,7 +5968,7 @@ return (_ctx, _cache) => {
|
||||
activator: "parent",
|
||||
location: "top"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[113] || (_cache[113] = [
|
||||
default: _withCtx(() => _cache[119] || (_cache[119] = [
|
||||
_createTextVNode(" 根据规则集自动添加 ")
|
||||
])),
|
||||
_: 1
|
||||
@@ -5970,8 +6006,8 @@ return (_ctx, _cache) => {
|
||||
]),
|
||||
_: 1
|
||||
}, 8, ["headers", "search", "items", "page", "items-per-page"]),
|
||||
_cache[114] || (_cache[114] = _createElementVNode("div", { class: "text-caption text-grey mt-2" }, " *置顶规则用于管理来自规则集的匹配规则,这些规则会动态更新。 ", -1)),
|
||||
_cache[115] || (_cache[115] = _createElementVNode("div", { class: "text-caption text-grey mt-2" }, " *对置顶规则的修改只有Clash更新配置后才会生效。 ", -1))
|
||||
_cache[120] || (_cache[120] = _createElementVNode("div", { class: "text-caption text-grey mt-2" }, " *置顶规则用于管理来自规则集的匹配规则,这些规则会动态更新。 ", -1)),
|
||||
_cache[121] || (_cache[121] = _createElementVNode("div", { class: "text-caption text-grey mt-2" }, " *对置顶规则的修改只有Clash更新配置后才会生效。 ", -1))
|
||||
])
|
||||
]),
|
||||
_: 1
|
||||
@@ -5981,7 +6017,7 @@ return (_ctx, _cache) => {
|
||||
_createElementVNode("div", _hoisted_19, [
|
||||
_createElementVNode("div", _hoisted_20, [
|
||||
_createElementVNode("div", _hoisted_21, [
|
||||
_cache[118] || (_cache[118] = _createElementVNode("div", { class: "text-h6" }, "代理组", -1)),
|
||||
_cache[124] || (_cache[124] = _createElementVNode("div", { class: "text-h6" }, "代理组", -1)),
|
||||
_createElementVNode("div", _hoisted_22, [
|
||||
_createVNode(_component_v_btn, {
|
||||
color: "primary",
|
||||
@@ -5989,12 +6025,12 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { left: "" }, {
|
||||
default: _withCtx(() => _cache[116] || (_cache[116] = [
|
||||
default: _withCtx(() => _cache[122] || (_cache[122] = [
|
||||
_createTextVNode("mdi-plus")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[117] || (_cache[117] = _createTextVNode(" 添加代理组 "))
|
||||
_cache[123] || (_cache[123] = _createTextVNode(" 添加代理组 "))
|
||||
]),
|
||||
_: 1
|
||||
})
|
||||
@@ -6026,7 +6062,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[119] || (_cache[119] = [
|
||||
default: _withCtx(() => _cache[125] || (_cache[125] = [
|
||||
_createTextVNode("mdi-code-json")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6044,7 +6080,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[120] || (_cache[120] = [
|
||||
default: _withCtx(() => _cache[126] || (_cache[126] = [
|
||||
_createTextVNode("mdi-pencil")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6062,7 +6098,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[121] || (_cache[121] = [
|
||||
default: _withCtx(() => _cache[127] || (_cache[127] = [
|
||||
_createTextVNode("mdi-delete")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6076,7 +6112,7 @@ return (_ctx, _cache) => {
|
||||
activator: "parent",
|
||||
location: "top"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[122] || (_cache[122] = [
|
||||
default: _withCtx(() => _cache[128] || (_cache[128] = [
|
||||
_createTextVNode(" 非手动添加 ")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6114,7 +6150,7 @@ return (_ctx, _cache) => {
|
||||
]),
|
||||
_: 1
|
||||
}, 8, ["headers", "items", "page", "items-per-page"]),
|
||||
_cache[123] || (_cache[123] = _createElementVNode("div", { class: "text-caption text-grey mt-2" }, null, -1))
|
||||
_cache[129] || (_cache[129] = _createElementVNode("div", { class: "text-caption text-grey mt-2" }, null, -1))
|
||||
])
|
||||
]),
|
||||
_: 1
|
||||
@@ -6124,7 +6160,7 @@ return (_ctx, _cache) => {
|
||||
_createElementVNode("div", _hoisted_26, [
|
||||
_createElementVNode("div", _hoisted_27, [
|
||||
_createElementVNode("div", _hoisted_28, [
|
||||
_cache[126] || (_cache[126] = _createElementVNode("div", { class: "text-h6" }, "出站代理", -1)),
|
||||
_cache[132] || (_cache[132] = _createElementVNode("div", { class: "text-h6" }, "出站代理", -1)),
|
||||
_createElementVNode("div", _hoisted_29, [
|
||||
_createVNode(_component_v_btn, {
|
||||
color: "primary",
|
||||
@@ -6132,12 +6168,12 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { left: "" }, {
|
||||
default: _withCtx(() => _cache[124] || (_cache[124] = [
|
||||
default: _withCtx(() => _cache[130] || (_cache[130] = [
|
||||
_createTextVNode("mdi-plus")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[125] || (_cache[125] = _createTextVNode(" 导入节点 "))
|
||||
_cache[131] || (_cache[131] = _createTextVNode(" 导入节点 "))
|
||||
]),
|
||||
_: 1
|
||||
})
|
||||
@@ -6171,7 +6207,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[127] || (_cache[127] = [
|
||||
default: _withCtx(() => _cache[133] || (_cache[133] = [
|
||||
_createTextVNode("mdi-code-json")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6189,7 +6225,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[128] || (_cache[128] = [
|
||||
default: _withCtx(() => _cache[134] || (_cache[134] = [
|
||||
_createTextVNode("mdi-delete")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6203,7 +6239,7 @@ return (_ctx, _cache) => {
|
||||
activator: "parent",
|
||||
location: "top"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[129] || (_cache[129] = [
|
||||
default: _withCtx(() => _cache[135] || (_cache[135] = [
|
||||
_createTextVNode(" 非手动添加 ")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6241,7 +6277,7 @@ return (_ctx, _cache) => {
|
||||
]),
|
||||
_: 1
|
||||
}, 8, ["headers", "items", "page", "items-per-page"]),
|
||||
_cache[130] || (_cache[130] = _createElementVNode("div", { class: "text-caption text-grey mt-2" }, null, -1))
|
||||
_cache[136] || (_cache[136] = _createElementVNode("div", { class: "text-caption text-grey mt-2" }, null, -1))
|
||||
])
|
||||
]),
|
||||
_: 1
|
||||
@@ -6251,7 +6287,7 @@ return (_ctx, _cache) => {
|
||||
_createElementVNode("div", _hoisted_33, [
|
||||
_createElementVNode("div", _hoisted_34, [
|
||||
_createElementVNode("div", _hoisted_35, [
|
||||
_cache[133] || (_cache[133] = _createElementVNode("div", { class: "text-h6" }, "规则集合", -1)),
|
||||
_cache[139] || (_cache[139] = _createElementVNode("div", { class: "text-h6" }, "规则集合", -1)),
|
||||
_createElementVNode("div", _hoisted_36, [
|
||||
_createVNode(_component_v_text_field, {
|
||||
modelValue: searchRuleProviders.value,
|
||||
@@ -6270,12 +6306,12 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { left: "" }, {
|
||||
default: _withCtx(() => _cache[131] || (_cache[131] = [
|
||||
default: _withCtx(() => _cache[137] || (_cache[137] = [
|
||||
_createTextVNode("mdi-plus")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[132] || (_cache[132] = _createTextVNode(" 添加规则集合 "))
|
||||
_cache[138] || (_cache[138] = _createTextVNode(" 添加规则集合 "))
|
||||
]),
|
||||
_: 1
|
||||
})
|
||||
@@ -6311,7 +6347,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[134] || (_cache[134] = [
|
||||
default: _withCtx(() => _cache[140] || (_cache[140] = [
|
||||
_createTextVNode("mdi-pencil")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6329,7 +6365,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[135] || (_cache[135] = [
|
||||
default: _withCtx(() => _cache[141] || (_cache[141] = [
|
||||
_createTextVNode("mdi-delete")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6343,7 +6379,7 @@ return (_ctx, _cache) => {
|
||||
activator: "parent",
|
||||
location: "top"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[136] || (_cache[136] = [
|
||||
default: _withCtx(() => _cache[142] || (_cache[142] = [
|
||||
_createTextVNode(" 非手动添加 ")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6390,7 +6426,7 @@ return (_ctx, _cache) => {
|
||||
_createElementVNode("div", _hoisted_40, [
|
||||
_createElementVNode("div", _hoisted_41, [
|
||||
_createElementVNode("div", _hoisted_42, [
|
||||
_cache[139] || (_cache[139] = _createElementVNode("div", { class: "text-h6" }, "Hosts", -1)),
|
||||
_cache[145] || (_cache[145] = _createElementVNode("div", { class: "text-h6" }, "Hosts", -1)),
|
||||
_createElementVNode("div", _hoisted_43, [
|
||||
_createVNode(_component_v_text_field, {
|
||||
modelValue: searchHosts.value,
|
||||
@@ -6409,12 +6445,12 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { left: "" }, {
|
||||
default: _withCtx(() => _cache[137] || (_cache[137] = [
|
||||
default: _withCtx(() => _cache[143] || (_cache[143] = [
|
||||
_createTextVNode("mdi-plus")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[138] || (_cache[138] = _createTextVNode(" 添加Hosts "))
|
||||
_cache[144] || (_cache[144] = _createTextVNode(" 添加Hosts "))
|
||||
]),
|
||||
_: 1
|
||||
})
|
||||
@@ -6470,7 +6506,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[140] || (_cache[140] = [
|
||||
default: _withCtx(() => _cache[146] || (_cache[146] = [
|
||||
_createTextVNode("mdi-pencil")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6487,7 +6523,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[141] || (_cache[141] = [
|
||||
default: _withCtx(() => _cache[147] || (_cache[147] = [
|
||||
_createTextVNode("mdi-delete")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6548,7 +6584,7 @@ return (_ctx, _cache) => {
|
||||
_createVNode(_component_v_card, { class: "h-100" }, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_card_title, { class: "text-h6 font-weight-medium" }, {
|
||||
default: _withCtx(() => _cache[142] || (_cache[142] = [
|
||||
default: _withCtx(() => _cache[148] || (_cache[148] = [
|
||||
_createTextVNode("状态信息")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6557,7 +6593,7 @@ return (_ctx, _cache) => {
|
||||
default: _withCtx(() => [
|
||||
_createElementVNode("div", _hoisted_47, [
|
||||
_createElementVNode("div", _hoisted_48, [
|
||||
_cache[143] || (_cache[143] = _createElementVNode("span", null, "状态", -1)),
|
||||
_cache[149] || (_cache[149] = _createElementVNode("span", null, "状态", -1)),
|
||||
_createVNode(_component_v_chip, {
|
||||
size: "small",
|
||||
color: status.value === 'running' ? 'success' : 'warning'
|
||||
@@ -6569,23 +6605,23 @@ return (_ctx, _cache) => {
|
||||
}, 8, ["color"])
|
||||
]),
|
||||
_createElementVNode("div", _hoisted_49, [
|
||||
_cache[144] || (_cache[144] = _createElementVNode("span", null, "订阅配置规则数", -1)),
|
||||
_cache[150] || (_cache[150] = _createElementVNode("span", null, "订阅配置规则数", -1)),
|
||||
_createElementVNode("span", null, _toDisplayString(subscriptionInfo.value.rule_size), 1)
|
||||
]),
|
||||
_createElementVNode("div", _hoisted_50, [
|
||||
_cache[145] || (_cache[145] = _createElementVNode("span", null, "置顶规则数", -1)),
|
||||
_cache[151] || (_cache[151] = _createElementVNode("span", null, "置顶规则数", -1)),
|
||||
_createElementVNode("span", null, _toDisplayString(sortedRules.value.length), 1)
|
||||
]),
|
||||
_createElementVNode("div", _hoisted_51, [
|
||||
_cache[146] || (_cache[146] = _createElementVNode("span", null, "规则集规则数", -1)),
|
||||
_cache[152] || (_cache[152] = _createElementVNode("span", null, "规则集规则数", -1)),
|
||||
_createElementVNode("span", null, _toDisplayString(sortedRulesetRules.value.length), 1)
|
||||
]),
|
||||
_createElementVNode("div", _hoisted_52, [
|
||||
_cache[147] || (_cache[147] = _createElementVNode("span", null, "代理组数", -1)),
|
||||
_cache[153] || (_cache[153] = _createElementVNode("span", null, "代理组数", -1)),
|
||||
_createElementVNode("span", null, _toDisplayString(proxyGroups.value.length), 1)
|
||||
]),
|
||||
_createElementVNode("div", _hoisted_53, [
|
||||
_cache[148] || (_cache[148] = _createElementVNode("span", null, "最后更新", -1)),
|
||||
_cache[154] || (_cache[154] = _createElementVNode("span", null, "最后更新", -1)),
|
||||
_createElementVNode("span", null, _toDisplayString(lastUpdated.value), 1)
|
||||
])
|
||||
])
|
||||
@@ -6607,7 +6643,7 @@ return (_ctx, _cache) => {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_card_title, { class: "d-flex justify-space-between align-center" }, {
|
||||
default: _withCtx(() => [
|
||||
_cache[150] || (_cache[150] = _createElementVNode("span", { class: "text-h6 font-weight-medium" }, "订阅链接", -1)),
|
||||
_cache[156] || (_cache[156] = _createElementVNode("span", { class: "text-h6 font-weight-medium" }, "订阅链接", -1)),
|
||||
_createVNode(_component_v_tooltip, {
|
||||
location: "top",
|
||||
text: "复制链接"
|
||||
@@ -6623,7 +6659,7 @@ return (_ctx, _cache) => {
|
||||
}), {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, null, {
|
||||
default: _withCtx(() => _cache[149] || (_cache[149] = [
|
||||
default: _withCtx(() => _cache[155] || (_cache[155] = [
|
||||
_createTextVNode("mdi-content-copy")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6647,12 +6683,12 @@ return (_ctx, _cache) => {
|
||||
color: "grey",
|
||||
class: "mr-2"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[151] || (_cache[151] = [
|
||||
default: _withCtx(() => _cache[157] || (_cache[157] = [
|
||||
_createTextVNode("mdi-link")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[152] || (_cache[152] = _createElementVNode("span", { class: "text-grey-darken-1" }, "原始链接:", -1))
|
||||
_cache[158] || (_cache[158] = _createElementVNode("span", { class: "text-grey-darken-1" }, "原始链接:", -1))
|
||||
]),
|
||||
_createElementVNode("div", _hoisted_56, [
|
||||
(Object.keys(subscriptionsInfo.value).length > 0)
|
||||
@@ -6673,7 +6709,7 @@ return (_ctx, _cache) => {
|
||||
]),
|
||||
_createElementVNode("div", _hoisted_58, [
|
||||
_createVNode(_component_v_icon, { color: "blue" }, {
|
||||
default: _withCtx(() => _cache[153] || (_cache[153] = [
|
||||
default: _withCtx(() => _cache[159] || (_cache[159] = [
|
||||
_createTextVNode("mdi-arrow-down-bold")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6684,12 +6720,12 @@ return (_ctx, _cache) => {
|
||||
color: "primary",
|
||||
class: "mr-2"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[154] || (_cache[154] = [
|
||||
default: _withCtx(() => _cache[160] || (_cache[160] = [
|
||||
_createTextVNode("mdi-link-variant")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[155] || (_cache[155] = _createElementVNode("span", { class: "text-grey-darken-1" }, "生成链接:", -1))
|
||||
_cache[161] || (_cache[161] = _createElementVNode("span", { class: "text-grey-darken-1" }, "生成链接:", -1))
|
||||
]),
|
||||
_createElementVNode("div", _hoisted_60, [
|
||||
_createElementVNode("a", {
|
||||
@@ -6723,12 +6759,12 @@ return (_ctx, _cache) => {
|
||||
_createVNode(_component_v_expansion_panel_title, null, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { left: "" }, {
|
||||
default: _withCtx(() => _cache[156] || (_cache[156] = [
|
||||
default: _withCtx(() => _cache[162] || (_cache[162] = [
|
||||
_createTextVNode("mdi-cloud-download")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[157] || (_cache[157] = _createElementVNode("span", { class: "text-subtitle-1 font-weight-medium" }, "订阅管理", -1))
|
||||
_cache[163] || (_cache[163] = _createElementVNode("span", { class: "text-subtitle-1 font-weight-medium" }, "订阅管理", -1))
|
||||
]),
|
||||
_: 1
|
||||
}),
|
||||
@@ -6741,7 +6777,7 @@ return (_ctx, _cache) => {
|
||||
variant: "tonal",
|
||||
class: "mb-4"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[158] || (_cache[158] = [
|
||||
default: _withCtx(() => _cache[164] || (_cache[164] = [
|
||||
_createTextVNode(" 暂无订阅信息,请先添加订阅链接 ")
|
||||
])),
|
||||
_: 1
|
||||
@@ -6827,11 +6863,11 @@ return (_ctx, _cache) => {
|
||||
: _createCommentVNode("", true)
|
||||
]),
|
||||
_createElementVNode("div", _hoisted_64, [
|
||||
_cache[159] || (_cache[159] = _createElementVNode("span", null, "已用流量:", -1)),
|
||||
_cache[165] || (_cache[165] = _createElementVNode("span", null, "已用流量:", -1)),
|
||||
_createElementVNode("strong", null, _toDisplayString(formatBytes(info.download + info.upload)), 1)
|
||||
]),
|
||||
_createElementVNode("div", _hoisted_65, [
|
||||
_cache[160] || (_cache[160] = _createElementVNode("span", null, "剩余流量:", -1)),
|
||||
_cache[166] || (_cache[166] = _createElementVNode("span", null, "剩余流量:", -1)),
|
||||
_createElementVNode("strong", null, _toDisplayString(formatBytes(info.total - info.download)), 1)
|
||||
]),
|
||||
_createVNode(_component_v_progress_linear, {
|
||||
@@ -6860,12 +6896,12 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { left: "" }, {
|
||||
default: _withCtx(() => _cache[161] || (_cache[161] = [
|
||||
default: _withCtx(() => _cache[167] || (_cache[167] = [
|
||||
_createTextVNode("mdi-cloud-sync")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[162] || (_cache[162] = _createTextVNode(" 更新订阅 "))
|
||||
_cache[168] || (_cache[168] = _createTextVNode(" 更新订阅 "))
|
||||
]),
|
||||
_: 2
|
||||
}, 1032, ["onClick", "loading"])
|
||||
@@ -6899,12 +6935,12 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { left: "" }, {
|
||||
default: _withCtx(() => _cache[163] || (_cache[163] = [
|
||||
default: _withCtx(() => _cache[169] || (_cache[169] = [
|
||||
_createTextVNode("mdi-refresh")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[164] || (_cache[164] = _createTextVNode(" 刷新数据 "))
|
||||
_cache[170] || (_cache[170] = _createTextVNode(" 刷新数据 "))
|
||||
]),
|
||||
_: 1
|
||||
}, 8, ["loading"]),
|
||||
@@ -6915,12 +6951,12 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { left: "" }, {
|
||||
default: _withCtx(() => _cache[165] || (_cache[165] = [
|
||||
default: _withCtx(() => _cache[171] || (_cache[171] = [
|
||||
_createTextVNode("mdi-cog")
|
||||
])),
|
||||
_: 1
|
||||
}),
|
||||
_cache[166] || (_cache[166] = _createTextVNode(" 配置 "))
|
||||
_cache[172] || (_cache[172] = _createTextVNode(" 配置 "))
|
||||
]),
|
||||
_: 1
|
||||
})
|
||||
@@ -7075,7 +7111,7 @@ return (_ctx, _cache) => {
|
||||
color: "secondary",
|
||||
onClick: closeRuleDialog
|
||||
}, {
|
||||
default: _withCtx(() => _cache[167] || (_cache[167] = [
|
||||
default: _withCtx(() => _cache[173] || (_cache[173] = [
|
||||
_createTextVNode("取消")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7084,7 +7120,7 @@ return (_ctx, _cache) => {
|
||||
color: "primary",
|
||||
type: "submit"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[168] || (_cache[168] = [
|
||||
default: _withCtx(() => _cache[174] || (_cache[174] = [
|
||||
_createTextVNode("保存")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7300,7 +7336,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
"prepend-inner": _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { color: "warning" }, {
|
||||
default: _withCtx(() => _cache[169] || (_cache[169] = [
|
||||
default: _withCtx(() => _cache[175] || (_cache[175] = [
|
||||
_createTextVNode("mdi-timer")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7330,7 +7366,7 @@ return (_ctx, _cache) => {
|
||||
}, {
|
||||
"prepend-inner": _withCtx(() => [
|
||||
_createVNode(_component_v_icon, { color: "warning" }, {
|
||||
default: _withCtx(() => _cache[170] || (_cache[170] = [
|
||||
default: _withCtx(() => _cache[176] || (_cache[176] = [
|
||||
_createTextVNode("mdi-timer")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7461,7 +7497,7 @@ return (_ctx, _cache) => {
|
||||
text: "",
|
||||
variant: "tonal"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[171] || (_cache[171] = [
|
||||
default: _withCtx(() => _cache[177] || (_cache[177] = [
|
||||
_createTextVNode(" 参考"),
|
||||
_createElementVNode("a", {
|
||||
href: "https://wiki.metacubex.one/config/proxy-groups/",
|
||||
@@ -7477,7 +7513,7 @@ return (_ctx, _cache) => {
|
||||
color: "secondary",
|
||||
onClick: _cache[59] || (_cache[59] = $event => (proxyGroupDialog.value = false))
|
||||
}, {
|
||||
default: _withCtx(() => _cache[172] || (_cache[172] = [
|
||||
default: _withCtx(() => _cache[178] || (_cache[178] = [
|
||||
_createTextVNode("取消")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7486,7 +7522,7 @@ return (_ctx, _cache) => {
|
||||
color: "primary",
|
||||
type: "submit"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[173] || (_cache[173] = [
|
||||
default: _withCtx(() => _cache[179] || (_cache[179] = [
|
||||
_createTextVNode("保存")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7512,7 +7548,7 @@ return (_ctx, _cache) => {
|
||||
_createVNode(_component_v_card, null, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_card_title, { class: "headline" }, {
|
||||
default: _withCtx(() => _cache[174] || (_cache[174] = [
|
||||
default: _withCtx(() => _cache[180] || (_cache[180] = [
|
||||
_createTextVNode("YAML 配置")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7538,7 +7574,7 @@ return (_ctx, _cache) => {
|
||||
color: "primary",
|
||||
onClick: _cache[62] || (_cache[62] = $event => (copyToClipboard(displayedYaml.value)))
|
||||
}, {
|
||||
default: _withCtx(() => _cache[175] || (_cache[175] = [
|
||||
default: _withCtx(() => _cache[181] || (_cache[181] = [
|
||||
_createTextVNode("复制")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7547,7 +7583,7 @@ return (_ctx, _cache) => {
|
||||
color: "primary",
|
||||
onClick: _cache[63] || (_cache[63] = $event => (yamlDialog.value = false))
|
||||
}, {
|
||||
default: _withCtx(() => _cache[176] || (_cache[176] = [
|
||||
default: _withCtx(() => _cache[182] || (_cache[182] = [
|
||||
_createTextVNode("关闭")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7570,7 +7606,7 @@ return (_ctx, _cache) => {
|
||||
_createVNode(_component_v_card, null, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_card_title, null, {
|
||||
default: _withCtx(() => _cache[177] || (_cache[177] = [
|
||||
default: _withCtx(() => _cache[183] || (_cache[183] = [
|
||||
_createTextVNode("导入规则")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7601,7 +7637,7 @@ return (_ctx, _cache) => {
|
||||
class: "mb-4",
|
||||
variant: "tonal"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[178] || (_cache[178] = [
|
||||
default: _withCtx(() => _cache[184] || (_cache[184] = [
|
||||
_createTextVNode(" 请输入 Clash 规则中的 "),
|
||||
_createElementVNode("strong", null, "rules", -1),
|
||||
_createTextVNode(" 字段,例如:"),
|
||||
@@ -7624,7 +7660,7 @@ return (_ctx, _cache) => {
|
||||
color: "secondary",
|
||||
onClick: _cache[67] || (_cache[67] = $event => (importRuleDialog.value = false, error.value=null))
|
||||
}, {
|
||||
default: _withCtx(() => _cache[179] || (_cache[179] = [
|
||||
default: _withCtx(() => _cache[185] || (_cache[185] = [
|
||||
_createTextVNode("取消")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7633,7 +7669,7 @@ return (_ctx, _cache) => {
|
||||
color: "primary",
|
||||
onClick: importRule
|
||||
}, {
|
||||
default: _withCtx(() => _cache[180] || (_cache[180] = [
|
||||
default: _withCtx(() => _cache[186] || (_cache[186] = [
|
||||
_createTextVNode("导入")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7656,7 +7692,7 @@ return (_ctx, _cache) => {
|
||||
_createVNode(_component_v_card, null, {
|
||||
default: _withCtx(() => [
|
||||
_createVNode(_component_v_card_title, null, {
|
||||
default: _withCtx(() => _cache[181] || (_cache[181] = [
|
||||
default: _withCtx(() => _cache[187] || (_cache[187] = [
|
||||
_createTextVNode("导入节点")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7702,7 +7738,7 @@ return (_ctx, _cache) => {
|
||||
class: "mb-4",
|
||||
variant: "tonal"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[182] || (_cache[182] = [
|
||||
default: _withCtx(() => _cache[188] || (_cache[188] = [
|
||||
_createTextVNode(" 请输入 Clash 规则中的 "),
|
||||
_createElementVNode("strong", null, "proxies", -1),
|
||||
_createTextVNode(" 字段,例如:"),
|
||||
@@ -7724,7 +7760,7 @@ return (_ctx, _cache) => {
|
||||
class: "mb-4",
|
||||
variant: "tonal"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[183] || (_cache[183] = [
|
||||
default: _withCtx(() => _cache[189] || (_cache[189] = [
|
||||
_createTextVNode(" 请输入 V2RayN 格式的分享链接,例如:"),
|
||||
_createElementVNode("br", null, null, -1),
|
||||
_createElementVNode("code", null, "vmess://xxxx", -1),
|
||||
@@ -7744,7 +7780,7 @@ return (_ctx, _cache) => {
|
||||
color: "secondary",
|
||||
onClick: _cache[72] || (_cache[72] = $event => (importExtraProxiesDialog.value=false, error.value=null))
|
||||
}, {
|
||||
default: _withCtx(() => _cache[184] || (_cache[184] = [
|
||||
default: _withCtx(() => _cache[190] || (_cache[190] = [
|
||||
_createTextVNode("取消")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7754,7 +7790,7 @@ return (_ctx, _cache) => {
|
||||
onClick: importExtraProxiesFun,
|
||||
loading: importProxiesLoading.value
|
||||
}, {
|
||||
default: _withCtx(() => _cache[185] || (_cache[185] = [
|
||||
default: _withCtx(() => _cache[191] || (_cache[191] = [
|
||||
_createTextVNode(" 导入 ")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7828,7 +7864,7 @@ return (_ctx, _cache) => {
|
||||
required: "",
|
||||
rules: [v => !!v || '当类型为文件时,路径不能为空'],
|
||||
class: "mb-4",
|
||||
hint: "文件路径,必须是唯一的"
|
||||
hint: "文件路径,不填写时会使用 url 的 MD5 作为文件名"
|
||||
}, null, 8, ["modelValue", "rules"]))
|
||||
: _createCommentVNode("", true),
|
||||
_createVNode(_component_v_text_field, {
|
||||
@@ -7911,7 +7947,7 @@ return (_ctx, _cache) => {
|
||||
color: "secondary",
|
||||
onClick: _cache[83] || (_cache[83] = $event => (ruleProviderDialog.value = false, error.value=null))
|
||||
}, {
|
||||
default: _withCtx(() => _cache[186] || (_cache[186] = [
|
||||
default: _withCtx(() => _cache[192] || (_cache[192] = [
|
||||
_createTextVNode("取消")
|
||||
])),
|
||||
_: 1
|
||||
@@ -7920,7 +7956,7 @@ return (_ctx, _cache) => {
|
||||
color: "primary",
|
||||
type: "submit"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[187] || (_cache[187] = [
|
||||
default: _withCtx(() => _cache[193] || (_cache[193] = [
|
||||
_createTextVNode("保存")
|
||||
])),
|
||||
_: 1
|
||||
@@ -8028,7 +8064,7 @@ return (_ctx, _cache) => {
|
||||
variant: "outlined",
|
||||
class: "mb-2"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[188] || (_cache[188] = [
|
||||
default: _withCtx(() => _cache[194] || (_cache[194] = [
|
||||
_createTextVNode(" 请在「高级选项」配置 Cloudflare CDN 优选 IPs ")
|
||||
])),
|
||||
_: 1
|
||||
@@ -8039,7 +8075,7 @@ return (_ctx, _cache) => {
|
||||
text: "",
|
||||
variant: "tonal"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[189] || (_cache[189] = [
|
||||
default: _withCtx(() => _cache[195] || (_cache[195] = [
|
||||
_createTextVNode(" 支持"),
|
||||
_createElementVNode("a", {
|
||||
href: "https://wiki.metacubex.one/handbook/syntax/#_8",
|
||||
@@ -8055,7 +8091,7 @@ return (_ctx, _cache) => {
|
||||
color: "secondary",
|
||||
onClick: _cache[88] || (_cache[88] = $event => (hostDialog.value = false, error.value=null))
|
||||
}, {
|
||||
default: _withCtx(() => _cache[190] || (_cache[190] = [
|
||||
default: _withCtx(() => _cache[196] || (_cache[196] = [
|
||||
_createTextVNode("取消")
|
||||
])),
|
||||
_: 1
|
||||
@@ -8064,7 +8100,7 @@ return (_ctx, _cache) => {
|
||||
color: "primary",
|
||||
type: "submit"
|
||||
}, {
|
||||
default: _withCtx(() => _cache[191] || (_cache[191] = [
|
||||
default: _withCtx(() => _cache[197] || (_cache[197] = [
|
||||
_createTextVNode("保存")
|
||||
])),
|
||||
_: 1
|
||||
@@ -8086,6 +8122,6 @@ return (_ctx, _cache) => {
|
||||
}
|
||||
|
||||
};
|
||||
const PageComponent = /*#__PURE__*/_export_sfc(_sfc_main, [['__scopeId',"data-v-d6db167c"]]);
|
||||
const PageComponent = /*#__PURE__*/_export_sfc(_sfc_main, [['__scopeId',"data-v-6aba879d"]]);
|
||||
|
||||
export { PageComponent as default };
|
||||
@@ -2,11 +2,11 @@ const currentImports = {};
|
||||
const exportSet = new Set(['Module', '__esModule', 'default', '_export_sfc']);
|
||||
let moduleMap = {
|
||||
"./Page":()=>{
|
||||
dynamicLoadingCss(["__federation_expose_Page-BOym_1fV.css"], false, './Page');
|
||||
return __federation_import('./__federation_expose_Page-D5l2MyNA.js').then(module =>Object.keys(module).every(item => exportSet.has(item)) ? () => module.default : () => module)},
|
||||
dynamicLoadingCss(["__federation_expose_Page-D1PURE3U.css"], false, './Page');
|
||||
return __federation_import('./__federation_expose_Page-DfeoSpny.js').then(module =>Object.keys(module).every(item => exportSet.has(item)) ? () => module.default : () => module)},
|
||||
"./Config":()=>{
|
||||
dynamicLoadingCss(["__federation_expose_Config-BrXQaadr.css"], false, './Config');
|
||||
return __federation_import('./__federation_expose_Config-NH09p1Am.js').then(module =>Object.keys(module).every(item => exportSet.has(item)) ? () => module.default : () => module)},
|
||||
dynamicLoadingCss(["__federation_expose_Config-rtAetK-O.css"], false, './Config');
|
||||
return __federation_import('./__federation_expose_Config-DcObTkjA.js').then(module =>Object.keys(module).every(item => exportSet.has(item)) ? () => module.default : () => module)},
|
||||
"./Dashboard":()=>{
|
||||
dynamicLoadingCss(["__federation_expose_Dashboard-vS9Qm2ZB.css"], false, './Dashboard');
|
||||
return __federation_import('./__federation_expose_Dashboard-BDSt5WaH.js').then(module =>Object.keys(module).every(item => exportSet.has(item)) ? () => module.default : () => module)},};
|
||||
|
||||
@@ -29,7 +29,7 @@ class ImdbSource(_PluginBase):
|
||||
# 插件图标
|
||||
plugin_icon = "IMDb_IOS-OSX_App.png"
|
||||
# 插件版本
|
||||
plugin_version = "1.5.6"
|
||||
plugin_version = "1.5.8"
|
||||
# 插件作者
|
||||
plugin_author = "wumode"
|
||||
# 作者主页
|
||||
@@ -60,7 +60,7 @@ class ImdbSource(_PluginBase):
|
||||
|
||||
def init_plugin(self, config: dict = None):
|
||||
|
||||
plugin_instance = self
|
||||
plugin_instance: ImdbSource = self
|
||||
|
||||
def patched_recognize_media(chain_self, meta: MetaBase = None,
|
||||
mtype: Optional[MediaType] = None,
|
||||
@@ -822,6 +822,14 @@ class ImdbSource(_PluginBase):
|
||||
ChainBase.async_recognize_media._patched_by == id(self) and
|
||||
self._original_async_method):
|
||||
ChainBase.async_recognize_media = self._original_async_method
|
||||
if self._scheduler:
|
||||
try:
|
||||
self._scheduler.remove_all_jobs()
|
||||
if self._scheduler.running:
|
||||
self._scheduler.shutdown()
|
||||
self._scheduler = None
|
||||
except Exception as e:
|
||||
logger.error(f"退出插件失败:{e}")
|
||||
|
||||
def get_module(self) -> Dict[str, Any]:
|
||||
"""
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -7,6 +7,7 @@
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
# Gemini
|
||||
|
||||
@@ -38,7 +39,7 @@ CEFR全称是Common European Framework of Reference for Languages。
|
||||
# 计划
|
||||
|
||||
- 双语字幕支持
|
||||
- 考试词汇标注
|
||||
- ~~考试词汇标注~~
|
||||
|
||||
# FAQ
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,5 @@
|
||||
pysubs2~=1.8.0
|
||||
langdetect~=1.0.9
|
||||
pymediainfo~=7.0.1
|
||||
pymediainfo~=7.0.1
|
||||
thinc==8.3.4
|
||||
spacy==3.8.7
|
||||
326
plugins.v2/multiclass/__init__.py
Normal file
326
plugins.v2/multiclass/__init__.py
Normal file
@@ -0,0 +1,326 @@
|
||||
from pathlib import Path
|
||||
from typing import Any, List, Dict, Tuple
|
||||
|
||||
from app.core.context import MediaInfo
|
||||
from app.core.event import eventmanager, Event
|
||||
from app.log import logger
|
||||
from app.plugins import _PluginBase
|
||||
from app.schemas.types import ChainEventType, MediaType, NotificationType
|
||||
|
||||
class MultiClass(_PluginBase):
|
||||
# 插件名称
|
||||
plugin_name = "视频多级分类"
|
||||
# 插件描述
|
||||
plugin_desc = "支持电影按照评分,年代和系列分类"
|
||||
# 插件图标
|
||||
plugin_icon = "Calibreweb_B.png"
|
||||
# 插件版本
|
||||
plugin_version = "0.1"
|
||||
# 插件作者
|
||||
plugin_author = "liuhangbin"
|
||||
# 作者主页
|
||||
author_url = "https://github.com/liuhangbin"
|
||||
# 插件配置项ID前缀
|
||||
plugin_config_prefix = "multiclass_"
|
||||
# 加载顺序
|
||||
plugin_order = 1
|
||||
# 可使用的用户级别
|
||||
auth_level = 1
|
||||
|
||||
_enabled = False
|
||||
_notify = False
|
||||
_year_class = False
|
||||
_vote_class = False
|
||||
_collection_class = False
|
||||
|
||||
def init_plugin(self, config: dict = None):
|
||||
|
||||
if config:
|
||||
self._enabled = config.get("enabled", False)
|
||||
self._notify = config.get("notify", False)
|
||||
self._year_class = config.get("year_class", False)
|
||||
self._vote_class = config.get("vote_class", False)
|
||||
self._collection_class = config.get("collection_class", False)
|
||||
|
||||
def get_state(self) -> bool:
|
||||
return self._enabled
|
||||
|
||||
def get_api(self) -> List[Dict[str, Any]]:
|
||||
pass
|
||||
|
||||
def get_form(self) -> Tuple[List[dict], Dict[str, Any]]:
|
||||
"""
|
||||
拼装插件配置页面,需要返回两块数据:1、页面配置;2、数据结构
|
||||
"""
|
||||
return [
|
||||
{
|
||||
'component': 'VForm',
|
||||
'content': [
|
||||
{
|
||||
'component': 'VRow',
|
||||
'content': [
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
'cols': 12,
|
||||
'md': 6
|
||||
},
|
||||
'content': [
|
||||
{
|
||||
'component': 'VSwitch',
|
||||
'props': {
|
||||
'model': 'enabled',
|
||||
'label': '启用插件',
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
'cols': 12,
|
||||
'md': 6
|
||||
},
|
||||
'content': [
|
||||
{
|
||||
'component': 'VSwitch',
|
||||
'props': {
|
||||
'model': 'year_class',
|
||||
'label': '按照年代分类',
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
'cols': 12,
|
||||
'md': 6
|
||||
},
|
||||
'content': [
|
||||
{
|
||||
'component': 'VSwitch',
|
||||
'props': {
|
||||
'model': 'vote_class',
|
||||
'label': '按照评分分类',
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
'cols': 12,
|
||||
'md': 6
|
||||
},
|
||||
'content': [
|
||||
{
|
||||
'component': 'VSwitch',
|
||||
'props': {
|
||||
'model': 'collection_class',
|
||||
'label': '按照系列分类',
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
'cols': 12,
|
||||
'md': 6
|
||||
},
|
||||
'content': [
|
||||
{
|
||||
'component': 'VSwitch',
|
||||
'props': {
|
||||
'model': 'notify',
|
||||
'label': '发送消息',
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'component': 'VRow',
|
||||
'content': [
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
'cols': 12,
|
||||
},
|
||||
'content': [
|
||||
{
|
||||
'component': 'VAlert',
|
||||
'props': {
|
||||
'type': 'info',
|
||||
'variant': 'tonal',
|
||||
'text': '插件目前仅支持电影(需要开启智能重命名)。如果按评分分类,7-9 高分,4-6 一般,1-3 垃圾。 系列电影不参与评分, 不按年代分类。'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
], {
|
||||
"enabled": False,
|
||||
"notify": False,
|
||||
"year_class": False,
|
||||
"vote_class": False,
|
||||
"collection_class": False
|
||||
}
|
||||
|
||||
def get_page(self) -> List[dict]:
|
||||
pass
|
||||
|
||||
@eventmanager.register(ChainEventType.TransferRename)
|
||||
def category_handler(self, event: Event):
|
||||
"""
|
||||
根据多级分类规则重新分类组装地址
|
||||
"""
|
||||
logger.debug(f"多级分类插件触发!")
|
||||
|
||||
# 基础验证
|
||||
if not self.get_state():
|
||||
logger.debug(f"多级分类插件未启用!")
|
||||
return
|
||||
if not event:
|
||||
logger.warning(f"多级分类异常:事件对象为空")
|
||||
return
|
||||
if not hasattr(event, 'event_data'):
|
||||
logger.warning(f"多级分类异常:事件数据为空")
|
||||
return
|
||||
|
||||
try:
|
||||
data = event.event_data
|
||||
|
||||
# 验证必要的数据字段
|
||||
if not hasattr(data, 'render_str') or not data.render_str:
|
||||
logger.warning(f"多级分类异常:render_str为空")
|
||||
return
|
||||
else:
|
||||
render_str = data.render_str
|
||||
|
||||
# 暂时只支持电影分类
|
||||
if not hasattr(data, 'rename_dict') or not data.rename_dict:
|
||||
logger.warning(f"多级分类异常:rename_dict为空")
|
||||
return
|
||||
else:
|
||||
rename_dict = data.rename_dict
|
||||
video_type = rename_dict.get("type", "")
|
||||
if video_type != "电影":
|
||||
logger.debug(f"多级分类异常:不支持的媒体类型: {video_type}, 只支持电影分类")
|
||||
return
|
||||
|
||||
# 安全获取数据字段
|
||||
title = rename_dict.get("title", "")
|
||||
en_title = rename_dict.get("en_title", "")
|
||||
year = rename_dict.get("year")
|
||||
vote_average = rename_dict.get("vote_average")
|
||||
media_info = rename_dict.get("__mediainfo__")
|
||||
|
||||
# 初始化默认值
|
||||
vote_count = 0
|
||||
c_name = None
|
||||
vote_path = "未知评分"
|
||||
decade = 0
|
||||
|
||||
# 安全处理媒体信息
|
||||
if media_info and hasattr(media_info, 'vote_count'):
|
||||
try:
|
||||
vote_count = int(media_info.vote_count) if media_info.vote_count else 0
|
||||
except (ValueError, TypeError):
|
||||
vote_count = 0
|
||||
|
||||
if hasattr(media_info, 'tmdb_info') and media_info.tmdb_info:
|
||||
collection = media_info.tmdb_info.get("belongs_to_collection")
|
||||
if collection and isinstance(collection, dict):
|
||||
c_name = collection.get("name")
|
||||
|
||||
# 安全处理评分数据
|
||||
try:
|
||||
if vote_average is not None:
|
||||
vote_average = float(vote_average)
|
||||
else:
|
||||
vote_average = 0
|
||||
except (ValueError, TypeError):
|
||||
vote_average = 0
|
||||
|
||||
# 评分分类逻辑
|
||||
if vote_count < 10:
|
||||
vote_average = 0
|
||||
vote_path = "评分不足"
|
||||
elif vote_average >= 7:
|
||||
vote_path = "高分电影"
|
||||
elif vote_average >= 4:
|
||||
vote_path = "一般电影"
|
||||
else:
|
||||
vote_path = "垃圾电影"
|
||||
|
||||
# 安全处理年份数据
|
||||
try:
|
||||
if year and str(year).isdigit():
|
||||
year_int = int(year)
|
||||
if 1900 <= year_int <= 2100: # 合理的年份范围
|
||||
decade = (year_int // 10) * 10
|
||||
else:
|
||||
decade = 0
|
||||
logger.warning(f"年份超出合理范围: {year}")
|
||||
else:
|
||||
decade = 0
|
||||
except (ValueError, TypeError):
|
||||
decade = 0
|
||||
logger.warning(f"年份转换失败: {year}")
|
||||
|
||||
|
||||
# 构建分类路径
|
||||
path_parts = []
|
||||
|
||||
if self._collection_class and c_name:
|
||||
# 当collection为true时,只添加collection name
|
||||
# 清理collection名称,移除特殊字符
|
||||
clean_c_name = str(c_name).strip()
|
||||
if clean_c_name:
|
||||
path_parts.append("系列电影")
|
||||
path_parts.append(clean_c_name)
|
||||
else:
|
||||
# 当collection不为true时,根据其他配置添加路径
|
||||
if self._vote_class and vote_path:
|
||||
path_parts.append(vote_path)
|
||||
if self._year_class and decade > 0:
|
||||
path_parts.append(f"{decade}s")
|
||||
|
||||
# 构建最终的路径
|
||||
if path_parts:
|
||||
# 确保render_str不为空
|
||||
safe_render_str = str(render_str).strip() if render_str else ""
|
||||
event.event_data.updated_str = f"{'/'.join(path_parts)}/{safe_render_str}"
|
||||
# 更新事件数据
|
||||
event.event_data.updated = True
|
||||
event.event_data.source = "MultiClass"
|
||||
|
||||
# 发送消息
|
||||
if self._notify:
|
||||
self.post_message(
|
||||
mtype=NotificationType.Organize,
|
||||
title="多级分类完成",
|
||||
text=f"已重新分类: {event.event_data.updated_str}",
|
||||
)
|
||||
else:
|
||||
event.event_data.updated = False
|
||||
logger.warning(f"多级分类失败: 未找到分类路径,请检查配置是否已开启")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"多级分类异常: {str(e)}", exc_info=True)
|
||||
# 确保即使出错也不会影响原始数据
|
||||
if hasattr(event, 'event_data') and event.event_data:
|
||||
event.event_data.updated = False
|
||||
event.event_data.updated_str = getattr(data, 'render_str', '') if data else ''
|
||||
|
||||
def stop_service(self):
|
||||
"""
|
||||
停止服务
|
||||
"""
|
||||
pass
|
||||
@@ -29,7 +29,7 @@ class ToBypassTrackers(_PluginBase):
|
||||
# 插件图标
|
||||
plugin_icon = "Clash_A.png"
|
||||
# 插件版本
|
||||
plugin_version = "1.4.2"
|
||||
plugin_version = "1.4.3"
|
||||
# 插件作者
|
||||
plugin_author = "wumode"
|
||||
# 作者主页
|
||||
@@ -68,7 +68,8 @@ class ToBypassTrackers(_PluginBase):
|
||||
self.ipv6_txt = self.get_data("ipv6_txt") if self.get_data("ipv6_txt") else ""
|
||||
self.ipv4_txt = self.get_data("ipv4_txt") if self.get_data("ipv4_txt") else ""
|
||||
try:
|
||||
with open(f"{settings.ROOT_PATH}/app/plugins/tobypasstrackers/sites/trackers", "r", encoding="utf-8") as f:
|
||||
site_file = settings.ROOT_PATH/'app'/'plugins'/'tobypasstrackers'/'sites'/'trackers'
|
||||
with open(site_file, "r", encoding="utf-8") as f:
|
||||
base64_str = f.read()
|
||||
self.trackers = json.loads(base64.b64decode(base64_str).decode("utf-8"))
|
||||
except Exception as e:
|
||||
@@ -101,7 +102,6 @@ class ToBypassTrackers(_PluginBase):
|
||||
)
|
||||
self._onlyonce = False
|
||||
self.__update_config()
|
||||
# self._scheduler.print_jobs()
|
||||
self._scheduler.start()
|
||||
|
||||
def get_state(self) -> bool:
|
||||
@@ -619,16 +619,14 @@ class ToBypassTrackers(_PluginBase):
|
||||
# Load Chnroute6 Lists
|
||||
res = RequestUtils().get_res(url=chnroute6_lists_url)
|
||||
if res is not None and res.status_code == 200:
|
||||
chnroute6_lists = res.text[:-1].split('\n')
|
||||
for ipr in chnroute6_lists:
|
||||
ipv6_list.append(ipr)
|
||||
chnroute6_lists = res.text.strip().split('\n')
|
||||
ipv6_list = [*chnroute6_lists]
|
||||
if self._china_ip_route:
|
||||
# Load Chnroute Lists
|
||||
res = RequestUtils().get_res(url=chnroute_lists_url)
|
||||
if res is not None and res.status_code == 200:
|
||||
chnroute_lists = res.text[:-1].split('\n')
|
||||
for ipr in chnroute_lists:
|
||||
ip_list.append(ipr)
|
||||
chnroute_lists = res.text.strip().split('\n')
|
||||
ip_list = [*chnroute_lists]
|
||||
do_sites = {site.domain: site.name for site in SiteOper().list_order_by_pri() if
|
||||
site.id in self._bypassed_sites}
|
||||
domain_name_map = {}
|
||||
|
||||
@@ -1 +1 @@
|
||||
eyJoZGRvbGJ5LmNvbSI6IFsidC5oZGRvbGJ5LmNvbSJdLCAidGp1cHQub3JnIjogWyJ0cmFja2VyLXB1YmxpYy50anVwdC5vcmciXSwgIm5pY2VwdC5uZXQiOiBbInd3dy5uaWNlcHQubmV0Il0sICJyb3VzaS56aXAiOiBbImhpdHB0LmNvbSJdLCAicHRob21lLm5ldCI6IFsicHRob21lLm5ldCJdLCAiaGR0aW1lLm9yZyI6IFsiaGR0aW1lLm9yZyJdLCAiZWFzdGdhbWUub3JnIjogWyJwdC5lYXN0Z2FtZS5vcmciXSwgInB0dGltZS5vcmciOiBbInd3dy5wdHRpbWUub3JnIl0sICJtLXRlYW0uY2MiOiBbInRyYWNrZXIubS10ZWFtLmNjIiwgInRyYWNrZXIubS10ZWFtLmlvIl0sICI1MnB0LnNpdGUiOiBbIjUycHQuc2l0ZSJdLCAicWluZ3dhcHQuY29tIjogWyJ0cmFja2VyLnFpbmd3YS5wcm8iLCAidHJhY2tlci5xaW5nd2FwdC5jb20iXSwgImhka3lsLmluIjogWyJ0cmFja2VyLmhka3lsLmluIl0sICJyYWluZ2ZoLnRvcCI6IFsicmFpbmdmaC50b3AiXSwgImhkZmFucy5vcmciOiBbImhkZmFucy5vcmciXSwgInB0bGdzLm9yZyI6IFsicHRsLmdzIiwgInJlbGF5MDEucHRsLmdzIl0sICJtb25pa2FkZXNpZ24udWsiOiBbInRyYWNrZXIubW9uaWthZGVzaWduLnVrIiwgImRhaWtpcmFpLm1vbmlrYWRlc2lnbi51ayIsICJhbmltZS1uby1pbmRleC5jb20iXSwgInB0c2Jhby5jbHViIjogWyJwdHNiYW8uY2x1YiJdLCAidG90aGVnbG9yeS5pbSI6IFsidHJhY2tlci50b3RoZWdsb3J5LmltIl0sICJ1Mi5kbWh5Lm9yZyI6IFsiZGF5ZHJlYW0uZG1oeS5iZXN0Il0sICJieXIucHQiOiBbInRyYWNrZXIuYnlyLnB0Il0sICJodWRidC5odXN0LmVkdS5jbiI6IFsiaHVkYnQuaHVzdC5lZHUuY24iXSwgImlsb2xpY29uLmNvbSI6IFsidHJhY2tlci5pbG9saWNvbi5jYyJdLCAiaGl0cHQuY29tIjogWyJoaXRwdC5jb20iXSwgImJ0c2Nob29sLmNsdWIiOiBbInB0LmJ0c2Nob29sLmNsdWIiXSwgImhkYXJlYS5jbHViIjogWyJ0cmFja2VyLmhkYXJlYS5jbHViIl0sICJzcHJpbmdzdW5kYXkubmV0IjogWyJvbjYuc3ByaW5nc3VuZGF5Lm5ldCIsICJvbi5zcHJpbmdzdW5kYXkubmV0Il0sICJ6bXB0LmNjIjogWyJ6bXB0LmNjIl0sICJjYXJwdC5uZXQiOiBbInRyYWNrZXIuY2FycHQubmV0Il0sICJpY2MyMDIyLmNvbSI6IFsidHJhY2tlci5pY2MyMDIyLnh5eiJdLCAia2VlcGZyZHMuY29tIjogWyJ0cmFja2VyLmtlZXBmcmRzLmNvbSJdLCAicHR6b25lLnh5eiI6IFsicHR6b25lLnh5eiJdLCAiY3NwdC50b3AiOiBbInRyYWNrZXIuY3NwdC50b3AiLCAidHJhY2tlci5jc3B0LmNjIiwgInRyYWNrZXIuY3NwdC5kYXRlIl0sICJjcmFicHQudmlwIjogWyJjcmFicHQudmlwIl0sICJva3B0Lm5ldCI6IFsid3d3Lm9rcHQubmV0Il0sICJnYW1lZ2FtZXB0LmNvbSI6IFsid3d3LmdhbWVnYW1lcHQuY29tIl0sICJhdWRpZW5jZXMubWUiOiBbInQuYXVkaWVuY2VzLm1lIiwgInRyYWNrZXIuY2luZWZpbGVzLmluZm8iXSwgInhpbmd5dW5nZS50b3AiOiBbInRyYWNrZXIueGluZ3l1bmdlLnRvcCIsICJ0cmFja2VyLnhpbmd5dW5nZS5zYnMiXSwgImV0OC5vcmciOiBbImV0OC5vcmciLCAidC5ldDgub3JnIl0sICJkaXNjZmFuLm5ldCI6IFsiZGlzY2Zhbi54eXoiXX0=
|
||||
eyI1MnB0LnNpdGUiOiBbIjUycHQuc2l0ZSJdLCAiYXVkaWVuY2VzLm1lIjogWyJ0LmF1ZGllbmNlcy5tZSIsICJ0cmFja2VyLmNpbmVmaWxlcy5pbmZvIl0sICJidHNjaG9vbC5jbHViIjogWyJwdC5idHNjaG9vbC5jbHViIl0sICJieXIucHQiOiBbInRyYWNrZXIuYnlyLnB0Il0sICJjYXJwdC5uZXQiOiBbInRyYWNrZXIuY2FycHQubmV0Il0sICJjcmFicHQudmlwIjogWyJjcmFicHQudmlwIl0sICJjc3B0LnRvcCI6IFsidHJhY2tlci5jc3B0LnRvcCIsICJ0cmFja2VyLmNzcHQuY2MiLCAidHJhY2tlci5jc3B0LmRhdGUiXSwgImRpc2NmYW4ubmV0IjogWyJkaXNjZmFuLnh5eiJdLCAiZWFzdGdhbWUub3JnIjogWyJwdC5lYXN0Z2FtZS5vcmciXSwgImV0OC5vcmciOiBbImV0OC5vcmciLCAidC5ldDgub3JnIl0sICJnYW1lZ2FtZXB0LmNvbSI6IFsid3d3LmdhbWVnYW1lcHQuY29tIl0sICJoZGFyZWEuY2x1YiI6IFsidHJhY2tlci5oZGFyZWEuY2x1YiJdLCAiaGRkb2xieS5jb20iOiBbInQuaGRkb2xieS5jb20iXSwgImhkZmFucy5vcmciOiBbImhkZmFucy5vcmciXSwgImhka3lsLmluIjogWyJ0cmFja2VyLmhka3lsLmluIl0sICJoZHRpbWUub3JnIjogWyJoZHRpbWUub3JnIl0sICJoaXRwdC5jb20iOiBbImhpdHB0LmNvbSJdLCAiaHVkYnQuaHVzdC5lZHUuY24iOiBbImh1ZGJ0Lmh1c3QuZWR1LmNuIl0sICJpY2MyMDIyLmNvbSI6IFsidHJhY2tlci5pY2MyMDIyLnh5eiJdLCAiaWxvbGljb24uY29tIjogWyJ0cmFja2VyLmlsb2xpY29uLmNjIl0sICJrZWVwZnJkcy5jb20iOiBbInRyYWNrZXIua2VlcGZyZHMuY29tIl0sICJtLXRlYW0uY2MiOiBbInRyYWNrZXIubS10ZWFtLmNjIiwgInRyYWNrZXIubS10ZWFtLmlvIl0sICJtb25pa2FkZXNpZ24udWsiOiBbInRyYWNrZXIubW9uaWthZGVzaWduLnVrIiwgImRhaWtpcmFpLm1vbmlrYWRlc2lnbi51ayIsICJhbmltZS1uby1pbmRleC5jb20iXSwgIm5pY2VwdC5uZXQiOiBbInd3dy5uaWNlcHQubmV0Il0sICJva3B0Lm5ldCI6IFsid3d3Lm9rcHQubmV0Il0sICJwdGhvbWUubmV0IjogWyJwdGhvbWUubmV0Il0sICJwdGxncy5vcmciOiBbInB0bC5ncyIsICJyZWxheTAxLnB0bC5ncyJdLCAicHRzYmFvLmNsdWIiOiBbInB0c2Jhby5jbHViIl0sICJwdHRpbWUub3JnIjogWyJ3d3cucHR0aW1lLm9yZyJdLCAicHR6b25lLnh5eiI6IFsicHR6b25lLnh5eiJdLCAicWluZ3dhcHQuY29tIjogWyJ0cmFja2VyLnFpbmd3YS5wcm8iLCAidHJhY2tlci5xaW5nd2FwdC5jb20iXSwgInJhaW5nZmgudG9wIjogWyJyYWluZ2ZoLnRvcCJdLCAicm91c2kuemlwIjogWyJoaXRwdC5jb20iXSwgInNwcmluZ3N1bmRheS5uZXQiOiBbIm9uNi5zcHJpbmdzdW5kYXkubmV0IiwgIm9uLnNwcmluZ3N1bmRheS5uZXQiXSwgInRqdXB0Lm9yZyI6IFsidHJhY2tlci1wdWJsaWMudGp1cHQub3JnIl0sICJ0b3RoZWdsb3J5LmltIjogWyJ0cmFja2VyLnRvdGhlZ2xvcnkuaW0iXSwgInUyLmRtaHkub3JnIjogWyJkYXlkcmVhbS5kbWh5LmJlc3QiXSwgInhpbmd5dW5nZS50b3AiOiBbInRyYWNrZXIueGluZ3l1bmdlLnRvcCIsICJ0cmFja2VyLnhpbmd5dW5nZS5zYnMiXSwgInptcHQuY2MiOiBbInptcHQuY2MiXSwgImhoYW5jbHViLnRvcCI6IFsidHJhY2tlci5oaGFuY2x1Yi50b3AiXSwgImhkY2l0eS5jaXR5IjogWyJzeW5jLmxlbml0ZXIub3JnIl19
|
||||
@@ -4,7 +4,6 @@ from abc import ABCMeta, abstractmethod
|
||||
from typing import Tuple
|
||||
|
||||
import chardet
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.helper.browser import PlaywrightHelper
|
||||
@@ -33,7 +32,7 @@ class _ISiteSigninHandler(metaclass=ABCMeta):
|
||||
return False
|
||||
|
||||
@abstractmethod
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
from typing import Tuple
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.log import logger
|
||||
from app.plugins.autosignin.sites import _ISiteSigninHandler
|
||||
from app.utils.string import StringUtils
|
||||
@@ -26,7 +24,7 @@ class BTSchool(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -3,7 +3,6 @@ import re
|
||||
from typing import Tuple
|
||||
|
||||
from lxml import etree
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.log import logger
|
||||
@@ -36,7 +35,7 @@ class CHDBits(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
from typing import Tuple
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.log import logger
|
||||
from app.plugins.autosignin.sites import _ISiteSigninHandler
|
||||
from app.utils.string import StringUtils
|
||||
@@ -26,7 +24,7 @@ class HaiDan(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import json
|
||||
from typing import Tuple
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.log import logger
|
||||
from app.plugins.autosignin.sites import _ISiteSigninHandler
|
||||
@@ -29,7 +27,7 @@ class Hares(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
from typing import Tuple
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.log import logger
|
||||
from app.plugins.autosignin.sites import _ISiteSigninHandler
|
||||
@@ -30,7 +28,7 @@ class HDArea(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -2,7 +2,6 @@ import json
|
||||
from typing import Tuple
|
||||
|
||||
from lxml import etree
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.log import logger
|
||||
@@ -30,7 +29,7 @@ class HDChina(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
from typing import Tuple
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.log import logger
|
||||
from app.plugins.autosignin.sites import _ISiteSigninHandler
|
||||
from app.utils.string import StringUtils
|
||||
@@ -28,7 +26,7 @@ class HDCity(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -2,8 +2,6 @@ import json
|
||||
import time
|
||||
from typing import Tuple
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.helper.ocr import OcrHelper
|
||||
from app.log import logger
|
||||
@@ -31,7 +29,7 @@ class HDSky(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import re
|
||||
from typing import Tuple
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.log import logger
|
||||
from app.plugins.autosignin.sites import _ISiteSigninHandler
|
||||
from app.utils.string import StringUtils
|
||||
@@ -30,7 +28,7 @@ class HDUpt(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
from typing import Tuple
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.plugins.autosignin.sites import _ISiteSigninHandler
|
||||
@@ -25,7 +22,7 @@ class MTorrent(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if cls.site_url in url.split(".") else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作,馒头实际没有签到,非仿真模式下需要更新访问时间
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
@@ -52,7 +49,7 @@ class MTorrent(_ISiteSigninHandler):
|
||||
else:
|
||||
return False, "模拟登录失败,无法打开网站"
|
||||
|
||||
def login(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def login(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行登录操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
from typing import Tuple
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.log import logger
|
||||
from app.plugins.autosignin.sites import _ISiteSigninHandler
|
||||
@@ -30,7 +28,7 @@ class NexusHD(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -3,7 +3,6 @@ import time
|
||||
from typing import Tuple
|
||||
|
||||
from lxml import etree
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.helper.ocr import OcrHelper
|
||||
@@ -32,7 +31,7 @@ class Opencd(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import json
|
||||
from typing import Tuple
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.log import logger
|
||||
from app.plugins.autosignin.sites import _ISiteSigninHandler
|
||||
from app.utils.string import StringUtils
|
||||
@@ -24,7 +22,7 @@ class PTerClub(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
from typing import Tuple
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.log import logger
|
||||
from app.plugins.autosignin.sites import _ISiteSigninHandler
|
||||
from app.utils.string import StringUtils
|
||||
@@ -26,7 +24,7 @@ class PTTime(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -6,7 +6,6 @@ from typing import Tuple
|
||||
|
||||
from PIL import Image
|
||||
from lxml import etree
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.log import logger
|
||||
@@ -46,7 +45,7 @@ class Tjupt(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import re
|
||||
from typing import Tuple
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.log import logger
|
||||
from app.plugins.autosignin.sites import _ISiteSigninHandler
|
||||
@@ -33,7 +31,7 @@ class TTG(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -4,7 +4,6 @@ import re
|
||||
from typing import Tuple
|
||||
|
||||
from lxml import etree
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.log import logger
|
||||
@@ -39,7 +38,7 @@ class U2(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
from typing import Tuple
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.plugins.autosignin.sites import _ISiteSigninHandler
|
||||
from app.utils.http import RequestUtils
|
||||
@@ -24,7 +22,7 @@ class YemaPT(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if cls.site_url in url else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
@@ -50,7 +48,7 @@ class YemaPT(_ISiteSigninHandler):
|
||||
else:
|
||||
return False, "签到失败,无法打开网站"
|
||||
|
||||
def login(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def login(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行登录操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -2,7 +2,6 @@ import json
|
||||
from typing import Tuple
|
||||
|
||||
from lxml import etree
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from app.core.config import settings
|
||||
from app.log import logger
|
||||
@@ -27,7 +26,7 @@ class ZhuQue(_ISiteSigninHandler):
|
||||
"""
|
||||
return True if StringUtils.url_equal(url, cls.site_url) else False
|
||||
|
||||
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
|
||||
def signin(self, site_info: dict) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行签到操作
|
||||
:param site_info: 站点信息,含有站点Url、站点Cookie、UA等信息
|
||||
|
||||
@@ -21,7 +21,7 @@ class DingdingMsg(_PluginBase):
|
||||
# 插件图标
|
||||
plugin_icon = "Dingding_A.png"
|
||||
# 插件版本
|
||||
plugin_version = "1.12"
|
||||
plugin_version = "1.13"
|
||||
# 插件作者
|
||||
plugin_author = "nnlegenda"
|
||||
# 作者主页
|
||||
@@ -209,6 +209,8 @@ class DingdingMsg(_PluginBase):
|
||||
if text:
|
||||
# 对text进行Markdown特殊字符转义
|
||||
text = re.sub(r"([_`])", r"\\\1", text)
|
||||
# 钉钉中需要在换行前有两个空格,才能够正常换行
|
||||
text = re.sub(r"\n", r" \n", text)
|
||||
else:
|
||||
text = ""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user