feat:重构代码模块
This commit is contained in:
23
README.md
Normal file
23
README.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# 定时任务
|
||||||
|
|
||||||
|
## 天气任务
|
||||||
|
### API接口
|
||||||
|
  接口地址:[和风天气](https://dev.qweather.com/)
|
||||||
|
|
||||||
|
### 使用说明
|
||||||
|
1. 登录和风天气控制台,点击设置,查看专属API Host。
|
||||||
|
2. 点击项目管理,新建项目,并添加凭据(本项目采用API KEY方式)。
|
||||||
|
3. 查看[接口文档](https://dev.qweather.com/docs/start/),编写业务逻辑。
|
||||||
|
|
||||||
|
## 股票任务
|
||||||
|
### API接口
|
||||||
|
  接口地址:东方财富网:http://push2.eastmoney.com/api/qt/stock/get
|
||||||
|
|
||||||
|
## 企业微信消息推送
|
||||||
|
### 接口文档
|
||||||
|
  [消息推送](https://developer.work.weixin.qq.com/document/path/99110)
|
||||||
|
|
||||||
|
### 使用说明
|
||||||
|
1. 在企业微信群创建消息推送。
|
||||||
|
2. 查看WebHook地址。
|
||||||
|
3. 根据文档编写业务逻辑。
|
||||||
29
main.py
29
main.py
@@ -1,36 +1,28 @@
|
|||||||
import schedule
|
import schedule
|
||||||
import time
|
import time
|
||||||
from log_config import logger
|
from config.log_config import logger
|
||||||
|
|
||||||
from daily_stock import get_stock_message, get_today_stock
|
from work.daily_stock import get_stock_message, get_today_stock
|
||||||
from daily_weather import get_today_indices, get_today_weather, get_weather_message
|
from work.daily_weather import get_today_indices, get_today_weather, get_weather_message
|
||||||
from wechat_message import send_wechat_message
|
from message.wechat_message import send_wechat_message, MessageEnum
|
||||||
|
|
||||||
|
|
||||||
def daily_weather_task():
|
def daily_weather_task():
|
||||||
logger.info("执行定时天气任务...")
|
logger.info("执行定时天气任务...")
|
||||||
weather = get_today_weather()
|
weather = get_today_weather()
|
||||||
indices = get_today_indices()
|
indices = get_today_indices()
|
||||||
message = get_weather_message(weather, indices)
|
send_wechat_message(MessageEnum.MARKDOWN2, get_weather_message(weather, indices), True)
|
||||||
send_wechat_message(message)
|
|
||||||
|
|
||||||
|
|
||||||
def daily_stock_task():
|
def daily_stock_task():
|
||||||
logger.info("执行定时股票任务...")
|
logger.info("执行定时股票任务...")
|
||||||
stock = get_today_stock()
|
stock = get_today_stock()
|
||||||
message = get_stock_message(stock)
|
send_wechat_message(MessageEnum.MARKDOWN, get_stock_message(stock))
|
||||||
send_wechat_message(message)
|
|
||||||
|
|
||||||
|
|
||||||
def daily_order_supper_task():
|
def daily_order_supper_task():
|
||||||
logger.info("执行定时订饭任务...")
|
logger.info("执行定时订饭任务...")
|
||||||
message = {
|
send_wechat_message(MessageEnum.TEXT, "📢 订饭时间到!记得订晚饭~")
|
||||||
"msgtype": "text",
|
|
||||||
"text": {
|
|
||||||
"content": "📢 订饭时间到!记得订晚饭~"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
send_wechat_message(message)
|
|
||||||
|
|
||||||
|
|
||||||
def setup_schedule():
|
def setup_schedule():
|
||||||
@@ -48,9 +40,9 @@ def run_schedule():
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
logger.info("程序启动,开始设置定时任务...")
|
logger.info("程序启动,开始设置定时任务...")
|
||||||
#daily_weather_task()
|
# daily_weather_task()
|
||||||
#daily_stock_task()
|
# daily_stock_task()
|
||||||
#daily_order_supper_task()
|
# daily_order_supper_task()
|
||||||
|
|
||||||
setup_schedule()
|
setup_schedule()
|
||||||
try:
|
try:
|
||||||
@@ -62,5 +54,6 @@ def main():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"程序发生错误: {str(e)}", exc_info=True)
|
logger.error(f"程序发生错误: {str(e)}", exc_info=True)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
40
message/wechat_message.py
Normal file
40
message/wechat_message.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
webhook_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send'
|
||||||
|
webhook_key_estun = 'f09eb098-f709-4fc6-83b5-4a08a8431b8f'
|
||||||
|
webhook_key_sweet_hut = '5ccae111-43a1-4672-a94f-0d34713259c0'
|
||||||
|
|
||||||
|
|
||||||
|
class MessageEnum(Enum):
|
||||||
|
TEXT = 'text'
|
||||||
|
MARKDOWN = 'markdown'
|
||||||
|
MARKDOWN2 = 'markdown2'
|
||||||
|
|
||||||
|
|
||||||
|
def send_wechat_message(message_type: MessageEnum, message: str, has_sweet_hut=False):
|
||||||
|
wechat_message = {}
|
||||||
|
match message_type:
|
||||||
|
case MessageEnum.TEXT:
|
||||||
|
wechat_message = {"msgtype": "text", "text": {"content": message}}
|
||||||
|
case MessageEnum.MARKDOWN:
|
||||||
|
wechat_message = {"msgtype": "markdown", "markdown": {"content": message}}
|
||||||
|
case MessageEnum.MARKDOWN2:
|
||||||
|
wechat_message = {"msgtype": "markdown_v2", "markdown_v2": {"content": message}}
|
||||||
|
|
||||||
|
requests.post(
|
||||||
|
webhook_url,
|
||||||
|
headers={"Content-Type": "application/json"},
|
||||||
|
params={'key': webhook_key_estun},
|
||||||
|
data=json.dumps(wechat_message, ensure_ascii=False).encode('utf-8')
|
||||||
|
)
|
||||||
|
|
||||||
|
if has_sweet_hut:
|
||||||
|
requests.post(
|
||||||
|
webhook_url,
|
||||||
|
headers={"Content-Type": "application/json"},
|
||||||
|
params={'key': webhook_key_sweet_hut},
|
||||||
|
data=json.dumps(wechat_message, ensure_ascii=False).encode('utf-8')
|
||||||
|
)
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import requests
|
|
||||||
import json
|
|
||||||
|
|
||||||
webhook_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send'
|
|
||||||
webhook_key = 'f09eb098-f709-4fc6-83b5-4a08a8431b8f'
|
|
||||||
|
|
||||||
|
|
||||||
def send_wechat_message(message):
|
|
||||||
response = requests.post(
|
|
||||||
webhook_url,
|
|
||||||
headers={
|
|
||||||
"Content-Type": "application/json"
|
|
||||||
},
|
|
||||||
params={'key': webhook_key},
|
|
||||||
data=json.dumps(message, ensure_ascii=False).encode('utf-8')
|
|
||||||
)
|
|
||||||
|
|
||||||
return response.json()
|
|
||||||
@@ -13,7 +13,7 @@ def get_today_stock(company_id=estun_id):
|
|||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
|
|
||||||
def get_stock_message(stock):
|
def get_stock_message(stock) -> str:
|
||||||
# 获取真实数据
|
# 获取真实数据
|
||||||
current_price = stock['data']['f43'] / 100
|
current_price = stock['data']['f43'] / 100
|
||||||
prev_close = stock['data']['f60'] / 100
|
prev_close = stock['data']['f60'] / 100
|
||||||
@@ -25,9 +25,4 @@ def get_stock_message(stock):
|
|||||||
# 根据涨跌确定颜色
|
# 根据涨跌确定颜色
|
||||||
color = "warning" if change_percent < 0 else "info"
|
color = "warning" if change_percent < 0 else "info"
|
||||||
|
|
||||||
return {
|
return f"📈 **埃斯顿(002747)**\n> 现价: <font color=\"{color}\">{current_price}元</font>\n> 涨跌: <font color=\"{color}\">{change_percent_rounded}%</font>"
|
||||||
"msgtype": "markdown",
|
|
||||||
"markdown": {
|
|
||||||
"content": f"📈 **埃斯顿(002747)**\n> 现价: <font color=\"{color}\">{current_price}元</font>\n> 涨跌: <font color=\"{color}\">{change_percent_rounded}%</font>"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
import requests
|
import requests
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
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=nanjing_location):
|
def get_today_weather(city_location=nanjing_location):
|
||||||
|
url = f'{weather_url}/v7/weather/3d'
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
f'{weather_url}v7/weather/3d',
|
url=url,
|
||||||
headers={
|
headers={'X-QW-Api-Key': f'{weather_api_key}'},
|
||||||
'X-QW-Api-Key': f'{weather_api_key}'
|
|
||||||
},
|
|
||||||
params={'location': city_location}
|
params={'location': city_location}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,21 +18,17 @@ def get_today_weather(city_location=nanjing_location):
|
|||||||
|
|
||||||
|
|
||||||
def get_today_indices(city_location=nanjing_location):
|
def get_today_indices(city_location=nanjing_location):
|
||||||
|
url = f'{weather_url}/v7/indices/1d'
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
f'{weather_url}v7/indices/1d',
|
url=url,
|
||||||
headers={
|
headers={'X-QW-Api-Key': f'{weather_api_key}'},
|
||||||
'X-QW-Api-Key': f'{weather_api_key}'
|
params={'location': city_location, 'type': '0'}
|
||||||
},
|
|
||||||
params={
|
|
||||||
'location': city_location,
|
|
||||||
'type': '0'
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
|
|
||||||
def get_weather_message(weather, indices):
|
def get_weather_message(weather, indices) -> str:
|
||||||
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}"
|
||||||
@@ -62,7 +57,7 @@ def get_weather_message(weather, indices):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 构建markdown内容
|
# 构建markdown内容
|
||||||
markdown_content = f"""# 🌤️ 今日天气播报
|
return f"""# 🌤️ 今日天气播报
|
||||||
## 📍 基本信息
|
## 📍 基本信息
|
||||||
**城市:** {weather_data["city"]}
|
**城市:** {weather_data["city"]}
|
||||||
**日期:** {weather_data["date"]}
|
**日期:** {weather_data["date"]}
|
||||||
@@ -75,19 +70,17 @@ def get_weather_message(weather, indices):
|
|||||||
- **风力:** {weather_data["wind"]}
|
- **风力:** {weather_data["wind"]}
|
||||||
|
|
||||||
## 📊 生活指数
|
## 📊 生活指数
|
||||||
| 指数类型 | 等级 | 建议 |
|
😊 **舒适度指数:** {weather_data["life_index"][0]["level"]}
|
||||||
|---------|-----|------|
|
建议:{weather_data["life_index"][0]["advice"]}
|
||||||
| 😊 舒适度指数 | {weather_data["life_index"][0]["level"]} | {weather_data["life_index"][0]["advice"]} |
|
|
||||||
| 👕 穿衣指数 | {weather_data["life_index"][1]["level"]} | {weather_data["life_index"][1]["advice"]} |
|
👕 **穿衣指数:** {weather_data["life_index"][1]["level"]}
|
||||||
| 🏃 运动指数 | {weather_data["life_index"][2]["level"]} | {weather_data["life_index"][2]["advice"]} |
|
建议:{weather_data["life_index"][1]["advice"]}
|
||||||
| 🚗 洗车指数 | {weather_data["life_index"][3]["level"]} | {weather_data["life_index"][3]["advice"]} |
|
|
||||||
|
🏃 **运动指数:** {weather_data["life_index"][2]["level"]}
|
||||||
|
建议:{weather_data["life_index"][2]["advice"]}
|
||||||
|
|
||||||
|
🚗 **洗车指数:** {weather_data["life_index"][3]["level"]}
|
||||||
|
建议:{weather_data["life_index"][3]["advice"]}
|
||||||
|
|
||||||
---
|
---
|
||||||
*数据来源:{weather_data['data_source']}*"""
|
*数据来源:{weather_data['data_source']}*"""
|
||||||
|
|
||||||
return {
|
|
||||||
"msgtype": "markdown_v2",
|
|
||||||
"markdown_v2": {
|
|
||||||
"content": markdown_content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user