Skip to content

Commit b3727d5

Browse files
authored
Merge pull request #9 from 6vision/feat-0.3
修复天气查询bug,新增热榜,优化帮助信息
2 parents a593aee + 1617535 commit b3727d5

7 files changed

Lines changed: 1322 additions & 43 deletions

File tree

Apilot.py

Lines changed: 123 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def __init__(self):
2525
super().__init__()
2626
try:
2727
self.conf = super().load_config()
28+
self.condition_2_and_3_cities = None # 天气查询,存储重复城市信息,Initially set to None
2829
if not self.conf:
2930
logger.warn("[Apilot] inited but alapi_token not found in config")
3031
self.alapi_token = None # Setting a default value for alapi_token
@@ -40,7 +41,7 @@ def on_handle_context(self, e_context: EventContext):
4041
ContextType.TEXT
4142
]:
4243
return
43-
content = e_context["context"].content
44+
content = e_context["context"].content.strip()
4445
logger.debug("[Apilot] on_handle_context. content: %s" % content)
4546

4647
if content == "早报":
@@ -60,19 +61,29 @@ def on_handle_context(self, e_context: EventContext):
6061
# Extract the part after "快递"
6162
tracking_number = content[2:].strip()
6263

64+
tracking_number = tracking_number.replace(':', ':') # 替换可能出现的中文符号
6365
# Check if alapi_token is available before calling the function
6466
if not self.alapi_token:
6567
self.handle_error("alapi_token not configured", "快递请求失败")
6668
reply = self.create_reply(ReplyType.TEXT, "请先配置alapi的token")
6769
else:
70+
# Check if the tracking_number starts with "SF" for Shunfeng (顺丰) Express
71+
if tracking_number.startswith("SF"):
72+
# Check if the user has included the last four digits of the phone number
73+
if ':' not in tracking_number:
74+
reply = self.create_reply(ReplyType.TEXT, "顺丰快递需要补充寄/收件人手机号后四位,格式:SF12345:0000")
75+
e_context["reply"] = reply
76+
e_context.action = EventAction.BREAK_PASS # 事件结束,并跳过处理context的默认逻辑
77+
return # End the function here
78+
6879
# Call query_express_info function with the extracted tracking_number and the alapi_token from config
6980
content = self.query_express_info(self.alapi_token, tracking_number)
7081
reply = self.create_reply(ReplyType.TEXT, content)
7182
e_context["reply"] = reply
7283
e_context.action = EventAction.BREAK_PASS # 事件结束,并跳过处理context的默认逻辑
7384

74-
match = re.match(r'^([\u4e00-\u9fa5]{2}座)$', content)
75-
if match:
85+
horoscope_match = re.match(r'^([\u4e00-\u9fa5]{2}座)$', content)
86+
if horoscope_match:
7687
if content in ZODIAC_MAPPING:
7788
zodiac_english = ZODIAC_MAPPING[content]
7889
content = self.get_horoscope(zodiac_english)
@@ -82,30 +93,49 @@ def on_handle_context(self, e_context: EventContext):
8293
e_context["reply"] = reply
8394
e_context.action = EventAction.BREAK_PASS # 事件结束,并跳过处理context的默认逻辑
8495

85-
if content == "微博热搜":
86-
content = self.get_weibo_hot_trends()
96+
hot_trend_match = re.search(r'(.{1,6})热榜$', content)
97+
if hot_trend_match:
98+
hot_trends_type = hot_trend_match.group(1).strip() # 提取匹配的组并去掉可能的空格
99+
content = self.get_hot_trends(hot_trends_type)
87100
reply = self.create_reply(ReplyType.TEXT, content)
88101
e_context["reply"] = reply
89102
e_context.action = EventAction.BREAK_PASS # 事件结束,并跳过处理context的默认逻辑
90103

104+
91105
# 天气查询
92-
weather_match = re.search(r'([\u4e00-\u9fa5]{1,6})的?天气$', content)
106+
weather_match = re.search(r'([\u4e00-\u9fa5]{1,6}|\d{1,10})\s*的?天气$', content)
93107
if weather_match:
94-
# 如果匹配成功,提取第一个捕获组(可能包含“的”的城市名)
95-
city_with_optional_de = weather_match.group(1)
96-
# 移除可能存在的“的”
97-
city = city_with_optional_de.replace('的', '')
108+
# 如果匹配成功,提取第一个捕获组
109+
content = weather_match.group(1)
98110
if not self.alapi_token:
99111
self.handle_error("alapi_token not configured", "天气请求失败")
100112
reply = self.create_reply(ReplyType.TEXT, "请先配置alapi的token")
101113
else:
102-
content = self.get_weather(self.alapi_token, city)
114+
content = self.get_weather(self.alapi_token, content)
103115
reply = self.create_reply(ReplyType.TEXT, content)
104116
e_context["reply"] = reply
105117
e_context.action = EventAction.BREAK_PASS # 事件结束,并跳过处理context的默认逻辑
106118

107-
def get_help_text(self, **kwargs):
108-
help_text = "\n🐳发送“早报”、“摸鱼”、“微博热搜”、“星座名称”会有惊喜!\n📦快递查询:<快递+快递单号>\n🌦️天气查询:城市+天气"
119+
def get_help_text(self, verbose=False, **kwargs):
120+
short_help_text = " 发送特定指令以获取早报、查询天气、星座运势、快递信息等!"
121+
122+
if not verbose:
123+
return short_help_text
124+
125+
help_text = "📚 发送关键词获取特定信息!\n"
126+
127+
# 娱乐和信息类
128+
help_text += "\n🎉 娱乐与资讯:\n"
129+
help_text += " 🌅 早报: 发送“早报”获取早报。\n"
130+
help_text += " 🐟 摸鱼: 发送“摸鱼”获取摸鱼人日历。\n"
131+
help_text += " 🔥 热榜: 发送“xx热榜”查看支持的热榜。\n"
132+
133+
# 查询类
134+
help_text += "\n🔍 查询工具:\n"
135+
help_text += " 🌦️ 天气: 发送“城市+天气”查天气,如“北京天气”。\n"
136+
help_text += " 📦 快递: 发送“快递+单号”查询快递状态。如“快递112345655”\n"
137+
help_text += " 🌌 星座: 发送星座名称查看今日运势,如“白羊座”。\n"
138+
109139
return help_text
110140

111141

@@ -150,7 +180,6 @@ def get_moyu_calendar(self):
150180
except Exception as e:
151181
return self.handle_error(e, "获取摸鱼日历信息失败")
152182

153-
154183
def get_horoscope(self, astro_sign: str, time_period: str = "today"):
155184
url = BASE_URL_VVHAN + "horoscope"
156185
params = {
@@ -191,24 +220,33 @@ def get_horoscope(self, astro_sign: str, time_period: str = "today"):
191220
except Exception as e:
192221
return self.handle_error(e, "获取星座信息失败")
193222

194-
195-
def get_weibo_hot_trends(self):
196-
url = BASE_URL_VVHAN + "wbhot"
197-
try:
198-
data = self.make_request(url, "GET")
199-
if isinstance(data, dict) and data['success'] == True:
200-
output = []
201-
topics = data['data']
202-
output.append(f'更新时间:{data["time"]}\n')
203-
for i, topic in enumerate(topics[:15], 1):
204-
formatted_str = f"{i}. {topic['title']} ({topic['hot']} 浏览)\nURL: {topic['url']}\n"
205-
output.append(formatted_str)
206-
return "\n".join(output)
207-
else:
208-
return self.handle_error(data, "热榜获取失败")
209-
except Exception as e:
210-
return self.handle_error(e, "获取热搜失败")
211-
223+
def get_hot_trends(self, hot_trends_type):
224+
# 查找映射字典以获取API参数
225+
hot_trends_type_en = hot_trend_types.get(hot_trends_type, None)
226+
if hot_trends_type_en is not None:
227+
url = BASE_URL_VVHAN + "hotlist?type=" + hot_trends_type_en
228+
try:
229+
data = self.make_request(url, "GET")
230+
if isinstance(data, dict) and data['success'] == True:
231+
output = []
232+
topics = data['data']
233+
output.append(f'更新时间:{data["update_time"]}\n')
234+
for i, topic in enumerate(topics[:15], 1):
235+
hot = topic.get('hot', '无热度参数, 0')
236+
formatted_str = f"{i}. {topic['title']} ({hot} 浏览)\nURL: {topic['url']}\n"
237+
output.append(formatted_str)
238+
return "\n".join(output)
239+
else:
240+
return self.handle_error(data, "热榜获取失败")
241+
except Exception as e:
242+
return self.handle_error(e, "获取热榜失败")
243+
else:
244+
supported_types = "/".join(hot_trend_types.keys())
245+
final_output = (
246+
f"👉 已支持的类型有:\n\n {supported_types}\n"
247+
f"\n📝 请按照以下格式发送:\n 类型+热榜 例如:微博热榜"
248+
)
249+
return final_output
212250

213251
def query_express_info(self, alapi_token, tracking_number, com="", order="asc"):
214252
url = BASE_URL_ALAPI + "kd"
@@ -238,12 +276,28 @@ def query_express_info(self, alapi_token, tracking_number, com="", order="asc"):
238276
except Exception as e:
239277
return self.handle_error(e, "快递查询失败")
240278

241-
def get_weather(self, alapi_token, city: str):
279+
def get_weather(self, alapi_token, city_or_id: str):
242280
url = BASE_URL_ALAPI + 'tianqi'
243-
params = {
244-
'city': city,
245-
'token': f'{alapi_token}' # 请将你的token填在这里
246-
}
281+
# 判断使用id还是city请求api
282+
if city_or_id.isnumeric(): # 判断是否为纯数字,也即是否为 city_id
283+
params = {
284+
'city_id': city_or_id,
285+
'token': f'{alapi_token}'
286+
}
287+
else:
288+
city_info = self.check_multiple_city_ids(city_or_id)
289+
if city_info:
290+
data = city_info['data']
291+
formatted_city_info = "\n".join(
292+
[f"{idx + 1}) {entry['province']}--{entry['leader']}, ID: {entry['city_id']}"
293+
for idx, entry in enumerate(data)]
294+
)
295+
return f"查询 <{city_or_id}> 具有多条数据:\n{formatted_city_info}\n请使用id查询,发送“id天气”"
296+
297+
params = {
298+
'city': city_or_id,
299+
'token': f'{alapi_token}'
300+
}
247301
try:
248302
weather_data = self.make_request(url, "GET", params=params)
249303
if isinstance(weather_data, dict) and weather_data.get('code') == 200:
@@ -330,7 +384,6 @@ def create_reply(self, reply_type, content):
330384
reply.content = content
331385
return reply
332386

333-
334387
def handle_error(self, error, message):
335388
logger.error(f"{message},错误信息:{error}")
336389
return message
@@ -341,6 +394,25 @@ def is_valid_url(self, url):
341394
return all([result.scheme, result.netloc])
342395
except ValueError:
343396
return False
397+
398+
def load_city_conditions(self):
399+
if self.condition_2_and_3_cities is None:
400+
try:
401+
json_file_path = os.path.join(os.path.dirname(__file__), 'duplicate-citys.json')
402+
with open(json_file_path, 'r', encoding='utf-8') as f:
403+
self.condition_2_and_3_cities = json.load(f)
404+
except Exception as e:
405+
return self.handle_error(e, "加载condition_2_and_3_cities.json失败")
406+
407+
408+
def check_multiple_city_ids(self, city):
409+
self.load_city_conditions()
410+
city_info = self.condition_2_and_3_cities.get(city, None)
411+
if city_info:
412+
return city_info
413+
return None
414+
415+
344416
ZODIAC_MAPPING = {
345417
'白羊座': 'aries',
346418
'金牛座': 'taurus',
@@ -355,3 +427,16 @@ def is_valid_url(self, url):
355427
'水瓶座': 'aquarius',
356428
'双鱼座': 'pisces'
357429
}
430+
431+
hot_trend_types = {
432+
"微博": "wbHot",
433+
"虎扑": "huPu",
434+
"知乎": "zhihuHot",
435+
"哔哩哔哩": "bili",
436+
"36氪": "36Ke",
437+
"抖音": "douyinHot",
438+
"少数派": "ssPai",
439+
"IT最新": "itNews",
440+
"IT科技": "itInfo"
441+
442+
}

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@
1818
复制插件目录的`config.json.template`文件并重命名为`config.json`,在`alapi_token`字段填入申请的token,token申请点击这里[alapi](https://admin.alapi.cn/account/center)
1919

2020
### 使用
21-
* 对话框发送“早报”、“摸鱼”、"微博热搜"、”任意星座名称”可以直接返回对应的内容!
21+
* 对话框发送“早报”、“摸鱼”、"微博热搜(已更新为"微博热榜)"、”任意星座名称”可以直接返回对应的内容!
2222

23-
2423

2524
<img src="img/早报.png" width="600" >
2625

@@ -34,13 +33,16 @@
3433

3534
* 快递查询格式:快递+快递编号。如:快递YT2505082504474,如下图!
3635

37-
3836

39-
<img src="img/快递.png" width="600" >
37+
<img src="img/快递.png" width="600" style="display: block; margin: auto;" />
4038

4139

4240

4341
* 天气查询格式:城市+天气。如:成都天气。(支持3400+城市天气,输入不正确或者查询失败返回北京天气)
4442

45-
<img src="img/天气.png" width="600" >
43+
<img src="img/天气.png" width="600" style="display: block; margin: auto;" />
44+
45+
* 热榜查询。支持:<微博/虎扑/知乎/哔哩哔哩/36氪/抖音/少数派/IT最新/IT科技>
46+
47+
<img src="img/热榜.png" width="600" >
4648

0 commit comments

Comments
 (0)