This commit is contained in:
MasonLiu 2024-12-25 18:40:20 +08:00
parent 163f6cf48d
commit 353f1db25d
19 changed files with 205 additions and 118 deletions

98
Core.py
View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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" # 添加分隔线以便区分不同文章

View File

@ -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)

View File

@ -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" # 添加分隔线以便区分不同文章

View File

@ -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" # 添加分隔线以便区分不同文章

View File

@ -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)

View File

@ -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>

View File

@ -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)

View File

@ -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']}"

View File

@ -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)

View File

@ -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>

Binary file not shown.

63
config/check_config.py Normal file
View 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

View File

@ -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

View File

@ -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

View File

@ -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 => {