feat:站点使用统计
This commit is contained in:
parent
5108dbbeb5
commit
c3ffe38d4d
@ -12,6 +12,7 @@ from app.core.security import verify_token
|
|||||||
from app.db import get_db
|
from app.db import get_db
|
||||||
from app.db.models.site import Site
|
from app.db.models.site import Site
|
||||||
from app.db.models.siteicon import SiteIcon
|
from app.db.models.siteicon import SiteIcon
|
||||||
|
from app.db.models.sitestatistic import SiteStatistic
|
||||||
from app.db.systemconfig_oper import SystemConfigOper
|
from app.db.systemconfig_oper import SystemConfigOper
|
||||||
from app.helper.sites import SitesHelper
|
from app.helper.sites import SitesHelper
|
||||||
from app.scheduler import Scheduler
|
from app.scheduler import Scheduler
|
||||||
@ -239,6 +240,22 @@ def read_site_by_domain(
|
|||||||
return site
|
return site
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/statistic/{site_url}", summary="站点统计信息", response_model=schemas.SiteStatistic)
|
||||||
|
def read_site_by_domain(
|
||||||
|
site_url: str,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
_: schemas.TokenPayload = Depends(verify_token)
|
||||||
|
) -> Any:
|
||||||
|
"""
|
||||||
|
通过域名获取站点统计信息
|
||||||
|
"""
|
||||||
|
domain = StringUtils.get_url_domain(site_url)
|
||||||
|
sitestatistic = SiteStatistic.get_by_domain(db, domain)
|
||||||
|
if sitestatistic:
|
||||||
|
return sitestatistic
|
||||||
|
return schemas.SiteStatistic(domain=domain)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/rss", summary="所有订阅站点", response_model=List[schemas.Site])
|
@router.get("/rss", summary="所有订阅站点", response_model=List[schemas.Site])
|
||||||
def read_rss_sites(db: Session = Depends(get_db)) -> List[dict]:
|
def read_rss_sites(db: Session = Depends(get_db)) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import base64
|
import base64
|
||||||
import re
|
import re
|
||||||
|
from datetime import datetime
|
||||||
from typing import Tuple, Optional
|
from typing import Tuple, Optional
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
@ -13,6 +14,7 @@ from app.db.models.site import Site
|
|||||||
from app.db.site_oper import SiteOper
|
from app.db.site_oper import SiteOper
|
||||||
from app.db.siteicon_oper import SiteIconOper
|
from app.db.siteicon_oper import SiteIconOper
|
||||||
from app.db.systemconfig_oper import SystemConfigOper
|
from app.db.systemconfig_oper import SystemConfigOper
|
||||||
|
from app.db.sytestatistic_oper import SiteStatisticOper
|
||||||
from app.helper.browser import PlaywrightHelper
|
from app.helper.browser import PlaywrightHelper
|
||||||
from app.helper.cloudflare import under_challenge
|
from app.helper.cloudflare import under_challenge
|
||||||
from app.helper.cookie import CookieHelper
|
from app.helper.cookie import CookieHelper
|
||||||
@ -43,6 +45,7 @@ class SiteChain(ChainBase):
|
|||||||
self.message = MessageHelper()
|
self.message = MessageHelper()
|
||||||
self.cookiecloud = CookieCloudHelper()
|
self.cookiecloud = CookieCloudHelper()
|
||||||
self.systemconfig = SystemConfigOper()
|
self.systemconfig = SystemConfigOper()
|
||||||
|
self.sitestatistic = SiteStatisticOper()
|
||||||
|
|
||||||
# 特殊站点登录验证
|
# 特殊站点登录验证
|
||||||
self.special_site_test = {
|
self.special_site_test = {
|
||||||
@ -350,12 +353,21 @@ class SiteChain(ChainBase):
|
|||||||
|
|
||||||
# 模拟登录
|
# 模拟登录
|
||||||
try:
|
try:
|
||||||
|
# 开始记时
|
||||||
|
start_time = datetime.now()
|
||||||
# 特殊站点测试
|
# 特殊站点测试
|
||||||
if self.special_site_test.get(domain):
|
if self.special_site_test.get(domain):
|
||||||
return self.special_site_test[domain](site_info)
|
state, message = self.special_site_test[domain](site_info)
|
||||||
|
else:
|
||||||
# 通用站点测试
|
# 通用站点测试
|
||||||
return self.__test(site_info)
|
state, message = self.__test(site_info)
|
||||||
|
# 统计
|
||||||
|
seconds = (datetime.now() - start_time).seconds
|
||||||
|
if state:
|
||||||
|
self.sitestatistic.success(domain=domain, seconds=seconds)
|
||||||
|
else:
|
||||||
|
self.sitestatistic.fail(domain)
|
||||||
|
return state, message
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return False, f"{str(e)}!"
|
return False, f"{str(e)}!"
|
||||||
|
|
||||||
|
@ -13,20 +13,18 @@ class SiteStatistic(Base):
|
|||||||
id = Column(Integer, Sequence('id'), primary_key=True, index=True)
|
id = Column(Integer, Sequence('id'), primary_key=True, index=True)
|
||||||
# 域名Key
|
# 域名Key
|
||||||
domain = Column(String, index=True)
|
domain = Column(String, index=True)
|
||||||
# 站点名
|
|
||||||
name = Column(String, nullable=False)
|
|
||||||
# 成功次数
|
# 成功次数
|
||||||
success = Column(Integer)
|
success = Column(Integer)
|
||||||
# 失败次数
|
# 失败次数
|
||||||
fail = Column(Integer)
|
fail = Column(Integer)
|
||||||
# 平均耗时 秒
|
# 平均耗时 秒
|
||||||
seconds = Column(Integer)
|
seconds = Column(Integer)
|
||||||
# 耗时记录 Json
|
|
||||||
note = Column(String)
|
|
||||||
# 最后一次访问状态 0-成功 1-失败
|
# 最后一次访问状态 0-成功 1-失败
|
||||||
lst_state = Column(Integer)
|
lst_state = Column(Integer)
|
||||||
# 最后访问时间
|
# 最后访问时间
|
||||||
lst_mod_date = Column(String, default=datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
|
lst_mod_date = Column(String, default=datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
|
||||||
|
# 耗时记录 Json
|
||||||
|
note = Column(String)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@db_query
|
@db_query
|
||||||
|
68
app/db/sytestatistic_oper.py
Normal file
68
app/db/sytestatistic_oper.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from app.db import DbOper
|
||||||
|
from app.db.models.sitestatistic import SiteStatistic
|
||||||
|
|
||||||
|
|
||||||
|
class SiteStatisticOper(DbOper):
|
||||||
|
"""
|
||||||
|
站点统计管理
|
||||||
|
"""
|
||||||
|
|
||||||
|
def success(self, domain: str, seconds: int = None):
|
||||||
|
"""
|
||||||
|
站点访问成功
|
||||||
|
"""
|
||||||
|
lst_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
sta = SiteStatistic.get_by_domain(self._db, domain)
|
||||||
|
if sta:
|
||||||
|
avg_seconds, note = None, {}
|
||||||
|
if seconds:
|
||||||
|
note: dict = json.loads(sta.note or "{}")
|
||||||
|
note[lst_date] = seconds
|
||||||
|
avg_times = len(note.keys())
|
||||||
|
avg_seconds = sum([v for v in note.values()]) // avg_times
|
||||||
|
sta.update(self._db, {
|
||||||
|
"success": sta.success + 1,
|
||||||
|
"seconds": avg_seconds or sta.seconds,
|
||||||
|
"lst_state": 0,
|
||||||
|
"lst_mod_date": lst_date,
|
||||||
|
"note": json.dumps(note) if note else sta.note
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
note = {}
|
||||||
|
if seconds:
|
||||||
|
note = {
|
||||||
|
lst_date: seconds
|
||||||
|
}
|
||||||
|
SiteStatistic(
|
||||||
|
domain=domain,
|
||||||
|
success=1,
|
||||||
|
fail=0,
|
||||||
|
seconds=seconds,
|
||||||
|
lst_state=0,
|
||||||
|
lst_mod_date=lst_date,
|
||||||
|
note=json.dumps(note)
|
||||||
|
).create(self._db)
|
||||||
|
|
||||||
|
def fail(self, domain: str):
|
||||||
|
"""
|
||||||
|
站点访问失败
|
||||||
|
"""
|
||||||
|
lst_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
sta = SiteStatistic.get_by_domain(self._db, domain)
|
||||||
|
if sta:
|
||||||
|
sta.update(self._db, {
|
||||||
|
"fail": sta.fail + 1,
|
||||||
|
"lst_state": 1,
|
||||||
|
"lst_mod_date": lst_date
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
SiteStatistic(
|
||||||
|
domain=domain,
|
||||||
|
success=0,
|
||||||
|
fail=1,
|
||||||
|
lst_state=1,
|
||||||
|
lst_mod_date=lst_date
|
||||||
|
).create(self._db)
|
@ -225,7 +225,7 @@ class RssHelper:
|
|||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def parse(url, proxy: bool = False, timeout: int = 30) -> Union[List[dict], None]:
|
def parse(url, proxy: bool = False, timeout: int = 15) -> Union[List[dict], None]:
|
||||||
"""
|
"""
|
||||||
解析RSS订阅URL,获取RSS中的种子信息
|
解析RSS订阅URL,获取RSS中的种子信息
|
||||||
:param url: RSS地址
|
:param url: RSS地址
|
||||||
|
@ -5,6 +5,7 @@ from ruamel.yaml import CommentedMap
|
|||||||
|
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
from app.core.context import TorrentInfo
|
from app.core.context import TorrentInfo
|
||||||
|
from app.db.sytestatistic_oper import SiteStatisticOper
|
||||||
from app.helper.sites import SitesHelper
|
from app.helper.sites import SitesHelper
|
||||||
from app.log import logger
|
from app.log import logger
|
||||||
from app.modules import _ModuleBase
|
from app.modules import _ModuleBase
|
||||||
@ -70,10 +71,12 @@ class IndexerModule(_ModuleBase):
|
|||||||
|
|
||||||
# 开始索引
|
# 开始索引
|
||||||
result_array = []
|
result_array = []
|
||||||
|
|
||||||
# 开始计时
|
# 开始计时
|
||||||
start_time = datetime.now()
|
start_time = datetime.now()
|
||||||
|
|
||||||
# 搜索多个关键字
|
# 搜索多个关键字
|
||||||
|
error_flag = False
|
||||||
for search_word in keywords:
|
for search_word in keywords:
|
||||||
# 可能为关键字或ttxxxx
|
# 可能为关键字或ttxxxx
|
||||||
if search_word \
|
if search_word \
|
||||||
@ -126,7 +129,14 @@ class IndexerModule(_ModuleBase):
|
|||||||
logger.error(f"{site.get('name')} 搜索出错:{str(err)}")
|
logger.error(f"{site.get('name')} 搜索出错:{str(err)}")
|
||||||
|
|
||||||
# 索引花费的时间
|
# 索引花费的时间
|
||||||
seconds = round((datetime.now() - start_time).seconds, 1)
|
seconds = (datetime.now() - start_time).seconds
|
||||||
|
|
||||||
|
# 统计索引情况
|
||||||
|
domain = StringUtils.get_url_domain(site.get("domain"))
|
||||||
|
if error_flag:
|
||||||
|
SiteStatisticOper().fail(domain)
|
||||||
|
else:
|
||||||
|
SiteStatisticOper().success(domain=domain, seconds=seconds)
|
||||||
|
|
||||||
# 返回结果
|
# 返回结果
|
||||||
if not result_array or len(result_array) == 0:
|
if not result_array or len(result_array) == 0:
|
||||||
|
@ -41,3 +41,23 @@ class Site(BaseModel):
|
|||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
|
|
||||||
|
|
||||||
|
class SiteStatistic(BaseModel):
|
||||||
|
# 站点ID
|
||||||
|
domain: Optional[int]
|
||||||
|
# 成功次数
|
||||||
|
success: Optional[int] = 0
|
||||||
|
# 失败次数
|
||||||
|
fail: Optional[int] = 0
|
||||||
|
# 平均响应时间
|
||||||
|
seconds: Optional[int] = 0
|
||||||
|
# 最后状态
|
||||||
|
lst_state: Optional[int] = 0
|
||||||
|
# 最后修改时间
|
||||||
|
lst_mod_date: Optional[str]
|
||||||
|
# 备注
|
||||||
|
note: Optional[str] = None
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
Loading…
x
Reference in New Issue
Block a user