From ccf1aa2f1dba7d3a7c80bd2c8f60ec67f58957c9 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sat, 25 Nov 2023 07:24:11 +0800 Subject: [PATCH 1/9] add plugin --- icons/setting.png | Bin 0 -> 22836 bytes plugins/configcenter/__init__.py | 88 +++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 icons/setting.png create mode 100644 plugins/configcenter/__init__.py diff --git a/icons/setting.png b/icons/setting.png new file mode 100644 index 0000000000000000000000000000000000000000..0ad88b03ada99aed2c0a37dd516158b3850edd55 GIT binary patch literal 22836 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 z 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 Ui<2#Vz6XyqRCQF!uUUuv4`DMLfdBvi literal 0 HcmV?d00001 diff --git a/plugins/configcenter/__init__.py b/plugins/configcenter/__init__.py new file mode 100644 index 0000000..969dc17 --- /dev/null +++ b/plugins/configcenter/__init__.py @@ -0,0 +1,88 @@ +from typing import Any, List, Dict, Tuple + +from app.plugins import _PluginBase + + +class ConfigCenter(_PluginBase): + # 插件名称 + plugin_name = "配置中心" + # 插件描述 + plugin_desc = "快速调整部分系统设定。" + # 插件图标 + plugin_icon = "setting.png" + # 主题色 + plugin_color = "#FC6220" + # 插件版本 + plugin_version = "1.0" + # 插件作者 + plugin_author = "jxxghp" + # 作者主页 + author_url = "https://github.com/jxxghp" + # 插件配置项ID前缀 + plugin_config_prefix = "configcenter_" + # 加载顺序 + plugin_order = 1 + # 可使用的用户级别 + auth_level = 1 + + # 私有属性 + _enabled = False + + def init_plugin(self, config: dict = None): + if config: + self._enabled = config.get("enabled") + + 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、数据结构 + """ + request_options = ["POST", "GET"] + return [ + { + 'component': 'VForm', + 'content': [ + { + 'component': 'VRow', + 'content': [ + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VSwitch', + 'props': { + 'model': 'enabled', + 'label': '启用插件', + } + } + ] + } + ] + } + ] + } + ], { + "enabled": False, + } + + def get_page(self) -> List[dict]: + pass + + def stop_service(self): + """ + 退出插件 + """ + pass From df955ab8bb67c4939b266baa8dbc8f344aa51d76 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sat, 25 Nov 2023 07:49:11 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 897f6b1..49ed81f 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ MoviePilot官方插件市场:https://github.com/jxxghp/MoviePilot-Plugins ### 1. 目录结构 -- 插件仓库需要保持与本项目一致的目录结构(建议fork后修改),仅支持Github仓库,`plugins`存放插件代码,一个插件一个子目录,**子目名名必须为插件类名的小写**,插件主类在`__init__.py`中编写。 +- 插件仓库需要保持与本项目一致的目录结构(建议fork后修改),仅支持Github仓库,`plugins`存放插件代码,一个插件一个子目录,**子目录名必须为插件类名的小写**,插件主类在`__init__.py`中编写。 - `package.json`为插件仓库中所有插件概要信息,用于在MoviePilot的插件市场显示,其中版本号等需与插件代码保持一致,通过修改版本号可触发MoviePilot显示插件更新。 ### 2. 插件图标 -- 插件图标可复用官方插件库中`icons`下已有图标,否则需使用完成的http格式的url图片链接(包括package.json中的icon和插件代码中的plugin_icon)。 +- 插件图标可复用官方插件库中`icons`下已有图标,否则需使用完整的http格式的url图片链接(包括package.json中的icon和插件代码中的plugin_icon)。 ### 3. 插件命名 - 插件命名请勿与官方库插件中的插件冲突,否则会在MoviePilot版本升级时被官方插件覆盖。 From a4474ad4b87647887c948df8c7608e939ad61e73 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sun, 26 Nov 2023 08:30:01 +0800 Subject: [PATCH 3/9] fix --- plugins/configcenter/__init__.py | 462 ++++++++++++++++++++++++++++++- 1 file changed, 455 insertions(+), 7 deletions(-) diff --git a/plugins/configcenter/__init__.py b/plugins/configcenter/__init__.py index 969dc17..7f646e0 100644 --- a/plugins/configcenter/__init__.py +++ b/plugins/configcenter/__init__.py @@ -1,5 +1,6 @@ from typing import Any, List, Dict, Tuple +from app.core.config import settings from app.plugins import _PluginBase @@ -31,6 +32,45 @@ class ConfigCenter(_PluginBase): def init_plugin(self, config: dict = None): if config: self._enabled = config.get("enabled") + settings.GITHUB_TOKEN = config.get("GITHUB_TOKEN", "") + settings.API_TOKEN = config.get("API_TOKEN", "") + settings.TMDB_API_DOMAIN = config.get("TMDB_API_DOMAIN", "") + settings.TMDB_IMAGE_DOMAIN = config.get("TMDB_IMAGE_DOMAIN", "") + settings.WALLPAPER = config.get("WALLPAPER", "") + settings.RECOGNIZE_SOURCE = config.get("RECOGNIZE_SOURCE", "") + settings.SCRAP_METADATA = config.get("SCRAP_METADATA", False) + settings.SCRAP_SOURCE = config.get("SCRAP_SOURCE", "") + settings.SCRAP_FOLLOW_TMDB = config.get("SCRAP_FOLLOW_TMDB", False) + settings.LIBRARY_PATH = config.get("LIBRARY_PATH", "") + settings.LIBRARY_MOVIE_NAME = config.get("LIBRARY_MOVIE_NAME", "") + settings.LIBRARY_TV_NAME = config.get("LIBRARY_TV_NAME", "") + settings.LIBRARY_ANIME_NAME = config.get("LIBRARY_ANIME_NAME", "") + settings.LIBRARY_CATEGORY = config.get("LIBRARY_CATEGORY", False) + settings.TRANSFER_TYPE = config.get("TRANSFER_TYPE", "") + settings.OVERWRITE_MODE = config.get("OVERWRITE_MODE", "") + settings.COOKIECLOUD_HOST = config.get("COOKIECLOUD_HOST", "") + settings.COOKIECLOUD_KEY = config.get("COOKIECLOUD_KEY", "") + settings.COOKIECLOUD_PASSWORD = config.get("COOKIECLOUD_PASSWORD", "") + settings.COOKIECLOUD_INTERVAL = config.get("COOKIECLOUD_INTERVAL", "") + settings.USER_AGENT = config.get("USER_AGENT", "") + settings.SUBSCRIBE_MODE = config.get("SUBSCRIBE_MODE", "") + settings.SUBSCRIBE_RSS_INTERVAL = config.get("SUBSCRIBE_RSS_INTERVAL", "") + settings.SUBSCRIBE_SEARCH = config.get("SUBSCRIBE_SEARCH", False) + settings.AUTO_DOWNLOAD_USER = config.get("AUTO_DOWNLOAD_USER", "") + settings.OCR_HOST = config.get("OCR_HOST", "") + settings.MESSAGER = config.get("MESSAGER", "") + settings.DOWNLOAD_PATH = config.get("DOWNLOAD_PATH", "") + settings.DOWNLOAD_MOVIE_PATH = config.get("DOWNLOAD_MOVIE_PATH", "") + settings.DOWNLOAD_TV_PATH = config.get("DOWNLOAD_TV_PATH", "") + settings.DOWNLOAD_ANIME_PATH = config.get("DOWNLOAD_ANIME_PATH", "") + settings.DOWNLOAD_CATEGORY = config.get("DOWNLOAD_CATEGORY", False) + settings.DOWNLOAD_SUBTITLE = config.get("DOWNLOAD_SUBTITLE", False) + settings.DOWNLOADER = config.get("DOWNLOADER", "") + settings.DOWNLOADER_MONITOR = config.get("DOWNLOADER_MONITOR", False) + settings.TORRENT_TAG = config.get("TORRENT_TAG", "") + settings.MEDIASERVER = config.get("MEDIASERVER", "") + settings.MEDIASERVER_SYNC_INTERVAL = config.get("MEDIASERVER_SYNC_INTERVAL", "") + settings.MEDIASERVER_SYNC_BLACKLIST = config.get("MEDIASERVER_SYNC_BLACKLIST", "") def get_state(self) -> bool: return self._enabled @@ -67,13 +107,421 @@ class ConfigCenter(_PluginBase): 'model': 'enabled', 'label': '启用插件', } - } - ] - } - ] - } - ] - } + }, + ], + }, + { + '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': 'TMDB图片地址', + } + }, + ], + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VSelect', + 'props': { + 'model': 'WALLPAPER', + 'label': '登录首页电影海报', + 'items': ['tmdb', 'bing'], + } + }, + ], + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VSelect', + 'props': { + 'model': 'RECOGNIZE_SOURCE', + 'label': '媒体信息识别来源', + 'items': ['themoviedb', 'douban'], + } + }, + ], + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VSwitch', + 'props': { + 'model': 'SCRAP_METADATA', + 'label': '刮削入库的媒体文件', + } + }, + ], + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VSelect', + 'props': { + 'model': 'SCRAP_SOURCE', + 'label': '刮削元数据及图片使用的数据源', + 'items': ['themoviedb', 'douban'], + } + }, + ], + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VSwitch', + 'props': { + 'model': 'SCRAP_FOLLOW_TMDB', + 'label': '新增已入库媒体是否跟随TMDB信息变化', + } + }, + ], + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VTextField', + 'props': { + 'model': 'LIBRARY_PATH', + 'label': '媒体库目录', + } + }, + ], + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VTextField', + 'props': { + 'model': 'LIBRARY_MOVIE_NAME', + 'label': '电影媒体库目录名称', + } + }, + ], + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VTextField', + 'props': { + 'model': 'LIBRARY_TV_NAME', + 'label': '电视剧媒体库目录名称', + } + }, + ], + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VTextField', + 'props': { + 'model': 'LIBRARY_ANIME_NAME', + 'label': '动漫媒体库目录名称', + } + }, + ], + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VSwitch', + 'props': { + 'model': 'LIBRARY_CATEGORY', + 'label': '媒体库二级分类开关', + } + }, + ], + }, + { + 'component': 'VSelect', + 'props': { + 'model': 'TRANSFER_TYPE', + 'label': '整理转移方式', + 'items': ['link', 'copy', 'move', 'softlink', 'rclone_copy', 'rclone_move'], + } + }, + { + 'component': 'VSelect', + 'props': { + 'model': 'OVERWRITE_MODE', + 'label': '转移覆盖模式', + 'items': ['never', 'size', 'always', 'latest'], + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'COOKIECLOUD_HOST', + 'label': 'CookieCloud服务器地址', + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'COOKIECLOUD_KEY', + 'label': 'CookieCloud用户KEY', + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'COOKIECLOUD_PASSWORD', + 'label': 'CookieCloud端对端加密密码', + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'COOKIECLOUD_INTERVAL', + 'label': 'CookieCloud同步间隔(分钟)', + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'USER_AGENT', + 'label': 'CookieCloud保存Cookie对应的浏览器UA', + } + }, + { + 'component': 'VSelect', + 'props': { + 'model': 'SUBSCRIBE_MODE', + 'label': '订阅模式', + 'items': ['rss', 'spider'], + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'SUBSCRIBE_RSS_INTERVAL', + 'label': 'RSS订阅模式刷新时间间隔(分钟)', + } + }, + { + 'component': 'VSwitch', + 'props': { + 'model': 'SUBSCRIBE_SEARCH', + 'label': '订阅搜索', + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'AUTO_DOWNLOAD_USER', + 'label': '远程交互搜索时自动择优下载的用户ID', + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'OCR_HOST', + 'label': 'OCR识别服务器地址', + } + }, + { + 'component': 'VSelect', + 'props': { + 'model': 'MESSAGER', + 'label': '消息通知渠道', + 'items': ['telegram', 'wechat', 'slack', 'synologychat'], + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'DOWNLOAD_PATH', + 'label': '下载保存目录', + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'DOWNLOAD_MOVIE_PATH', + 'label': '电影下载保存目录路径', + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'DOWNLOAD_TV_PATH', + 'label': '电视剧下载保存目录路径', + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'DOWNLOAD_ANIME_PATH', + 'label': '动漫下载保存目录路径', + } + }, + { + 'component': 'VSwitch', + 'props': { + 'model': 'DOWNLOAD_CATEGORY', + 'label': '下载二级分类开关', + } + }, + { + 'component': 'VSwitch', + 'props': { + 'model': 'DOWNLOAD_SUBTITLE', + 'label': '下载站点字幕', + } + }, + { + 'component': 'VSelect', + 'props': { + 'model': 'DOWNLOADER', + 'label': '下载器', + 'items': ['qbittorrent', 'transmission'], + } + }, + { + 'component': 'VSwitch', + 'props': { + 'model': 'DOWNLOADER_MONITOR', + 'label': '下载器监控', + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'TORRENT_TAG', + 'label': '下载器种子标签', + } + }, + { + 'component': 'VSelect', + 'props': { + 'model': 'MEDIASERVER', + 'label': '媒体服务器', + 'items': ['emby', 'jellyfin', 'plex'], + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'MEDIASERVER_SYNC_INTERVAL', + 'label': '媒体服务器同步间隔(小时)', + } + }, + { + 'component': 'VTextField', + 'props': { + 'model': 'MEDIASERVER_SYNC_BLACKLIST', + 'label': '媒体服务器同步黑名单', + } + }, + ], + }, + ], + }, ], { "enabled": False, } From 721c118fd165e6d3bac08ae86a9276862261b6c1 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sun, 26 Nov 2023 19:31:42 +0800 Subject: [PATCH 4/9] fix --- package.json | 9 + plugins/configcenter/__init__.py | 999 ++++++++++++++++++++----------- 2 files changed, 662 insertions(+), 346 deletions(-) diff --git a/package.json b/package.json index d15604e..8707798 100644 --- a/package.json +++ b/package.json @@ -322,5 +322,14 @@ "color": "#FFFFFF", "author": "jxxghp", "level": 1 + }, + "ConfigCenter": { + "name": "配置中心", + "description": "快速调整部分系统设定。", + "version": "1.0", + "icon": "setting.png", + "color": "#FC6220", + "author": "jxxghp", + "level": 1 } } \ No newline at end of file diff --git a/plugins/configcenter/__init__.py b/plugins/configcenter/__init__.py index 7f646e0..309d4a4 100644 --- a/plugins/configcenter/__init__.py +++ b/plugins/configcenter/__init__.py @@ -32,45 +32,50 @@ class ConfigCenter(_PluginBase): def init_plugin(self, config: dict = None): if config: self._enabled = config.get("enabled") - settings.GITHUB_TOKEN = config.get("GITHUB_TOKEN", "") - settings.API_TOKEN = config.get("API_TOKEN", "") - settings.TMDB_API_DOMAIN = config.get("TMDB_API_DOMAIN", "") - settings.TMDB_IMAGE_DOMAIN = config.get("TMDB_IMAGE_DOMAIN", "") - settings.WALLPAPER = config.get("WALLPAPER", "") + settings.GITHUB_TOKEN = config.get("GITHUB_TOKEN", settings.GITHUB_TOKEN) + settings.API_TOKEN = config.get("API_TOKEN", settings.API_TOKEN) + settings.TMDB_API_DOMAIN = config.get("TMDB_API_DOMAIN", settings.TMDB_API_DOMAIN) + settings.TMDB_IMAGE_DOMAIN = config.get("TMDB_IMAGE_DOMAIN", settings.TMDB_IMAGE_DOMAIN) + settings.WALLPAPER = config.get("WALLPAPER", settings.WALLPAPER) settings.RECOGNIZE_SOURCE = config.get("RECOGNIZE_SOURCE", "") - settings.SCRAP_METADATA = config.get("SCRAP_METADATA", False) - settings.SCRAP_SOURCE = config.get("SCRAP_SOURCE", "") - settings.SCRAP_FOLLOW_TMDB = config.get("SCRAP_FOLLOW_TMDB", False) - settings.LIBRARY_PATH = config.get("LIBRARY_PATH", "") - settings.LIBRARY_MOVIE_NAME = config.get("LIBRARY_MOVIE_NAME", "") - settings.LIBRARY_TV_NAME = config.get("LIBRARY_TV_NAME", "") - settings.LIBRARY_ANIME_NAME = config.get("LIBRARY_ANIME_NAME", "") - settings.LIBRARY_CATEGORY = config.get("LIBRARY_CATEGORY", False) - settings.TRANSFER_TYPE = config.get("TRANSFER_TYPE", "") - settings.OVERWRITE_MODE = config.get("OVERWRITE_MODE", "") - settings.COOKIECLOUD_HOST = config.get("COOKIECLOUD_HOST", "") - settings.COOKIECLOUD_KEY = config.get("COOKIECLOUD_KEY", "") - settings.COOKIECLOUD_PASSWORD = config.get("COOKIECLOUD_PASSWORD", "") - settings.COOKIECLOUD_INTERVAL = config.get("COOKIECLOUD_INTERVAL", "") - settings.USER_AGENT = config.get("USER_AGENT", "") - settings.SUBSCRIBE_MODE = config.get("SUBSCRIBE_MODE", "") - settings.SUBSCRIBE_RSS_INTERVAL = config.get("SUBSCRIBE_RSS_INTERVAL", "") - settings.SUBSCRIBE_SEARCH = config.get("SUBSCRIBE_SEARCH", False) - settings.AUTO_DOWNLOAD_USER = config.get("AUTO_DOWNLOAD_USER", "") - settings.OCR_HOST = config.get("OCR_HOST", "") - settings.MESSAGER = config.get("MESSAGER", "") - settings.DOWNLOAD_PATH = config.get("DOWNLOAD_PATH", "") - settings.DOWNLOAD_MOVIE_PATH = config.get("DOWNLOAD_MOVIE_PATH", "") - settings.DOWNLOAD_TV_PATH = config.get("DOWNLOAD_TV_PATH", "") - settings.DOWNLOAD_ANIME_PATH = config.get("DOWNLOAD_ANIME_PATH", "") - settings.DOWNLOAD_CATEGORY = config.get("DOWNLOAD_CATEGORY", False) - settings.DOWNLOAD_SUBTITLE = config.get("DOWNLOAD_SUBTITLE", False) - settings.DOWNLOADER = config.get("DOWNLOADER", "") - settings.DOWNLOADER_MONITOR = config.get("DOWNLOADER_MONITOR", False) - settings.TORRENT_TAG = config.get("TORRENT_TAG", "") - settings.MEDIASERVER = config.get("MEDIASERVER", "") - settings.MEDIASERVER_SYNC_INTERVAL = config.get("MEDIASERVER_SYNC_INTERVAL", "") - settings.MEDIASERVER_SYNC_BLACKLIST = config.get("MEDIASERVER_SYNC_BLACKLIST", "") + settings.SCRAP_METADATA = config.get("SCRAP_METADATA", settings.SCRAP_METADATA) + settings.SCRAP_FOLLOW_TMDB = config.get("SCRAP_FOLLOW_TMDB", settings.SCRAP_FOLLOW_TMDB) + settings.LIBRARY_PATH = config.get("LIBRARY_PATH", settings.LIBRARY_PATH) + settings.LIBRARY_MOVIE_NAME = config.get("LIBRARY_MOVIE_NAME", settings.LIBRARY_MOVIE_NAME) + settings.LIBRARY_TV_NAME = config.get("LIBRARY_TV_NAME", settings.LIBRARY_TV_NAME) + settings.LIBRARY_ANIME_NAME = config.get("LIBRARY_ANIME_NAME", settings.LIBRARY_ANIME_NAME) + settings.LIBRARY_CATEGORY = config.get("LIBRARY_CATEGORY", settings.LIBRARY_CATEGORY) + settings.TRANSFER_TYPE = config.get("TRANSFER_TYPE", settings.TRANSFER_TYPE) + settings.OVERWRITE_MODE = config.get("OVERWRITE_MODE", settings.OVERWRITE_MODE) + settings.COOKIECLOUD_HOST = config.get("COOKIECLOUD_HOST", settings.COOKIECLOUD_HOST) + settings.COOKIECLOUD_KEY = config.get("COOKIECLOUD_KEY", settings.COOKIECLOUD_KEY) + settings.COOKIECLOUD_PASSWORD = config.get("COOKIECLOUD_PASSWORD", settings.COOKIECLOUD_PASSWORD) + settings.COOKIECLOUD_INTERVAL = config.get("COOKIECLOUD_INTERVAL", settings.COOKIECLOUD_INTERVAL) + settings.USER_AGENT = config.get("USER_AGENT", settings.USER_AGENT) + settings.SUBSCRIBE_MODE = config.get("SUBSCRIBE_MODE", settings.SUBSCRIBE_MODE) + settings.SUBSCRIBE_RSS_INTERVAL = config.get("SUBSCRIBE_RSS_INTERVAL", settings.SUBSCRIBE_RSS_INTERVAL) + settings.SUBSCRIBE_SEARCH = config.get("SUBSCRIBE_SEARCH", settings.SUBSCRIBE_SEARCH) + settings.AUTO_DOWNLOAD_USER = config.get("AUTO_DOWNLOAD_USER", settings.AUTO_DOWNLOAD_USER) + settings.OCR_HOST = config.get("OCR_HOST", settings.OCR_HOST) + messagers = config.get("MESSAGER") or [] + if messagers: + settings.MESSAGER = ",".join(messagers) + settings.DOWNLOAD_PATH = config.get("DOWNLOAD_PATH", settings.DOWNLOAD_PATH) + settings.DOWNLOAD_MOVIE_PATH = config.get("DOWNLOAD_MOVIE_PATH", settings.DOWNLOAD_MOVIE_PATH) + settings.DOWNLOAD_TV_PATH = config.get("DOWNLOAD_TV_PATH", settings.DOWNLOAD_TV_PATH) + settings.DOWNLOAD_ANIME_PATH = config.get("DOWNLOAD_ANIME_PATH", settings.DOWNLOAD_ANIME_PATH) + settings.DOWNLOAD_CATEGORY = config.get("DOWNLOAD_CATEGORY", settings.DOWNLOAD_CATEGORY) + settings.DOWNLOAD_SUBTITLE = config.get("DOWNLOAD_SUBTITLE", settings.DOWNLOAD_SUBTITLE) + settings.DOWNLOADER = config.get("DOWNLOADER", settings.DOWNLOADER) + settings.DOWNLOADER_MONITOR = config.get("DOWNLOADER_MONITOR", settings.DOWNLOADER_MONITOR) + settings.TORRENT_TAG = config.get("TORRENT_TAG", settings.TORRENT_TAG) + media_servers = config.get("MEDIASERVER") or [] + if media_servers: + settings.MEDIASERVER = ",".join(media_servers) + settings.MEDIASERVER_SYNC_INTERVAL = config.get("MEDIASERVER_SYNC_INTERVAL", + settings.MEDIASERVER_SYNC_INTERVAL) + settings.MEDIASERVER_SYNC_BLACKLIST = config.get("MEDIASERVER_SYNC_BLACKLIST", + settings.MEDIASERVER_SYNC_BLACKLIST) def get_state(self) -> bool: return self._enabled @@ -89,441 +94,743 @@ class ConfigCenter(_PluginBase): request_options = ["POST", "GET"] return [ { - 'component': 'VForm', - 'content': [ + "component": "VForm", + "content": [ { - 'component': 'VRow', - 'content': [ + "component": "VRow", + "content": [ { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VSwitch', - 'props': { - 'model': 'enabled', - 'label': '启用插件', + "component": "VSwitch", + "props": { + "model": "enabled", + "label": "启用插件" } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VTextField', - 'props': { - 'model': 'GITHUB_TOKEN', - 'label': 'Github Token', + "component": "VTextField", + "props": { + "model": "GITHUB_TOKEN", + "label": "Github Token" } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VTextField', - 'props': { - 'model': 'API_TOKEN', - 'label': 'API密钥', + "component": "VTextField", + "props": { + "model": "API_TOKEN", + "label": "API密钥" } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VTextField', - 'props': { - 'model': 'TMDB_API_DOMAIN', - 'label': 'TMDB API地址', + "component": "VTextField", + "props": { + "model": "TMDB_API_DOMAIN", + "label": "TMDB API地址" } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VTextField', - 'props': { - 'model': 'TMDB_IMAGE_DOMAIN', - 'label': 'TMDB图片地址', + "component": "VTextField", + "props": { + "model": "TMDB_IMAGE_DOMAIN", + "label": "TheMovieDb图片代理" } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VSelect', - 'props': { - 'model': 'WALLPAPER', - 'label': '登录首页电影海报', - 'items': ['tmdb', 'bing'], + "component": "VSelect", + "props": { + "model": "WALLPAPER", + "label": "登录首页电影海报", + "items": [ + {"title": "TheMovieDb电影海报", "value": "tmdb"}, + {"title": "Bing每日壁纸", "value": "bing"} + ] } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VSelect', - 'props': { - 'model': 'RECOGNIZE_SOURCE', - 'label': '媒体信息识别来源', - 'items': ['themoviedb', 'douban'], + "component": "VSelect", + "props": { + "model": "RECOGNIZE_SOURCE", + "label": "媒体信息识别来源", + "items": [ + {"title": "themoviedb", "value": "TheMovieDb"}, + {"title": "douban", "value": "豆瓣"} + ] } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VSwitch', - 'props': { - 'model': 'SCRAP_METADATA', - 'label': '刮削入库的媒体文件', + "component": "VSwitch", + "props": { + "model": "SCRAP_METADATA", + "label": "刮削入库的媒体文件" } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VSelect', - 'props': { - 'model': 'SCRAP_SOURCE', - 'label': '刮削元数据及图片使用的数据源', - 'items': ['themoviedb', 'douban'], + "component": "VSelect", + "props": { + "model": "SCRAP_SOURCE", + "label": "刮削元数据及图片使用的数据源", + "items": [ + {"title": "themoviedb", "value": "TheMovieDb"}, + {"title": "douban", "value": "豆瓣"}, + ] } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VSwitch', - 'props': { - 'model': 'SCRAP_FOLLOW_TMDB', - 'label': '新增已入库媒体是否跟随TMDB信息变化', + "component": "VSwitch", + "props": { + "model": "SCRAP_FOLLOW_TMDB", + "label": "新增入库跟随TMDB信息变化" } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VTextField', - 'props': { - 'model': 'LIBRARY_PATH', - 'label': '媒体库目录', + "component": "VTextField", + "props": { + "model": "LIBRARY_PATH", + "label": "媒体库目录" } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VTextField', - 'props': { - 'model': 'LIBRARY_MOVIE_NAME', - 'label': '电影媒体库目录名称', + "component": "VTextField", + "props": { + "model": "LIBRARY_MOVIE_NAME", + "label": "电影目录名称" } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VTextField', - 'props': { - 'model': 'LIBRARY_TV_NAME', - 'label': '电视剧媒体库目录名称', + "component": "VTextField", + "props": { + "model": "LIBRARY_TV_NAME", + "label": "电视剧目录名称" } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VTextField', - 'props': { - 'model': 'LIBRARY_ANIME_NAME', - 'label': '动漫媒体库目录名称', + "component": "VTextField", + "props": { + "model": "LIBRARY_ANIME_NAME", + "label": "动漫目录名称" } - }, - ], + } + ] }, { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 + "component": "VCol", + "props": { + "cols": 12, + "md": 6 }, - 'content': [ + "content": [ { - 'component': 'VSwitch', - 'props': { - 'model': 'LIBRARY_CATEGORY', - 'label': '媒体库二级分类开关', + "component": "VSwitch", + "props": { + "model": "LIBRARY_CATEGORY", + "label": "开启媒体库二级分类" } - }, - ], + } + ] }, { - 'component': 'VSelect', - 'props': { - 'model': 'TRANSFER_TYPE', - 'label': '整理转移方式', - 'items': ['link', 'copy', 'move', 'softlink', 'rclone_copy', 'rclone_move'], - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VSelect", + "props": { + "model": "TRANSFER_TYPE", + "label": "整理转移方式", + "items": [ + {"title": "硬链接", "value": "link"}, + {"title": "复制", "value": "copy"}, + {"title": "移动", "value": "move"}, + {"title": "软链接", "value": "softlink"}, + {"title": "rclone复制", "value": "rclone_copy"}, + {"title": "rclone移动", "value": "rclone_move"} + ] + } + } + ] }, { - 'component': 'VSelect', - 'props': { - 'model': 'OVERWRITE_MODE', - 'label': '转移覆盖模式', - 'items': ['never', 'size', 'always', 'latest'], - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VSelect", + "props": { + "model": "OVERWRITE_MODE", + "label": "转移覆盖模式", + "items": [ + {"title": "从不覆盖", "value": "never"}, + {"title": "按大小覆盖", "value": "size"}, + {"title": "总是覆盖", "value": "always"}, + {"title": "仅保留最新版本", "value": "latest"} + ] + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'COOKIECLOUD_HOST', - 'label': 'CookieCloud服务器地址', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "COOKIECLOUD_HOST", + "label": "CookieCloud服务器地址" + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'COOKIECLOUD_KEY', - 'label': 'CookieCloud用户KEY', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "COOKIECLOUD_KEY", + "label": "CookieCloud用户KEY" + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'COOKIECLOUD_PASSWORD', - 'label': 'CookieCloud端对端加密密码', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "COOKIECLOUD_PASSWORD", + "label": "CookieCloud端对端加密密码" + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'COOKIECLOUD_INTERVAL', - 'label': 'CookieCloud同步间隔(分钟)', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "COOKIECLOUD_INTERVAL", + "label": "CookieCloud同步间隔(分钟)" + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'USER_AGENT', - 'label': 'CookieCloud保存Cookie对应的浏览器UA', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "USER_AGENT", + "label": "CookieCloud浏览器UA" + } + } + ] }, { - 'component': 'VSelect', - 'props': { - 'model': 'SUBSCRIBE_MODE', - 'label': '订阅模式', - 'items': ['rss', 'spider'], - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VSelect", + "props": { + "model": "SUBSCRIBE_MODE", + "label": "订阅模式", + "items": [ + {"title": "站点RSS", "value": "rss"}, + {"title": "自动", "value": "spider"} + ] + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'SUBSCRIBE_RSS_INTERVAL', - 'label': 'RSS订阅模式刷新时间间隔(分钟)', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "SUBSCRIBE_RSS_INTERVAL", + "label": "RSS订阅刷新间隔(分钟)" + } + } + ] }, { - 'component': 'VSwitch', - 'props': { - 'model': 'SUBSCRIBE_SEARCH', - 'label': '订阅搜索', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "SUBSCRIBE_SEARCH", + "label": "开启订阅搜索" + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'AUTO_DOWNLOAD_USER', - 'label': '远程交互搜索时自动择优下载的用户ID', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "AUTO_DOWNLOAD_USER", + "label": "自动择优下载用户列表" + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'OCR_HOST', - 'label': 'OCR识别服务器地址', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "OCR_HOST", + "label": "验证码识别服务器" + } + } + ] }, { - 'component': 'VSelect', - 'props': { - 'model': 'MESSAGER', - 'label': '消息通知渠道', - 'items': ['telegram', 'wechat', 'slack', 'synologychat'], - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VSelect", + "props": { + "model": "MESSAGER", + "label": "消息通知渠道", + "items": [ + {"title": "Telegram", "value": "telegram"}, + {"title": "微信", "value": "wechat"}, + {"title": "Slack", "value": "slack"}, + {"title": "SynologyChat", "value": "synologychat"} + ] + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'DOWNLOAD_PATH', - 'label': '下载保存目录', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "DOWNLOAD_PATH", + "label": "下载保存目录" + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'DOWNLOAD_MOVIE_PATH', - 'label': '电影下载保存目录路径', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "DOWNLOAD_MOVIE_PATH", + "label": "电影下载保存目录" + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'DOWNLOAD_TV_PATH', - 'label': '电视剧下载保存目录路径', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "DOWNLOAD_TV_PATH", + "label": "电视剧下载保存目录" + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'DOWNLOAD_ANIME_PATH', - 'label': '动漫下载保存目录路径', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "DOWNLOAD_ANIME_PATH", + "label": "动漫下载保存目录" + } + } + ] }, { - 'component': 'VSwitch', - 'props': { - 'model': 'DOWNLOAD_CATEGORY', - 'label': '下载二级分类开关', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "DOWNLOAD_CATEGORY", + "label": "开启下载二级分类" + } + } + ] }, { - 'component': 'VSwitch', - 'props': { - 'model': 'DOWNLOAD_SUBTITLE', - 'label': '下载站点字幕', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "DOWNLOAD_SUBTITLE", + "label": "自动下载站点字幕" + } + } + ] }, { - 'component': 'VSelect', - 'props': { - 'model': 'DOWNLOADER', - 'label': '下载器', - 'items': ['qbittorrent', 'transmission'], - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VSelect", + "props": { + "model": "DOWNLOADER", + "label": "下载器", + "items": [ + {"title": "QBittorrent", "value": "qbittorrent"}, + {"title": "Transmission", "value": "transmission"} + ] + } + } + ] }, { - 'component': 'VSwitch', - 'props': { - 'model': 'DOWNLOADER_MONITOR', - 'label': '下载器监控', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "DOWNLOADER_MONITOR", + "label": "开启下载器监控" + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'TORRENT_TAG', - 'label': '下载器种子标签', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "TORRENT_TAG", + "label": "下载器种子标签" + } + } + ] }, { - 'component': 'VSelect', - 'props': { - 'model': 'MEDIASERVER', - 'label': '媒体服务器', - 'items': ['emby', 'jellyfin', 'plex'], - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VSelect", + "props": { + "model": "MEDIASERVER", + "label": "媒体服务器", + 'chips': True, + 'multiple': True, + "items": [ + {"title": "Emby", "value": "emby"}, + {"title": "Jellyfin", "value": "jellyfin"}, + {"title": "Plex", "value": "plex"} + ] + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'MEDIASERVER_SYNC_INTERVAL', - 'label': '媒体服务器同步间隔(小时)', - } + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "MEDIASERVER_SYNC_INTERVAL", + "label": "媒体服务器同步间隔(小时)" + } + } + ] }, { - 'component': 'VTextField', - 'props': { - 'model': 'MEDIASERVER_SYNC_BLACKLIST', - 'label': '媒体服务器同步黑名单', - } - }, - ], - }, - ], - }, + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VTextField", + "props": { + "model": "MEDIASERVER_SYNC_BLACKLIST", + "label": "媒体服务器同步黑名单" + } + } + ] + } + ] + } + ] + } ], { "enabled": False, + "GITHUB_TOKEN": settings.GITHUB_TOKEN, + "API_TOKEN": settings.API_TOKEN, + "TMDB_API_DOMAIN": settings.TMDB_API_DOMAIN, + "TMDB_IMAGE_DOMAIN": settings.TMDB_IMAGE_DOMAIN, + "WALLPAPER": settings.WALLPAPER, + "RECOGNIZE_SOURCE": settings.RECOGNIZE_SOURCE, + "SCRAP_METADATA": settings.SCRAP_METADATA, + "SCRAP_SOURCE": settings.SCRAP_SOURCE, + "SCRAP_FOLLOW_TMDB": settings.SCRAP_FOLLOW_TMDB, + "LIBRARY_PATH": settings.LIBRARY_PATH, + "LIBRARY_MOVIE_NAME": settings.LIBRARY_MOVIE_NAME, + "LIBRARY_TV_NAME": settings.LIBRARY_TV_NAME, + "LIBRARY_ANIME_NAME": settings.LIBRARY_ANIME_NAME, + "LIBRARY_CATEGORY": settings.LIBRARY_CATEGORY, + "TRANSFER_TYPE": settings.TRANSFER_TYPE, + "OVERWRITE_MODE": settings.OVERWRITE_MODE, + "COOKIECLOUD_HOST": settings.COOKIECLOUD_HOST, + "COOKIECLOUD_KEY": settings.COOKIECLOUD_KEY, + "COOKIECLOUD_PASSWORD": settings.COOKIECLOUD_PASSWORD, + "COOKIECLOUD_INTERVAL": settings.COOKIECLOUD_INTERVAL, + "USER_AGENT": settings.USER_AGENT, + "SUBSCRIBE_MODE": settings.SUBSCRIBE_MODE, + "SUBSCRIBE_RSS_INTERVAL": settings.SUBSCRIBE_RSS_INTERVAL, + "SUBSCRIBE_SEARCH": settings.SUBSCRIBE_SEARCH, + "AUTO_DOWNLOAD_USER": settings.AUTO_DOWNLOAD_USER, + "OCR_HOST": settings.OCR_HOST, + "MESSAGER": settings.MESSAGER.split(","), + "DOWNLOAD_PATH": settings.DOWNLOAD_PATH, + "DOWNLOAD_MOVIE_PATH": settings.DOWNLOAD_MOVIE_PATH, + "DOWNLOAD_TV_PATH": settings.DOWNLOAD_TV_PATH, + "DOWNLOAD_ANIME_PATH": settings.DOWNLOAD_ANIME_PATH, + "DOWNLOAD_CATEGORY": settings.DOWNLOAD_CATEGORY, + "DOWNLOAD_SUBTITLE": settings.DOWNLOAD_SUBTITLE, + "DOWNLOADER": settings.DOWNLOADER, + "DOWNLOADER_MONITOR": settings.DOWNLOADER_MONITOR, + "TORRENT_TAG": settings.TORRENT_TAG, + "MEDIASERVER": settings.MEDIASERVER.split(","), + "MEDIASERVER_SYNC_INTERVAL": settings.MEDIASERVER_SYNC_INTERVAL, + "MEDIASERVER_SYNC_BLACKLIST": settings.MEDIASERVER_SYNC_BLACKLIST } def get_page(self) -> List[dict]: From b2cd5ea57749711f21934e1e4e371cc776d091d5 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sun, 26 Nov 2023 20:06:06 +0800 Subject: [PATCH 5/9] =?UTF-8?q?feat=20=E9=85=8D=E7=BD=AE=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/configcenter/__init__.py | 417 +++++++++++++++++++------------ 1 file changed, 252 insertions(+), 165 deletions(-) diff --git a/plugins/configcenter/__init__.py b/plugins/configcenter/__init__.py index 309d4a4..c664b87 100644 --- a/plugins/configcenter/__init__.py +++ b/plugins/configcenter/__init__.py @@ -1,6 +1,7 @@ from typing import Any, List, Dict, Tuple from app.core.config import settings +from app.log import logger from app.plugins import _PluginBase @@ -32,50 +33,52 @@ class ConfigCenter(_PluginBase): def init_plugin(self, config: dict = None): if config: self._enabled = config.get("enabled") - settings.GITHUB_TOKEN = config.get("GITHUB_TOKEN", settings.GITHUB_TOKEN) - settings.API_TOKEN = config.get("API_TOKEN", settings.API_TOKEN) - settings.TMDB_API_DOMAIN = config.get("TMDB_API_DOMAIN", settings.TMDB_API_DOMAIN) - settings.TMDB_IMAGE_DOMAIN = config.get("TMDB_IMAGE_DOMAIN", settings.TMDB_IMAGE_DOMAIN) - settings.WALLPAPER = config.get("WALLPAPER", settings.WALLPAPER) - settings.RECOGNIZE_SOURCE = config.get("RECOGNIZE_SOURCE", "") - settings.SCRAP_METADATA = config.get("SCRAP_METADATA", settings.SCRAP_METADATA) - settings.SCRAP_FOLLOW_TMDB = config.get("SCRAP_FOLLOW_TMDB", settings.SCRAP_FOLLOW_TMDB) - settings.LIBRARY_PATH = config.get("LIBRARY_PATH", settings.LIBRARY_PATH) - settings.LIBRARY_MOVIE_NAME = config.get("LIBRARY_MOVIE_NAME", settings.LIBRARY_MOVIE_NAME) - settings.LIBRARY_TV_NAME = config.get("LIBRARY_TV_NAME", settings.LIBRARY_TV_NAME) - settings.LIBRARY_ANIME_NAME = config.get("LIBRARY_ANIME_NAME", settings.LIBRARY_ANIME_NAME) - settings.LIBRARY_CATEGORY = config.get("LIBRARY_CATEGORY", settings.LIBRARY_CATEGORY) - settings.TRANSFER_TYPE = config.get("TRANSFER_TYPE", settings.TRANSFER_TYPE) - settings.OVERWRITE_MODE = config.get("OVERWRITE_MODE", settings.OVERWRITE_MODE) - settings.COOKIECLOUD_HOST = config.get("COOKIECLOUD_HOST", settings.COOKIECLOUD_HOST) - settings.COOKIECLOUD_KEY = config.get("COOKIECLOUD_KEY", settings.COOKIECLOUD_KEY) - settings.COOKIECLOUD_PASSWORD = config.get("COOKIECLOUD_PASSWORD", settings.COOKIECLOUD_PASSWORD) - settings.COOKIECLOUD_INTERVAL = config.get("COOKIECLOUD_INTERVAL", settings.COOKIECLOUD_INTERVAL) - settings.USER_AGENT = config.get("USER_AGENT", settings.USER_AGENT) - settings.SUBSCRIBE_MODE = config.get("SUBSCRIBE_MODE", settings.SUBSCRIBE_MODE) - settings.SUBSCRIBE_RSS_INTERVAL = config.get("SUBSCRIBE_RSS_INTERVAL", settings.SUBSCRIBE_RSS_INTERVAL) - settings.SUBSCRIBE_SEARCH = config.get("SUBSCRIBE_SEARCH", settings.SUBSCRIBE_SEARCH) - settings.AUTO_DOWNLOAD_USER = config.get("AUTO_DOWNLOAD_USER", settings.AUTO_DOWNLOAD_USER) - settings.OCR_HOST = config.get("OCR_HOST", settings.OCR_HOST) - messagers = config.get("MESSAGER") or [] - if messagers: - settings.MESSAGER = ",".join(messagers) - settings.DOWNLOAD_PATH = config.get("DOWNLOAD_PATH", settings.DOWNLOAD_PATH) - settings.DOWNLOAD_MOVIE_PATH = config.get("DOWNLOAD_MOVIE_PATH", settings.DOWNLOAD_MOVIE_PATH) - settings.DOWNLOAD_TV_PATH = config.get("DOWNLOAD_TV_PATH", settings.DOWNLOAD_TV_PATH) - settings.DOWNLOAD_ANIME_PATH = config.get("DOWNLOAD_ANIME_PATH", settings.DOWNLOAD_ANIME_PATH) - settings.DOWNLOAD_CATEGORY = config.get("DOWNLOAD_CATEGORY", settings.DOWNLOAD_CATEGORY) - settings.DOWNLOAD_SUBTITLE = config.get("DOWNLOAD_SUBTITLE", settings.DOWNLOAD_SUBTITLE) - settings.DOWNLOADER = config.get("DOWNLOADER", settings.DOWNLOADER) - settings.DOWNLOADER_MONITOR = config.get("DOWNLOADER_MONITOR", settings.DOWNLOADER_MONITOR) - settings.TORRENT_TAG = config.get("TORRENT_TAG", settings.TORRENT_TAG) - media_servers = config.get("MEDIASERVER") or [] - if media_servers: - settings.MEDIASERVER = ",".join(media_servers) - settings.MEDIASERVER_SYNC_INTERVAL = config.get("MEDIASERVER_SYNC_INTERVAL", - settings.MEDIASERVER_SYNC_INTERVAL) - settings.MEDIASERVER_SYNC_BLACKLIST = config.get("MEDIASERVER_SYNC_BLACKLIST", - settings.MEDIASERVER_SYNC_BLACKLIST) + if self._enabled: + logger.info(f"正在应用配置中心配置:{config}") + settings.GITHUB_TOKEN = config.get("GITHUB_TOKEN", settings.GITHUB_TOKEN) + settings.API_TOKEN = config.get("API_TOKEN", settings.API_TOKEN) + settings.TMDB_API_DOMAIN = config.get("TMDB_API_DOMAIN", settings.TMDB_API_DOMAIN) + settings.TMDB_IMAGE_DOMAIN = config.get("TMDB_IMAGE_DOMAIN", settings.TMDB_IMAGE_DOMAIN) + settings.WALLPAPER = config.get("WALLPAPER", settings.WALLPAPER) + settings.RECOGNIZE_SOURCE = config.get("RECOGNIZE_SOURCE", "") + settings.SCRAP_METADATA = config.get("SCRAP_METADATA", settings.SCRAP_METADATA) + settings.SCRAP_FOLLOW_TMDB = config.get("SCRAP_FOLLOW_TMDB", settings.SCRAP_FOLLOW_TMDB) + settings.LIBRARY_PATH = config.get("LIBRARY_PATH", settings.LIBRARY_PATH) + settings.LIBRARY_MOVIE_NAME = config.get("LIBRARY_MOVIE_NAME", settings.LIBRARY_MOVIE_NAME) + settings.LIBRARY_TV_NAME = config.get("LIBRARY_TV_NAME", settings.LIBRARY_TV_NAME) + settings.LIBRARY_ANIME_NAME = config.get("LIBRARY_ANIME_NAME", settings.LIBRARY_ANIME_NAME) + settings.LIBRARY_CATEGORY = config.get("LIBRARY_CATEGORY", settings.LIBRARY_CATEGORY) + settings.TRANSFER_TYPE = config.get("TRANSFER_TYPE", settings.TRANSFER_TYPE) + settings.OVERWRITE_MODE = config.get("OVERWRITE_MODE", settings.OVERWRITE_MODE) + settings.COOKIECLOUD_HOST = config.get("COOKIECLOUD_HOST", settings.COOKIECLOUD_HOST) + settings.COOKIECLOUD_KEY = config.get("COOKIECLOUD_KEY", settings.COOKIECLOUD_KEY) + settings.COOKIECLOUD_PASSWORD = config.get("COOKIECLOUD_PASSWORD", settings.COOKIECLOUD_PASSWORD) + settings.COOKIECLOUD_INTERVAL = config.get("COOKIECLOUD_INTERVAL", settings.COOKIECLOUD_INTERVAL) + settings.USER_AGENT = config.get("USER_AGENT", settings.USER_AGENT) + settings.SUBSCRIBE_MODE = config.get("SUBSCRIBE_MODE", settings.SUBSCRIBE_MODE) + settings.SUBSCRIBE_RSS_INTERVAL = config.get("SUBSCRIBE_RSS_INTERVAL", settings.SUBSCRIBE_RSS_INTERVAL) + settings.SUBSCRIBE_SEARCH = config.get("SUBSCRIBE_SEARCH", settings.SUBSCRIBE_SEARCH) + settings.AUTO_DOWNLOAD_USER = config.get("AUTO_DOWNLOAD_USER", settings.AUTO_DOWNLOAD_USER) + settings.OCR_HOST = config.get("OCR_HOST", settings.OCR_HOST) + messagers = config.get("MESSAGER") or [] + if messagers: + settings.MESSAGER = ",".join(messagers) + settings.DOWNLOAD_PATH = config.get("DOWNLOAD_PATH", settings.DOWNLOAD_PATH) + settings.DOWNLOAD_MOVIE_PATH = config.get("DOWNLOAD_MOVIE_PATH", settings.DOWNLOAD_MOVIE_PATH) + settings.DOWNLOAD_TV_PATH = config.get("DOWNLOAD_TV_PATH", settings.DOWNLOAD_TV_PATH) + settings.DOWNLOAD_ANIME_PATH = config.get("DOWNLOAD_ANIME_PATH", settings.DOWNLOAD_ANIME_PATH) + settings.DOWNLOAD_CATEGORY = config.get("DOWNLOAD_CATEGORY", settings.DOWNLOAD_CATEGORY) + settings.DOWNLOAD_SUBTITLE = config.get("DOWNLOAD_SUBTITLE", settings.DOWNLOAD_SUBTITLE) + settings.DOWNLOADER = config.get("DOWNLOADER", settings.DOWNLOADER) + settings.DOWNLOADER_MONITOR = config.get("DOWNLOADER_MONITOR", settings.DOWNLOADER_MONITOR) + settings.TORRENT_TAG = config.get("TORRENT_TAG", settings.TORRENT_TAG) + media_servers = config.get("MEDIASERVER") or [] + if media_servers: + settings.MEDIASERVER = ",".join(media_servers) + settings.MEDIASERVER_SYNC_INTERVAL = config.get("MEDIASERVER_SYNC_INTERVAL", + settings.MEDIASERVER_SYNC_INTERVAL) + settings.MEDIASERVER_SYNC_BLACKLIST = config.get("MEDIASERVER_SYNC_BLACKLIST", + settings.MEDIASERVER_SYNC_BLACKLIST) def get_state(self) -> bool: return self._enabled @@ -91,7 +94,6 @@ class ConfigCenter(_PluginBase): """ 拼装插件配置页面,需要返回两块数据:1、页面配置;2、数据结构 """ - request_options = ["POST", "GET"] return [ { "component": "VForm", @@ -115,6 +117,11 @@ class ConfigCenter(_PluginBase): } ] }, + ] + }, + { + 'component': 'VRow', + 'content': [ { "component": "VCol", "props": { @@ -174,7 +181,47 @@ class ConfigCenter(_PluginBase): "component": "VTextField", "props": { "model": "TMDB_IMAGE_DOMAIN", - "label": "TheMovieDb图片代理" + "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"}, + ] } } ] @@ -198,7 +245,12 @@ class ConfigCenter(_PluginBase): } } ] - }, + } + ] + }, + { + 'component': 'VRow', + 'content': [ { "component": "VCol", "props": { @@ -207,14 +259,10 @@ class ConfigCenter(_PluginBase): }, "content": [ { - "component": "VSelect", + "component": "VSwitch", "props": { - "model": "RECOGNIZE_SOURCE", - "label": "媒体信息识别来源", - "items": [ - {"title": "themoviedb", "value": "TheMovieDb"}, - {"title": "douban", "value": "豆瓣"} - ] + "model": "LIBRARY_CATEGORY", + "label": "开启媒体库二级分类" } } ] @@ -234,43 +282,12 @@ class ConfigCenter(_PluginBase): } } ] - }, - { - "component": "VCol", - "props": { - "cols": 12, - "md": 6 - }, - "content": [ - { - "component": "VSelect", - "props": { - "model": "SCRAP_SOURCE", - "label": "刮削元数据及图片使用的数据源", - "items": [ - {"title": "themoviedb", "value": "TheMovieDb"}, - {"title": "douban", "value": "豆瓣"}, - ] - } - } - ] - }, - { - "component": "VCol", - "props": { - "cols": 12, - "md": 6 - }, - "content": [ - { - "component": "VSwitch", - "props": { - "model": "SCRAP_FOLLOW_TMDB", - "label": "新增入库跟随TMDB信息变化" - } - } - ] - }, + } + ] + }, + { + 'component': 'VRow', + 'content': [ { "component": "VCol", "props": { @@ -335,22 +352,6 @@ class ConfigCenter(_PluginBase): } ] }, - { - "component": "VCol", - "props": { - "cols": 12, - "md": 6 - }, - "content": [ - { - "component": "VSwitch", - "props": { - "model": "LIBRARY_CATEGORY", - "label": "开启媒体库二级分类" - } - } - ] - }, { "component": "VCol", "props": { @@ -396,7 +397,33 @@ class ConfigCenter(_PluginBase): } } ] - }, + } + ] + }, + { + 'component': 'VRow', + 'content': [ + { + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "SCRAP_FOLLOW_TMDB", + "label": "新增入库跟随TMDB信息变化" + } + } + ] + } + ] + }, + { + 'component': 'VRow', + 'content': [ { "component": "VCol", "props": { @@ -464,8 +491,7 @@ class ConfigCenter(_PluginBase): { "component": "VCol", "props": { - "cols": 12, - "md": 6 + "cols": 12 }, "content": [ { @@ -476,7 +502,12 @@ class ConfigCenter(_PluginBase): } } ] - }, + } + ] + }, + { + 'component': 'VRow', + 'content': [ { "component": "VCol", "props": { @@ -512,7 +543,12 @@ class ConfigCenter(_PluginBase): } } ] - }, + } + ] + }, + { + 'component': 'VRow', + 'content': [ { "component": "VCol", "props": { @@ -524,7 +560,36 @@ class ConfigCenter(_PluginBase): "component": "VSwitch", "props": { "model": "SUBSCRIBE_SEARCH", - "label": "开启订阅搜索" + "label": "开启订阅定时搜索" + } + } + ] + } + ] + }, + { + 'component': 'VRow', + 'content': [ + { + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VSelect", + "props": { + "model": "MESSAGER", + "label": "消息通知渠道", + 'chips': True, + 'multiple': True, + "items": [ + {"title": "Telegram", "value": "telegram"}, + {"title": "微信", "value": "wechat"}, + {"title": "Slack", "value": "slack"}, + {"title": "SynologyChat", "value": "synologychat"} + ] } } ] @@ -544,12 +609,16 @@ class ConfigCenter(_PluginBase): } } ] - }, + } + ] + }, + { + 'component': 'VRow', + 'content': [ { "component": "VCol", "props": { - "cols": 12, - "md": 6 + "cols": 12 }, "content": [ { @@ -561,28 +630,6 @@ class ConfigCenter(_PluginBase): } ] }, - { - "component": "VCol", - "props": { - "cols": 12, - "md": 6 - }, - "content": [ - { - "component": "VSelect", - "props": { - "model": "MESSAGER", - "label": "消息通知渠道", - "items": [ - {"title": "Telegram", "value": "telegram"}, - {"title": "微信", "value": "wechat"}, - {"title": "Slack", "value": "slack"}, - {"title": "SynologyChat", "value": "synologychat"} - ] - } - } - ] - }, { "component": "VCol", "props": { @@ -646,6 +693,27 @@ class ConfigCenter(_PluginBase): } } ] + } + ] + }, + { + 'component': 'VRow', + 'content': [ + { + "component": "VCol", + "props": { + "cols": 12, + "md": 6 + }, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "DOWNLOADER_MONITOR", + "label": "开启下载器监控" + } + } + ] }, { "component": "VCol", @@ -662,23 +730,12 @@ class ConfigCenter(_PluginBase): } } ] - }, - { - "component": "VCol", - "props": { - "cols": 12, - "md": 6 - }, - "content": [ - { - "component": "VSwitch", - "props": { - "model": "DOWNLOAD_SUBTITLE", - "label": "自动下载站点字幕" - } - } - ] - }, + } + ] + }, + { + 'component': 'VRow', + 'content': [ { "component": "VCol", "props": { @@ -707,14 +764,19 @@ class ConfigCenter(_PluginBase): }, "content": [ { - "component": "VSwitch", + "component": "VTextField", "props": { - "model": "DOWNLOADER_MONITOR", - "label": "开启下载器监控" + "model": "TORRENT_TAG", + "label": "下载器种子标签" } } ] - }, + } + ] + }, + { + 'component': 'VRow', + 'content': [ { "component": "VCol", "props": { @@ -723,14 +785,19 @@ class ConfigCenter(_PluginBase): }, "content": [ { - "component": "VTextField", + "component": "VSwitch", "props": { - "model": "TORRENT_TAG", - "label": "下载器种子标签" + "model": "DOWNLOAD_SUBTITLE", + "label": "自动下载站点字幕" } } ] - }, + } + ] + }, + { + 'component': 'VRow', + 'content': [ { "component": "VCol", "props": { @@ -773,8 +840,7 @@ class ConfigCenter(_PluginBase): { "component": "VCol", "props": { - "cols": 12, - "md": 6 + "cols": 12 }, "content": [ { @@ -787,6 +853,27 @@ class ConfigCenter(_PluginBase): ] } ] + }, + { + 'component': 'VRow', + 'content': [ + { + 'component': 'VCol', + 'props': { + 'cols': 12, + }, + 'content': [ + { + 'component': 'VAlert', + 'props': { + 'type': 'info', + 'variant': 'tonal', + 'text': '注意:本插件只是运行时临时修改生效系统配置,并不会实际改变环境变量或app.env中的配置值。' + } + } + ] + } + ] } ] } From b66af6ac276b9cc6cd81d66f52677ef01c38490d Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sun, 26 Nov 2023 20:10:32 +0800 Subject: [PATCH 6/9] =?UTF-8?q?feat=20=E9=85=8D=E7=BD=AE=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/configcenter/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/configcenter/__init__.py b/plugins/configcenter/__init__.py index c664b87..915b7e7 100644 --- a/plugins/configcenter/__init__.py +++ b/plugins/configcenter/__init__.py @@ -23,7 +23,7 @@ class ConfigCenter(_PluginBase): # 插件配置项ID前缀 plugin_config_prefix = "configcenter_" # 加载顺序 - plugin_order = 1 + plugin_order = 0 # 可使用的用户级别 auth_level = 1 From a8132e01cc0dfc90d7c3a7e43c5959623c59e211 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sun, 26 Nov 2023 21:18:52 +0800 Subject: [PATCH 7/9] fix ConfigCenter --- icons/setting.png | Bin 22836 -> 0 bytes package.json | 2 +- plugins/configcenter/__init__.py | 166 ++++++++++++++++--------------- 3 files changed, 86 insertions(+), 82 deletions(-) delete mode 100644 icons/setting.png diff --git a/icons/setting.png b/icons/setting.png deleted file mode 100644 index 0ad88b03ada99aed2c0a37dd516158b3850edd55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22836 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 z 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 Ui<2#Vz6XyqRCQF!uUUuv4`DMLfdBvi diff --git a/package.json b/package.json index 8707798..f5afc9c 100644 --- a/package.json +++ b/package.json @@ -326,7 +326,7 @@ "ConfigCenter": { "name": "配置中心", "description": "快速调整部分系统设定。", - "version": "1.0", + "version": "1.1", "icon": "setting.png", "color": "#FC6220", "author": "jxxghp", diff --git a/plugins/configcenter/__init__.py b/plugins/configcenter/__init__.py index 915b7e7..5950c33 100644 --- a/plugins/configcenter/__init__.py +++ b/plugins/configcenter/__init__.py @@ -15,7 +15,7 @@ class ConfigCenter(_PluginBase): # 主题色 plugin_color = "#FC6220" # 插件版本 - plugin_version = "1.0" + plugin_version = "1.1" # 插件作者 plugin_author = "jxxghp" # 作者主页 @@ -29,56 +29,33 @@ class ConfigCenter(_PluginBase): # 私有属性 _enabled = False + settings_attributes = [ + "GITHUB_TOKEN", "API_TOKEN", "TMDB_API_DOMAIN", "TMDB_IMAGE_DOMAIN", "WALLPAPER", + "RECOGNIZE_SOURCE", "SCRAP_METADATA", "SCRAP_FOLLOW_TMDB", "LIBRARY_PATH", + "LIBRARY_MOVIE_NAME", "LIBRARY_TV_NAME", "LIBRARY_ANIME_NAME", "LIBRARY_CATEGORY", + "TRANSFER_TYPE", "OVERWRITE_MODE", "COOKIECLOUD_HOST", "COOKIECLOUD_KEY", + "COOKIECLOUD_PASSWORD", "COOKIECLOUD_INTERVAL", "USER_AGENT", "SUBSCRIBE_MODE", + "SUBSCRIBE_RSS_INTERVAL", "SUBSCRIBE_SEARCH", "AUTO_DOWNLOAD_USER", "OCR_HOST", + "DOWNLOAD_PATH", "DOWNLOAD_MOVIE_PATH", "DOWNLOAD_TV_PATH", + "DOWNLOAD_ANIME_PATH", "DOWNLOAD_CATEGORY", "DOWNLOAD_SUBTITLE", "DOWNLOADER", + "DOWNLOADER_MONITOR", "TORRENT_TAG", "MEDIASERVER_SYNC_INTERVAL", + "MEDIASERVER_SYNC_BLACKLIST", "PLUGIN_MARKET", "MOVIE_RENAME_FORMAT", + "TV_RENAME_FORMAT" + ] def init_plugin(self, config: dict = None): if config: self._enabled = config.get("enabled") if self._enabled: logger.info(f"正在应用配置中心配置:{config}") - settings.GITHUB_TOKEN = config.get("GITHUB_TOKEN", settings.GITHUB_TOKEN) - settings.API_TOKEN = config.get("API_TOKEN", settings.API_TOKEN) - settings.TMDB_API_DOMAIN = config.get("TMDB_API_DOMAIN", settings.TMDB_API_DOMAIN) - settings.TMDB_IMAGE_DOMAIN = config.get("TMDB_IMAGE_DOMAIN", settings.TMDB_IMAGE_DOMAIN) - settings.WALLPAPER = config.get("WALLPAPER", settings.WALLPAPER) - settings.RECOGNIZE_SOURCE = config.get("RECOGNIZE_SOURCE", "") - settings.SCRAP_METADATA = config.get("SCRAP_METADATA", settings.SCRAP_METADATA) - settings.SCRAP_FOLLOW_TMDB = config.get("SCRAP_FOLLOW_TMDB", settings.SCRAP_FOLLOW_TMDB) - settings.LIBRARY_PATH = config.get("LIBRARY_PATH", settings.LIBRARY_PATH) - settings.LIBRARY_MOVIE_NAME = config.get("LIBRARY_MOVIE_NAME", settings.LIBRARY_MOVIE_NAME) - settings.LIBRARY_TV_NAME = config.get("LIBRARY_TV_NAME", settings.LIBRARY_TV_NAME) - settings.LIBRARY_ANIME_NAME = config.get("LIBRARY_ANIME_NAME", settings.LIBRARY_ANIME_NAME) - settings.LIBRARY_CATEGORY = config.get("LIBRARY_CATEGORY", settings.LIBRARY_CATEGORY) - settings.TRANSFER_TYPE = config.get("TRANSFER_TYPE", settings.TRANSFER_TYPE) - settings.OVERWRITE_MODE = config.get("OVERWRITE_MODE", settings.OVERWRITE_MODE) - settings.COOKIECLOUD_HOST = config.get("COOKIECLOUD_HOST", settings.COOKIECLOUD_HOST) - settings.COOKIECLOUD_KEY = config.get("COOKIECLOUD_KEY", settings.COOKIECLOUD_KEY) - settings.COOKIECLOUD_PASSWORD = config.get("COOKIECLOUD_PASSWORD", settings.COOKIECLOUD_PASSWORD) - settings.COOKIECLOUD_INTERVAL = config.get("COOKIECLOUD_INTERVAL", settings.COOKIECLOUD_INTERVAL) - settings.USER_AGENT = config.get("USER_AGENT", settings.USER_AGENT) - settings.SUBSCRIBE_MODE = config.get("SUBSCRIBE_MODE", settings.SUBSCRIBE_MODE) - settings.SUBSCRIBE_RSS_INTERVAL = config.get("SUBSCRIBE_RSS_INTERVAL", settings.SUBSCRIBE_RSS_INTERVAL) - settings.SUBSCRIBE_SEARCH = config.get("SUBSCRIBE_SEARCH", settings.SUBSCRIBE_SEARCH) - settings.AUTO_DOWNLOAD_USER = config.get("AUTO_DOWNLOAD_USER", settings.AUTO_DOWNLOAD_USER) - settings.OCR_HOST = config.get("OCR_HOST", settings.OCR_HOST) + for attribute in self.settings_attributes: + setattr(settings, attribute, config.get(attribute) or getattr(settings, attribute)) messagers = config.get("MESSAGER") or [] if messagers: settings.MESSAGER = ",".join(messagers) - settings.DOWNLOAD_PATH = config.get("DOWNLOAD_PATH", settings.DOWNLOAD_PATH) - settings.DOWNLOAD_MOVIE_PATH = config.get("DOWNLOAD_MOVIE_PATH", settings.DOWNLOAD_MOVIE_PATH) - settings.DOWNLOAD_TV_PATH = config.get("DOWNLOAD_TV_PATH", settings.DOWNLOAD_TV_PATH) - settings.DOWNLOAD_ANIME_PATH = config.get("DOWNLOAD_ANIME_PATH", settings.DOWNLOAD_ANIME_PATH) - settings.DOWNLOAD_CATEGORY = config.get("DOWNLOAD_CATEGORY", settings.DOWNLOAD_CATEGORY) - settings.DOWNLOAD_SUBTITLE = config.get("DOWNLOAD_SUBTITLE", settings.DOWNLOAD_SUBTITLE) - settings.DOWNLOADER = config.get("DOWNLOADER", settings.DOWNLOADER) - settings.DOWNLOADER_MONITOR = config.get("DOWNLOADER_MONITOR", settings.DOWNLOADER_MONITOR) - settings.TORRENT_TAG = config.get("TORRENT_TAG", settings.TORRENT_TAG) media_servers = config.get("MEDIASERVER") or [] if media_servers: settings.MEDIASERVER = ",".join(media_servers) - settings.MEDIASERVER_SYNC_INTERVAL = config.get("MEDIASERVER_SYNC_INTERVAL", - settings.MEDIASERVER_SYNC_INTERVAL) - settings.MEDIASERVER_SYNC_BLACKLIST = config.get("MEDIASERVER_SYNC_BLACKLIST", - settings.MEDIASERVER_SYNC_BLACKLIST) def get_state(self) -> bool: return self._enabled @@ -94,6 +71,13 @@ class ConfigCenter(_PluginBase): """ 拼装插件配置页面,需要返回两块数据:1、页面配置;2、数据结构 """ + default_settings = { + "enabled": False, + } + for attribute in self.settings_attributes: + default_settings[attribute] = getattr(settings, attribute) + default_settings["MESSAGER"] = settings.MESSAGER.split(",") + default_settings["MEDIASERVER"] = settings.MEDIASERVER.split(",") return [ { "component": "VForm", @@ -854,6 +838,67 @@ class ConfigCenter(_PluginBase): } ] }, + { + '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': [ @@ -877,48 +922,7 @@ class ConfigCenter(_PluginBase): } ] } - ], { - "enabled": False, - "GITHUB_TOKEN": settings.GITHUB_TOKEN, - "API_TOKEN": settings.API_TOKEN, - "TMDB_API_DOMAIN": settings.TMDB_API_DOMAIN, - "TMDB_IMAGE_DOMAIN": settings.TMDB_IMAGE_DOMAIN, - "WALLPAPER": settings.WALLPAPER, - "RECOGNIZE_SOURCE": settings.RECOGNIZE_SOURCE, - "SCRAP_METADATA": settings.SCRAP_METADATA, - "SCRAP_SOURCE": settings.SCRAP_SOURCE, - "SCRAP_FOLLOW_TMDB": settings.SCRAP_FOLLOW_TMDB, - "LIBRARY_PATH": settings.LIBRARY_PATH, - "LIBRARY_MOVIE_NAME": settings.LIBRARY_MOVIE_NAME, - "LIBRARY_TV_NAME": settings.LIBRARY_TV_NAME, - "LIBRARY_ANIME_NAME": settings.LIBRARY_ANIME_NAME, - "LIBRARY_CATEGORY": settings.LIBRARY_CATEGORY, - "TRANSFER_TYPE": settings.TRANSFER_TYPE, - "OVERWRITE_MODE": settings.OVERWRITE_MODE, - "COOKIECLOUD_HOST": settings.COOKIECLOUD_HOST, - "COOKIECLOUD_KEY": settings.COOKIECLOUD_KEY, - "COOKIECLOUD_PASSWORD": settings.COOKIECLOUD_PASSWORD, - "COOKIECLOUD_INTERVAL": settings.COOKIECLOUD_INTERVAL, - "USER_AGENT": settings.USER_AGENT, - "SUBSCRIBE_MODE": settings.SUBSCRIBE_MODE, - "SUBSCRIBE_RSS_INTERVAL": settings.SUBSCRIBE_RSS_INTERVAL, - "SUBSCRIBE_SEARCH": settings.SUBSCRIBE_SEARCH, - "AUTO_DOWNLOAD_USER": settings.AUTO_DOWNLOAD_USER, - "OCR_HOST": settings.OCR_HOST, - "MESSAGER": settings.MESSAGER.split(","), - "DOWNLOAD_PATH": settings.DOWNLOAD_PATH, - "DOWNLOAD_MOVIE_PATH": settings.DOWNLOAD_MOVIE_PATH, - "DOWNLOAD_TV_PATH": settings.DOWNLOAD_TV_PATH, - "DOWNLOAD_ANIME_PATH": settings.DOWNLOAD_ANIME_PATH, - "DOWNLOAD_CATEGORY": settings.DOWNLOAD_CATEGORY, - "DOWNLOAD_SUBTITLE": settings.DOWNLOAD_SUBTITLE, - "DOWNLOADER": settings.DOWNLOADER, - "DOWNLOADER_MONITOR": settings.DOWNLOADER_MONITOR, - "TORRENT_TAG": settings.TORRENT_TAG, - "MEDIASERVER": settings.MEDIASERVER.split(","), - "MEDIASERVER_SYNC_INTERVAL": settings.MEDIASERVER_SYNC_INTERVAL, - "MEDIASERVER_SYNC_BLACKLIST": settings.MEDIASERVER_SYNC_BLACKLIST - } + ], default_settings def get_page(self) -> List[dict]: pass From 0875c947a8dead1cbfab5c8e67b3d959d0f4a382 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sun, 26 Nov 2023 21:52:50 +0800 Subject: [PATCH 8/9] Add files via upload --- icons/setting.png | Bin 0 -> 22836 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 icons/setting.png diff --git a/icons/setting.png b/icons/setting.png new file mode 100644 index 0000000000000000000000000000000000000000..0ad88b03ada99aed2c0a37dd516158b3850edd55 GIT binary patch literal 22836 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 z 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 Ui<2#Vz6XyqRCQF!uUUuv4`DMLfdBvi literal 0 HcmV?d00001 From d64fbdf733b713b97939456de7b3ced8ffed58d9 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Mon, 27 Nov 2023 08:20:49 +0800 Subject: [PATCH 9/9] fix typo --- plugins/configcenter/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/configcenter/__init__.py b/plugins/configcenter/__init__.py index 5950c33..60733a3 100644 --- a/plugins/configcenter/__init__.py +++ b/plugins/configcenter/__init__.py @@ -733,7 +733,7 @@ class ConfigCenter(_PluginBase): "model": "DOWNLOADER", "label": "下载器", "items": [ - {"title": "QBittorrent", "value": "qbittorrent"}, + {"title": "Qbittorrent", "value": "qbittorrent"}, {"title": "Transmission", "value": "transmission"} ] }