hyper-bot 0.741__tar.gz → 0.772__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.
Files changed (27) hide show
  1. {hyper-bot-0.741 → hyper-bot-0.772}/Hyper/Adapters/OneBot.py +31 -43
  2. {hyper-bot-0.741 → hyper-bot-0.772}/Hyper/Adapters/OneBotLib/Manager.py +43 -9
  3. hyper-bot-0.772/Hyper/Adapters/OneBotLib/Res.py +90 -0
  4. hyper-bot-0.772/Hyper/Adapters/Satori.py +94 -0
  5. {hyper-bot-0.741 → hyper-bot-0.772}/Hyper/Configurator.py +5 -3
  6. {hyper-bot-0.741 → hyper-bot-0.772}/Hyper/Errors.py +6 -0
  7. {hyper-bot-0.741 → hyper-bot-0.772}/Hyper/Events.py +5 -1
  8. {hyper-bot-0.741 → hyper-bot-0.772}/Hyper/Listener.py +2 -0
  9. {hyper-bot-0.741 → hyper-bot-0.772}/Hyper/Manager.py +2 -0
  10. hyper-bot-0.772/Hyper/Network.py +156 -0
  11. {hyper-bot-0.741 → hyper-bot-0.772}/Hyper/Segments.py +32 -85
  12. hyper-bot-0.772/Hyper/Utils/Logic.py +333 -0
  13. hyper-bot-0.772/Hyper/Utils/TypeExt.py +177 -0
  14. {hyper-bot-0.741 → hyper-bot-0.772}/PKG-INFO +1 -1
  15. {hyper-bot-0.741 → hyper-bot-0.772}/hyper_bot.egg-info/PKG-INFO +1 -1
  16. {hyper-bot-0.741 → hyper-bot-0.772}/hyper_bot.egg-info/SOURCES.txt +4 -3
  17. {hyper-bot-0.741 → hyper-bot-0.772}/setup.py +2 -2
  18. hyper-bot-0.741/Hyper/Logic.py +0 -167
  19. hyper-bot-0.741/Hyper/ModuleClass.py +0 -67
  20. hyper-bot-0.741/Hyper/Network.py +0 -77
  21. hyper-bot-0.741/Hyper/WordSafety.py +0 -40
  22. {hyper-bot-0.741 → hyper-bot-0.772}/Hyper/DataBase.py +0 -0
  23. {hyper-bot-0.741 → hyper-bot-0.772}/Hyper/Logger.py +0 -0
  24. {hyper-bot-0.741 → hyper-bot-0.772}/LICENSE +0 -0
  25. {hyper-bot-0.741 → hyper-bot-0.772}/hyper_bot.egg-info/dependency_links.txt +0 -0
  26. {hyper-bot-0.741 → hyper-bot-0.772}/hyper_bot.egg-info/top_level.txt +0 -0
  27. {hyper-bot-0.741 → hyper-bot-0.772}/setup.cfg +0 -0
@@ -1,15 +1,15 @@
1
1
  import json
2
- import queue
3
2
  import threading
4
3
  import time
5
4
  import asyncio
6
5
  import os
7
6
  from typing import Union
8
7
 
9
- from Hyper import Configurator, Errors, Logger, Logic, Manager, Network, Events
8
+ from Hyper import Errors, Network, Events
9
+ from Hyper.Utils import Logic
10
+ from Hyper.Manager import reports
10
11
  from Hyper.Events import *
11
12
 
12
- reports = queue.Queue()
13
13
  config = Configurator.cm.get_cfg()
14
14
  logger = Logger.Logger()
15
15
  logger.set_level(config.log_level)
@@ -24,20 +24,13 @@ class Actions:
24
24
  self.connection = cnt_i
25
25
 
26
26
  def __getattr__(self, item) -> callable:
27
- def wrapper(no_return: bool, **kwargs) -> Manager.Ret | None:
28
- if no_return:
29
- Manager.Packet(
30
- str(item),
31
- **kwargs
32
- ).send_to(self.connection)
33
- return None
34
- else:
35
- packet = Manager.Packet(
36
- str(item),
37
- **kwargs
38
- )
39
- packet.send_to(self.connection)
40
- return get_ret(packet.echo)
27
+ def wrapper(**kwargs) -> str:
28
+ packet = Manager.Packet(
29
+ str(item),
30
+ **kwargs
31
+ )
32
+ packet.send_to(self.connection)
33
+ return packet.echo
41
34
 
42
35
  return wrapper
43
36
 
@@ -59,8 +52,17 @@ class Actions:
59
52
  )
60
53
  else:
61
54
  raise Errors.ArgsInvalidError("'send' API requires 'group_id' or 'user_id' but none of them are provided.")
62
- packet.send_to(self.connection)
63
- return get_ret(packet.echo)
55
+ retried = 0
56
+ while 1:
57
+ packet.send_to(self.connection)
58
+ result = Manager.Ret.fetch(packet.echo)
59
+ if result.ret_code != 0 or (4 <= len(str(result.data.message_id)) <= 6):
60
+ retried += 1
61
+ if retried >= 5:
62
+ return result
63
+ await asyncio.sleep(1)
64
+ else:
65
+ return result
64
66
 
65
67
  @Logger.AutoLogAsync.register(Logger.AutoLog.templates().recall, logger)
66
68
  async def del_message(self, message_id: int) -> None:
@@ -90,13 +92,13 @@ class Actions:
90
92
  async def get_login_info(self) -> Manager.Ret:
91
93
  packet = Manager.Packet("get_login_info")
92
94
  packet.send_to(self.connection)
93
- return get_ret(packet.echo)
95
+ return Manager.Ret.fetch(packet.echo)
94
96
 
95
97
  @Logic.Cacher().cache_async
96
98
  async def get_version_info(self) -> Manager.Ret:
97
99
  packet = Manager.Packet("get_version_info")
98
100
  packet.send_to(self.connection)
99
- return get_ret(packet.echo)
101
+ return Manager.Ret.fetch(packet.echo)
100
102
 
101
103
  async def send_forward_msg(self, message: Manager.Message) -> Manager.Ret:
102
104
  packet = Manager.Packet(
@@ -104,7 +106,7 @@ class Actions:
104
106
  messages=await message.get()
105
107
  )
106
108
  packet.send_to(self.connection)
107
- return get_ret(packet.echo)
109
+ return Manager.Ret.fetch(packet.echo)
108
110
 
109
111
  async def send_group_forward_msg(self, group_id: int, message: Manager.Message) -> Manager.Ret:
110
112
  packet = Manager.Packet(
@@ -113,7 +115,7 @@ class Actions:
113
115
  messages=await message.get()
114
116
  )
115
117
  packet.send_to(self.connection)
116
- return get_ret(packet.echo)
118
+ return Manager.Ret.fetch(packet.echo)
117
119
 
118
120
  @Logger.AutoLogAsync.register(Logger.AutoLog.templates().set_req, logger)
119
121
  async def set_group_add_request(self, flag: str, sub_type: str, approve: bool, reason: str = "Refused") -> None:
@@ -133,7 +135,7 @@ class Actions:
133
135
  no_cache=True,
134
136
  )
135
137
  packet.send_to(self.connection)
136
- return get_ret(packet.echo)
138
+ return Manager.Ret.fetch(packet.echo)
137
139
 
138
140
  @Logic.Cacher().cache_async
139
141
  async def get_group_member_info(self, group_id: int, user_id: int) -> Manager.Ret:
@@ -144,7 +146,7 @@ class Actions:
144
146
  no_cache=True
145
147
  )
146
148
  packet.send_to(self.connection)
147
- return get_ret(packet.echo)
149
+ return Manager.Ret.fetch(packet.echo)
148
150
 
149
151
  @Logic.Cacher().cache_async
150
152
  async def get_group_info(self, group_id: int) -> Manager.Ret:
@@ -154,12 +156,12 @@ class Actions:
154
156
  no_cache=True
155
157
  )
156
158
  packet.send_to(self.connection)
157
- return get_ret(packet.echo)
159
+ return Manager.Ret.fetch(packet.echo)
158
160
 
159
161
  async def get_status(self) -> Manager.Ret:
160
162
  packet = Manager.Packet("get_status")
161
163
  packet.send_to(self.connection)
162
- return get_ret(packet.echo)
164
+ return Manager.Ret.fetch(packet.echo)
163
165
 
164
166
  @Logger.AutoLogAsync.register(Logger.AutoLog.templates().set_ess, logger)
165
167
  async def set_essence_msg(self, message_id: int) -> None:
@@ -182,7 +184,7 @@ class Actions:
182
184
  message_id=msg_id
183
185
  )
184
186
  packet.send_to(self.connection)
185
- return get_ret(packet.echo)
187
+ return Manager.Ret.fetch(packet.echo)
186
188
 
187
189
 
188
190
  async def tester(message_data: Event, actions: Actions) -> None:
@@ -191,7 +193,7 @@ async def tester(message_data: Event, actions: Actions) -> None:
191
193
 
192
194
  async def __handler(data: dict, actions: Actions) -> None:
193
195
  if data.get("echo") is not None:
194
- reports.put(Manager.Ret(data))
196
+ reports.put(data)
195
197
  elif data.get("post_type") == "meta_event" or data.get("user_id") == data.get("self_id"):
196
198
  pass
197
199
  else:
@@ -208,7 +210,6 @@ async def __handler(data: dict, actions: Actions) -> None:
208
210
 
209
211
 
210
212
  handler: callable = tester
211
- connection: callable = tester
212
213
 
213
214
 
214
215
  def reg(func: callable):
@@ -216,20 +217,7 @@ def reg(func: callable):
216
217
  handler = func
217
218
 
218
219
 
219
- def get_ret(echo: str) -> Manager.Ret:
220
- old = None
221
- while True:
222
- content: Manager.Ret = reports.get()
223
- if old is not None:
224
- reports.put(old)
225
- if content.echo == echo:
226
- return content
227
- else:
228
- old = content
229
-
230
-
231
220
  def run():
232
- global connection
233
221
  try:
234
222
  if handler is tester:
235
223
  raise Errors.ListenerNotRegisteredError("No handler registered")
@@ -1,11 +1,13 @@
1
- from Hyper import Logic, Configurator, Logger, Network
2
- from Hyper.Logger import levels
3
- from Hyper.Segments import *
1
+ import Hyper.Utils.TypeExt
2
+ from Hyper import Configurator, Logger, Network, Segments
3
+ from Hyper.Utils import Logic
4
4
 
5
5
  from typing import Union
6
- import inspect
6
+ import queue
7
7
  import random
8
+ import json
8
9
 
10
+ reports = queue.Queue()
9
11
  config = Configurator.cm.get_cfg()
10
12
  logger = Logger.Logger()
11
13
  logger.set_level(config.log_level)
@@ -33,7 +35,30 @@ class Packet:
33
35
  connection.send(self.endpoint, payload, self.echo)
34
36
 
35
37
 
38
+ class MessageBuilder:
39
+ def __init__(self):
40
+ self.sgs = []
41
+
42
+ def __getattr__(self, item):
43
+ if item == "build":
44
+ def build() -> Message:
45
+ return Message(*self.sgs)
46
+
47
+ return build
48
+
49
+ elif item in Segments.message_types.keys():
50
+ def wrapper(*args, **kwargs):
51
+ self.sgs.append(Segments.message_types[item]["type"](*args, **kwargs))
52
+ return self
53
+
54
+ return wrapper
55
+ else:
56
+ return None
57
+
58
+
36
59
  class Message:
60
+ builder = MessageBuilder()
61
+
37
62
  def __init__(self, *args):
38
63
  if len(args) == 1 and isinstance(args[0], list):
39
64
  contents = args[0]
@@ -47,10 +72,7 @@ class Message:
47
72
  self.contents.append(content)
48
73
 
49
74
  async def get(self) -> list:
50
- ret = []
51
- for i in self.contents:
52
- ret.append(i.to_json())
53
- return ret
75
+ return self.get_sync()
54
76
 
55
77
  def get_sync(self) -> list:
56
78
  ret = []
@@ -93,5 +115,17 @@ class Ret:
93
115
  def __init__(self, json_data: dict):
94
116
  self.status = json_data["status"]
95
117
  self.ret_code = json_data["retcode"]
96
- self.data = json_data.get("data")
118
+ self.data = Hyper.Utils.TypeExt.ObjectedDict(json_data.get("data"))
97
119
  self.echo = json_data.get("echo")
120
+
121
+ @classmethod
122
+ def fetch(cls, echo: str) -> "Ret":
123
+ old = None
124
+ while True:
125
+ content = reports.get()
126
+ if old is not None:
127
+ reports.put(old)
128
+ if content["echo"] == echo:
129
+ return cls(content)
130
+ else:
131
+ old = content
@@ -0,0 +1,90 @@
1
+ message_types = {}
2
+
3
+ def segment_builder(sg_type: str, summary_tmp: str = None):
4
+ # print(inspect.get_annotations(cls))
5
+ def inner_builder(cls):
6
+ var = dict(vars(cls))
7
+ anns: dict = var.get("__annotations__", False) or dict()
8
+
9
+ def init(self, *args, **kwargs):
10
+ arg = {}
11
+ if len(args) > 0:
12
+ for i in args:
13
+ arg[list(anns.keys())[list(args).index(i)]] = i
14
+
15
+ if len(kwargs) > 0:
16
+ for i in kwargs:
17
+ try:
18
+ arg[i] = anns[i](kwargs[i])
19
+ except TypeError:
20
+ arg[i] = kwargs[i]
21
+ new_arg = arg.copy()
22
+
23
+ if len(anns) > len(arg):
24
+ for i in anns.keys():
25
+ if i not in arg.keys():
26
+ if i not in var.keys():
27
+ new_arg[i] = None
28
+ continue
29
+ if not isinstance(var[i], anns[i]):
30
+ new_arg[i] = anns[i](var[i])
31
+ else:
32
+ new_arg[i] = var[i]
33
+
34
+ for i in new_arg:
35
+ setattr(self, i, new_arg[i])
36
+
37
+ cls.__init__ = init
38
+
39
+ def to_json(self) -> dict:
40
+ base = {"type": sg_type, "data": {}}
41
+ for i in anns:
42
+ if getattr(self, i) is None:
43
+ continue
44
+ if not isinstance(getattr(self, i), anns[i]):
45
+ base["data"][i] = anns[i](getattr(self, i))
46
+ else:
47
+ base["data"][i] = getattr(self, i)
48
+ # try:
49
+ # base["data"][i] = anns[i](getattr(self, i))
50
+ # except TypeError:
51
+ # base["data"][i] = getattr(self, i)
52
+ return base
53
+
54
+ cls.to_json = to_json
55
+
56
+ def to_str(self) -> str:
57
+ text = summary_tmp
58
+ if text is None:
59
+ text = "[]"
60
+ if "<" not in text and ">" not in text:
61
+ return text
62
+
63
+ for i in anns:
64
+ if f"<{i}>" in summary_tmp:
65
+ try:
66
+ v = self.__getattribute__(i)
67
+ except AttributeError:
68
+ v = None
69
+ text = text.replace(f"<{i}>", str(v))
70
+
71
+ return text
72
+
73
+ cls.__str__ = to_str if cls().__str__() == "__not_set__" else cls.__str__
74
+
75
+ message_types[sg_type] = {
76
+ "type": cls,
77
+ "args": list(anns.keys())
78
+ }
79
+
80
+ return cls
81
+
82
+ return inner_builder
83
+
84
+
85
+ class Base:
86
+ def __init__(self, *args, **kwargs): ...
87
+
88
+ def to_json(self) -> dict: ...
89
+
90
+ def __str__(self) -> str: return "__not_set__"
@@ -0,0 +1,94 @@
1
+ from Hyper.Adapters.OneBot import *
2
+ from Hyper.Errors import *
3
+
4
+
5
+ class Actions(Actions):
6
+ def __init__(self, cnt: Union[Network.WebsocketConnection, Network.HTTPConnection, Network.SatoriConnection]):
7
+ self.connection = cnt
8
+
9
+ class CustomAction:
10
+ def __init__(self,
11
+ cnt_i: Union[Network.WebsocketConnection, Network.HTTPConnection, Network.SatoriConnection]):
12
+ self.connection = cnt_i
13
+
14
+ def __getattr__(self, item) -> callable:
15
+ def wrapper(**kwargs) -> str:
16
+ packet = Manager.Packet(
17
+ str(item),
18
+ **kwargs
19
+ )
20
+ packet.send_to(self.connection)
21
+ return packet.echo
22
+
23
+ return wrapper
24
+
25
+ self.custom = CustomAction(self.connection)
26
+
27
+
28
+ async def __handler(data: dict, actions: Actions) -> None:
29
+ if data["op"] == 2:
30
+ pass
31
+ else:
32
+ # task = asyncio.create_task(handler(Events.em.new(data), actions))
33
+ # timed = 0
34
+ #
35
+ # while not task.done():
36
+ # await asyncio.sleep(0.1)
37
+ # timed += 0.1
38
+ # if timed >= 30:
39
+ # task.cancel()
40
+ # logger.log(f"处理{task.get_name()}超时", level=Logger.levels.ERROR)
41
+ # break
42
+ print(data)
43
+
44
+
45
+ def reg(func: callable):
46
+ global handler
47
+ handler = func
48
+
49
+
50
+ def run():
51
+ try:
52
+ if handler is tester:
53
+ raise Errors.ListenerNotRegisteredError("No handler registered")
54
+ # connection = websocket.WebSocket()
55
+ if isinstance(config.connection, Configurator.WSConnectionC):
56
+ connection = Network.SatoriConnection(
57
+ config.connection.host, config.connection.port, config.connection.token
58
+ )
59
+ else:
60
+ raise ConfigError
61
+ retried = 0
62
+ while True:
63
+ try:
64
+ connection.connect()
65
+ except ConnectionRefusedError or TimeoutError:
66
+ if retried >= config.connection.retries:
67
+ logger.log(f"重试次数达到最大值({config.connection.retries}),退出", level=Logger.levels.CRITICAL)
68
+ break
69
+
70
+ logger.log(f"连接建立失败,3秒后重试({retried}/{config.connection.retries})",
71
+ level=Logger.levels.WARNING)
72
+ retried += 1
73
+ time.sleep(3)
74
+ continue
75
+ logger.log("成功建立连接", level=Logger.levels.INFO)
76
+ retried = 0
77
+ actions = Actions(connection)
78
+ while True:
79
+ try:
80
+ data = connection.recv()
81
+ except ConnectionResetError:
82
+ logger.log("连接断开", level=Logger.levels.ERROR)
83
+ break
84
+ except json.decoder.JSONDecodeError:
85
+ logger.log("收到错误的JSON内容", level=Logger.levels.ERROR)
86
+ threading.Thread(target=lambda: asyncio.run(__handler(data, actions))).start()
87
+ except KeyboardInterrupt:
88
+ logger.log("正在退出(Ctrl+C)", level=Logger.levels.WARNING)
89
+ try:
90
+ connection.close()
91
+ except:
92
+ pass
93
+ os._exit(0)
94
+
@@ -1,13 +1,14 @@
1
1
  import typing
2
2
 
3
- from Hyper import Logic
3
+ from Hyper.Utils import Logic
4
4
 
5
5
 
6
6
  class WSConnectionC:
7
- def __init__(self, host: str, port: int, retries: int = 0):
7
+ def __init__(self, host: str, port: int, retries: int = 0, satori_token: str = None):
8
8
  self.host: str = host
9
9
  self.port: int = port
10
10
  self.retries: int = retries
11
+ self.token: str = satori_token
11
12
 
12
13
 
13
14
  class HTTPConnectionC:
@@ -55,7 +56,8 @@ class Config:
55
56
  self.connection = WSConnectionC(
56
57
  config_json["Connection"]["host"],
57
58
  config_json["Connection"]["port"],
58
- config_json["Connection"]["retries"]
59
+ config_json["Connection"]["retries"],
60
+ config_json["Connection"]["satori_token"]
59
61
  )
60
62
  elif config_json["Connection"]["mode"] == "HTTP":
61
63
  self.connection = HTTPConnectionC(
@@ -16,3 +16,9 @@ class ListenerNotRegisteredError(Exception):
16
16
  class ArgsInvalidError(Exception):
17
17
  def __init__(self, message: str = None):
18
18
  super().__init__(message)
19
+
20
+
21
+ class ConfigError(Exception):
22
+ def __init__(self, message: str = None):
23
+ super().__init__(message)
24
+
@@ -1,4 +1,5 @@
1
1
  from Hyper import Configurator, Logger, Manager
2
+ from Hyper.Utils.TypeExt import Integer
2
3
  from Hyper.Segments import message_types
3
4
  from Hyper.Logger import levels
4
5
 
@@ -14,10 +15,12 @@ class EventManager:
14
15
  "notice": {},
15
16
  "request": {}
16
17
  }
18
+ self.events = []
17
19
 
18
20
  def reg(self, type_of: str, str_eql: str) -> callable:
19
21
  def wrapper(cls):
20
22
  self.event_lis[type_of][str_eql] = cls
23
+ self.events.append(cls)
21
24
  return cls
22
25
 
23
26
  return wrapper
@@ -88,7 +91,7 @@ class Event:
88
91
  self.user_id = data.get("user_id")
89
92
  self.group_id = data.get("group_id")
90
93
 
91
- self.is_owner = int(self.user_id) in config.owner
94
+ self.is_owner = Integer.convert_from(self.user_id) in config.owner
92
95
  self.servicing = False
93
96
  self.blocked = True if self.user_id in config.black_list or self.group_id in config.black_list else False
94
97
  self.is_silent = self.user_id in config.silents or self.group_id in config.silents or 0 in config.silents
@@ -103,6 +106,7 @@ class MessageEvent(Event):
103
106
  self.sub_type = data.get("sub_type")
104
107
  self.message_id = str(data.get("message_id"))
105
108
  self.message = gen_message(data=data)
109
+ self.msg_str = str(self.message)
106
110
 
107
111
 
108
112
  @em.reg("message", "private")
@@ -4,4 +4,6 @@ config = Configurator.cm.get_cfg()
4
4
 
5
5
  if config.protocol == "OneBot":
6
6
  from Hyper.Adapters.OneBot import *
7
+ elif config.protocol == "Satori":
8
+ from Hyper.Adapters.Satori import *
7
9
  servicing = []
@@ -4,3 +4,5 @@ config = cm.get_cfg()
4
4
 
5
5
  if config.protocol == "OneBot":
6
6
  from Hyper.Adapters.OneBotLib.Manager import *
7
+ elif config.protocol == "Satori":
8
+ from Hyper.Adapters.SatoriLib.Manager import *
@@ -0,0 +1,156 @@
1
+ import asyncio
2
+ import time
3
+ import websocket
4
+ import httpx
5
+ import queue
6
+ import flask
7
+ import traceback
8
+ import json
9
+ import logging
10
+ import threading
11
+
12
+
13
+ class WebsocketConnection:
14
+ def __init__(self, url: str):
15
+ self.ws = websocket.WebSocket()
16
+ self.url = url
17
+
18
+ def connect(self) -> None:
19
+ self.ws.connect(self.url)
20
+
21
+ def send(self, message: str) -> None:
22
+ self.ws.send(message)
23
+
24
+ def close(self) -> None:
25
+ self.ws.close()
26
+
27
+ def recv(self) -> dict:
28
+ return json.loads(self.ws.recv())
29
+
30
+
31
+ class HTTPConnection:
32
+ def __init__(self, url: str, listener_url: str):
33
+ self.url = url
34
+ listener_url = listener_url.replace("http://", "")
35
+ listener_url = listener_url.replace("https://", "")
36
+ self.listener_url = listener_url.split(":")[0]
37
+ try:
38
+ self.port = int(listener_url.split(":")[1])
39
+ except IndexError:
40
+ self.port = 8080
41
+ self.app = flask.Flask(__name__)
42
+ self.app.config["LOGGER_HANDLER_POLICY"] = "never"
43
+ logging.getLogger("werkzeug").setLevel(logging.ERROR)
44
+ self.reports = queue.Queue()
45
+
46
+ self.listener_started = False
47
+
48
+ def __start_listener(self) -> None:
49
+ @self.app.route("/", methods=["POST"])
50
+ def listener():
51
+ self.reports.put(flask.request.json)
52
+ return {}
53
+
54
+ # self.app.run(host=self.listener_url, port=self.port)
55
+
56
+ threading.Thread(target=lambda: self.app.run(host=self.listener_url, port=self.port)).start()
57
+ self.listener_started = True
58
+
59
+ def connect(self) -> None:
60
+ if not self.listener_started:
61
+ self.__start_listener()
62
+ httpx.post(self.url)
63
+ traceback.print_exc()
64
+
65
+ def recv(self) -> dict:
66
+ return self.reports.get()
67
+
68
+ def send(self, endpoint: str, data: dict, echo: str) -> None:
69
+ response = httpx.post(f"{self.url}/{endpoint}", json=data)
70
+ res = response.json()
71
+ res["echo"] = echo
72
+ self.reports.put(res)
73
+
74
+ @staticmethod
75
+ def close() -> None:
76
+ shutdown_func = flask.request.environ.get('werkzeug.server.shutdown')
77
+ if shutdown_func is None:
78
+ raise RuntimeError('Not running with the Werkzeug Server')
79
+ shutdown_func()
80
+
81
+
82
+ class SatoriConnection:
83
+ def __init__(self, host: str, port: int, token: str = None):
84
+ self.ws = websocket.WebSocket()
85
+ self.host = host
86
+ self.port = port
87
+ self.token = token
88
+ self.reports = queue.Queue()
89
+
90
+ def heart_beat(self) -> None:
91
+ while 1:
92
+ time.sleep(10)
93
+ self.ws.send(json.dumps({"op": 1, "body": {}}))
94
+
95
+ def connect(self) -> None:
96
+ self.ws.connect(f"ws://{self.host}:{self.port}/v1/events")
97
+ payload = {
98
+ "op": 3,
99
+ "body": {
100
+ "token": self.token
101
+ }
102
+ }
103
+ self.ws.send(json.dumps(payload))
104
+ res = json.loads(self.ws.recv())
105
+ if res["op"] == 4:
106
+ threading.Thread(target=self.heart_beat).start()
107
+ else:
108
+ raise ConnectionError("连接失败")
109
+
110
+ def send(self, payload: dict, echo: str = None) -> None:
111
+ response = httpx.post(f"http://{self.host}:{self.port}", json=payload)
112
+ try:
113
+ data = response.json()
114
+ data["echo"] = echo
115
+ self.reports.put(data)
116
+ except:
117
+ pass
118
+
119
+ def close(self) -> None:
120
+ pass
121
+
122
+ def recv(self) -> dict:
123
+ return json.loads(self.ws.recv())
124
+
125
+ #
126
+ # class KritorConnection:
127
+ # def __init__(self, host: str, port: int, account: str, ticket: str):
128
+ # self.channel = grpc.insecure_channel(f"{host}:{port}")
129
+ # self.account = account
130
+ # self.ticket = ticket
131
+ #
132
+ # def connect(self) -> None:
133
+ # auth_stub = AuthenticationServiceStub(self.channel)
134
+ # response = auth_stub.Authenticate(
135
+ # AuthenticateRequest(
136
+ # account=self.account,
137
+ # ticket=self.ticket
138
+ # )
139
+ # )
140
+ # if response.AuthenticateResponseCode != 0:
141
+ # raise ConnectionError("鉴权失败")
142
+ #
143
+ # def send(self, stub, payload: dict, echo: str = None) -> None:
144
+ # response = httpx.post(f"http://{self.host}:{self.port}", json=payload)
145
+ # try:
146
+ # data = response.json()
147
+ # data["echo"] = echo
148
+ # self.reports.put(data)
149
+ # except:
150
+ # pass
151
+ #
152
+ # def close(self) -> None:
153
+ # pass
154
+ #
155
+ # def recv(self) -> dict:
156
+ # return json.loads(self.ws.recv())