Files
cjgc_upload/invalid_scheduler.py
2026-02-10 09:20:12 +08:00

185 lines
6.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import requests
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from main import DeviceAutomation
import globals.apis as apis
import random
from datetime import datetime, timedelta
## --- 配置区 ---
API_URL = "http://your-api-server.com/api/tasks" # 替换为真实的接口地址
MAX_WORKERS = 3 # 最大并发线程数,建议根据网络带宽调整
TIME_FILE_PATH = r"D:\time.txt" # 电脑D盘下的路径
def parse_time_config():
"""
解析 D:\time.txt 文件
返回格式: { "用户名": "16:40:20", ... }
"""
time_map = {}
if not os.path.exists(TIME_FILE_PATH):
print(f"⚠️ 未找到配置文件: {TIME_FILE_PATH}")
return time_map
try:
with open(TIME_FILE_PATH, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line:
continue
# 使用正则匹配用户名、时间、状态
# 兼容 wangshun 16:40:20 true 和 cdwzq3liangchaoyong 15:06:35 true
match = re.search(r'(\w+)\s+(\d{2}:\d{2}:\d{2})\s+ok', line)
if match:
username = match.group(1)
scheduled_time = match.group(2)
time_map[username] = scheduled_time
except Exception as e:
print(f"❌ 解析 time.txt 失败: {e}")
return time_map
def get_remote_tasks():
"""
从接口获取数据
"""
try:
# 1. 先获取本地文件中的配置
local_times = parse_time_config()
if not local_times:
print("❌ time.txt 中没有有效的 ok 任务或文件为空")
return {}
# 2. 从服务器获取账户
accounts = apis.get_accounts_from_server("68c0dbfdb7cbcd616e7c5ab5")
if not accounts:
print("❌ 未从服务器获取到账户信息,终止流程")
return {}
# filtered_accounts = [account for account in accounts if account.get('is_ok') == 1]
# # print("✅ 获取账户信息成功", filtered_accounts)
# # current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# # 从原始 accounts 数据中筛选有 device_ip 和 device_port 且不为 None 的账户
# device_dict = {}
# for account in filtered_accounts:
# device_ip = account.get('device_ip')
# device_port = account.get('device_port')
# # 检查 device_ip 和 device_port 是否都存在且不为 None
# if device_ip and device_port:
# # 拼接为 ip:port 格式
# key = f"{device_ip}:{device_port}"
# # 添加当前时间
# # device_dict[key] = current_time
# # 获取当前时间的 datetime 对象
# current_datetime = datetime.now()
# # 生成1-2小时的随机时间
# random_hours = random.uniform(1, 2)
# # 计算未来时间datetime 对象可以加 timedelta
# future_datetime = current_datetime + timedelta(hours=random_hours)
# # 将 datetime 对象格式化为字符串
# time_str = future_datetime.strftime("%Y-%m-%d %H:%M:%S")
# # 添加时间字符串到字典
# device_dict[key] = time_str
# # 结果
# print(device_dict)
# return device_dict
device_dict = {}
today_str = datetime.now().strftime("%Y-%m-%d")
for account in accounts:
# 条件1: 接口返回 is_ok == 1
if account.get('is_ok') != 1:
continue
username = account.get('username') # 假设接口中用户名的 key 是 username
device_ip = account.get('device_ip')
device_port = account.get('device_port')
# 条件2: 用户名在 time.txt 中且状态为 true (已经在 local_times 过滤过)
if username in local_times and device_ip and device_port:
key = f"{device_ip}:{device_port}"
# 拼接成完整的 YYYY-MM-DD HH:MM:SS
full_time_str = f"{today_str} {local_times[username]}"
device_dict[key] = full_time_str
print(f"✅ 匹配成功,待执行任务详情: {device_dict}")
return device_dict
# # 模拟数据供测试
# return {
# "192.168.1.45:5555": "2026-02-03 10:20:00",
# "192.168.1.100:5556": "2026-02-03 10:20:20",
# "192.168.31.12:5557": "2026-02-03 10:21:00"
# }
except Exception as e:
print(f"❌ 获取接口任务失败: {e}")
return {}
def run_task(address, target_time):
"""
单个线程的任务包装器
"""
# 格式化账号/设备名:确保带上端口号
device_address = address
print(f"🕒 [等待/启动] 设备: {device_address} | 预定时间: {target_time}")
# 解析目标时间
target_datetime = datetime.strptime(target_time, "%Y-%m-%d %H:%M:%S")
current_datetime = datetime.now()
# 计算等待时间
wait_seconds = (target_datetime - current_datetime).total_seconds()
# 如果需要等待
if wait_seconds > 0:
print(f"⏳ [等待中] 设备: {device_address} | 等待时间: {wait_seconds:.2f}")
time.sleep(wait_seconds)
print(f"▶️ [开始执行] 设备: {device_address} | 当前时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
else:
print(f"▶️ [开始执行] 设备: {device_address} | 当前时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
try:
# 创建DeviceAutomation实例并执行上传逻辑
automation = DeviceAutomation(device_address)
result = automation.handle_app_state()
return f"{device_address} 完成: {result}"
except Exception as e:
return f"{device_address} 报错: {str(e)}"
def monitor_center():
"""调度中心"""
tasks_data = get_remote_tasks()
if not tasks_data:
print("📭 接口未返回任何任务,程序退出。")
return
print(f"🗂️ 发现 {len(tasks_data)} 个待处理账号,开始建立线程池...")
# 使用线程池并发执行
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
# 提交所有任务
future_to_device = {
executor.submit(run_task, acc, t): acc
for acc, t in tasks_data.items()
}
# 实时打印完成情况
for future in as_completed(future_to_device):
print(future.result())
if __name__ == "__main__":
print("🚀 自动化调度程序启动...")
monitor_center()
print("🏁 所有并发任务处理序列结束。")