修改上传人员信息表为D盘固定位置;新增上传弹窗检查

This commit is contained in:
2026-02-09 08:53:41 +08:00
parent 5c38228a1c
commit ac4d41c70b
30 changed files with 111274 additions and 883 deletions

185
invalid_scheduler.py Normal file
View File

@@ -0,0 +1,185 @@
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+true', 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 中没有有效的 true 任务或文件为空")
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("🏁 所有并发任务处理序列结束。")