feat:增加股票和订饭任务
This commit is contained in:
9
Dockerfile
Normal file
9
Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM python:3.12-slim
|
||||||
|
WORKDIR /app
|
||||||
|
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||||
|
RUN echo 'Asia/Shanghai' > /etc/timezone
|
||||||
|
COPY ./packages /app/packages
|
||||||
|
COPY requirements.txt /app/
|
||||||
|
RUN pip install --no-cache-dir --no-index --find-links=/app/packages -r requirements.txt
|
||||||
|
COPY . /app/
|
||||||
|
CMD ["python", "main.py"]
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
import requests
|
import requests
|
||||||
|
|
||||||
from wechat_message import send_wechat_message
|
|
||||||
|
|
||||||
stock_url = 'http://push2.eastmoney.com/api/qt/stock/get'
|
stock_url = 'http://push2.eastmoney.com/api/qt/stock/get'
|
||||||
estun_id = '0.002747'
|
estun_id = '0.002747'
|
||||||
|
|
||||||
def get_today_stock(company_id: str):
|
|
||||||
|
def get_today_stock(company_id=estun_id):
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
stock_url,
|
stock_url,
|
||||||
params={'secid': company_id}
|
params={'secid': company_id}
|
||||||
@@ -14,25 +13,21 @@ def get_today_stock(company_id: str):
|
|||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
def get_stock_message(stock):
|
||||||
stock = get_today_stock(estun_id)
|
|
||||||
|
|
||||||
# 获取真实数据
|
# 获取真实数据
|
||||||
current_price = stock['data']['f43'] / 100
|
current_price = stock['data']['f43'] / 100
|
||||||
prev_close = stock['data']['f60'] / 100
|
prev_close = stock['data']['f60'] / 100
|
||||||
|
|
||||||
# 计算涨跌幅
|
# 计算涨跌幅
|
||||||
change_percent = (current_price - prev_close) / prev_close * 100
|
change_percent = (current_price - prev_close) / prev_close * 100
|
||||||
change_percent_rounded = round(change_percent, 2)
|
change_percent_rounded = round(change_percent, 2)
|
||||||
|
|
||||||
# 根据涨跌确定颜色
|
# 根据涨跌确定颜色
|
||||||
color = "warning" if change_percent < 0 else "info"
|
color = "warning" if change_percent < 0 else "info"
|
||||||
|
|
||||||
message = {
|
return {
|
||||||
"msgtype": "markdown",
|
"msgtype": "markdown",
|
||||||
"markdown": {
|
"markdown": {
|
||||||
"content": f"📈 **埃斯顿(002747)**\n> 现价: <font color=\"{color}\">{current_price}</font>\n> 涨跌: <font color=\"{color}\">{change_percent_rounded}%</font>"
|
"content": f"📈 **埃斯顿(002747)**\n> 现价: <font color=\"{color}\">{current_price}元</font>\n> 涨跌: <font color=\"{color}\">{change_percent_rounded}%</font>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send_wechat_message(message)
|
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
import requests
|
import requests
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from wechat_message import send_wechat_message
|
|
||||||
|
|
||||||
weather_url = 'https://p478kygkjw.re.qweatherapi.com/'
|
weather_url = 'https://p478kygkjw.re.qweatherapi.com/'
|
||||||
weather_api_key = '4aa47f183c694aaa812ff018be8270e4'
|
weather_api_key = '4aa47f183c694aaa812ff018be8270e4'
|
||||||
nanjing_location = '101190101'
|
nanjing_location = '101190101'
|
||||||
|
|
||||||
|
|
||||||
def get_today_weather(city_location: int):
|
def get_today_weather(city_location=nanjing_location):
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
f'{weather_url}v7/weather/3d',
|
f'{weather_url}v7/weather/3d',
|
||||||
headers={
|
headers={
|
||||||
@@ -20,7 +18,7 @@ def get_today_weather(city_location: int):
|
|||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
|
|
||||||
def get_today_indices(city_location: int):
|
def get_today_indices(city_location=nanjing_location):
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
f'{weather_url}v7/indices/1d',
|
f'{weather_url}v7/indices/1d',
|
||||||
headers={
|
headers={
|
||||||
@@ -35,15 +33,11 @@ def get_today_indices(city_location: int):
|
|||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
def get_weather_message(weather, indices):
|
||||||
weather = get_today_weather(nanjing_location)
|
|
||||||
|
|
||||||
textDay = weather['daily'][0]['textDay']
|
textDay = weather['daily'][0]['textDay']
|
||||||
textNight = weather['daily'][0]['textNight']
|
textNight = weather['daily'][0]['textNight']
|
||||||
weather_desc = textDay if textDay == textNight else f"{textDay}转{textNight}"
|
weather_desc = textDay if textDay == textNight else f"{textDay}转{textNight}"
|
||||||
|
|
||||||
indices = get_today_indices(nanjing_location)
|
|
||||||
|
|
||||||
# 定义天气数据变量
|
# 定义天气数据变量
|
||||||
weather_data = {
|
weather_data = {
|
||||||
"city": "南京",
|
"city": "南京",
|
||||||
@@ -55,11 +49,15 @@ if __name__ == '__main__':
|
|||||||
"humidity": weather['daily'][0]['humidity'] + "%",
|
"humidity": weather['daily'][0]['humidity'] + "%",
|
||||||
"wind": weather['daily'][0]['windDirDay'] + " " + weather['daily'][0]['windScaleDay'] + "级",
|
"wind": weather['daily'][0]['windDirDay'] + " " + weather['daily'][0]['windScaleDay'] + "级",
|
||||||
"life_index": [
|
"life_index": [
|
||||||
{"type": "舒适度指数", "icon": "😊", "level": indices['daily'][7]['category'], "advice": indices['daily'][7]['text']},
|
{"type": "舒适度指数", "icon": "😊", "level": indices['daily'][7]['category'],
|
||||||
{"type": "穿衣指数", "icon": "👕", "level": indices['daily'][2]['category'], "advice": indices['daily'][2]['text']},
|
"advice": indices['daily'][7]['text']},
|
||||||
{"type": "运动指数", "icon": "🏃", "level": indices['daily'][0]['category'], "advice": indices['daily'][0]['text']},
|
{"type": "穿衣指数", "icon": "👕", "level": indices['daily'][2]['category'],
|
||||||
{"type": "洗车指数", "icon": "🚗", "level": indices['daily'][1]['category'], "advice": indices['daily'][1]['text']}
|
"advice": indices['daily'][2]['text']},
|
||||||
],
|
{"type": "运动指数", "icon": "🏃", "level": indices['daily'][0]['category'],
|
||||||
|
"advice": indices['daily'][0]['text']},
|
||||||
|
{"type": "洗车指数", "icon": "🚗", "level": indices['daily'][1]['category'],
|
||||||
|
"advice": indices['daily'][1]['text']}
|
||||||
|
],
|
||||||
"data_source": "中央气象台"
|
"data_source": "中央气象台"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,11 +85,9 @@ if __name__ == '__main__':
|
|||||||
---
|
---
|
||||||
*数据来源:{weather_data['data_source']}*"""
|
*数据来源:{weather_data['data_source']}*"""
|
||||||
|
|
||||||
message = {
|
return {
|
||||||
"msgtype": "markdown_v2",
|
"msgtype": "markdown_v2",
|
||||||
"markdown_v2": {
|
"markdown_v2": {
|
||||||
"content": markdown_content
|
"content": markdown_content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send_wechat_message(message)
|
|
||||||
|
|||||||
33
log_config.py
Normal file
33
log_config.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import sys
|
||||||
|
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
# 日志格式
|
||||||
|
STDOUT_FORMAT = (
|
||||||
|
"<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | "
|
||||||
|
"<level>{level: <8}</level> | "
|
||||||
|
"<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - "
|
||||||
|
"<level>{message}</level>"
|
||||||
|
)
|
||||||
|
|
||||||
|
FILE_FORMAT = (
|
||||||
|
"{time:YYYY-MM-DD HH:mm:ss.SSS} | "
|
||||||
|
"{level: <8} | "
|
||||||
|
"{name}:{function}:{line} - {message}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 移除默认处理器
|
||||||
|
logger.remove()
|
||||||
|
|
||||||
|
# 添加控制台处理器
|
||||||
|
logger.add(
|
||||||
|
sink=sys.stdout,
|
||||||
|
level="INFO",
|
||||||
|
format=STDOUT_FORMAT,
|
||||||
|
colorize=True,
|
||||||
|
backtrace=True, # 显示完整异常堆栈
|
||||||
|
diagnose=True, # 显示详细异常信息
|
||||||
|
)
|
||||||
|
|
||||||
|
# 导出配置好的logger
|
||||||
|
__all__ = ["logger"]
|
||||||
66
main.py
Normal file
66
main.py
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import schedule
|
||||||
|
import time
|
||||||
|
from log_config import logger
|
||||||
|
|
||||||
|
from daily_stock import get_stock_message, get_today_stock
|
||||||
|
from daily_weather import get_today_indices, get_today_weather, get_weather_message
|
||||||
|
from wechat_message import send_wechat_message
|
||||||
|
|
||||||
|
|
||||||
|
def daily_weather_task():
|
||||||
|
logger.info("执行定时天气任务...")
|
||||||
|
weather = get_today_weather()
|
||||||
|
indices = get_today_indices()
|
||||||
|
message = get_weather_message(weather, indices)
|
||||||
|
send_wechat_message(message)
|
||||||
|
|
||||||
|
|
||||||
|
def daily_stock_task():
|
||||||
|
logger.info("执行定时股票任务...")
|
||||||
|
stock = get_today_stock()
|
||||||
|
message = get_stock_message(stock)
|
||||||
|
send_wechat_message(message)
|
||||||
|
|
||||||
|
|
||||||
|
def daily_order_supper_task():
|
||||||
|
logger.info("执行定时订饭任务...")
|
||||||
|
message = {
|
||||||
|
"msgtype": "text",
|
||||||
|
"text": {
|
||||||
|
"content": "📢 订饭时间到!记得订晚饭~"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
send_wechat_message(message)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_schedule():
|
||||||
|
schedule.every().day.at("09:00").do(daily_weather_task)
|
||||||
|
schedule.every().day.at("15:30").do(daily_stock_task)
|
||||||
|
schedule.every().day.at("14:00").do(daily_order_supper_task)
|
||||||
|
|
||||||
|
|
||||||
|
def run_schedule():
|
||||||
|
"""运行定时任务"""
|
||||||
|
while True:
|
||||||
|
schedule.run_pending()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
logger.info("程序启动,开始设置定时任务...")
|
||||||
|
#daily_weather_task()
|
||||||
|
#daily_stock_task()
|
||||||
|
#daily_order_supper_task()
|
||||||
|
|
||||||
|
setup_schedule()
|
||||||
|
try:
|
||||||
|
run_schedule()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
logger.info("\n程序被用户中断,正在退出...")
|
||||||
|
schedule.clear()
|
||||||
|
logger.info("所有定时任务已清除")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"程序发生错误: {str(e)}", exc_info=True)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
6
requirements.txt
Normal file
6
requirements.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
schedule~=0.6.0
|
||||||
|
requests~=2.31.0
|
||||||
|
charset-normalizer~=3.3.2
|
||||||
|
loguru~=0.7.3
|
||||||
|
|
||||||
|
# pip download -r requirements.txt -d ./packages --only-binary=:all: --platform manylinux2014_x86_64 --python-version 3.12 --abi cp312 -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
@@ -5,7 +5,7 @@ webhook_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send'
|
|||||||
webhook_key = 'f09eb098-f709-4fc6-83b5-4a08a8431b8f'
|
webhook_key = 'f09eb098-f709-4fc6-83b5-4a08a8431b8f'
|
||||||
|
|
||||||
|
|
||||||
def send_wechat_message(message: str):
|
def send_wechat_message(message):
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
webhook_url,
|
webhook_url,
|
||||||
headers={
|
headers={
|
||||||
@@ -15,4 +15,4 @@ def send_wechat_message(message: str):
|
|||||||
data=json.dumps(message, ensure_ascii=False).encode('utf-8')
|
data=json.dumps(message, ensure_ascii=False).encode('utf-8')
|
||||||
)
|
)
|
||||||
|
|
||||||
return response.json()
|
return response.json()
|
||||||
|
|||||||
Reference in New Issue
Block a user