Files
2024-07-09 13:14:56 +08:00

598 lines
24 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import copy
from typing import Any, List, Dict, Tuple
from dotenv import set_key
from app.core.config import settings
from app.core.module import ModuleManager
from app.log import logger
from app.plugins import _PluginBase
class ConfigCenter(_PluginBase):
# 插件名称
plugin_name = "配置中心"
# 插件描述
plugin_desc = "快速调整部分系统设定。"
# 插件图标
plugin_icon = "setting.png"
# 插件版本
plugin_version = "2.6"
# 插件作者
plugin_author = "jxxghp"
# 作者主页
author_url = "https://github.com/jxxghp"
# 插件配置项ID前缀
plugin_config_prefix = "configcenter_"
# 加载顺序
plugin_order = 0
# 可使用的用户级别
auth_level = 1
# 私有属性
_enabled = False
_params = ""
_writeenv = False
settings_attributes = [
"GITHUB_TOKEN", "API_TOKEN", "TMDB_API_DOMAIN", "TMDB_IMAGE_DOMAIN", "WALLPAPER",
"RECOGNIZE_SOURCE", "SCRAP_FOLLOW_TMDB", "AUTO_DOWNLOAD_USER",
"OCR_HOST", "DOWNLOAD_SUBTITLE", "PLUGIN_MARKET", "MOVIE_RENAME_FORMAT",
"TV_RENAME_FORMAT", "FANART_ENABLE", "DOH_ENABLE", "SEARCH_MULTIPLE_NAME", "META_CACHE_EXPIRE",
"GITHUB_PROXY", "DOH_DOMAINS", "DOH_RESOLVERS"
]
def init_plugin(self, config: dict = None):
if not config:
return
self._enabled = config.get("enabled")
self._writeenv = config.get("writeenv")
if not self._enabled:
return
logger.info(f"正在应用配置中心配置:{config}")
for attribute in self.settings_attributes:
setattr(settings, attribute, config.get(attribute) or getattr(settings, attribute))
# 自定义配置,以换行分隔
self._params = config.get("params") or ""
for key, value in self.__parse_params(self._params).items():
if hasattr(settings, key):
setattr(settings, key, str(value))
# 重新加载模块
ModuleManager().stop()
ModuleManager().load_modules()
# 如果写入app.env文件则关闭插件开关
if self._writeenv:
# 写入env文件
self.update_env(config)
# 自动关闭插件
self._enabled = False
logger.info("配置中心设置已写入app.env文件插件关闭...")
# 保存配置
config.update({"enabled": False})
self.update_config(config)
def update_env(self, config: dict):
"""
更新设置到app.env
"""
if not config:
return
# 避免修改原值
conf = copy.deepcopy(config)
# 自定义配置,以换行分隔
config_params = self.__parse_params(conf.get("params"))
conf.update(config_params)
# 读写app.env
env_path = settings.CONFIG_PATH / "app.env"
for key, value in conf.items():
if not key:
continue
# 如果参数不在支持列表中, 则跳过
if key not in self.settings_attributes and key not in config_params:
continue
if value is None or str(value) == "None":
value = ''
else:
value = str(value)
set_key(env_path, key, value)
logger.info("app.env文件写入完成")
self.systemmessage.put("配置中心设置已写入app.env文件插件关闭", title="配置中心")
@staticmethod
def __parse_params(param_str: str) -> dict:
"""
解析自定义配置
"""
if not param_str:
return {}
result = {}
params = param_str.split("\n")
for param in params:
if not param:
continue
if str(param).strip().startswith("#"):
continue
parts = param.split("=", 1)
if len(parts) != 2:
continue
key = parts[0].strip()
value = parts[1].strip()
if not key:
continue
if not value:
continue
result[key] = value
return result
def get_state(self) -> bool:
return self._enabled
@staticmethod
def get_command() -> List[Dict[str, Any]]:
pass
def get_api(self) -> List[Dict[str, Any]]:
pass
def get_form(self) -> Tuple[List[dict], Dict[str, Any]]:
"""
拼装插件配置页面需要返回两块数据1、页面配置2、数据结构
"""
default_settings = {
"enabled": False,
"params": "",
}
for attribute in self.settings_attributes:
default_settings[attribute] = getattr(settings, attribute)
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": "writeenv",
"label": "写入app.env文件"
}
}
]
},
]
},
{
'component': 'VRow',
'content': [
{
"component": "VCol",
"props": {
"cols": 12,
"md": 6
},
"content": [
{
"component": "VTextField",
"props": {
"model": "GITHUB_TOKEN",
"label": "Github Token"
}
}
]
},
{
"component": "VCol",
"props": {
"cols": 12,
"md": 6
},
"content": [
{
"component": "VTextField",
"props": {
"model": "API_TOKEN",
"label": "API密钥"
}
}
]
},
{
"component": "VCol",
"props": {
"cols": 12,
"md": 6
},
"content": [
{
"component": "VTextField",
"props": {
"model": "TMDB_API_DOMAIN",
"label": "TMDB API地址"
}
}
]
},
{
"component": "VCol",
"props": {
"cols": 12,
"md": 6
},
"content": [
{
"component": "VTextField",
"props": {
"model": "TMDB_IMAGE_DOMAIN",
"label": "TheMovieDb图片服务器"
}
}
]
},
{
"component": "VCol",
"props": {
"cols": 12,
"md": 6
},
"content": [
{
"component": "VSelect",
"props": {
"model": "RECOGNIZE_SOURCE",
"label": "媒体信息识别来源",
"items": [
{"title": "TheMovieDb", "value": "themoviedb"},
{"title": "豆瓣", "value": "douban"}
]
}
}
]
},
{
"component": "VCol",
"props": {
"cols": 12,
"md": 6
},
"content": [
{
"component": "VSelect",
"props": {
"model": "SCRAP_SOURCE",
"label": "刮削元数据及图片使用的数据源",
"items": [
{"title": "TheMovieDb", "value": "themoviedb"},
{"title": "豆瓣", "value": "douban"},
]
}
}
]
},
{
"component": "VCol",
"props": {
"cols": 12,
"md": 6
},
"content": [
{
"component": "VSelect",
"props": {
"model": "WALLPAPER",
"label": "登录首页电影海报",
"items": [
{"title": "TheMovieDb电影海报", "value": "tmdb"},
{"title": "Bing每日壁纸", "value": "bing"}
]
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
"component": "VCol",
"props": {
"cols": 12,
"md": 6
},
"content": [
{
"component": "VTextField",
"props": {
"model": "OCR_HOST",
"label": "验证码识别服务器"
}
}
]
},
{
"component": "VCol",
"props": {
"cols": 12,
"md": 6
},
"content": [
{
"component": "VTextField",
"props": {
"model": "GITHUB_PROXY",
"label": "Github加速服务器",
"placeholder": "https://mirror.ghproxy.com/"
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
"component": "VCol",
"props": {
"cols": 12,
"md": 6
},
"content": [
{
"component": "VTextField",
"props": {
"model": "DOH_DOMAINS",
"label": "DOH解析的域名",
"placeholder": "多个域名使用,分隔"
}
}
]
},
{
"component": "VCol",
"props": {
"cols": 12,
"md": 6
},
"content": [
{
"component": "VTextField",
"props": {
"model": "DOH_RESOLVERS",
"label": "DOH解析服务器",
"placeholder": "多个地址使用,分隔"
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
"component": "VCol",
"props": {
"cols": 12,
},
"content": [
{
"component": "VTextarea",
"props": {
"model": "MOVIE_RENAME_FORMAT",
"label": "电影重命名格式"
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
"component": "VCol",
"props": {
"cols": 12,
},
"content": [
{
"component": "VTextarea",
"props": {
"model": "TV_RENAME_FORMAT",
"label": "电视剧重命名格式"
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
"component": "VCol",
"props": {
"cols": 12,
},
"content": [
{
"component": "VTextarea",
"props": {
"model": "PLUGIN_MARKET",
"label": "插件市场",
"placeholder": "多个地址使用,分隔"
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
"component": "VCol",
"props": {
"cols": 12,
},
"content": [
{
"component": "VTextarea",
"props": {
"model": "params",
"label": "自定义配置",
"placeholder": "每行一个配置项,格式:配置项=值"
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
"component": "VCol",
"props": {
"cols": 12,
"md": 4
},
"content": [
{
"component": "VSwitch",
"props": {
"model": "DOWNLOAD_SUBTITLE",
"label": "自动下载站点字幕"
}
}
]
},
{
"component": "VCol",
"props": {
"cols": 12,
"md": 4
},
"content": [
{
"component": "VSwitch",
"props": {
"model": "SCRAP_FOLLOW_TMDB",
"label": "新增入库跟随TMDB信息变化"
}
}
]
},
{
"component": "VCol",
"props": {
"cols": 12,
"md": 4
},
"content": [
{
"component": "VSwitch",
"props": {
"model": "FANART_ENABLE",
"label": "使用Fanart图片数据源"
}
}
]
},
{
"component": "VCol",
"props": {
"cols": 12,
"md": 4
},
"content": [
{
"component": "VSwitch",
"props": {
"model": "DOH_ENABLE",
"label": "启用DNS over HTTPS"
}
}
]
},
{
"component": "VCol",
"props": {
"cols": 12,
"md": 4
},
"content": [
{
"component": "VSwitch",
"props": {
"model": "SEARCH_MULTIPLE_NAME",
"label": "资源搜索整合多名称搜索结果"
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
},
'content': [
{
'component': 'VAlert',
'props': {
'type': 'info',
'variant': 'tonal',
'text': '注意开启写入app.env后将直接修改配置文件否则只是运行时修改生效对应配置插件关闭且重启后配置失效有些自定义配置需要重启才能生效。'
}
}
]
}
]
}
]
}
], default_settings
def get_page(self) -> List[dict]:
pass
def stop_service(self):
"""
退出插件
"""
pass