天气订阅功能优化
This commit is contained in:
@@ -21,25 +21,25 @@ class WeatherRedisManager:
|
||||
"""处理 Redis 数据存取"""
|
||||
|
||||
def __init__(self, db_manager):
|
||||
self.redis = db_manager
|
||||
self.redis = db_manager.get_redis_connection()
|
||||
self.prefix = "bot:weather:"
|
||||
|
||||
async def add_subscription(self, key: str, data: dict):
|
||||
def add_subscription(self, key: str, data: dict):
|
||||
"""添加订阅 (存入标准城市名和ID)"""
|
||||
redis_key = f"{self.prefix}subs"
|
||||
# 存入 JSON 字符串
|
||||
await self.redis.hset(redis_key, key, json.dumps(data, ensure_ascii=False))
|
||||
self.redis.hset(redis_key, key, json.dumps(data, ensure_ascii=False))
|
||||
|
||||
async def remove_subscription(self, key: str):
|
||||
def remove_subscription(self, key: str):
|
||||
"""取消订阅"""
|
||||
redis_key = f"{self.prefix}subs"
|
||||
await self.redis.hdel(redis_key, key)
|
||||
self.redis.hdel(redis_key, key)
|
||||
|
||||
async def get_all_subscriptions(self) -> Dict[str, dict]:
|
||||
def get_all_subscriptions(self) -> Dict[str, dict]:
|
||||
"""获取所有订阅数据"""
|
||||
redis_key = f"{self.prefix}subs"
|
||||
try:
|
||||
raw_data = await self.redis.hgetall(redis_key)
|
||||
raw_data = self.redis.hgetall(redis_key)
|
||||
result = {}
|
||||
if raw_data:
|
||||
for k, v in raw_data.items():
|
||||
@@ -51,20 +51,20 @@ class WeatherRedisManager:
|
||||
logger.error(f"Redis 读取订阅失败: {e}")
|
||||
return {}
|
||||
|
||||
async def get_history(self, city_id: str) -> Optional[dict]:
|
||||
def get_history(self, city_id: str) -> Optional[dict]:
|
||||
"""获取某城市(ID)昨天的历史数据"""
|
||||
# 注意:这里改用 city_id 作为 Key,确保唯一性
|
||||
redis_key = f"{self.prefix}history:{city_id}"
|
||||
data = await self.redis.get(redis_key)
|
||||
data = self.redis.get(redis_key)
|
||||
if data:
|
||||
return json.loads(data)
|
||||
return None
|
||||
|
||||
async def save_history(self, city_id: str, data: dict):
|
||||
def save_history(self, city_id: str, data: dict):
|
||||
"""保存今天的核心数据 (Key 为 city_id)"""
|
||||
redis_key = f"{self.prefix}history:{city_id}"
|
||||
# 有效期 48 小时
|
||||
await self.redis.set(redis_key, json.dumps(data, ensure_ascii=False), ex=172800)
|
||||
self.redis.set(redis_key, json.dumps(data, ensure_ascii=False), ex=172800)
|
||||
|
||||
|
||||
# ================= 插件主体类 =================
|
||||
@@ -198,7 +198,7 @@ class WeatherPlugin(MessagePluginInterface):
|
||||
"created_at": str(datetime.datetime.now())
|
||||
}
|
||||
|
||||
await self.redis_manager.add_subscription(unique_id, sub_data)
|
||||
self.redis_manager.add_subscription(unique_id, sub_data)
|
||||
|
||||
# 反馈时告诉用户标准名
|
||||
msg = f"✅ 订阅成功!\n已锁定城市:{city_info['adm1']} - {std_city_name}\n每天 08:00 推送早报。"
|
||||
@@ -208,7 +208,7 @@ class WeatherPlugin(MessagePluginInterface):
|
||||
# 使用 ID 获取天气,避免再次 Geo 查询
|
||||
weather_data = await self._fetch_weather_by_id(city_id)
|
||||
if weather_data:
|
||||
await self._save_today_as_history(city_id, weather_data)
|
||||
self._save_today_as_history(city_id, weather_data)
|
||||
|
||||
return True, "订阅成功"
|
||||
|
||||
@@ -216,7 +216,7 @@ class WeatherPlugin(MessagePluginInterface):
|
||||
elif content.startswith("取消订阅"):
|
||||
if not self.redis_manager: return False, "数据库不可用"
|
||||
unique_id = f"{roomid}_{sender}" if roomid else f"private_{sender}"
|
||||
await self.redis_manager.remove_subscription(unique_id)
|
||||
self.redis_manager.remove_subscription(unique_id)
|
||||
await bot.send_text_message(roomid or sender, "✅ 已取消天气订阅。", sender)
|
||||
return True, "取消成功"
|
||||
|
||||
@@ -263,7 +263,7 @@ class WeatherPlugin(MessagePluginInterface):
|
||||
async def _execute_daily_push(self):
|
||||
"""执行全量推送 (基于 ID 聚合)"""
|
||||
self.LOG.info("🚀 执行每日推送...")
|
||||
subs = await self.redis_manager.get_all_subscriptions()
|
||||
subs = self.redis_manager.get_all_subscriptions()
|
||||
if not subs: return
|
||||
|
||||
# 1. 按 [city_id] 聚合 (真正的去重)
|
||||
@@ -289,7 +289,7 @@ class WeatherPlugin(MessagePluginInterface):
|
||||
if not api_data: continue
|
||||
|
||||
# 获取 Redis 历史 (Key 也是 ID)
|
||||
history_data = await self.redis_manager.get_history(city_id)
|
||||
history_data = self.redis_manager.get_history(city_id)
|
||||
|
||||
# 生成文案
|
||||
push_content = self._analyze_weather_change(city_name, api_data, history_data)
|
||||
@@ -312,7 +312,7 @@ class WeatherPlugin(MessagePluginInterface):
|
||||
self.LOG.error(f"推送给 {target_id} 失败: {send_e}")
|
||||
|
||||
# 存档
|
||||
await self._save_today_as_history(city_id, api_data)
|
||||
self._save_today_as_history(city_id, api_data)
|
||||
|
||||
except Exception as e:
|
||||
self.LOG.error(f"处理城市ID {city_id} 推送失败: {e}")
|
||||
@@ -464,7 +464,7 @@ class WeatherPlugin(MessagePluginInterface):
|
||||
self.LOG.error(f"WeatherAPI(ID) 失败: {e}")
|
||||
return None
|
||||
|
||||
async def _save_today_as_history(self, city_id: str, api_data: dict):
|
||||
def _save_today_as_history(self, city_id: str, api_data: dict):
|
||||
"""保存历史 (Key使用 ID)"""
|
||||
if not self.redis_manager: return
|
||||
try:
|
||||
@@ -475,7 +475,7 @@ class WeatherPlugin(MessagePluginInterface):
|
||||
"tempMin": today_fc['tempMin'],
|
||||
"text": today_fc['textDay']
|
||||
}
|
||||
await self.redis_manager.save_history(city_id, data)
|
||||
self.redis_manager.save_history(city_id, data)
|
||||
except Exception as e:
|
||||
self.LOG.error(f"存档失败: {e}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user