From a9e58b9caf58f368748f6d1e15d04e77e70883b7 Mon Sep 17 00:00:00 2001 From: xuzhi Date: Wed, 20 Mar 2024 09:28:33 +0000 Subject: [PATCH] Add plugin IPDetect --- icons/ipAddress.png | Bin 0 -> 22654 bytes package.json | 8 + plugins/ipdetect/__init__.py | 520 +++++++++++++++++++++++++++++++++++ 3 files changed, 528 insertions(+) create mode 100644 icons/ipAddress.png create mode 100644 plugins/ipdetect/__init__.py diff --git a/icons/ipAddress.png b/icons/ipAddress.png new file mode 100644 index 0000000000000000000000000000000000000000..89e8708466c94dc60a4d7e45021d656be3e83692 GIT binary patch literal 22654 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 bool: + return self._enabled + + def detect_ip(self): + if len(self._setting_keys) == 0: + return + local_ip = self.get_local_ip() + current_ip = self.parse_ip(self.get_value(self._setting_keys[0])) + logger.info(f"current_ip: {current_ip}") + if local_ip == current_ip: + logger.info(f"当前IP地址为{local_ip},没有变化!") + if self._notify: + self.post_message( + mtype=NotificationType.SiteMessage, + title=f"【本地IP检测】", + text=f"未检测到IP地址变化!", + ) + + return + for key in self._setting_keys: + prefix = ( + True + if key == "EMBY_PLAY_HOST" + or key == "PLEX_PLAY_HOST" + or key == "JELLYFIN_PLAY_HOST" + else False + ) + self.update_key_value(key, local_ip, prefix) + # 重新加载模块 + logger.info("重新加载模块") + ModuleManager().reload() + Scheduler().init() + if self._notify: + self.post_message( + mtype=NotificationType.SiteMessage, + title=f"【本地IP检测】", + text=f"检测到本地IP变为{local_ip},已更新服务地址!", + ) + + def update_key_value(self, k, v, prefix): + old_value = self.get_value(k) + if prefix: # http(s)://ip:port + ip_pattern = r"https?://(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+)" + v = re.sub( + ip_pattern, + lambda m: "{}://{}:{}".format(m.group(0).split(":")[0], v, m.group(2)), + old_value, + ) + else: # ip:port + ip_pattern = r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+)' + v = re.sub(ip_pattern, r'{}:\2'.format(v), old_value) + if hasattr(settings, k): + if v == "None": + v = None + setattr(settings, k, v) + if v is None: + v = "" + else: + v = str(v) + set_key(settings.CONFIG_PATH / "app.env", k, v) + logger.info(f"重新设置服务地址{k}成功!") + + def get_value(self, key): + if key == "QB_HOST": + return settings.QB_HOST + elif key == "TR_HOST": + return settings.TR_HOST + elif key == "EMBY_HOST": + return settings.EMBY_HOST + elif key == "EMBY_PLAY_HOST": + return settings.EMBY_PLAY_HOST + elif key == "JELLYFIN_HOST": + return settings.JELLYFIN_HOST + elif key == "JELLYFIN_PLAY_HOST": + return settings.JELLYFIN_PLAY_HOST + elif key == "PLEX_HOST": + return settings.PLEX_HOST + elif key == "PLEX_PLAY_HOST": + return settings.PLEX_PLAY_HOST + else: + return None + + def parse_ip(self, ip): + ip_pattern = r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' + match = re.search(ip_pattern, ip) + if match: + return match.group(1) + else: + return None + + def get_service(self) -> List[Dict[str, Any]]: + """ + 注册插件公共服务 + [{ + "id": "服务ID", + "name": "服务名称", + "trigger": "触发器:cron/interval/date/CronTrigger.from_crontab()", + "func": self.xxx, + "kwargs": {} # 定时器参数 + }] + """ + if self._enabled and self._cron: + return [ + { + "id": "IpDetect", + "name": "检测本地IP变化", + "trigger": CronTrigger.from_crontab(self._cron), + "func": self.detect_ip, + "kwargs": {}, + } + ] + + def get_local_ip(self): + try: + # 创建一个 UDP 套接字 + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + # 连接到一个虚拟的目标IP和端口 + s.connect(("10.255.255.255", 1)) + # 获取本地 IP 地址 + local_ip = s.getsockname()[0] + logger.info(f"当前本地IP为:{local_ip}") + return local_ip + except socket.error: + return "127.0.0.1" # 如果无法获取到本地IP,则返回本地回环地址 + + @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]]: + 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": 4}, + "content": [ + { + "component": "VTextField", + "props": { + "model": "cron", + "label": "检测周期", + }, + } + ], + }, + ], + }, + { + "component": "VRow", + "content": [ + { + "component": "VCol", + "props": {"cols": 12, "md": 6}, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "notify", + "label": "发送通知", + }, + } + ], + }, + { + "component": "VCol", + "props": {"cols": 12, "md": 6}, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "onlyonce", + "label": "立即运行一次", + }, + } + ], + }, + ], + }, + { + "component": "VRow", + "content": [ + { + "component": "VCol", + "props": {"cols": 12, "md": 6}, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "enable_qb", + "label": "QB下载器", + }, + } + ], + }, + { + "component": "VCol", + "props": {"cols": 12, "md": 6}, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "enable_tr", + "label": "TR下载器", + }, + } + ], + }, + ], + }, + { + "component": "VRow", + "content": [ + { + "component": "VCol", + "props": {"cols": 12, "md": 6}, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "enable_emby", + "label": "Emby服务", + }, + } + ], + }, + { + "component": "VCol", + "props": {"cols": 12, "md": 6}, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "enable_emby_play", + "label": "Emby外网播放", + }, + } + ], + }, + ], + }, + { + "component": "VRow", + "content": [ + { + "component": "VCol", + "props": {"cols": 12, "md": 6}, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "enable_jellyfin", + "label": "Jellyfin服务", + }, + } + ], + }, + { + "component": "VCol", + "props": {"cols": 12, "md": 6}, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "enable_jellyfin_play", + "label": "Jellyfin外网播放", + }, + } + ], + }, + ], + }, + { + "component": "VRow", + "content": [ + { + "component": "VCol", + "props": {"cols": 12, "md": 6}, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "enable_plex", + "label": "Plex服务", + }, + } + ], + }, + { + "component": "VCol", + "props": {"cols": 12, "md": 6}, + "content": [ + { + "component": "VSwitch", + "props": { + "model": "enable_plex_play", + "label": "Plex外网播放", + }, + } + ], + }, + ], + }, + { + "component": "VRow", + "content": [ + { + "component": "VCol", + "props": { + "cols": 12, + }, + "content": [ + { + "component": "VAlert", + "props": { + "type": "info", + "variant": "tonal", + "text": "本插件针对部署在本地的服务,如QB下载器、Emby服务等,检测到本地IP变化时同步修改服务地址,请勾选部署在本地的服务。", + }, + } + ] + }, + { + "component": "VCol", + "props": { + "cols": 12, + }, + "content": [ + { + "component": "VAlert", + "props": { + "type": "info", + "variant": "tonal", + "text": "本插件不适用于桥接模式的Docker,因为获取不到Host的IP地址", + }, + } + ], + }, + + ], + }, + ], + } + ], { + "enabled": False, + "notify": False, + "onlyonce": False, + "enable_qb": False, + "enable_tr": False, + "enable_emby": False, + "enable_emby_play": False, + "enable_jellyfin": False, + "enable_jellyfin_play": False, + "enable_plex": False, + "enable_plex_play": False, + } + + def get_page(self) -> List[dict]: + pass + + def stop_service(self): + pass