update
This commit is contained in:
parent
163f6cf48d
commit
353f1db25d
98
Core.py
98
Core.py
@ -24,6 +24,7 @@ from GotoSend.xianzhi import Src_xianzhi
|
|||||||
from GotoSend.freebuf import Src_freebuf
|
from GotoSend.freebuf import Src_freebuf
|
||||||
from GotoSend.qianxin import Src_qianxin
|
from GotoSend.qianxin import Src_qianxin
|
||||||
from GotoSend.seebug import Src_seebug
|
from GotoSend.seebug import Src_seebug
|
||||||
|
from config.check_config import get_core_config, get_debug_config
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
# 清除所有已有的日志记录器配置
|
# 清除所有已有的日志记录器配置
|
||||||
@ -35,21 +36,20 @@ logger.add("./log/core.log",
|
|||||||
compression="zip",
|
compression="zip",
|
||||||
encoding="utf-8")
|
encoding="utf-8")
|
||||||
# shell终端打印日志
|
# shell终端打印日志
|
||||||
# logger.add(lambda msg: print(msg),
|
debug = get_debug_config()
|
||||||
# format="{time:YYYY-MM-DD HH:mm:ss} - {level} - {name}:{function}:{line} - {message}")
|
if debug == "True":
|
||||||
|
logger.add(lambda msg: print(msg),
|
||||||
|
format="{time:YYYY-MM-DD HH:mm:ss} - {level} - {name}:{function}:{line} - {message}")
|
||||||
|
|
||||||
# 加载参数
|
def signal_handler(sig, frame):
|
||||||
with open('./config.yaml', 'r', encoding="utf-8") as file:
|
logger.info("接收到退出信号,程序即将退出...")
|
||||||
config = yaml.safe_load(file)
|
sys.exit(0)
|
||||||
# sleep_time = int(f"{config['sleep_time']}")
|
|
||||||
e_hour = int(f"{config['e_hour']}")
|
|
||||||
choice = int(f"{config['circle']}")
|
|
||||||
fs_activate = f"{config['fs_activate']}"
|
|
||||||
wx_activate = f"{config['wx_activate']}"
|
|
||||||
ding_activate = f"{config['ding_activate']}"
|
|
||||||
lx_activate = f"{config['lx_activate']}"
|
|
||||||
|
|
||||||
|
# 全局变量
|
||||||
|
signal.signal(signal.SIGINT, signal_handler) # Ctrl+C
|
||||||
|
signal.signal(signal.SIGTERM, signal_handler) # kill命令
|
||||||
webhook_url_once, timestamp_once, sign_once = gen_sign()
|
webhook_url_once, timestamp_once, sign_once = gen_sign()
|
||||||
|
e_hour, choice, fs_activate, wx_activate, ding_activate, lx_activate, url_web = get_core_config()
|
||||||
|
|
||||||
def check_avaliable(info_long, info_short, title, webhook_url, timestamp, sign):
|
def check_avaliable(info_long, info_short, title, webhook_url, timestamp, sign):
|
||||||
if info_long: # 发送完整文章相关内容
|
if info_long: # 发送完整文章相关内容
|
||||||
@ -121,52 +121,17 @@ def send_job(time_1):
|
|||||||
check_avaliable(result_seebug_long, result_seebug_short, "Seebug社区资讯", webhook_url, timestamp, sign)
|
check_avaliable(result_seebug_long, result_seebug_short, "Seebug社区资讯", webhook_url, timestamp, sign)
|
||||||
|
|
||||||
if fs_activate == "True":
|
if fs_activate == "True":
|
||||||
send_result = SendToFeishu("[点此访问](https://info.masonliu.com)网站以查看全部文章。", "单次运行结束", webhook_url, timestamp, sign)
|
send_result = SendToFeishu(f"[点此访问]({url_web})网站以查看全部文章。", "单次运行结束", webhook_url, timestamp, sign)
|
||||||
logger.info(send_result)
|
logger.info(send_result)
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
if wx_activate == "True":
|
if wx_activate == "True":
|
||||||
send_result = SendToWX("[点此访问](https://info.masonliu.com)网站以查看全部文章。", "单次运行结束")
|
send_result = SendToWX(f"[点此访问]({url_web})网站以查看全部文章。", "单次运行结束")
|
||||||
logger.info(send_result)
|
logger.info(send_result)
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
logger.info("执行完毕,等待下一次执行...")
|
logger.info("执行完毕,等待下一次执行...")
|
||||||
|
|
||||||
def signal_handler(sig, frame):
|
|
||||||
logger.info("接收到退出信号,程序即将退出...")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, signal_handler) # Ctrl+C
|
|
||||||
signal.signal(signal.SIGTERM, signal_handler) # kill命令
|
|
||||||
|
|
||||||
|
|
||||||
def main_loop(choice):
|
|
||||||
if choice == 1:
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
# 执行任务
|
|
||||||
send_job(e_hour)
|
|
||||||
time.sleep(e_hour * 60 * 60 - 3 * 60)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"发生错误: {e}, 程序已暂停")
|
|
||||||
# result = SendToFeishu(f"发生错误: {e}, 程序已退出", "报错信息")
|
|
||||||
# logger.info(result)
|
|
||||||
exit()
|
|
||||||
|
|
||||||
elif choice == 0:
|
|
||||||
# 设置每天的特定时间点执行job函数
|
|
||||||
schedule.every().day.at("09:00").do(send_job, 12)
|
|
||||||
schedule.every().day.at("12:00").do(send_job, 3)
|
|
||||||
schedule.every().day.at("15:00").do(send_job, 3)
|
|
||||||
schedule.every().day.at("18:00").do(send_job, 3)
|
|
||||||
schedule.every().day.at("21:00").do(send_job, 3)
|
|
||||||
|
|
||||||
while True:
|
|
||||||
schedule.run_pending()
|
|
||||||
time.sleep(60) # 每分钟检查一次是否有任务需要执行
|
|
||||||
|
|
||||||
# 探测rss源状态
|
# 探测rss源状态
|
||||||
def check_rss_status(url):
|
def check_rss_status(url):
|
||||||
try:
|
try:
|
||||||
@ -202,9 +167,33 @@ def test_rss_source():
|
|||||||
|
|
||||||
return rss_info
|
return rss_info
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def main_loop(choice):
|
||||||
print("程序正在运行当中。")
|
if choice == 1:
|
||||||
time.sleep(5) # 添加短暂的延迟
|
while True:
|
||||||
|
try:
|
||||||
|
# 执行任务
|
||||||
|
send_job(e_hour)
|
||||||
|
time.sleep(e_hour * 60 * 60 - 3 * 60)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"发生错误: {e}, 程序已暂停")
|
||||||
|
# result = SendToFeishu(f"发生错误: {e}, 程序已退出", "报错信息")
|
||||||
|
# logger.info(result)
|
||||||
|
exit()
|
||||||
|
|
||||||
|
elif choice == 0:
|
||||||
|
# 设置每天的特定时间点执行job函数
|
||||||
|
schedule.every().day.at("09:00").do(send_job, 12)
|
||||||
|
schedule.every().day.at("12:00").do(send_job, 3)
|
||||||
|
schedule.every().day.at("15:00").do(send_job, 3)
|
||||||
|
schedule.every().day.at("18:00").do(send_job, 3)
|
||||||
|
schedule.every().day.at("21:00").do(send_job, 3)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
schedule.run_pending()
|
||||||
|
time.sleep(60) # 每分钟检查一次是否有任务需要执行
|
||||||
|
|
||||||
|
def send_first_message():
|
||||||
rss_info = test_rss_source()
|
rss_info = test_rss_source()
|
||||||
start_info = ""
|
start_info = ""
|
||||||
start_info += "程序已启动,当前时间为:" + datetime.now().strftime("%Y-%m-%d %H:%M:%S") + "\n"
|
start_info += "程序已启动,当前时间为:" + datetime.now().strftime("%Y-%m-%d %H:%M:%S") + "\n"
|
||||||
@ -229,9 +218,14 @@ if __name__ == "__main__":
|
|||||||
logger.info(result)
|
logger.info(result)
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
logger.info("程序正在运行当中。")
|
||||||
|
time.sleep(5) # 添加短暂的延迟
|
||||||
|
|
||||||
# 首次运行先暂停两分钟
|
# 首次运行先暂停两分钟
|
||||||
# time.sleep(2 * 60)
|
# time.sleep(2 * 60)
|
||||||
|
|
||||||
# 主程序
|
# 主程序
|
||||||
|
send_first_message()
|
||||||
main_loop(choice)
|
main_loop(choice)
|
@ -112,17 +112,16 @@ def get_filtered_articles(entries, Is_short):
|
|||||||
record = ""
|
record = ""
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
if Is_short == False:
|
if Is_short == False:
|
||||||
result += f"作者:{entry[5]}\n文章:{entry[1]}\n"
|
result += f"文章:[{entry[1]}]({entry[2]})\n作者:{entry[5]}\n"
|
||||||
result += f"链接:{entry[2]}\n上传时间:{entry[4]}\n"
|
result += f"上传时间:{entry[4]}\n"
|
||||||
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
if Is_short == True:
|
if Is_short == True:
|
||||||
result += f"文章:{entry[1]}\n"
|
result += f"文章:[{entry[1]}]({entry[2]})\n"
|
||||||
result += f"链接:{entry[2]}\n上传时间:{entry[4]}\n"
|
result += f"链接:{entry[2]}\n上传时间:{entry[4]}\n"
|
||||||
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
||||||
|
|
||||||
record += f"#### 文章:{entry[1]}\n"
|
record += f"#### 文章:[{entry[1]}]({entry[2]})\n"
|
||||||
record += f"**作者**:{entry[5]}\n"
|
record += f"**作者**:{entry[5]}\n"
|
||||||
record += f"**链接**:{entry[2]}\n"
|
|
||||||
record += f"**上传时间**:{entry[4]}\n"
|
record += f"**上传时间**:{entry[4]}\n"
|
||||||
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
record_md(record)
|
record_md(record)
|
||||||
|
@ -107,18 +107,17 @@ def get_filtered_articles(entries, Is_short):
|
|||||||
record = ""
|
record = ""
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
if Is_short == False:
|
if Is_short == False:
|
||||||
result += f"作者:{entry[6]}\n来源:{entry[3]}\n文章:{entry[1]}\n"
|
result += f"文章:[{entry[1]}]({entry[2]})\n作者:{entry[6]}\n来源:{entry[3]}\n"
|
||||||
result += f"链接:{entry[2]}\n上传时间:{entry[5]}\n"
|
result += f"上传时间:{entry[5]}\n"
|
||||||
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
elif Is_short == True:
|
elif Is_short == True:
|
||||||
result += f"文章:{entry[1]}\n"
|
result += f"文章:{entry[1]}\n"
|
||||||
result += f"链接:{entry[2]}\n上传时间:{entry[5]}\n"
|
result += f"链接:{entry[2]}\n上传时间:{entry[5]}\n"
|
||||||
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
||||||
|
|
||||||
record += f"#### 文章:{entry[1]}\n"
|
record += f"#### 文章:[{entry[1]}]({entry[2]})\n"
|
||||||
record += f"**作者**:{entry[6]}\n"
|
record += f"**作者**:{entry[6]}\n"
|
||||||
record += f"**来源**:{entry[3]}\n"
|
record += f"**来源**:{entry[3]}\n"
|
||||||
record += f"**链接**:{entry[2]}\n"
|
|
||||||
record += f"**上传时间**:{entry[5]}\n"
|
record += f"**上传时间**:{entry[5]}\n"
|
||||||
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
record_md(record)
|
record_md(record)
|
||||||
|
@ -114,18 +114,18 @@ def get_filtered_articles(entries, Is_short):
|
|||||||
record = ""
|
record = ""
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
if Is_short == False:
|
if Is_short == False:
|
||||||
result += f"作者:{entry[5]}\n文章:{entry[1]}\n"
|
result += f"文章:[{entry[1]}]({entry[2]})\n"
|
||||||
result += f"链接:[点此访问]({entry[2]})\n上传时间:{entry[4]}\n"
|
result += f"作者:{entry[5]}\n"
|
||||||
|
result += f"上传时间:{entry[4]}\n"
|
||||||
result += f"简介:{entry[3]}\n"
|
result += f"简介:{entry[3]}\n"
|
||||||
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
if Is_short == True:
|
if Is_short == True:
|
||||||
result += f"文章:{entry[1]}\n"
|
result += f"文章:[{entry[1]}]({entry[2]})\n"
|
||||||
result += f"链接:[点此访问]({entry[2]})\n上传时间:{entry[4]}\n"
|
result += f"上传时间:{entry[4]}\n"
|
||||||
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
||||||
|
|
||||||
record += f"#### 文章:{entry[1]}\n"
|
record += f"#### 文章:[{entry[1]}]({entry[2]})\n"
|
||||||
record += f"**作者**:{entry[5]}\n"
|
record += f"**作者**:{entry[5]}\n"
|
||||||
record += f"**链接**:[点此访问]({entry[2]})\n"
|
|
||||||
record += f"**上传时间**:{entry[4]}\n"
|
record += f"**上传时间**:{entry[4]}\n"
|
||||||
record += f"**简介**:{entry[3]}\n"
|
record += f"**简介**:{entry[3]}\n"
|
||||||
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
|
@ -113,17 +113,16 @@ def get_filtered_articles(entries, Is_short):
|
|||||||
record = ""
|
record = ""
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
if Is_short == False:
|
if Is_short == False:
|
||||||
result += f"类型:{entry[5]}\n文章:{entry[1]}\n"
|
result += f"文章:[{entry[1]}]({entry[2]})\n类型:{entry[5]}\n"
|
||||||
result += f"链接:{entry[2]}\n上传时间:{entry[4]}\n"
|
result += f"上传时间:{entry[4]}\n"
|
||||||
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
elif Is_short == True:
|
elif Is_short == True:
|
||||||
result += f"文章:{entry[1]}\n"
|
result += f"文章:[{entry[1]}]({entry[2]})\n"
|
||||||
result += f"链接:{entry[2]}\n上传时间:{entry[4]}\n"
|
result += f"上传时间:{entry[4]}\n"
|
||||||
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
||||||
|
|
||||||
record += f"#### 文章:{entry[1]}\n"
|
record += f"#### 文章:[{entry[1]}]({entry[2]})\n"
|
||||||
record += f"**类型**:{entry[5]}\n"
|
record += f"**类型**:{entry[5]}\n"
|
||||||
record += f"**链接**:{entry[2]}\n"
|
|
||||||
record += f"**上传时间**:{entry[4]}\n"
|
record += f"**上传时间**:{entry[4]}\n"
|
||||||
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
record_md(record)
|
record_md(record)
|
||||||
|
@ -104,18 +104,17 @@ def get_filtered_articles(entries, Is_short):
|
|||||||
record = ""
|
record = ""
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
if Is_short == False:
|
if Is_short == False:
|
||||||
result += f"来源:{entry[3]}\n文章:{entry[1]}\n"
|
result += f"文章:[{entry[1]}]({entry[2]})\n来源:{entry[3]}\n"
|
||||||
result += f"链接:{entry[2]}\n上传时间:{entry[5]}\n"
|
result += f"上传时间:{entry[5]}\n"
|
||||||
result += f"描述:{entry[4]}\n"
|
result += f"描述:{entry[4]}\n"
|
||||||
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
if Is_short == False:
|
if Is_short == False:
|
||||||
result += f"文章:{entry[1]}\n"
|
result += f"文章:[{entry[1]}]({entry[2]})\n"
|
||||||
result += f"链接:{entry[2]}\n上传时间:{entry[5]}\n"
|
result += f"上传时间:{entry[5]}\n"
|
||||||
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
||||||
|
|
||||||
record += f"#### 文章:{entry[1]}\n"
|
record += f"#### 文章:[{entry[1]}]({entry[2]})\n"
|
||||||
record += f"**来源**:{entry[3]}\n"
|
record += f"**来源**:{entry[3]}\n"
|
||||||
record += f"**链接**:{entry[2]}\n"
|
|
||||||
record += f"**上传时间**:{entry[5]}\n"
|
record += f"**上传时间**:{entry[5]}\n"
|
||||||
record += f"**描述**:{entry[4]}\n"
|
record += f"**描述**:{entry[4]}\n"
|
||||||
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
|
@ -111,18 +111,17 @@ def get_filtered_articles(entries, Is_short):
|
|||||||
record = ""
|
record = ""
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
if Is_short == False:
|
if Is_short == False:
|
||||||
result += f"类型:{entry[3]}\n文章:{entry[1]}"
|
result += f"文章:[{entry[1]}]({entry[2]})\n类型:{entry[3]}\n"
|
||||||
result += f"链接:{entry[2]}\n上传时间:{entry[5]}\n"
|
result += f"上传时间:{entry[5]}\n"
|
||||||
result += f"{entry[4]}\n"
|
result += f"{entry[4]}\n"
|
||||||
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
if Is_short == True:
|
if Is_short == True:
|
||||||
result += f"文章:{entry[1]}"
|
result += f"文章:[{entry[1]}]({entry[2]})"
|
||||||
result += f"链接:{entry[2]}\n上传时间:{entry[5]}\n"
|
result += f"上传时间:{entry[5]}\n"
|
||||||
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
||||||
|
|
||||||
record += f"#### 文章:{entry[1]}\n"
|
record += f"#### 文章:[{entry[1]}]({entry[2]})\n"
|
||||||
record += f"**类型**:{entry[3]}\n"
|
record += f"**类型**:{entry[3]}\n"
|
||||||
record += f"**链接**:{entry[2]}\n"
|
|
||||||
record += f"**上传时间**:{entry[5]}\n"
|
record += f"**上传时间**:{entry[5]}\n"
|
||||||
record += f"{entry[4]}\n"
|
record += f"{entry[4]}\n"
|
||||||
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
|
@ -110,16 +110,15 @@ def get_filtered_articles(entries, Is_short):
|
|||||||
record = ""
|
record = ""
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
if Is_short == False:
|
if Is_short == False:
|
||||||
result += f"文章:{entry[1]}\n"
|
result += f"文章:[{entry[1]}]({entry[2]})\n"
|
||||||
result += f"链接:{entry[2]}\n上传时间:{entry[3]}\n"
|
result += f"上传时间:{entry[3]}\n"
|
||||||
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
if Is_short == False:
|
if Is_short == False:
|
||||||
result += f"文章:{entry[1]}\n"
|
result += f"文章:[{entry[1]}]({entry[2]})\n"
|
||||||
result += f"链接:{entry[2]}\n上传时间:{entry[3]}\n"
|
result += f"上传时间:{entry[3]}\n"
|
||||||
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
result += "\n" + "-" * 3 + "\n" # 添加分隔线以便区分不同文章
|
||||||
|
|
||||||
record += f"#### 文章:{entry[1]}\n"
|
record += f"#### 文章:[{entry[1]}]({entry[2]})\n"
|
||||||
record += f"**链接**:{entry[2]}\n"
|
|
||||||
record += f"**上传时间**:{entry[3]}\n"
|
record += f"**上传时间**:{entry[3]}\n"
|
||||||
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
record += "\n" + "-" * 40 + "\n" # 添加分隔线以便区分不同文章
|
||||||
record_md(record)
|
record_md(record)
|
||||||
|
@ -3,6 +3,11 @@ RSS订阅链接来源:https://github.com/zhengjim/Chinese-Security-RSS <br>
|
|||||||
使用python-json进行格式化,然后使用飞书webhook机器人进行发送 <br>
|
使用python-json进行格式化,然后使用飞书webhook机器人进行发送 <br>
|
||||||
config.yaml可指定大部分可能需要的参数 <br>
|
config.yaml可指定大部分可能需要的参数 <br>
|
||||||
|
|
||||||
|
### 项目特色 <br>
|
||||||
|
- 模块化:爬虫(获取信息部分)、分析(对获取的json信息进行筛选分析存储)、推送(推送至各渠道)、网页等各模块均可单独运行。 <br>
|
||||||
|
- 轻量化:默认使用sqlite以及其他常见的各系统自带的库,用户仅需配置python环境,不会占用过多内存。 <br>
|
||||||
|
- 简单化:配置好config后即可一步运行,效率极高。 <br>
|
||||||
|
|
||||||
### 日志相关
|
### 日志相关
|
||||||
请查看./log文件夹下内容 <br>
|
请查看./log文件夹下内容 <br>
|
||||||
|
|
||||||
@ -20,7 +25,7 @@ centos: `yum install screen` <br>
|
|||||||
随后便可直接运行:`python Core.py` <br>
|
随后便可直接运行:`python Core.py` <br>
|
||||||
web运行:`python ./web/app.py` <br>
|
web运行:`python ./web/app.py` <br>
|
||||||
随后web网页将会在本地5000端口启动,访问即可,使用反向代理即可以域名映射到外网 <br>
|
随后web网页将会在本地5000端口启动,访问即可,使用反向代理即可以域名映射到外网 <br>
|
||||||
直接访问web域名即可查看历史推送,访问路径/log即可查看程序运行日志 <br>
|
直接访问web域名即可查看历史推送,访问路径/log即可查看程序运行日志,/weblog查看flask日志 <br>
|
||||||
|
|
||||||
### 配置 <br>
|
### 配置 <br>
|
||||||
首先先在飞书中创建群组,然后再创建WebHook机器人 <br>
|
首先先在飞书中创建群组,然后再创建WebHook机器人 <br>
|
||||||
|
@ -9,7 +9,7 @@ import time
|
|||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
def gen_sign():
|
def gen_sign():
|
||||||
with open('./config.yaml', 'r', encoding="utf-8") as file:
|
with open('./config/config.yaml', 'r', encoding="utf-8") as file:
|
||||||
config = yaml.safe_load(file)
|
config = yaml.safe_load(file)
|
||||||
secret = f"{config['fs_secret']}"
|
secret = f"{config['fs_secret']}"
|
||||||
# print(secret)
|
# print(secret)
|
||||||
|
@ -7,7 +7,7 @@ from email.mime.text import MIMEText
|
|||||||
from email.header import Header
|
from email.header import Header
|
||||||
|
|
||||||
# 加载参数
|
# 加载参数
|
||||||
with open('./config.yaml', 'r', encoding="utf-8") as file:
|
with open('./config/config.yaml', 'r', encoding="utf-8") as file:
|
||||||
config = yaml.safe_load(file)
|
config = yaml.safe_load(file)
|
||||||
mail_host = f"{config['mail_host']}"
|
mail_host = f"{config['mail_host']}"
|
||||||
mail_user = f"{config['mail_user']}"
|
mail_user = f"{config['mail_user']}"
|
||||||
|
@ -9,7 +9,7 @@ import hmac
|
|||||||
import time
|
import time
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
with open('./config.yaml', 'r', encoding="utf-8") as file:
|
with open('./config/config.yaml', 'r', encoding="utf-8") as file:
|
||||||
config = yaml.safe_load(file)
|
config = yaml.safe_load(file)
|
||||||
webhook_url = f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={config['wx_key']}"
|
webhook_url = f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={config['wx_key']}"
|
||||||
# print(webhook_url)
|
# print(webhook_url)
|
||||||
|
19
UpdateLOG.md
19
UpdateLOG.md
@ -1,21 +1,26 @@
|
|||||||
### 从2024年12月15日开始记录
|
|
||||||
|
|
||||||
### 问题反馈 <br>
|
### 问题反馈 <br>
|
||||||
- 准点发送的文章在定点推送模式下可能会被遗漏推送 <br>
|
- 准点发送的文章在定点推送模式下可能会被遗漏推送 <br>
|
||||||
- 钉钉/企业微信/蓝信webhook存在字节长度限制,需要优化程序推送逻辑 <br>
|
- 钉钉/企业微信/蓝信webhook存在字节长度限制,需要优化程序推送逻辑 <br>
|
||||||
|
|
||||||
### 下一步计划 <br>
|
### 下一步计划(待完成) <br>
|
||||||
- 添加更多RSS订阅源(持续进行中) <br>
|
- 添加更多RSS订阅源(持续进行中) <br>
|
||||||
|
- 添加更多推送方式,如邮件、微信等 <br>
|
||||||
|
- 添加GitHub等监测源(参考github-cve-monitor) <br>
|
||||||
|
- 添加Mysql作为数据库存储 <br>
|
||||||
|
|
||||||
|
### 下一步计划(已完成) <br>
|
||||||
- 将所有打印信息转为logging info并存档(已完成)<br>
|
- 将所有打印信息转为logging info并存档(已完成)<br>
|
||||||
- 将logging info转为异步的loguru(已完成) <br>
|
- 将logging info转为异步的loguru(已完成) <br>
|
||||||
- 探查异常中断原因(已发现,获取rss源时的请求未做超时) <br>
|
- 探查异常中断原因(已解决,获取rss源时的请求未做超时检测) <br>
|
||||||
- 添加超时机制,防止程序异常卡死(已完成) <br>
|
- 添加超时机制,防止程序异常卡死(已完成) <br>
|
||||||
- 存档所有推送文章方便以后查看(已完成) <br>
|
- 存档所有推送文章方便以后查看(已完成) <br>
|
||||||
- 添加更多推送方式,如邮件、微信等 <br>
|
- 创建Web网页以展示最新推送(info.masonliu.com,已完成) <br>
|
||||||
- 创建Web网页以展示最新推送(info.masonliu.com) <br>
|
|
||||||
|
|
||||||
### 更新日志
|
### 更新日志
|
||||||
|
#### 从2024年12月15日开始记录
|
||||||
- 2024年12月15日早:优化了文件结构,修复了日志记录时的小BUG,添加web展示日志功能 <br>
|
- 2024年12月15日早:优化了文件结构,修复了日志记录时的小BUG,添加web展示日志功能 <br>
|
||||||
- 2024年12月15日晚:修复了单次运行结束时的校验错误问题 <br>
|
- 2024年12月15日晚:修复了单次运行结束时的校验错误问题 <br>
|
||||||
- 2024年12月18日早:添加了短文本推送机制,一定程度上解决了长字节推送问题(解决办法正在思考中) <br>
|
- 2024年12月18日早:添加了短文本推送机制,一定程度上解决了长字节推送问题(解决办法正在思考中) <br>
|
||||||
- 2024年12月24日晚:上传了测试0.1版本,修复了报错问题 <br>
|
- 2024年12月24日晚:上传了测试0.1版本,修复了报错问题 <br>
|
||||||
|
- 2024年12月25日早:优化了代码逻辑和表现 <br>
|
||||||
|
- 2024年12月25日晚:优化了推送报文格式 <br>
|
BIN
config/__pycache__/check_config.cpython-312.pyc
Normal file
BIN
config/__pycache__/check_config.cpython-312.pyc
Normal file
Binary file not shown.
63
config/check_config.py
Normal file
63
config/check_config.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import yaml
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
# 清除所有已有的日志记录器配置
|
||||||
|
logger.remove()
|
||||||
|
|
||||||
|
logger.add("./log/core.log",
|
||||||
|
format="{time:YYYY-MM-DD HH:mm:ss} - {level} - {name}:{function}:{line} - {message}",
|
||||||
|
rotation="100 MB",
|
||||||
|
compression="zip",
|
||||||
|
encoding="utf-8")
|
||||||
|
# shell终端打印日志
|
||||||
|
logger.add(lambda msg: print(msg),
|
||||||
|
format="{time:YYYY-MM-DD HH:mm:ss} - {level} - {name}:{function}:{line} - {message}")
|
||||||
|
|
||||||
|
def get_core_config():
|
||||||
|
# 加载参数
|
||||||
|
with open('./config/config.yaml', 'r', encoding="utf-8") as file:
|
||||||
|
config = yaml.safe_load(file)
|
||||||
|
logger.debug(f"Loaded config: {config}") # 输出加载的配置
|
||||||
|
|
||||||
|
choice = int(f"{config['circle']}")
|
||||||
|
e_hour = int(config.get('e_hour', '4')) # 默认循环时间为4小时
|
||||||
|
|
||||||
|
fs_activate = f"{config['fs_activate']}"
|
||||||
|
if fs_activate == "True":
|
||||||
|
fs_key = config.get('fs_key')
|
||||||
|
fs_secret = config.get('fs_secret')
|
||||||
|
if not fs_key or not fs_secret:
|
||||||
|
logger.error("飞书相关配置不能为空,请检查配置文件./config/config.yaml")
|
||||||
|
exit(5)
|
||||||
|
|
||||||
|
wx_activate = f"{config['wx_activate']}"
|
||||||
|
if wx_activate == "True":
|
||||||
|
wx_key = config.get('wx_key')
|
||||||
|
if not wx_key:
|
||||||
|
logger.error("企业微信相关配置不能为空,请检查配置文件./config/config.yaml")
|
||||||
|
exit(5)
|
||||||
|
|
||||||
|
ding_activate = f"{config['ding_activate']}"
|
||||||
|
if ding_activate == "True":
|
||||||
|
ding_key = config.get('ding_key')
|
||||||
|
if not ding_key:
|
||||||
|
logger.error("钉钉相关配置不能为空,请检查配置文件./config/config.yaml")
|
||||||
|
exit(5)
|
||||||
|
|
||||||
|
lx_activate = f"{config['lx_activate']}"
|
||||||
|
if lx_activate == "True":
|
||||||
|
lx_key = config.get('lx_key')
|
||||||
|
if not lx_key:
|
||||||
|
logger.error("蓝信相关配置不能为空,请检查配置文件./config/config.yaml")
|
||||||
|
exit(5)
|
||||||
|
|
||||||
|
url_web = f"{config['url']}"
|
||||||
|
|
||||||
|
return e_hour, choice, fs_activate, wx_activate, ding_activate, lx_activate, url_web
|
||||||
|
|
||||||
|
def get_debug_config():
|
||||||
|
with open('./config/config.yaml', 'r', encoding="utf-8") as file:
|
||||||
|
config = yaml.safe_load(file)
|
||||||
|
debug = f"{config['debug']}"
|
||||||
|
|
||||||
|
return debug
|
@ -1,17 +1,19 @@
|
|||||||
# 飞书相关配置信息
|
# 飞书相关配置信息
|
||||||
fs_activate: True
|
fs_activate: True
|
||||||
fs_key: # 此处填写token,记得冒号后空一格,如aa04a02f-d7bf-4279-bd48-44c4f28c8f74
|
fs_key: aa04a02f-d7bf-4279-bd48-44c4f28c8f74 # 此处填写token,记得冒号后空一格,如aa04a02f-d7bf-4279-bd48-44c4f28c8f74
|
||||||
fs_secret: # 此处填写签名密钥,记得冒号后空一格,如4tq65T4jm1MO2IlxvHxBWe
|
fs_secret: 4tq65T4jm1MO2IlxvHxBWe # 此处填写签名密钥,记得冒号后空一格,如4tq65T4jm1MO2IlxvHxBWe
|
||||||
|
|
||||||
# 企业微信相关配置信息
|
# 企业微信相关配置信息
|
||||||
wx_activate: True
|
wx_activate: False
|
||||||
wx_key: # 此处填写token,记得冒号后空一格,如9a3dd6ff-75d6-4208-bc4b-77724a5805d6
|
wx_key: # 此处填写token,记得冒号后空一格,如9a3dd6ff-75d6-4208-bc4b-77724a5805d6
|
||||||
|
|
||||||
# 钉钉相关配置信息
|
# 钉钉相关配置信息
|
||||||
ding_activate: False
|
ding_activate: False
|
||||||
|
ding_key:
|
||||||
|
|
||||||
# 蓝信相关配置信息
|
# 蓝信相关配置信息
|
||||||
lx_activate: False
|
lx_activate: False
|
||||||
|
lx_key:
|
||||||
|
|
||||||
# 邮件配置,邮件推送正在完善中
|
# 邮件配置,邮件推送正在完善中
|
||||||
mail_host: smtp.masonliu.com #设置服务器
|
mail_host: smtp.masonliu.com #设置服务器
|
||||||
@ -21,4 +23,10 @@ sender: test@masonliu.com
|
|||||||
receivers: ['2857911564@qq.com']
|
receivers: ['2857911564@qq.com']
|
||||||
# 结算时间范围
|
# 结算时间范围
|
||||||
e_hour: 4 # 程序运行时间间隔
|
e_hour: 4 # 程序运行时间间隔
|
||||||
circle: 1 # 是否启用循环,设置为0后将设置为特定时间点运行
|
circle: 0 # 是否启用循环,设置为0后将设置为特定时间点运行
|
||||||
|
|
||||||
|
# 网址配置
|
||||||
|
url: https://info.masonliu.com/ # 请设置为您自己反代的域名,或者改为 http://127.0.0.1:5000 或者对应IP域名
|
||||||
|
|
||||||
|
# 调试模式
|
||||||
|
debug: True
|
38
web/app.py
38
web/app.py
@ -1,5 +1,6 @@
|
|||||||
from flask import Flask, jsonify, render_template
|
from flask import Flask, jsonify, render_template
|
||||||
import os
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
@ -8,58 +9,75 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|||||||
PARENT_DIR = os.path.dirname(BASE_DIR) # 上一个文件夹
|
PARENT_DIR = os.path.dirname(BASE_DIR) # 上一个文件夹
|
||||||
SEC_NEWS_PATH = os.path.join(PARENT_DIR, 'history', 'sec_news.md')
|
SEC_NEWS_PATH = os.path.join(PARENT_DIR, 'history', 'sec_news.md')
|
||||||
TECH_PASSAGE_PATH = os.path.join(PARENT_DIR, 'history', 'tech_passage.md')
|
TECH_PASSAGE_PATH = os.path.join(PARENT_DIR, 'history', 'tech_passage.md')
|
||||||
CORE_LOG_PATH = os.path.join(PARENT_DIR, 'log', 'core.log') # 新增日志文件路径
|
CORE_LOG_PATH = os.path.join(PARENT_DIR, 'log', 'core.log')
|
||||||
|
WEB_LOG_PATH = os.path.join(PARENT_DIR, 'log', 'app.log')
|
||||||
|
|
||||||
|
# 配置日志记录器
|
||||||
|
logging.basicConfig(
|
||||||
|
filename=WEB_LOG_PATH,
|
||||||
|
level=logging.INFO,
|
||||||
|
format= '%(asctime)s - %(levelname)s - %(message)s'
|
||||||
|
)
|
||||||
|
|
||||||
# 替换输出内容
|
|
||||||
def replace_content(content):
|
def replace_content(content):
|
||||||
content = content.replace('####', '###')
|
content = content.replace('####', '###')
|
||||||
|
content = content.replace(r"e:\Self-Tool-Code\PyBot", '.') # 修改: 使用原始字符串避免转义问题
|
||||||
return content
|
return content
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
|
logging.info("访问主页")
|
||||||
return render_template('index.html')
|
return render_template('index.html')
|
||||||
|
|
||||||
@app.route('/get-sec-news')
|
@app.route('/get-sec-news')
|
||||||
def get_sec_news():
|
def get_sec_news():
|
||||||
print(f"尝试打开安全新闻历史推送文件: {SEC_NEWS_PATH}")
|
logging.info(f"尝试打开安全新闻历史推送文件: {SEC_NEWS_PATH}")
|
||||||
try:
|
try:
|
||||||
with open(SEC_NEWS_PATH, 'r', encoding='utf-8') as file:
|
with open(SEC_NEWS_PATH, 'r', encoding='utf-8') as file:
|
||||||
content = file.read()
|
content = file.read()
|
||||||
content = replace_content(content)
|
content = replace_content(content)
|
||||||
return jsonify({'content': content}), 200
|
return jsonify({'content': content}), 200
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print(f"文件缺失: {SEC_NEWS_PATH}")
|
logging.error(f"文件缺失: {SEC_NEWS_PATH}")
|
||||||
return jsonify({'error': '安全新闻历史推送文件缺失!'}), 404
|
return jsonify({'error': '安全新闻历史推送文件缺失!'}), 404
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"读取时出错: {SEC_NEWS_PATH}, 原因: {str(e)}")
|
logging.error(f"读取时出错: {SEC_NEWS_PATH}, 原因: {str(e)}")
|
||||||
return jsonify({'error': str(e)}), 500
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
@app.route('/get-tech-passage')
|
@app.route('/get-tech-passage')
|
||||||
def get_tech_passage():
|
def get_tech_passage():
|
||||||
print(f"尝试打开技术文章历史推送文件: {TECH_PASSAGE_PATH}")
|
logging.info(f"尝试打开技术文章历史推送文件: {TECH_PASSAGE_PATH}")
|
||||||
try:
|
try:
|
||||||
with open(TECH_PASSAGE_PATH, 'r', encoding='utf-8') as file:
|
with open(TECH_PASSAGE_PATH, 'r', encoding='utf-8') as file:
|
||||||
content = file.read()
|
content = file.read()
|
||||||
content = replace_content(content)
|
content = replace_content(content)
|
||||||
return jsonify({'content': content}), 200
|
return jsonify({'content': content}), 200
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print(f"文件缺失: {TECH_PASSAGE_PATH}")
|
logging.error(f"文件缺失: {TECH_PASSAGE_PATH}")
|
||||||
return jsonify({'error': '技术文章历史推送文件缺失!'}), 404
|
return jsonify({'error': '技术文章历史推送文件缺失!'}), 404
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"读取时出错: {TECH_PASSAGE_PATH}, 原因: {str(e)}")
|
logging.error(f"读取时出错: {TECH_PASSAGE_PATH}, 原因: {str(e)}")
|
||||||
return jsonify({'error': str(e)}), 500
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
@app.route('/log')
|
@app.route('/log')
|
||||||
def get_log():
|
def get_log():
|
||||||
print(f"尝试打开核心日志文件: {CORE_LOG_PATH}")
|
logging.info(f"尝试打开核心日志文件: {CORE_LOG_PATH}")
|
||||||
# 读取日志文件内容
|
# 读取日志文件内容
|
||||||
with open(CORE_LOG_PATH, 'r', encoding='utf-8') as file:
|
with open(CORE_LOG_PATH, 'r', encoding='utf-8') as file:
|
||||||
log_content = file.read()
|
log_content = file.read()
|
||||||
# 将日志内容传递给模板
|
# 将日志内容传递给模板
|
||||||
return render_template('log.html', log_content=log_content)
|
return render_template('log.html', log_content=log_content)
|
||||||
|
|
||||||
|
@app.route('/weblog')
|
||||||
|
def get_weblog():
|
||||||
|
logging.info(f"尝试打开Web应用日志文件: {WEB_LOG_PATH}")
|
||||||
|
with open(WEB_LOG_PATH, 'r') as file:
|
||||||
|
log_content = file.read()
|
||||||
|
log_content = replace_content(log_content)
|
||||||
|
return render_template('log.html', log_content=log_content)
|
||||||
|
|
||||||
def run_server():
|
def run_server():
|
||||||
app.run(host='0.0.0.0', port=5000)
|
app.run(host='0.0.0.0', port=5000)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(debug=True) # 在生产环境中应设置为 False
|
app.run(debug=False) # 在生产环境中应设置为 False
|
@ -99,7 +99,7 @@
|
|||||||
const htmlContent = marked.parse(data.content);
|
const htmlContent = marked.parse(data.content);
|
||||||
document.getElementById('markdown-content').innerHTML = htmlContent;
|
document.getElementById('markdown-content').innerHTML = htmlContent;
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('markdown-content').innerHTML = '<p>加载历史推送文件时出错!</p>';
|
document.getElementById('markdown-content').innerHTML = '<p>加载历史推送文件时出错!(推送历史记录为空)</p>';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
@ -119,7 +119,7 @@
|
|||||||
const htmlContent = marked.parse(data.content);
|
const htmlContent = marked.parse(data.content);
|
||||||
document.getElementById('markdown-content').innerHTML = htmlContent;
|
document.getElementById('markdown-content').innerHTML = htmlContent;
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('markdown-content').innerHTML = '<p>加载历史推送文件时出错!</p>';
|
document.getElementById('markdown-content').innerHTML = '<p>加载历史推送文件时出错!(推送历史记录为空)</p>';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
Loading…
Reference in New Issue
Block a user