From 723370053970a0dab6baf4e5ec94d972f734688e Mon Sep 17 00:00:00 2001 From: teddy Date: Thu, 26 Jun 2025 17:24:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E7=B3=BB=E7=BB=9F=E5=B9=B6=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将硬编码的时间配置改为从CONFIG读取 - 支持多接收人配置,修改open_id为数组类型 - 增加发送时间等待功能,确保消息在指定时间发送 - 改进停止定时任务的进程查找逻辑 - 更新配置项,增加checking_time、sending_time和message字段 --- config.py | 11 +++--- scheduler.py | 3 +- send_filemsg.py | 34 ++++++++++-------- send_openmsg.py | 37 ++++++++++--------- sendmsg.py | 33 +++++++++++++++-- stop_scheduler.py | 91 ++++++++++++++++++++++++++++++++++++++++------- 6 files changed, 156 insertions(+), 53 deletions(-) diff --git a/config.py b/config.py index d375548..d1ad9e3 100644 --- a/config.py +++ b/config.py @@ -1,7 +1,10 @@ CONFIG = { - "app_id": "cli_a8de57f7e95f100c", - "app_secret": "jm2nkFnnSNVS3n076VOPfh8k7q0hEKVp", - "open_id": "ou_bd33a5f75dd2ccb005a21e4dd01f930c", + "app_id": "cli_a8d64a7be63a500e", + "app_secret": "mcK8aTiq0CLtkzGs2aTZpcnom5J4o6yB", + "open_id": ["ou_c6466a45623096cf7a34d94fe30c6c73", "ou_3b94d0caf83dbced8b0e26af4852a281"], "file_path": "C:\\Users\\22251\\OneDrive\\桌面\\picture\\", - "messages_reciever": "File Transfer" + "messages_reciever": "文件传输", + "checking_time": "17:15", + "sending_time": "17:17", + "message": "新的一天,从华智长盈每日AI新闻开始!让我们一起看看今天AI圈有啥新鲜事!" } \ No newline at end of file diff --git a/scheduler.py b/scheduler.py index 8bf22d4..7e3cccc 100644 --- a/scheduler.py +++ b/scheduler.py @@ -4,6 +4,7 @@ import subprocess import sys import os from datetime import datetime +from config import CONFIG def run_sendmsg(): """执行sendmsg.py脚本""" @@ -22,7 +23,7 @@ def run_sendmsg(): def main(): """主函数 - 设置定时任务""" # 每天17:30执行任务 - schedule.every().day.at("17:40").do(run_sendmsg) + schedule.every().day.at(CONFIG['checking_time']).do(run_sendmsg) print(f"[{datetime.now()}] 定时任务已启动,将在每天17:30执行sendmsg.py") print("按Ctrl+C停止程序") diff --git a/send_filemsg.py b/send_filemsg.py index ad7997c..30cc891 100644 --- a/send_filemsg.py +++ b/send_filemsg.py @@ -5,30 +5,34 @@ from lark_oapi.api.im.v1 import * from config import CONFIG def main(): + + Local_openid = CONFIG['open_id'] + client = lark.Client.builder() \ .app_id(CONFIG['app_id']) \ .app_secret(CONFIG['app_secret']) \ .log_level(lark.LogLevel.DEBUG) \ .build() + for local_openid in Local_openid: # 构造请求对象 - request: CreateMessageRequest = CreateMessageRequest.builder() \ - .receive_id_type("open_id") \ - .request_body(CreateMessageRequestBody.builder() - .receive_id(CONFIG['open_id']) - .msg_type("text") - .content("{\"text\":\"未找到指定图片\"}") - .build()) \ - .build() + request: CreateMessageRequest = CreateMessageRequest.builder() \ + .receive_id_type("open_id") \ + .request_body(CreateMessageRequestBody.builder() + .receive_id(local_openid) + .msg_type("text") + .content("{\"text\":\"未找到指定图片,请手动发送\"}") + .build()) \ + .build() - # 发起请求 - response: CreateMessageResponse = client.im.v1.message.create(request) + # 发起请求 + response: CreateMessageResponse = client.im.v1.message.create(request) - # 处理失败返回 - if not response.success(): - lark.logger.error( - f"client.im.v1.message.create failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}") - return + # 处理失败返回 + if not response.success(): + lark.logger.error( + f"client.im.v1.message.create failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}") + return # 处理业务结果 lark.logger.info(lark.JSON.marshal(response.data, indent=4)) diff --git a/send_openmsg.py b/send_openmsg.py index e4062d8..b87cf69 100644 --- a/send_openmsg.py +++ b/send_openmsg.py @@ -5,6 +5,8 @@ from lark_oapi.api.im.v1 import * from config import CONFIG def main(): + + Local_openid = CONFIG['open_id'] # 创建client client = lark.Client.builder() \ .app_id(CONFIG['app_id']) \ @@ -13,26 +15,27 @@ def main(): .build() # 构造请求对象 - request: CreateMessageRequest = CreateMessageRequest.builder() \ - .receive_id_type("open_id") \ - .request_body(CreateMessageRequestBody.builder() - .receive_id(CONFIG['open_id']) - .msg_type("text") - .content("{\"text\":\"请打开微信或者登录微信\"}") - .build()) \ - .build() + for local_openid in Local_openid: + request: CreateMessageRequest = CreateMessageRequest.builder() \ + .receive_id_type("open_id") \ + .request_body(CreateMessageRequestBody.builder() + .receive_id(local_openid) + .msg_type("text") + .content("{\"text\":\"请打开微信或者登录微信\"}") + .build()) \ + .build() - # 发起请求 - response: CreateMessageResponse = client.im.v1.message.create(request) + # 发起请求 + response: CreateMessageResponse = client.im.v1.message.create(request) - # 处理失败返回 - if not response.success(): - lark.logger.error( - f"client.im.v1.message.create failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}") - return + # 处理失败返回 + if not response.success(): + lark.logger.error( + f"client.im.v1.message.create failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}") + return - # 处理业务结果 - lark.logger.info(lark.JSON.marshal(response.data, indent=4)) + # 处理业务结果 + lark.logger.info(lark.JSON.marshal(response.data, indent=4)) if __name__ == "__main__": main() \ No newline at end of file diff --git a/sendmsg.py b/sendmsg.py index 9ca155d..c2eff02 100644 --- a/sendmsg.py +++ b/sendmsg.py @@ -1,5 +1,5 @@ from wxauto import WeChat -from datetime import date +from datetime import date, datetime, time as dt_time import sys import os import subprocess @@ -7,6 +7,27 @@ import json from config import CONFIG import time +def wait_until_time(): + """等待到配置的发送时间""" + now = datetime.now() + + # 从配置文件中读取发送时间 + send_time_str = CONFIG['sending_time'] # "17:10" + hour, minute = map(int, send_time_str.split(':')) + + target_time = now.replace(hour=hour, minute=minute, second=0, microsecond=0) + + # 如果当前时间已经过了今天的发送时间,则设置为明天的发送时间 + if now >= target_time: + target_time = target_time.replace(day=target_time.day + 1) + + wait_seconds = (target_time - now).total_seconds() + print(f"当前时间: {now.strftime('%Y-%m-%d %H:%M:%S')}") + print(f"将在 {target_time.strftime('%Y-%m-%d %H:%M:%S')} 执行发送操作") + print(f"等待时间: {wait_seconds/3600:.2f} 小时") + + time.sleep(wait_seconds) + def send_daily_message(): """发送每日消息的主函数""" today = date.today() @@ -20,13 +41,19 @@ def send_daily_message(): subprocess.run([sys.executable, 'send_openmsg.py']) return False - msg = 'hello, wxauto!' + msg = CONFIG['message'] who = CONFIG['messages_reciever'] if os.path.isfile(file_path): print("找到了指定文件!") - wx.SendFiles(filepath=file_path, who="File Transfer") + + # 等待到配置的时间再执行发送操作 + wait_until_time() + + print("开始发送文件和消息...") + wx.SendFiles(filepath=file_path, who=who) wx.SendMsg(msg=msg, who=who) + print("发送完成!") return True else: print("没找到指定文件") diff --git a/stop_scheduler.py b/stop_scheduler.py index 7f1dff6..c128d2d 100644 --- a/stop_scheduler.py +++ b/stop_scheduler.py @@ -1,25 +1,90 @@ import subprocess import sys import os +import psutil +from pathlib import Path def stop_scheduler(): """停止定时任务进程""" + stopped_count = 0 + try: - # 查找并结束scheduler.py进程 - result = subprocess.run(['tasklist', '/FI', 'IMAGENAME eq pythonw.exe', '/FO', 'CSV'], - capture_output=True, text=True) + # 方法1: 使用psutil精确查找进程 + current_dir = str(Path(__file__).parent) - if 'scheduler.py' in result.stdout: - # 结束包含scheduler.py的pythonw进程 - subprocess.run(['taskkill', '/F', '/IM', 'pythonw.exe'], check=True) - print("定时任务已停止") - else: - print("未找到运行中的定时任务") + for proc in psutil.process_iter(['pid', 'name', 'cmdline']): + try: + if proc.info['name'] in ['python.exe', 'pythonw.exe']: + cmdline = proc.info['cmdline'] + if cmdline and len(cmdline) > 1: + # 检查是否是我们的scheduler.py进程 + if 'scheduler.py' in ' '.join(cmdline) and current_dir in ' '.join(cmdline): + print(f"找到进程: PID={proc.info['pid']}, 命令行={' '.join(cmdline)}") + proc.terminate() + proc.wait(timeout=5) # 等待进程正常结束 + print(f"已终止进程 PID={proc.info['pid']}") + stopped_count += 1 + except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): + continue + + except ImportError: + print("psutil模块未安装,使用备用方法...") + # 方法2: 备用方法 - 改进的tasklist方式 + try: + # 获取详细的进程信息 + result = subprocess.run(['wmic', 'process', 'where', 'name="pythonw.exe"', 'get', 'ProcessId,CommandLine', '/format:csv'], + capture_output=True, text=True, encoding='gbk') - except subprocess.CalledProcessError as e: - print(f"停止进程时出错: {e}") - except Exception as e: - print(f"发生错误: {e}") + lines = result.stdout.strip().split('\n') + current_dir = str(Path(__file__).parent) + + for line in lines[1:]: # 跳过标题行 + if line.strip() and 'scheduler.py' in line and current_dir in line: + # 提取PID + parts = line.split(',') + if len(parts) >= 2: + pid = parts[-1].strip() + if pid.isdigit(): + subprocess.run(['taskkill', '/F', '/PID', pid], check=True) + print(f"已终止进程 PID={pid}") + stopped_count += 1 + + except subprocess.CalledProcessError as e: + print(f"备用方法执行失败: {e}") + + # 方法3: 最后的备用方案 + try: + result = subprocess.run(['tasklist', '/FI', 'IMAGENAME eq pythonw.exe', '/FO', 'CSV'], + capture_output=True, text=True) + + if 'pythonw.exe' in result.stdout: + print("警告: 找到pythonw.exe进程,但无法确定是否为目标进程") + response = input("是否强制结束所有pythonw.exe进程?(y/N): ") + if response.lower() == 'y': + subprocess.run(['taskkill', '/F', '/IM', 'pythonw.exe'], check=True) + print("已强制结束所有pythonw.exe进程") + stopped_count += 1 + + except subprocess.CalledProcessError as e: + print(f"最后备用方案失败: {e}") + + if stopped_count > 0: + print(f"成功停止了 {stopped_count} 个定时任务进程") + else: + print("未找到运行中的定时任务进程") + + # 额外检查:查看是否还有相关进程 + print("\n检查剩余进程...") + try: + result = subprocess.run(['tasklist', '/FI', 'IMAGENAME eq pythonw.exe'], + capture_output=True, text=True) + if 'pythonw.exe' in result.stdout: + print("仍有pythonw.exe进程在运行:") + print(result.stdout) + else: + print("没有发现pythonw.exe进程") + except: + pass if __name__ == "__main__": stop_scheduler() \ No newline at end of file