From cc8759747c13e278bd7259e60bbebf749199e056 Mon Sep 17 00:00:00 2001 From: Cxx0822 <1556464090@qq.com> Date: Tue, 14 Oct 2025 19:23:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0=E8=82=A1=E7=A5=A8?= =?UTF-8?q?=E5=92=8C=E8=AE=A2=E9=A5=AD=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 9 +++++++ daily_stock.py | 23 +++++++---------- daily_weather.py | 30 ++++++++++----------- log_config.py | 33 ++++++++++++++++++++++++ main.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 6 +++++ wechat_message.py | 4 +-- 7 files changed, 138 insertions(+), 33 deletions(-) create mode 100644 Dockerfile create mode 100644 log_config.py create mode 100644 main.py create mode 100644 requirements.txt diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0d0d423 --- /dev/null +++ b/Dockerfile @@ -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"] diff --git a/daily_stock.py b/daily_stock.py index 92f108b..10e7a00 100644 --- a/daily_stock.py +++ b/daily_stock.py @@ -1,11 +1,10 @@ import requests -from wechat_message import send_wechat_message - stock_url = 'http://push2.eastmoney.com/api/qt/stock/get' estun_id = '0.002747' -def get_today_stock(company_id: str): + +def get_today_stock(company_id=estun_id): response = requests.get( stock_url, params={'secid': company_id} @@ -14,25 +13,21 @@ def get_today_stock(company_id: str): return response.json() -if __name__ == '__main__': - stock = get_today_stock(estun_id) - +def get_stock_message(stock): # 获取真实数据 - current_price = stock['data']['f43'] / 100 + current_price = stock['data']['f43'] / 100 prev_close = stock['data']['f60'] / 100 - + # 计算涨跌幅 change_percent = (current_price - prev_close) / prev_close * 100 change_percent_rounded = round(change_percent, 2) - + # 根据涨跌确定颜色 color = "warning" if change_percent < 0 else "info" - - message = { + + return { "msgtype": "markdown", "markdown": { - "content": f"📈 **埃斯顿(002747)**\n> 现价: {current_price}\n> 涨跌: {change_percent_rounded}%" + "content": f"📈 **埃斯顿(002747)**\n> 现价: {current_price}元\n> 涨跌: {change_percent_rounded}%" } } - - send_wechat_message(message) \ No newline at end of file diff --git a/daily_weather.py b/daily_weather.py index 707ba6a..f65b529 100644 --- a/daily_weather.py +++ b/daily_weather.py @@ -1,14 +1,12 @@ import requests from datetime import datetime -from wechat_message import send_wechat_message - weather_url = 'https://p478kygkjw.re.qweatherapi.com/' weather_api_key = '4aa47f183c694aaa812ff018be8270e4' nanjing_location = '101190101' -def get_today_weather(city_location: int): +def get_today_weather(city_location=nanjing_location): response = requests.get( f'{weather_url}v7/weather/3d', headers={ @@ -20,7 +18,7 @@ def get_today_weather(city_location: int): return response.json() -def get_today_indices(city_location: int): +def get_today_indices(city_location=nanjing_location): response = requests.get( f'{weather_url}v7/indices/1d', headers={ @@ -35,15 +33,11 @@ def get_today_indices(city_location: int): return response.json() -if __name__ == '__main__': - weather = get_today_weather(nanjing_location) - +def get_weather_message(weather, indices): textDay = weather['daily'][0]['textDay'] textNight = weather['daily'][0]['textNight'] weather_desc = textDay if textDay == textNight else f"{textDay}转{textNight}" - indices = get_today_indices(nanjing_location) - # 定义天气数据变量 weather_data = { "city": "南京", @@ -55,11 +49,15 @@ if __name__ == '__main__': "humidity": weather['daily'][0]['humidity'] + "%", "wind": weather['daily'][0]['windDirDay'] + " " + weather['daily'][0]['windScaleDay'] + "级", "life_index": [ - {"type": "舒适度指数", "icon": "😊", "level": indices['daily'][7]['category'], "advice": indices['daily'][7]['text']}, - {"type": "穿衣指数", "icon": "👕", "level": indices['daily'][2]['category'], "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']} - ], + {"type": "舒适度指数", "icon": "😊", "level": indices['daily'][7]['category'], + "advice": indices['daily'][7]['text']}, + {"type": "穿衣指数", "icon": "👕", "level": indices['daily'][2]['category'], + "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": "中央气象台" } @@ -87,11 +85,9 @@ if __name__ == '__main__': --- *数据来源:{weather_data['data_source']}*""" - message = { + return { "msgtype": "markdown_v2", "markdown_v2": { "content": markdown_content } } - - send_wechat_message(message) diff --git a/log_config.py b/log_config.py new file mode 100644 index 0000000..e278841 --- /dev/null +++ b/log_config.py @@ -0,0 +1,33 @@ +import sys + +from loguru import logger + +# 日志格式 +STDOUT_FORMAT = ( + "{time:YYYY-MM-DD HH:mm:ss.SSS} | " + "{level: <8} | " + "{name}:{function}:{line} - " + "{message}" +) + +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"] diff --git a/main.py b/main.py new file mode 100644 index 0000000..62d34c3 --- /dev/null +++ b/main.py @@ -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() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..b7ace55 --- /dev/null +++ b/requirements.txt @@ -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 diff --git a/wechat_message.py b/wechat_message.py index d57e8e0..c6fe32e 100644 --- a/wechat_message.py +++ b/wechat_message.py @@ -5,7 +5,7 @@ webhook_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send' webhook_key = 'f09eb098-f709-4fc6-83b5-4a08a8431b8f' -def send_wechat_message(message: str): +def send_wechat_message(message): response = requests.post( webhook_url, headers={ @@ -15,4 +15,4 @@ def send_wechat_message(message: str): data=json.dumps(message, ensure_ascii=False).encode('utf-8') ) - return response.json() \ No newline at end of file + return response.json()