From 375ae7a5ea949145fcaffc08f5134ad4c94bec00 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Thu, 9 May 2024 15:59:32 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AB=99=E7=82=B9=E5=88=B7=E6=B5=81=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=BB=AA=E8=A1=A8=E6=9D=BF=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 5 +- plugins/brushflow/__init__.py | 663 ++++++++++++++++-------------- plugins/sitestatistic/__init__.py | 3 +- 3 files changed, 365 insertions(+), 306 deletions(-) diff --git a/package.json b/package.json index 61e2b44..b62f6e9 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "name": "站点数据统计", "description": "自动统计和展示站点数据。", "labels": "站点", - "version": "3.1", + "version": "3.2", "icon": "statistic.png", "author": "lightolly", "level": 2, @@ -303,11 +303,12 @@ "name": "站点刷流", "description": "自动托管刷流,将会提高对应站点的访问频率。", "labels": "刷流", - "version": "3.0", + "version": "3.1", "icon": "brush.jpg", "author": "jxxghp,InfinityPacer", "level": 2, "history": { + "v3.1": "支持仪表板显示站点刷流数据,需要主程序升级v1.8.7+版本", "v3.0": "优化不同站点刷流到相同种子的逻辑,修复数据页滚动闪烁,部分日志优化", "v2.9": "优化动态删除消息推送,优化配置页UI显示及部分配置项,支持配置种子分类以及开启自动分类管理,取消单独适配站点时区逻辑,可通过配置项「pubtime」自行适配", "v2.8": "优化UI显示以及提升性能", diff --git a/plugins/brushflow/__init__.py b/plugins/brushflow/__init__.py index 57ae976..b618693 100644 --- a/plugins/brushflow/__init__.py +++ b/plugins/brushflow/__init__.py @@ -40,6 +40,7 @@ class BrushConfig: self.enabled = config.get("enabled", False) self.notify = config.get("notify", True) self.onlyonce = config.get("onlyonce", False) + self.dashboard = config.get("dashboard", True) self.brushsites = config.get("brushsites", []) self.downloader = config.get("downloader", "qbittorrent") self.disksize = self.__parse_number(config.get("disksize")) @@ -251,7 +252,7 @@ class BrushFlow(_PluginBase): # 插件图标 plugin_icon = "brush.jpg" # 插件版本 - plugin_version = "3.0" + plugin_version = "3.1" # 插件作者 plugin_author = "jxxghp,InfinityPacer" # 作者主页 @@ -442,6 +443,342 @@ class BrushFlow(_PluginBase): return services + def __get_total_elements(self) -> List[dict]: + """ + 组装汇总元素 + """ + # 统计数据 + statistic_info = self.__get_statistic_info() + # 总上传量 + total_uploaded = StringUtils.str_filesize(statistic_info.get("uploaded") or 0) + # 总下载量 + total_downloaded = StringUtils.str_filesize(statistic_info.get("downloaded") or 0) + # 下载种子数 + total_count = statistic_info.get("count") or 0 + # 删除种子数 + total_deleted = statistic_info.get("deleted") or 0 + # 待归档种子数 + total_unarchived = statistic_info.get("unarchived") or 0 + # 活跃种子数 + total_active = statistic_info.get("active") or 0 + # 活跃上传量 + total_active_uploaded = StringUtils.str_filesize(statistic_info.get("active_uploaded") or 0) + # 活跃下载量 + total_active_downloaded = StringUtils.str_filesize(statistic_info.get("active_downloaded") or 0) + + return [ + # 总上传量 + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 3, + 'sm': 6 + }, + 'content': [ + { + 'component': 'VCard', + 'props': { + 'variant': 'tonal', + }, + 'content': [ + { + 'component': 'VCardText', + 'props': { + 'class': 'd-flex align-center', + }, + 'content': [ + { + 'component': 'VAvatar', + 'props': { + 'rounded': True, + 'variant': 'text', + 'class': 'me-3' + }, + 'content': [ + { + 'component': 'VImg', + 'props': { + 'src': '/plugin_icon/upload.png' + } + } + ] + }, + { + 'component': 'div', + 'content': [ + { + 'component': 'span', + 'props': { + 'class': 'text-caption' + }, + 'text': '总上传量 / 活跃' + }, + { + 'component': 'div', + 'props': { + 'class': 'd-flex align-center flex-wrap' + }, + 'content': [ + { + 'component': 'span', + 'props': { + 'class': 'text-h6' + }, + 'text': f"{total_uploaded} / {total_active_uploaded}" + } + ] + } + ] + } + ] + } + ] + }, + ] + }, + # 总下载量 + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 3, + 'sm': 6 + }, + 'content': [ + { + 'component': 'VCard', + 'props': { + 'variant': 'tonal', + }, + 'content': [ + { + 'component': 'VCardText', + 'props': { + 'class': 'd-flex align-center', + }, + 'content': [ + { + 'component': 'VAvatar', + 'props': { + 'rounded': True, + 'variant': 'text', + 'class': 'me-3' + }, + 'content': [ + { + 'component': 'VImg', + 'props': { + 'src': '/plugin_icon/download.png' + } + } + ] + }, + { + 'component': 'div', + 'content': [ + { + 'component': 'span', + 'props': { + 'class': 'text-caption' + }, + 'text': '总下载量 / 活跃' + }, + { + 'component': 'div', + 'props': { + 'class': 'd-flex align-center flex-wrap' + }, + 'content': [ + { + 'component': 'span', + 'props': { + 'class': 'text-h6' + }, + 'text': f"{total_downloaded} / {total_active_downloaded}" + } + ] + } + ] + } + ] + } + ] + }, + ] + }, + # 下载种子数 + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 3, + 'sm': 6 + }, + 'content': [ + { + 'component': 'VCard', + 'props': { + 'variant': 'tonal', + }, + 'content': [ + { + 'component': 'VCardText', + 'props': { + 'class': 'd-flex align-center', + }, + 'content': [ + { + 'component': 'VAvatar', + 'props': { + 'rounded': True, + 'variant': 'text', + 'class': 'me-3' + }, + 'content': [ + { + 'component': 'VImg', + 'props': { + 'src': '/plugin_icon/seed.png' + } + } + ] + }, + { + 'component': 'div', + 'content': [ + { + 'component': 'span', + 'props': { + 'class': 'text-caption' + }, + 'text': '下载种子数 / 活跃' + }, + { + 'component': 'div', + 'props': { + 'class': 'd-flex align-center flex-wrap' + }, + 'content': [ + { + 'component': 'span', + 'props': { + 'class': 'text-h6' + }, + 'text': f"{total_count} / {total_active}" + } + ] + } + ] + } + ] + } + ] + }, + ] + }, + # 删除种子数 + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 3, + 'sm': 6 + }, + 'content': [ + { + 'component': 'VCard', + 'props': { + 'variant': 'tonal', + }, + 'content': [ + { + 'component': 'VCardText', + 'props': { + 'class': 'd-flex align-center', + }, + 'content': [ + { + 'component': 'VAvatar', + 'props': { + 'rounded': True, + 'variant': 'text', + 'class': 'me-3' + }, + 'content': [ + { + 'component': 'VImg', + 'props': { + 'src': '/plugin_icon/delete.png' + } + } + ] + }, + { + 'component': 'div', + 'content': [ + { + 'component': 'span', + 'props': { + 'class': 'text-caption' + }, + 'text': '删除种子数 / 待归档' + }, + { + 'component': 'div', + 'props': { + 'class': 'd-flex align-center flex-wrap' + }, + 'content': [ + { + 'component': 'span', + 'props': { + 'class': 'text-h6' + }, + 'text': f"{total_deleted} / {total_unarchived}" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + ] + + def get_dashboard(self) -> Optional[Tuple[Dict[str, Any], Dict[str, Any], List[dict]]]: + """ + 获取插件仪表盘页面,需要返回:1、仪表板col配置字典;2、全局配置(自动刷新等);3、仪表板页面元素配置json(含数据) + 1、col配置参考: + { + "cols": 12, "md": 6 + } + 2、全局配置参考: + { + "refresh": 10 // 自动刷新时间,单位秒 + } + 3、页面配置使用Vuetify组件拼装,参考:https://vuetifyjs.com/ + """ + if not self._brush_config.dashboard: + return None + # 列配置 + cols = { + "cols": 12 + } + # 全局配置 + attrs = {} + # 拼装页面元素 + elements = [ + { + 'component': 'VRow', + 'content': self.__get_total_elements() + } + ] + return cols, attrs, elements + def get_form(self) -> Tuple[List[dict], Dict[str, Any]]: """ 拼装插件配置页面,需要返回两块数据:1、页面配置;2、数据结构 @@ -461,7 +798,7 @@ class BrushFlow(_PluginBase): 'component': 'VCol', 'props': { 'cols': 12, - 'md': 4 + 'md': 3 }, 'content': [ { @@ -477,7 +814,7 @@ class BrushFlow(_PluginBase): 'component': 'VCol', 'props': { 'cols': 12, - 'md': 4 + 'md': 3 }, 'content': [ { @@ -493,7 +830,7 @@ class BrushFlow(_PluginBase): 'component': 'VCol', 'props': { 'cols': 12, - 'md': 4 + 'md': 3 }, 'content': [ { @@ -504,6 +841,22 @@ class BrushFlow(_PluginBase): } } ] + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 3 + }, + 'content': [ + { + 'component': 'VSwitch', + 'props': { + 'model': 'dashboard', + 'label': '在仪表板中显示', + } + } + ] } ] }, @@ -1503,8 +1856,6 @@ class BrushFlow(_PluginBase): def get_page(self) -> List[dict]: # 种子明细 torrents = self.get_data("torrents") or {} - # 统计数据 - statistic_info = self.__get_statistic_info() if not torrents: return [ @@ -1520,22 +1871,7 @@ class BrushFlow(_PluginBase): data_list = torrents.values() # 按time倒序排序 data_list = sorted(data_list, key=lambda x: x.get("time") or 0, reverse=True) - # 总上传量 - total_uploaded = StringUtils.str_filesize(statistic_info.get("uploaded") or 0) - # 总下载量 - total_downloaded = StringUtils.str_filesize(statistic_info.get("downloaded") or 0) - # 下载种子数 - total_count = statistic_info.get("count") or 0 - # 删除种子数 - total_deleted = statistic_info.get("deleted") or 0 - # 待归档种子数 - total_unarchived = statistic_info.get("unarchived") or 0 - # 活跃种子数 - total_active = statistic_info.get("active") or 0 - # 活跃上传量 - total_active_uploaded = StringUtils.str_filesize(statistic_info.get("active_uploaded") or 0) - # 活跃下载量 - total_active_downloaded = StringUtils.str_filesize(statistic_info.get("active_downloaded") or 0) + # 表格标题 headers = [ {'title': '站点', 'key': 'site', 'sortable': True}, @@ -1568,287 +1904,7 @@ class BrushFlow(_PluginBase): 'overflow': 'hidden', } }, - 'content': [ - # 总上传量 - { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 3, - 'sm': 6 - }, - 'content': [ - { - 'component': 'VCard', - 'props': { - 'variant': 'tonal', - }, - 'content': [ - { - 'component': 'VCardText', - 'props': { - 'class': 'd-flex align-center', - }, - 'content': [ - { - 'component': 'VAvatar', - 'props': { - 'rounded': True, - 'variant': 'text', - 'class': 'me-3' - }, - 'content': [ - { - 'component': 'VImg', - 'props': { - 'src': '/plugin_icon/upload.png' - } - } - ] - }, - { - 'component': 'div', - 'content': [ - { - 'component': 'span', - 'props': { - 'class': 'text-caption' - }, - 'text': '总上传量 / 活跃' - }, - { - 'component': 'div', - 'props': { - 'class': 'd-flex align-center flex-wrap' - }, - 'content': [ - { - 'component': 'span', - 'props': { - 'class': 'text-h6' - }, - 'text': f"{total_uploaded} / {total_active_uploaded}" - } - ] - } - ] - } - ] - } - ] - }, - ] - }, - # 总下载量 - { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 3, - 'sm': 6 - }, - 'content': [ - { - 'component': 'VCard', - 'props': { - 'variant': 'tonal', - }, - 'content': [ - { - 'component': 'VCardText', - 'props': { - 'class': 'd-flex align-center', - }, - 'content': [ - { - 'component': 'VAvatar', - 'props': { - 'rounded': True, - 'variant': 'text', - 'class': 'me-3' - }, - 'content': [ - { - 'component': 'VImg', - 'props': { - 'src': '/plugin_icon/download.png' - } - } - ] - }, - { - 'component': 'div', - 'content': [ - { - 'component': 'span', - 'props': { - 'class': 'text-caption' - }, - 'text': '总下载量 / 活跃' - }, - { - 'component': 'div', - 'props': { - 'class': 'd-flex align-center flex-wrap' - }, - 'content': [ - { - 'component': 'span', - 'props': { - 'class': 'text-h6' - }, - 'text': f"{total_downloaded} / {total_active_downloaded}" - } - ] - } - ] - } - ] - } - ] - }, - ] - }, - # 下载种子数 - { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 3, - 'sm': 6 - }, - 'content': [ - { - 'component': 'VCard', - 'props': { - 'variant': 'tonal', - }, - 'content': [ - { - 'component': 'VCardText', - 'props': { - 'class': 'd-flex align-center', - }, - 'content': [ - { - 'component': 'VAvatar', - 'props': { - 'rounded': True, - 'variant': 'text', - 'class': 'me-3' - }, - 'content': [ - { - 'component': 'VImg', - 'props': { - 'src': '/plugin_icon/seed.png' - } - } - ] - }, - { - 'component': 'div', - 'content': [ - { - 'component': 'span', - 'props': { - 'class': 'text-caption' - }, - 'text': '下载种子数 / 活跃' - }, - { - 'component': 'div', - 'props': { - 'class': 'd-flex align-center flex-wrap' - }, - 'content': [ - { - 'component': 'span', - 'props': { - 'class': 'text-h6' - }, - 'text': f"{total_count} / {total_active}" - } - ] - } - ] - } - ] - } - ] - }, - ] - }, - # 删除种子数 - { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 3, - 'sm': 6 - }, - 'content': [ - { - 'component': 'VCard', - 'props': { - 'variant': 'tonal', - }, - 'content': [ - { - 'component': 'VCardText', - 'props': { - 'class': 'd-flex align-center', - }, - 'content': [ - { - 'component': 'VAvatar', - 'props': { - 'rounded': True, - 'variant': 'text', - 'class': 'me-3' - }, - 'content': [ - { - 'component': 'VImg', - 'props': { - 'src': '/plugin_icon/delete.png' - } - } - ] - }, - { - 'component': 'div', - 'content': [ - { - 'component': 'span', - 'props': { - 'class': 'text-caption' - }, - 'text': '删除种子数 / 待归档' - }, - { - 'component': 'div', - 'props': { - 'class': 'd-flex align-center flex-wrap' - }, - 'content': [ - { - 'component': 'span', - 'props': { - 'class': 'text-h6' - }, - 'text': f"{total_deleted} / {total_unarchived}" - } - ] - } - ] - } - ] - } - ] - } - ] - }, + 'content': self.__get_total_elements() + [ # 种子明细 { 'component': 'VRow', @@ -2926,6 +2982,7 @@ class BrushFlow(_PluginBase): "onlyonce": brush_config.onlyonce, "enabled": brush_config.enabled, "notify": brush_config.notify, + "dashboard": brush_config.dashboard, "brushsites": brush_config.brushsites, "downloader": brush_config.downloader, "disksize": brush_config.disksize, diff --git a/plugins/sitestatistic/__init__.py b/plugins/sitestatistic/__init__.py index 9c37725..de84561 100644 --- a/plugins/sitestatistic/__init__.py +++ b/plugins/sitestatistic/__init__.py @@ -43,7 +43,7 @@ class SiteStatistic(_PluginBase): # 插件图标 plugin_icon = "statistic.png" # 插件版本 - plugin_version = "3.1" + plugin_version = "3.2" # 插件作者 plugin_author = "lightolly" # 作者主页 @@ -1450,6 +1450,7 @@ class SiteStatistic(_PluginBase): self.update_config({ "enabled": self._enabled, "onlyonce": self._onlyonce, + "dashboard": self._dashboard, "cron": self._cron, "notify": self._notify, "sitemsg": self._sitemsg,