diff --git a/app/api/endpoints/dashboard.py b/app/api/endpoints/dashboard.py
index 96d7f1c7..3c660adc 100644
--- a/app/api/endpoints/dashboard.py
+++ b/app/api/endpoints/dashboard.py
@@ -24,12 +24,15 @@ def statistic(_: schemas.TokenPayload = Depends(verify_token)) -> Any:
查询媒体数量统计信息
"""
media_statistic = DashboardChain().media_statistic()
- return schemas.Statistic(
- movie_count=media_statistic.movie_count,
- tv_count=media_statistic.tv_count,
- episode_count=media_statistic.episode_count,
- user_count=media_statistic.user_count
- )
+ if media_statistic:
+ return schemas.Statistic(
+ movie_count=media_statistic.movie_count,
+ tv_count=media_statistic.tv_count,
+ episode_count=media_statistic.episode_count,
+ user_count=media_statistic.user_count
+ )
+ else:
+ return schemas.Statistic()
@router.get("/storage", summary="存储空间", response_model=schemas.Storage)
diff --git a/app/plugins/autosignin/__init__.py b/app/plugins/autosignin/__init__.py
index f0ac89c3..9d1fef85 100644
--- a/app/plugins/autosignin/__init__.py
+++ b/app/plugins/autosignin/__init__.py
@@ -265,12 +265,12 @@ class AutoSignIn(_PluginBase):
拼装插件详情页面,需要返回页面配置,同时附带数据
"""
# 最近两天的日期数组
- date_list = [str((datetime.now() - timedelta(days=i)).date()) for i in range(2)]
+ date_list = [(datetime.now() - timedelta(days=i)).date() for i in range(2)]
# 最近一天的签到数据
current_day = ""
sign_data = []
for day in date_list:
- current_day = f"{datetime.now().month}月{datetime.now().day}日"
+ current_day = f"{day.month}月{day.day}日"
sign_data = self.get_data(current_day)
if sign_data:
break
diff --git a/app/plugins/doubansync/__init__.py b/app/plugins/doubansync/__init__.py
index cca7154d..b867edf4 100644
--- a/app/plugins/doubansync/__init__.py
+++ b/app/plugins/doubansync/__init__.py
@@ -258,6 +258,7 @@ class DoubanSync(_PluginBase):
mtype = history.get("type")
time_str = history.get("time")
overview = history.get("overview")
+ doubanid = history.get("doubanid")
contents.append(
{
'component': 'VCard',
@@ -278,7 +279,7 @@ class DoubanSync(_PluginBase):
'height': 120,
'width': 80,
'aspect-ratio': '2/3',
- 'class': 'object-cover rounded shadow ring-gray-500',
+ 'class': 'object-cover shadow ring-gray-500',
'cover': True
}
}
@@ -292,7 +293,16 @@ class DoubanSync(_PluginBase):
'props': {
'class': 'pa-2 font-bold break-words whitespace-break-spaces'
},
- 'text': title
+ 'content': [
+ {
+ 'component': 'a',
+ 'props': {
+ 'href': f"https://movie.douban.com/subject/{doubanid}",
+ 'target': '_blank'
+ },
+ 'text': title
+ }
+ ]
},
{
'component': 'VCardText',
diff --git a/app/plugins/sitestatistic/__init__.py b/app/plugins/sitestatistic/__init__.py
index f862ef59..a51fcc47 100644
--- a/app/plugins/sitestatistic/__init__.py
+++ b/app/plugins/sitestatistic/__init__.py
@@ -1,5 +1,5 @@
import warnings
-from datetime import datetime
+from datetime import datetime, timedelta
from multiprocessing.dummy import Pool as ThreadPool
from threading import Lock
from typing import Optional, Any, List, Dict, Tuple
@@ -265,7 +265,320 @@ class SiteStatistic(_PluginBase):
"""
拼装插件详情页面,需要返回页面配置,同时附带数据
"""
- pass
+ #
+ # 最近两天的日期数组
+ date_list = [(datetime.now() - timedelta(days=i)).date() for i in range(2)]
+ # 最近一天的签到数据
+ stattistic_data: Dict[str, Dict[str, Any]] = {}
+ for day in date_list:
+ current_day = day.strftime("%Y-%m-%d")
+ stattistic_data = self.get_data(current_day)
+ if stattistic_data:
+ break
+ if not stattistic_data:
+ return [
+ {
+ 'component': 'div',
+ 'text': '暂无数据',
+ 'props': {
+ 'class': 'text-center',
+ }
+ }
+ ]
+
+ # 总上传量
+ total_upload = sum([data.get("upload")
+ for data in stattistic_data.values() if data.get("upload")])
+ # 总下载量
+ total_download = sum([data.get("download")
+ for data in stattistic_data.values() if data.get("download")])
+ # 总做种数
+ total_seed = sum([data.get("seeding")
+ for data in stattistic_data.values() if data.get("seeding")])
+ # 总做种体积
+ total_seed_size = sum([data.get("seeding_size")
+ for data in stattistic_data.values() if data.get("seeding_size")])
+
+ # 拼装页面
+ return [
+ {
+ 'component': 'VRow',
+ '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': 'VIcon',
+ 'html': ''
+ }
+ ]
+ },
+ {
+ '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': StringUtils.str_filesize(total_upload)
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ ]
+ },
+ # 总下载量
+ {
+ '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': 'VIcon',
+ 'html': ''
+ }
+ ]
+ },
+ {
+ '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': StringUtils.str_filesize(total_download)
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ ]
+ },
+ # 总做种数
+ {
+ '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': 'VIcon',
+ 'html': ''
+ }
+ ]
+ },
+ {
+ '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'{"{:,}".format(total_seed)}'
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ ]
+ },
+ # 总做种体积
+ {
+ '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': 'VIcon',
+ 'html': ''
+ }
+ ]
+ },
+ {
+ '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': StringUtils.str_filesize(total_seed_size)
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
def stop_service(self):
"""