nonebot-plugin-railwaytools 2.2.4__tar.gz → 2.2.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/PKG-INFO +3 -3
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/README.md +2 -2
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/nonebot_plugin_railwaytools/api.py +2 -1
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/nonebot_plugin_railwaytools/route_info.py +28 -58
- nonebot_plugin_railwaytools-2.2.5/nonebot_plugin_railwaytools/station_info.py +140 -0
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/nonebot_plugin_railwaytools/utils.py +41 -4
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/nonebot_plugin_railwaytools.egg-info/PKG-INFO +3 -3
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/pyproject.toml +1 -1
- nonebot_plugin_railwaytools-2.2.4/nonebot_plugin_railwaytools/station_info.py +0 -142
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/LICENSE +0 -0
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/nonebot_plugin_railwaytools/__init__.py +0 -0
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/nonebot_plugin_railwaytools/emu_function.py +0 -0
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/nonebot_plugin_railwaytools/picture_function.py +0 -0
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/nonebot_plugin_railwaytools/station_screen.py +0 -0
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/nonebot_plugin_railwaytools/train_info.py +0 -0
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/nonebot_plugin_railwaytools.egg-info/SOURCES.txt +0 -0
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/nonebot_plugin_railwaytools.egg-info/dependency_links.txt +0 -0
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/nonebot_plugin_railwaytools.egg-info/requires.txt +0 -0
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/nonebot_plugin_railwaytools.egg-info/top_level.txt +0 -0
- {nonebot_plugin_railwaytools-2.2.4 → nonebot_plugin_railwaytools-2.2.5}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nonebot-plugin-railwaytools
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.5
|
|
4
4
|
Summary: 这是一个火车迷也许觉得很好用的铁路机器人工具箱
|
|
5
5
|
Author-email: leaf2006 <leafdeveloper@qq.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -254,7 +254,6 @@ example:
|
|
|
254
254
|
🤖:
|
|
255
255
|
【宣杭线】线路信息:
|
|
256
256
|
线路类型:普速铁路
|
|
257
|
-
服务类型:客货两用
|
|
258
257
|
单/复线:复线铁路
|
|
259
258
|
设计时速:暂无数据
|
|
260
259
|
|
|
@@ -291,7 +290,6 @@ example:
|
|
|
291
290
|
🤖:
|
|
292
291
|
【上海】基础信息如下:
|
|
293
292
|
电报码:SHH
|
|
294
|
-
拼音码:SHA
|
|
295
293
|
所属路局:中国铁路上海局
|
|
296
294
|
位置:上海市 静安区
|
|
297
295
|
本站办理客运业务
|
|
@@ -312,6 +310,8 @@ example:
|
|
|
312
310
|
数据来源:cnrail.geogv.org
|
|
313
311
|
```
|
|
314
312
|
|
|
313
|
+
由于cnrail的更新,现在还支持查询地铁车站。建议在查询地铁站时,在地铁站名后加“地铁站”二字,方便搜索
|
|
314
|
+
|
|
315
315
|
- 通过车号查询下关站收录的机车户口照:`/下关站` [机车车号] 或 `/xgz` [机车车号] (例如:/下关站 DF7C-5030)
|
|
316
316
|
```
|
|
317
317
|
example:
|
|
@@ -236,7 +236,6 @@ example:
|
|
|
236
236
|
🤖:
|
|
237
237
|
【宣杭线】线路信息:
|
|
238
238
|
线路类型:普速铁路
|
|
239
|
-
服务类型:客货两用
|
|
240
239
|
单/复线:复线铁路
|
|
241
240
|
设计时速:暂无数据
|
|
242
241
|
|
|
@@ -273,7 +272,6 @@ example:
|
|
|
273
272
|
🤖:
|
|
274
273
|
【上海】基础信息如下:
|
|
275
274
|
电报码:SHH
|
|
276
|
-
拼音码:SHA
|
|
277
275
|
所属路局:中国铁路上海局
|
|
278
276
|
位置:上海市 静安区
|
|
279
277
|
本站办理客运业务
|
|
@@ -294,6 +292,8 @@ example:
|
|
|
294
292
|
数据来源:cnrail.geogv.org
|
|
295
293
|
```
|
|
296
294
|
|
|
295
|
+
由于cnrail的更新,现在还支持查询地铁车站。建议在查询地铁站时,在地铁站名后加“地铁站”二字,方便搜索
|
|
296
|
+
|
|
297
297
|
- 通过车号查询下关站收录的机车户口照:`/下关站` [机车车号] 或 `/xgz` [机车车号] (例如:/下关站 DF7C-5030)
|
|
298
298
|
```
|
|
299
299
|
example:
|
|
@@ -7,7 +7,8 @@ class API:
|
|
|
7
7
|
api_EMU_route_schedule = "https://rail.re/img/"
|
|
8
8
|
api_xiaguanzhan = "http://www.xiaguanzhan.com/uploadfiles/"
|
|
9
9
|
api_station_screen = "https://apis.uctb.cn/api/12306?"
|
|
10
|
-
api_cnrail_geogv = "http://cnrail.geogv.org/api/v1/"
|
|
10
|
+
# api_cnrail_geogv = "http://cnrail.geogv.org/api/v1/"
|
|
11
|
+
api_cnrail_geogv = "http://cnrail.geogv.org/api/"
|
|
11
12
|
|
|
12
13
|
headers = { # 加个请求头,保险一点
|
|
13
14
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
|
@@ -43,102 +43,72 @@ async def handle_route_info(event:Event, args: Message = CommandArg()):
|
|
|
43
43
|
if not res_search_data:
|
|
44
44
|
await route_info.finish("未收录该线路或线路不存在,请重新输入!")
|
|
45
45
|
else:
|
|
46
|
-
for
|
|
47
|
-
|
|
46
|
+
for search_results in res_search_data: # 搜索在所有搜索结果中属于“铁路”类别的条目
|
|
47
|
+
search_query = search_results['query']
|
|
48
|
+
search_name = search_results['name']
|
|
49
|
+
if "rail/" in search_query:
|
|
48
50
|
if is_hsr == False:
|
|
49
|
-
if "高速" not in
|
|
51
|
+
if "高速" not in search_name:
|
|
50
52
|
break
|
|
51
53
|
else:
|
|
52
54
|
break
|
|
53
|
-
|
|
54
|
-
rail_id = res_search_data[i][0]
|
|
55
|
+
rail_id = search_query.replace("rail/","") # 去除query中的前缀rail/,这部分将不作为rail_id使用
|
|
55
56
|
|
|
56
|
-
#
|
|
57
|
-
url_route_info = f"{API.api_cnrail_geogv}rail/{rail_id}?locale=zhcn"
|
|
57
|
+
url_route_info = f"{API.api_cnrail_geogv}feature/{rail_id}?locale=zhcn" # 已更新为新版调用方式
|
|
58
58
|
route_info_res = await client.get(url_route_info)
|
|
59
59
|
route_info_raw_data = json.loads(route_info_res.text)
|
|
60
60
|
route_info_data = route_info_raw_data['data']
|
|
61
61
|
|
|
62
62
|
route_info_name = route_info_data['name'] # 线路名称
|
|
63
63
|
|
|
64
|
-
if route_info_data['
|
|
64
|
+
if route_info_data['lines'] == "2": # 线路形态
|
|
65
65
|
route_info_linenum = "复线铁路"
|
|
66
|
-
elif route_info_data['
|
|
66
|
+
elif route_info_data['lines'] == "1":
|
|
67
67
|
route_info_linenum = "单线铁路"
|
|
68
68
|
else:
|
|
69
|
-
route_info_linenum = route_info_data['
|
|
69
|
+
route_info_linenum = route_info_data['lines']
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
design_speed_raw = route_info_data.get("design_speed")
|
|
72
|
+
if not design_speed_raw or str(design_speed_raw).strip().lower() == "null":
|
|
72
73
|
route_info_designSpeed = "暂无数据"
|
|
73
74
|
else:
|
|
74
|
-
route_info_designSpeed =
|
|
75
|
+
route_info_designSpeed = str(design_speed_raw)
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
route_info_railService = "货运"
|
|
78
|
-
elif route_info_data['railService'] == "P":
|
|
79
|
-
route_info_railService = "客运"
|
|
80
|
-
elif route_info_data['railService'] == "PF":
|
|
81
|
-
route_info_railService = "客货两用"
|
|
82
|
-
elif route_info_data['railService'] == "P2F1":
|
|
83
|
-
route_info_railService = "客运为主,兼顾货运"
|
|
84
|
-
else:
|
|
85
|
-
route_info_railService = route_info_data['railService']
|
|
86
|
-
|
|
87
|
-
if route_info_data['railType'] == "CONV": # 线路类型
|
|
88
|
-
route_info_railType = "普速铁路"
|
|
89
|
-
elif route_info_data['railType'] == "RR":
|
|
90
|
-
route_info_railType = "快速铁路"
|
|
91
|
-
elif route_info_data['railType'] == "HSR":
|
|
92
|
-
route_info_railType = "高速铁路"
|
|
93
|
-
else:
|
|
94
|
-
route_info_railType = route_info_data['railType']
|
|
77
|
+
route_info_railType = route_info_data['railtype'] # 新版模式
|
|
95
78
|
|
|
96
|
-
|
|
97
|
-
|
|
79
|
+
# 作者心还怪好的,新版调用方式的那个stations确实比原来的好
|
|
80
|
+
stations_list = route_info_data['stations']
|
|
81
|
+
if not stations_list or stations_list == "null":
|
|
82
|
+
route_info_stations = "暂无沿途车站数据"
|
|
98
83
|
else:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
count_raw_diagram = len(raw_diagram) - 1
|
|
105
|
-
while num < count_raw_diagram:
|
|
106
|
-
if not raw_diagram[num][3] or raw_diagram[num][2] not in ['SST','MST']:
|
|
107
|
-
num += 1
|
|
108
|
-
continue
|
|
109
|
-
|
|
110
|
-
station_name = raw_diagram[num][3][0][2]
|
|
111
|
-
raw_kilometerage = str(raw_diagram[num][1])
|
|
112
|
-
if raw_kilometerage.strip() == "":
|
|
84
|
+
route_info_stations = ""
|
|
85
|
+
for counts in range(len(stations_list)):
|
|
86
|
+
station_name = stations_list[counts]['name']
|
|
87
|
+
kilometerage_raw = stations_list[counts]['mileage']
|
|
88
|
+
if kilometerage_raw is None:
|
|
113
89
|
kilometerage = ""
|
|
114
90
|
else:
|
|
115
|
-
kilometerage = f"{
|
|
116
|
-
|
|
117
|
-
count += 1
|
|
118
|
-
num += 1
|
|
119
|
-
|
|
91
|
+
kilometerage = f"{kilometerage_raw}Km"
|
|
92
|
+
route_info_stations += f"【{str(counts+1)}】{station_name} {kilometerage} \n"
|
|
120
93
|
|
|
94
|
+
# 这里跟随原网站弃用“服务类型”
|
|
121
95
|
route_info_result = Message([
|
|
122
|
-
# "线路名称:",route_info_name,"\n",
|
|
123
96
|
"【",route_info_name,"】线路信息:\n"
|
|
124
97
|
"线路类型:",route_info_railType,"\n",
|
|
125
|
-
"服务类型:",route_info_railService,"\n",
|
|
126
98
|
"单/复线:",route_info_linenum,"\n",
|
|
127
99
|
"设计时速:",route_info_designSpeed,"\n \n",
|
|
128
100
|
"----------沿途车站----------\n",
|
|
129
|
-
|
|
101
|
+
route_info_stations,
|
|
130
102
|
"------------------------------ \n \n",
|
|
131
103
|
"*本表所列起点终点为该线路里程接算站,里程为营业用运价里程,与线路实际运行长度并不相同\n"
|
|
132
104
|
"数据来源:cnrail.geogv.org",
|
|
133
|
-
|
|
134
105
|
])
|
|
135
106
|
|
|
136
107
|
except (httpx.ReadTimeout,httpx.ConnectTimeout):
|
|
137
108
|
route_info_result = "请求超时,请稍等一下再试"
|
|
138
109
|
except Exception as error:
|
|
139
|
-
route_info_result = "发生异常:" + str(error)
|
|
110
|
+
route_info_result = "发生异常:" + str(error) # TODO
|
|
140
111
|
|
|
141
|
-
|
|
142
112
|
await route_info.finish(route_info_result)
|
|
143
113
|
|
|
144
114
|
else:
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Copyright © Leaf developer 2023-2026
|
|
2
|
+
# 本文件负责实现“查询车站信息”功能
|
|
3
|
+
|
|
4
|
+
import httpx
|
|
5
|
+
import json
|
|
6
|
+
from nonebot import on_command
|
|
7
|
+
from nonebot.adapters import Event
|
|
8
|
+
from nonebot.adapters.onebot.v11 import Message, MessageSegment
|
|
9
|
+
from nonebot.plugin import PluginMetadata
|
|
10
|
+
from nonebot.params import CommandArg
|
|
11
|
+
from nonebot.rule import to_me
|
|
12
|
+
from .utils import utils
|
|
13
|
+
from .api import API
|
|
14
|
+
|
|
15
|
+
station_info = on_command("车站",aliases={"cz","车站信息","站"},priority=5,block=True)
|
|
16
|
+
|
|
17
|
+
@station_info.handle()
|
|
18
|
+
async def handle_station_info(event:Event, args: Message = CommandArg()):
|
|
19
|
+
raw_message = str(event.get_message()).strip()
|
|
20
|
+
command_part = utils.get_command_part(raw_message)
|
|
21
|
+
valid_commands = ['车站','cz','车站信息','站']
|
|
22
|
+
if command_part not in valid_commands:
|
|
23
|
+
return
|
|
24
|
+
if station_name_input := args.extract_plain_text():
|
|
25
|
+
is_metro_sta = False
|
|
26
|
+
if "地铁站" in station_name_input:
|
|
27
|
+
station_name_input = station_name_input.replace("地铁站","")
|
|
28
|
+
is_metro_sta = True
|
|
29
|
+
elif "站" in station_name_input: # 防止搜索出现问题
|
|
30
|
+
station_name_input = station_name_input.replace("站","")
|
|
31
|
+
elif "车站" in station_name_input:
|
|
32
|
+
station_name_input = station_name_input.replace("车站","")
|
|
33
|
+
else:
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
async with httpx.AsyncClient(headers=API.headers) as client:
|
|
38
|
+
res_search_data = await utils.cnrail_search(station_name_input)
|
|
39
|
+
if not res_search_data:
|
|
40
|
+
await station_info.finish("未收录该车站或车站不存在,请重新输入!")
|
|
41
|
+
else:
|
|
42
|
+
# 为了适应网站加入了地铁的新特性,将搜索与获取数据两步放在一起,便于对地铁车站与国铁车站重名现象的处理
|
|
43
|
+
sta_info_formatted_data = ""
|
|
44
|
+
for search_results in res_search_data:
|
|
45
|
+
search_query = search_results['query']
|
|
46
|
+
search_name = search_results['name']
|
|
47
|
+
if "geo/" in search_query and station_name_input == search_name:
|
|
48
|
+
sta_id = search_query.replace("geo/","")
|
|
49
|
+
url_sta_info = f"{API.api_cnrail_geogv}poi/{sta_id}?locale=zhcn"
|
|
50
|
+
sta_info_res = await client.get(url_sta_info)
|
|
51
|
+
sta_info_formatted_data = utils.decrypt_cnrail_data(sta_info_res.text)
|
|
52
|
+
|
|
53
|
+
if is_metro_sta == True:
|
|
54
|
+
if sta_info_formatted_data['featureType'] == "地铁站":
|
|
55
|
+
break
|
|
56
|
+
else:
|
|
57
|
+
if sta_info_formatted_data['featureType'] == "火车站":
|
|
58
|
+
break
|
|
59
|
+
|
|
60
|
+
sta_status_judge = sta_info_formatted_data['featureType'] # 上一步判断车站类型是为了筛选重名地铁站,防止误选,这里不是
|
|
61
|
+
if sta_status_judge == "地铁站":
|
|
62
|
+
is_metro_sta = True
|
|
63
|
+
|
|
64
|
+
sta_detail = sta_info_formatted_data['exd'][0]['data']
|
|
65
|
+
# 站名
|
|
66
|
+
if is_metro_sta == True:
|
|
67
|
+
sta_name = sta_info_formatted_data['name'] + "地铁站"
|
|
68
|
+
else:
|
|
69
|
+
sta_name = sta_info_formatted_data['name']
|
|
70
|
+
|
|
71
|
+
# 电报码
|
|
72
|
+
sta_telecode_raw = sta_detail.get("tele_code")
|
|
73
|
+
if not sta_telecode_raw or str(sta_telecode_raw).strip() == "null":
|
|
74
|
+
sta_telecode = ""
|
|
75
|
+
else:
|
|
76
|
+
sta_telecode = f"电报码:{sta_detail['tele_code']}\n"
|
|
77
|
+
|
|
78
|
+
sta_bureau = f"所属单位:{sta_detail['operators'][0]['name']}\n"
|
|
79
|
+
sta_location = f"位置:{sta_info_formatted_data['location']}\n"
|
|
80
|
+
|
|
81
|
+
serviceclass_judge = sta_detail.get('trainservice')
|
|
82
|
+
if is_metro_sta == True:
|
|
83
|
+
sta_serviceclass = "" # 地铁车站特殊处理
|
|
84
|
+
elif not serviceclass_judge and is_metro_sta == False:
|
|
85
|
+
sta_serviceclass = "本站不办理客运业务\n"
|
|
86
|
+
else:
|
|
87
|
+
sta_serviceclass = "本站办理客运业务\n"
|
|
88
|
+
|
|
89
|
+
hr_line = "------------------------------ \n"
|
|
90
|
+
# 沿途车站
|
|
91
|
+
|
|
92
|
+
if not sta_detail.get('connection'):
|
|
93
|
+
sta_route_info = f"{hr_line}暂无该车站线路数据\n"
|
|
94
|
+
else:
|
|
95
|
+
sta_route_data = sta_detail['connection']
|
|
96
|
+
sta_route_info = ""
|
|
97
|
+
for route in sta_route_data:
|
|
98
|
+
linename = route['linename']
|
|
99
|
+
next_data = route['next'][0]
|
|
100
|
+
if next_data.get('adj'): # 如果下一站不是null,则必然有dest_station;如果下一站是null,本站必然是终点站
|
|
101
|
+
next_sta = next_data['adj']['name']
|
|
102
|
+
next_dest_sta = f"({next_data['dest']['name']})方向"
|
|
103
|
+
else:
|
|
104
|
+
if next_data['dest']['status'] == "END":
|
|
105
|
+
next_sta = "起迄站"
|
|
106
|
+
next_dest_sta = ""
|
|
107
|
+
|
|
108
|
+
prev_data = route['prev'][0]
|
|
109
|
+
if prev_data.get('adj'):
|
|
110
|
+
prev_sta = prev_data['adj']['name']
|
|
111
|
+
prev_dest_sta = f"({prev_data['dest']['name']})方向"
|
|
112
|
+
else:
|
|
113
|
+
if prev_data['dest']['status'] == "END":
|
|
114
|
+
prev_sta = "起迄站"
|
|
115
|
+
prev_dest_sta = ""
|
|
116
|
+
|
|
117
|
+
sta_route_info += f"{hr_line}【{linename}】\n下站{next_dest_sta}:{next_sta}\n上站{prev_dest_sta}:{prev_sta}\n"
|
|
118
|
+
# TODO
|
|
119
|
+
|
|
120
|
+
sta_info_result = Message([
|
|
121
|
+
"【",sta_name,"】基础信息如下:\n",
|
|
122
|
+
sta_telecode,
|
|
123
|
+
sta_bureau,
|
|
124
|
+
sta_location,
|
|
125
|
+
sta_serviceclass,
|
|
126
|
+
sta_route_info,
|
|
127
|
+
"------------------------------\n \n",
|
|
128
|
+
"数据来源:cnrail.geogv.org",
|
|
129
|
+
|
|
130
|
+
])
|
|
131
|
+
except (httpx.ReadTimeout,httpx.ConnectTimeout):
|
|
132
|
+
sta_info_result = "请求超时,请稍等一下再试"
|
|
133
|
+
except Exception as error:
|
|
134
|
+
sta_info_result = "发生异常:" + str(error)
|
|
135
|
+
|
|
136
|
+
await station_info.finish(sta_info_result)
|
|
137
|
+
|
|
138
|
+
else:
|
|
139
|
+
await station_info.finish("请输入线路名称")
|
|
140
|
+
|
|
@@ -20,11 +20,10 @@ class utils:
|
|
|
20
20
|
|
|
21
21
|
async def cnrail_search(input_text):
|
|
22
22
|
"""cnrail的搜索模块,获取rail id必用"""
|
|
23
|
-
url_search = f"{API.api_cnrail_geogv}
|
|
23
|
+
url_search = f"{API.api_cnrail_geogv}search?keyword={input_text}"
|
|
24
24
|
async with httpx.AsyncClient(headers=API.headers) as client:
|
|
25
25
|
res_search = await client.get(url_search)
|
|
26
|
-
|
|
27
|
-
res_search_data = res_search_raw_data['data']
|
|
26
|
+
res_search_data = json.loads(res_search.text) # Fixed:适配新版api调用方式
|
|
28
27
|
return res_search_data
|
|
29
28
|
|
|
30
29
|
def get_command_part(raw_message):
|
|
@@ -52,4 +51,42 @@ class utils:
|
|
|
52
51
|
else:
|
|
53
52
|
frame = "No traceback frame"
|
|
54
53
|
exc_only = "".join(te.format_exception_only()).strip()
|
|
55
|
-
return f"{frame}\n{exc_only}"
|
|
54
|
+
return f"{frame}\n{exc_only}"
|
|
55
|
+
|
|
56
|
+
def decrypt_cnrail_data(encrypted_str: str) -> dict:
|
|
57
|
+
"""
|
|
58
|
+
解密 cnrail.geogv.org API 返回的混淆字符串
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
# 如果最外层包着多余的引号,先通过 json.loads 脱掉引号转为正常的内部字符串
|
|
62
|
+
if encrypted_str.startswith('"') and encrypted_str.endswith('"'):
|
|
63
|
+
try:
|
|
64
|
+
encrypted_str = json.loads(encrypted_str)
|
|
65
|
+
except json.JSONDecodeError:
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
if not encrypted_str:
|
|
69
|
+
return "ERR"
|
|
70
|
+
|
|
71
|
+
key_length = ord(encrypted_str[0]) # 第一位字符的 ASCII 码值代表密钥的长度,如结果为\u0007则提取为7
|
|
72
|
+
key = encrypted_str[1:1+key_length] # 紧接着的key_length个字符是密钥
|
|
73
|
+
payload = encrypted_str[1+key_length:] # 剩下的都是加密过的密文
|
|
74
|
+
|
|
75
|
+
# 解密部分
|
|
76
|
+
decrypted_chars = []
|
|
77
|
+
for i, char in enumerate(payload):
|
|
78
|
+
key_char = key[i % len(key)]
|
|
79
|
+
|
|
80
|
+
# 密文字符 ASCII - 密钥字符 ASCII = 原文字符 ASCII
|
|
81
|
+
decrypted_char_code = ord(char) - ord(key_char)
|
|
82
|
+
decrypted_chars.append(chr(decrypted_char_code)) # 由ASCII解密为普通字符串
|
|
83
|
+
|
|
84
|
+
decrypted_str = "".join(decrypted_chars)
|
|
85
|
+
|
|
86
|
+
try:
|
|
87
|
+
return json.loads(decrypted_str)
|
|
88
|
+
except json.JSONDecodeError:
|
|
89
|
+
return "ERR"
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nonebot-plugin-railwaytools
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.5
|
|
4
4
|
Summary: 这是一个火车迷也许觉得很好用的铁路机器人工具箱
|
|
5
5
|
Author-email: leaf2006 <leafdeveloper@qq.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -254,7 +254,6 @@ example:
|
|
|
254
254
|
🤖:
|
|
255
255
|
【宣杭线】线路信息:
|
|
256
256
|
线路类型:普速铁路
|
|
257
|
-
服务类型:客货两用
|
|
258
257
|
单/复线:复线铁路
|
|
259
258
|
设计时速:暂无数据
|
|
260
259
|
|
|
@@ -291,7 +290,6 @@ example:
|
|
|
291
290
|
🤖:
|
|
292
291
|
【上海】基础信息如下:
|
|
293
292
|
电报码:SHH
|
|
294
|
-
拼音码:SHA
|
|
295
293
|
所属路局:中国铁路上海局
|
|
296
294
|
位置:上海市 静安区
|
|
297
295
|
本站办理客运业务
|
|
@@ -312,6 +310,8 @@ example:
|
|
|
312
310
|
数据来源:cnrail.geogv.org
|
|
313
311
|
```
|
|
314
312
|
|
|
313
|
+
由于cnrail的更新,现在还支持查询地铁车站。建议在查询地铁站时,在地铁站名后加“地铁站”二字,方便搜索
|
|
314
|
+
|
|
315
315
|
- 通过车号查询下关站收录的机车户口照:`/下关站` [机车车号] 或 `/xgz` [机车车号] (例如:/下关站 DF7C-5030)
|
|
316
316
|
```
|
|
317
317
|
example:
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
# Copyright © Leaf developer 2023-2026
|
|
2
|
-
# 本文件负责实现“查询车站信息”功能
|
|
3
|
-
|
|
4
|
-
import httpx
|
|
5
|
-
import json
|
|
6
|
-
from nonebot import on_command
|
|
7
|
-
from nonebot.adapters import Event
|
|
8
|
-
from nonebot.adapters.onebot.v11 import Message, MessageSegment
|
|
9
|
-
from nonebot.plugin import PluginMetadata
|
|
10
|
-
from nonebot.params import CommandArg
|
|
11
|
-
from nonebot.rule import to_me
|
|
12
|
-
from .utils import utils
|
|
13
|
-
from .api import API
|
|
14
|
-
|
|
15
|
-
station_info = on_command("车站",aliases={"cz","车站信息","站"},priority=5,block=True)
|
|
16
|
-
|
|
17
|
-
@station_info.handle()
|
|
18
|
-
async def handle_station_info(event:Event, args: Message = CommandArg()):
|
|
19
|
-
raw_message = str(event.get_message()).strip()
|
|
20
|
-
command_part = utils.get_command_part(raw_message)
|
|
21
|
-
valid_commands = ['车站','cz','车站信息','站']
|
|
22
|
-
if command_part not in valid_commands:
|
|
23
|
-
return
|
|
24
|
-
if station_name_input := args.extract_plain_text():
|
|
25
|
-
if "站" in station_name_input: # 防止搜索出现问题
|
|
26
|
-
station_name_input = station_name_input.replace("站","")
|
|
27
|
-
elif "车站" in station_name_input:
|
|
28
|
-
station_name_input = station_name_input("车站","")
|
|
29
|
-
else:
|
|
30
|
-
pass
|
|
31
|
-
|
|
32
|
-
try:
|
|
33
|
-
async with httpx.AsyncClient(headers=API.headers) as client:
|
|
34
|
-
res_search_data = await utils.cnrail_search(station_name_input)
|
|
35
|
-
if not res_search_data:
|
|
36
|
-
await station_info.finish("未收录该车站或车站不存在,请重新输入!")
|
|
37
|
-
else:
|
|
38
|
-
for i in range(len(res_search_data)): # 搜索所有搜索结果中属于“车站”类别的 条目
|
|
39
|
-
if res_search_data[i][2] == station_name_input and res_search_data[i][1] == "STATION":
|
|
40
|
-
continue_search = False
|
|
41
|
-
break
|
|
42
|
-
else:
|
|
43
|
-
continue_search = True
|
|
44
|
-
|
|
45
|
-
if continue_search == True:
|
|
46
|
-
for i in range(len(res_search_data)):
|
|
47
|
-
if res_search_data[i][1] == "STATION":
|
|
48
|
-
break
|
|
49
|
-
else:
|
|
50
|
-
pass
|
|
51
|
-
|
|
52
|
-
rail_id = res_search_data[i][0]
|
|
53
|
-
|
|
54
|
-
url_sta_basic_info = f"{API.api_cnrail_geogv}station/{rail_id}?locale=zhcn&query-override=&requestGeom=true" # 车站基本信息
|
|
55
|
-
url_sta_route_info = f"{API.api_cnrail_geogv}station-link/{rail_id}?locale=zhcn&query-override=" # 车站所属线路
|
|
56
|
-
|
|
57
|
-
sta_basic_info_res = await client.get(url_sta_basic_info)
|
|
58
|
-
sta_basic_info_data = json.loads(sta_basic_info_res.text) # 返回数据直接可以使用,没有套了个"data":{}的壳
|
|
59
|
-
|
|
60
|
-
sta_route_info_res = await client.get(url_sta_route_info)
|
|
61
|
-
sta_route_info_rawdata = json.loads(sta_route_info_res.text)
|
|
62
|
-
|
|
63
|
-
sta_telecode_rawdata = sta_basic_info_data['teleCode'] # 电报码
|
|
64
|
-
sta_pinyincode_rawdata = sta_basic_info_data['pinyinCode'] # 拼音码
|
|
65
|
-
sta_location_rawdata = sta_basic_info_data['location'] # 所在地点
|
|
66
|
-
sta_serviceclass_rawdata = sta_basic_info_data['serviceClass'] # 服务类型
|
|
67
|
-
|
|
68
|
-
sta_name = sta_basic_info_data['localName'] # 车站名称
|
|
69
|
-
sta_bureau = "所属路局:" + sta_basic_info_data['bureau'].get("name") + "\n" # 所属单位
|
|
70
|
-
|
|
71
|
-
if not sta_telecode_rawdata or sta_telecode_rawdata.strip() == "null":
|
|
72
|
-
sta_telecode = ""
|
|
73
|
-
else:
|
|
74
|
-
sta_telecode = f"电报码:{sta_telecode_rawdata}\n"
|
|
75
|
-
|
|
76
|
-
if not sta_pinyincode_rawdata or sta_pinyincode_rawdata.strip() == "null":
|
|
77
|
-
sta_pinyincode = ""
|
|
78
|
-
else:
|
|
79
|
-
sta_pinyincode = f"拼音码:{sta_pinyincode_rawdata}\n"
|
|
80
|
-
|
|
81
|
-
if not sta_location_rawdata or sta_location_rawdata.strip() == "null":
|
|
82
|
-
sta_location = ""
|
|
83
|
-
else:
|
|
84
|
-
sta_location = f"位置:{sta_location_rawdata}\n"
|
|
85
|
-
|
|
86
|
-
if sta_serviceclass_rawdata == "":
|
|
87
|
-
sta_serviceclass = "本站不办理客运业务\n"
|
|
88
|
-
else:
|
|
89
|
-
sta_serviceclass = "本站办理客运业务\n"
|
|
90
|
-
|
|
91
|
-
hr_line = "------------------------------ \n"
|
|
92
|
-
if sta_route_info_rawdata['success'] == False:
|
|
93
|
-
sta_route_info_result = f"{hr_line}暂无该车站线路数据\n"
|
|
94
|
-
else:
|
|
95
|
-
sta_route_info_data = sta_route_info_rawdata['data']
|
|
96
|
-
sta_route_info_result = ""
|
|
97
|
-
for i in range(len(sta_route_info_data)):
|
|
98
|
-
railname = sta_route_info_data[i]['railName']
|
|
99
|
-
|
|
100
|
-
next_station_raw = sta_route_info_data[i]['next'][0][2]
|
|
101
|
-
terminal_station_raw = sta_route_info_data[i]['next'][0][8]
|
|
102
|
-
if next_station_raw == "*" and terminal_station_raw == "*":
|
|
103
|
-
next_station = "起迄站"
|
|
104
|
-
terminal_station = ""
|
|
105
|
-
else:
|
|
106
|
-
next_station = next_station_raw
|
|
107
|
-
terminal_station = f"({terminal_station_raw})方向"
|
|
108
|
-
|
|
109
|
-
prev_station_raw = sta_route_info_data[i]['prev'][0][2]
|
|
110
|
-
starting_station_raw = sta_route_info_data[i]['prev'][0][8]
|
|
111
|
-
if prev_station_raw == "*" and starting_station_raw == "*":
|
|
112
|
-
prev_station = "起迄站"
|
|
113
|
-
starting_station = ""
|
|
114
|
-
else:
|
|
115
|
-
prev_station = prev_station_raw
|
|
116
|
-
starting_station = f"({starting_station_raw})方向"
|
|
117
|
-
|
|
118
|
-
sta_route_info_result += f"{hr_line}【{railname}】\n 下站{terminal_station}:{next_station}\n 上站{starting_station}:{prev_station}\n"
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
sta_info_result = Message([
|
|
122
|
-
"【",sta_name,"】基础信息如下:\n",
|
|
123
|
-
sta_telecode,
|
|
124
|
-
sta_pinyincode,
|
|
125
|
-
sta_bureau,
|
|
126
|
-
sta_location,
|
|
127
|
-
sta_serviceclass,
|
|
128
|
-
sta_route_info_result,
|
|
129
|
-
"------------------------------\n \n",
|
|
130
|
-
"数据来源:cnrail.geogv.org",
|
|
131
|
-
|
|
132
|
-
])
|
|
133
|
-
except (httpx.ReadTimeout,httpx.ConnectTimeout):
|
|
134
|
-
sta_info_result = "请求超时,请稍等一下再试"
|
|
135
|
-
except Exception as error:
|
|
136
|
-
sta_info_result = "发生异常:" + str(error)
|
|
137
|
-
|
|
138
|
-
await station_info.finish(sta_info_result)
|
|
139
|
-
|
|
140
|
-
else:
|
|
141
|
-
await station_info.finish("请输入线路名称")
|
|
142
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|