You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.7 KiB
140 lines
4.7 KiB
|
|
import threading
|
|
from time import sleep
|
|
from typing import List, Dict
|
|
from mycode.DBManager import DBManager
|
|
from datetime import datetime, timedelta
|
|
from mycode.TaskManager import g_TaskM
|
|
|
|
class PollingManager:
|
|
def __init__(self):
|
|
self.DBM = DBManager()
|
|
self.brun = True
|
|
self.bUpdate = False
|
|
self.p_th = None
|
|
|
|
def parse_time(self,time_str: str) -> datetime:
|
|
"""将时间字符串转为 datetime 对象"""
|
|
if not time_str:
|
|
return None
|
|
try:
|
|
return datetime.datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')
|
|
except ValueError:
|
|
return None
|
|
|
|
def need_check(self,target: Dict) -> bool:
|
|
now = datetime.datetime.now()
|
|
period = target[5]
|
|
start_time_str = target[6]
|
|
last_time = self.parse_time(target[7])
|
|
|
|
# 不巡检的目标
|
|
if target[4] == 0 or period == 0:
|
|
return False
|
|
|
|
# 当前时间是否达到设定开始时间
|
|
if start_time_str:
|
|
try:
|
|
# 只取时间部分用于每天/每周的对比
|
|
st_hour, st_minute = map(int, start_time_str.strip().split(':')[:2])
|
|
except Exception:
|
|
return False
|
|
else:
|
|
st_hour, st_minute = 0, 0
|
|
|
|
# 当天设定执行时间点
|
|
target_time = now.replace(hour=st_hour, minute=st_minute, second=0, microsecond=0)
|
|
|
|
# 如果 last_time 已经检查过今天了,就跳过
|
|
if last_time and last_time >= target_time:
|
|
return False
|
|
|
|
if period == 1: # 每天
|
|
return now >= target_time
|
|
elif period == 2: # 每周
|
|
return now.weekday() == 0 and now >= target_time # 每周一执行
|
|
elif period == 3: # 每月
|
|
return now.day == 1 and now >= target_time # 每月1号执行
|
|
else:
|
|
return False
|
|
|
|
def should_poll(self,polling_period: int, start_time_str: str, last_time_str: str = None) -> bool:
|
|
now = datetime.now()
|
|
|
|
# 无周期,直接返回 False
|
|
if polling_period == 0:
|
|
return False
|
|
|
|
try:
|
|
# 获取比较基准时间
|
|
if last_time_str:
|
|
base_time = datetime.strptime(last_time_str, "%Y-%m-%d %H:%M:%S")
|
|
elif start_time_str:
|
|
base_time = datetime.strptime(start_time_str, "%Y-%m-%d %H:%M:%S")
|
|
if now > base_time:
|
|
return True
|
|
else:
|
|
return False
|
|
except Exception as e:
|
|
print(f"时间格式错误: {e}")
|
|
return False
|
|
|
|
if polling_period == 1:
|
|
# 每天:超过 24 小时
|
|
return (now - base_time) >= timedelta(days=1)
|
|
|
|
elif polling_period == 2:
|
|
# 每周:要到下一个“周一的那个时间点”
|
|
weekday = base_time.weekday() # 0=周一, ..., 6=周日
|
|
days_to_next_monday = (7 - weekday) % 7 or 7 # 至少是下一个周一
|
|
next_monday = base_time + timedelta(days=days_to_next_monday)
|
|
next_monday = next_monday.replace(hour=base_time.hour, minute=base_time.minute, second=base_time.second)
|
|
return now >= next_monday
|
|
|
|
elif polling_period == 3:
|
|
# 每月:下个月的 1 号,时间点与原始时间相同
|
|
year = base_time.year + (base_time.month // 12)
|
|
month = (base_time.month % 12) + 1
|
|
next_month_first = datetime(year, month, 1, base_time.hour, base_time.minute, base_time.second)
|
|
return now >= next_month_first
|
|
|
|
return False
|
|
|
|
def do_check(self,target):
|
|
print(f"巡检中: {target[2]} (类型: {target[9]})")
|
|
#创建task---并初始化待办
|
|
g_TaskM.create_polling_task(target)
|
|
|
|
|
|
def update_last_time(self, target_id):
|
|
now_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
strsql = "UPDATE target SET polling_last_time=%s WHERE ID=%s;"
|
|
params = (now_str,target_id)
|
|
bok,_ = self.DBM.safe_do_sql(strsql,params)
|
|
|
|
def needUpdateTargets(self):
|
|
self.bUpdate = True
|
|
|
|
def polling_th(self):
|
|
strsql = "select * from target;"
|
|
targets = self.DBM.do_select(strsql)
|
|
while self.brun:
|
|
if self.bUpdate:
|
|
targets = self.DBM.do_select(strsql)
|
|
self.bUpdate =False
|
|
|
|
for target in targets:
|
|
if self.should_poll(target[5],target[6],target[7]):
|
|
self.do_check(target)
|
|
self.update_last_time(target[0])
|
|
|
|
sleep(60 * 60) #一个小时
|
|
|
|
def run_polling(self):
|
|
self.p_th = threading.Thread(target=self.polling_th(), name=f"p_th")
|
|
self.p_th.start()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
PM = PollingManager()
|
|
PM.polling_th()
|