dimples 1.2.1__tar.gz → 1.2.4__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 (147) hide show
  1. dimples-1.2.4/LICENSE +21 -0
  2. dimples-1.2.4/PKG-INFO +31 -0
  3. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/network/session.py +2 -2
  4. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/terminal.py +2 -0
  5. {dimples-1.2.1 → dimples-1.2.4}/dimples/conn/flexible.py +25 -9
  6. {dimples-1.2.1 → dimples-1.2.4}/dimples/conn/gatekeeper.py +0 -20
  7. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/dos/base.py +10 -10
  8. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/dos/document.py +3 -3
  9. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/dos/group.py +6 -6
  10. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/dos/group_history.py +2 -2
  11. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/dos/group_keys.py +2 -2
  12. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/dos/login.py +2 -2
  13. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/dos/meta.py +2 -2
  14. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/dos/private.py +14 -14
  15. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/dos/station.py +13 -13
  16. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/dos/user.py +2 -2
  17. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/t_meta.py +1 -1
  18. {dimples-1.2.1 → dimples-1.2.4}/dimples/edge/octopus.py +0 -8
  19. {dimples-1.2.1 → dimples-1.2.4}/dimples/edge/shared.py +26 -6
  20. {dimples-1.2.1 → dimples-1.2.4}/dimples/edge/start.py +7 -3
  21. {dimples-1.2.1 → dimples-1.2.4}/dimples/group/helper.py +1 -1
  22. {dimples-1.2.1 → dimples-1.2.4}/dimples/register/run.py +7 -3
  23. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/archivist.py +3 -2
  24. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/dispatcher.py +0 -8
  25. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/push.py +0 -8
  26. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/session.py +17 -10
  27. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/session_center.py +56 -28
  28. {dimples-1.2.1 → dimples-1.2.4}/dimples/station/handler.py +1 -0
  29. {dimples-1.2.1 → dimples-1.2.4}/dimples/station/shared.py +26 -6
  30. {dimples-1.2.1 → dimples-1.2.4}/dimples/station/start.py +7 -3
  31. {dimples-1.2.1 → dimples-1.2.4}/dimples/utils/__init__.py +2 -1
  32. {dimples-1.2.1 → dimples-1.2.4}/dimples/utils/cache.py +0 -8
  33. {dimples-1.2.1 → dimples-1.2.4}/dimples/utils/log.py +3 -3
  34. dimples-1.2.4/dimples.egg-info/PKG-INFO +31 -0
  35. {dimples-1.2.1 → dimples-1.2.4}/dimples.egg-info/SOURCES.txt +1 -1
  36. {dimples-1.2.1 → dimples-1.2.4}/dimples.egg-info/entry_points.txt +0 -1
  37. {dimples-1.2.1 → dimples-1.2.4}/dimples.egg-info/requires.txt +1 -0
  38. {dimples-1.2.1 → dimples-1.2.4}/setup.py +3 -1
  39. dimples-1.2.1/PKG-INFO +0 -22
  40. dimples-1.2.1/dimples/utils/dos.py +0 -227
  41. dimples-1.2.1/dimples.egg-info/PKG-INFO +0 -22
  42. {dimples-1.2.1 → dimples-1.2.4}/README.md +0 -0
  43. {dimples-1.2.1 → dimples-1.2.4}/dimples/__init__.py +0 -0
  44. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/__init__.py +0 -0
  45. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/archivist.py +0 -0
  46. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/checkpoint.py +0 -0
  47. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/cpu/__init__.py +0 -0
  48. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/cpu/commands.py +0 -0
  49. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/cpu/creator.py +0 -0
  50. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/cpu/group.py +0 -0
  51. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/cpu/grp_expel.py +0 -0
  52. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/cpu/grp_invite.py +0 -0
  53. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/cpu/grp_join.py +0 -0
  54. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/cpu/grp_query.py +0 -0
  55. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/cpu/grp_quit.py +0 -0
  56. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/cpu/grp_reset.py +0 -0
  57. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/cpu/grp_resign.py +0 -0
  58. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/cpu/handshake.py +0 -0
  59. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/facebook.py +0 -0
  60. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/messenger.py +0 -0
  61. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/network/__init__.py +0 -0
  62. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/network/state.py +0 -0
  63. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/network/transition.py +0 -0
  64. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/packer.py +0 -0
  65. {dimples-1.2.1 → dimples-1.2.4}/dimples/client/processor.py +0 -0
  66. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/__init__.py +0 -0
  67. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/anonymous.py +0 -0
  68. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/ans.py +0 -0
  69. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/archivist.py +0 -0
  70. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/compat/__init__.py +0 -0
  71. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/compat/btc.py +0 -0
  72. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/compat/compatible.py +0 -0
  73. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/compat/entity.py +0 -0
  74. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/compat/meta.py +0 -0
  75. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/compat/network.py +0 -0
  76. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/dbi/__init__.py +0 -0
  77. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/dbi/account.py +0 -0
  78. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/dbi/message.py +0 -0
  79. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/dbi/session.py +0 -0
  80. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/facebook.py +0 -0
  81. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/messenger.py +0 -0
  82. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/packer.py +0 -0
  83. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/processer.py +0 -0
  84. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/protocol/__init__.py +0 -0
  85. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/protocol/ans.py +0 -0
  86. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/protocol/block.py +0 -0
  87. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/protocol/handshake.py +0 -0
  88. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/protocol/login.py +0 -0
  89. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/protocol/mute.py +0 -0
  90. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/protocol/report.py +0 -0
  91. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/register.py +0 -0
  92. {dimples-1.2.1 → dimples-1.2.4}/dimples/common/session.py +0 -0
  93. {dimples-1.2.1 → dimples-1.2.4}/dimples/conn/__init__.py +0 -0
  94. {dimples-1.2.1 → dimples-1.2.4}/dimples/conn/gate.py +0 -0
  95. {dimples-1.2.1 → dimples-1.2.4}/dimples/conn/mars.py +0 -0
  96. {dimples-1.2.1 → dimples-1.2.4}/dimples/conn/mtp.py +0 -0
  97. {dimples-1.2.1 → dimples-1.2.4}/dimples/conn/protocol/__init__.py +0 -0
  98. {dimples-1.2.1 → dimples-1.2.4}/dimples/conn/protocol/mars.py +0 -0
  99. {dimples-1.2.1 → dimples-1.2.4}/dimples/conn/protocol/ws.py +0 -0
  100. {dimples-1.2.1 → dimples-1.2.4}/dimples/conn/queue.py +0 -0
  101. {dimples-1.2.1 → dimples-1.2.4}/dimples/conn/seeker.py +0 -0
  102. {dimples-1.2.1 → dimples-1.2.4}/dimples/conn/session.py +0 -0
  103. {dimples-1.2.1 → dimples-1.2.4}/dimples/conn/ws.py +0 -0
  104. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/__init__.py +0 -0
  105. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/account.py +0 -0
  106. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/dos/__init__.py +0 -0
  107. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/message.py +0 -0
  108. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/session.py +0 -0
  109. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/t_cipherkey.py +0 -0
  110. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/t_document.py +0 -0
  111. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/t_group.py +0 -0
  112. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/t_group_history.py +0 -0
  113. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/t_group_keys.py +0 -0
  114. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/t_login.py +0 -0
  115. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/t_message.py +0 -0
  116. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/t_private.py +0 -0
  117. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/t_station.py +0 -0
  118. {dimples-1.2.1 → dimples-1.2.4}/dimples/database/t_user.py +0 -0
  119. {dimples-1.2.1 → dimples-1.2.4}/dimples/edge/__init__.py +0 -0
  120. {dimples-1.2.1 → dimples-1.2.4}/dimples/group/__init__.py +0 -0
  121. {dimples-1.2.1 → dimples-1.2.4}/dimples/group/admin.py +0 -0
  122. {dimples-1.2.1 → dimples-1.2.4}/dimples/group/builder.py +0 -0
  123. {dimples-1.2.1 → dimples-1.2.4}/dimples/group/delegate.py +0 -0
  124. {dimples-1.2.1 → dimples-1.2.4}/dimples/group/emitter.py +0 -0
  125. {dimples-1.2.1 → dimples-1.2.4}/dimples/group/manager.py +0 -0
  126. {dimples-1.2.1 → dimples-1.2.4}/dimples/group/packer.py +0 -0
  127. {dimples-1.2.1 → dimples-1.2.4}/dimples/register/__init__.py +0 -0
  128. {dimples-1.2.1 → dimples-1.2.4}/dimples/register/base.py +0 -0
  129. {dimples-1.2.1 → dimples-1.2.4}/dimples/register/ext.py +0 -0
  130. {dimples-1.2.1 → dimples-1.2.4}/dimples/register/shared.py +0 -0
  131. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/__init__.py +0 -0
  132. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/cpu/__init__.py +0 -0
  133. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/cpu/ans.py +0 -0
  134. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/cpu/document.py +0 -0
  135. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/cpu/handshake.py +0 -0
  136. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/cpu/login.py +0 -0
  137. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/cpu/report.py +0 -0
  138. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/messenger.py +0 -0
  139. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/packer.py +0 -0
  140. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/processor.py +0 -0
  141. {dimples-1.2.1 → dimples-1.2.4}/dimples/server/trace.py +0 -0
  142. {dimples-1.2.1 → dimples-1.2.4}/dimples/station/__init__.py +0 -0
  143. {dimples-1.2.1 → dimples-1.2.4}/dimples/utils/config.py +0 -0
  144. {dimples-1.2.1 → dimples-1.2.4}/dimples/utils/runner.py +0 -0
  145. {dimples-1.2.1 → dimples-1.2.4}/dimples.egg-info/dependency_links.txt +0 -0
  146. {dimples-1.2.1 → dimples-1.2.4}/dimples.egg-info/top_level.txt +0 -0
  147. {dimples-1.2.1 → dimples-1.2.4}/setup.cfg +0 -0
dimples-1.2.4/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Albert Moky
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
dimples-1.2.4/PKG-INFO ADDED
@@ -0,0 +1,31 @@
1
+ Metadata-Version: 2.1
2
+ Name: dimples
3
+ Version: 1.2.4
4
+ Summary: DIMP Library for Edges and Stations
5
+ Home-page: https://github.com/dimchat/demo-py
6
+ Author: Albert Moky
7
+ Author-email: albert.moky@gmail.com
8
+ License: MIT
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: dimplugins>=2.0.0
15
+ Requires-Dist: dimsdk>=2.0.0
16
+ Requires-Dist: dimp>=2.0.0
17
+ Requires-Dist: dkd>=2.0.0
18
+ Requires-Dist: mkm>=2.0.0
19
+ Requires-Dist: startrek>=2.1.1
20
+ Requires-Dist: tcp>=2.1.1
21
+ Requires-Dist: udp>=2.1.1
22
+ Requires-Dist: aiou>=0.1.0
23
+
24
+ # DIMP Library for Edges and Stations (Python version)
25
+
26
+ [![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/dimchat/demo-py/blob/master/LICENSE)
27
+ [![Version](https://img.shields.io/badge/alpha-0.1.0-red.svg)](https://github.com/dimchat/demo-py/wiki)
28
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/dimchat/demo-py/pulls)
29
+ [![Platform](https://img.shields.io/badge/Platform-Python%203-brightgreen.svg)](https://github.com/dimchat/demo-py/wiki)
30
+
31
+ Copyright © 2018-2022 Albert Moky
@@ -147,7 +147,7 @@ class ClientSession(BaseSession):
147
147
 
148
148
  # Override
149
149
  async def docker_status_changed(self, previous: DockerStatus, current: DockerStatus, docker: Docker):
150
- # super().docker_status_changed(previous=previous, current=current, docker=docker)
150
+ # await super().docker_status_changed(previous=previous, current=current, docker=docker)
151
151
  if current is None or current == DockerStatus.ERROR:
152
152
  # connection error or session finished
153
153
  self.set_active(active=False)
@@ -159,7 +159,7 @@ class ClientSession(BaseSession):
159
159
 
160
160
  # Override
161
161
  async def docker_received(self, ship: Arrival, docker: Docker):
162
- # super().docker_received(ship=ship, docker=docker)
162
+ # await super().docker_received(ship=ship, docker=docker)
163
163
  all_responses = []
164
164
  messenger = self.messenger
165
165
  # 1. get data packages from arrival ship's payload
@@ -75,6 +75,7 @@ class Terminal(Runner, DeviceMixin, Logging, StateDelegate):
75
75
 
76
76
  # Override
77
77
  async def setup(self):
78
+ await super().setup()
78
79
  session = self.session
79
80
  session.fsm.delegate = self
80
81
  await session.start()
@@ -82,6 +83,7 @@ class Terminal(Runner, DeviceMixin, Logging, StateDelegate):
82
83
  # Override
83
84
  async def finish(self):
84
85
  await self.session.stop()
86
+ await super().finish()
85
87
 
86
88
  # Override
87
89
  async def process(self) -> bool:
@@ -36,6 +36,7 @@ from startrek import Connection
36
36
  from startrek import Arrival, Departure
37
37
  from startrek import StarDocker
38
38
 
39
+ from ..utils import Logging
39
40
  from .protocol import DeparturePacker
40
41
 
41
42
  from .ws import WSDocker
@@ -43,7 +44,7 @@ from .mtp import MTPStreamDocker, TransactionID, MTPHelper
43
44
  from .mars import MarsStreamDocker, MarsHelper
44
45
 
45
46
 
46
- class FlexibleDocker(StarDocker, DeparturePacker):
47
+ class FlexibleDocker(StarDocker, DeparturePacker, Logging):
47
48
 
48
49
  def __init__(self, remote: SocketAddress, local: Optional[SocketAddress]):
49
50
  super().__init__(remote=remote, local=local)
@@ -61,7 +62,7 @@ class FlexibleDocker(StarDocker, DeparturePacker):
61
62
  elif MarsStreamDocker.check(data=data):
62
63
  docker = MarsStreamDocker(remote=self.remote_address, local=self.local_address)
63
64
  else:
64
- print('[FlexibleDocker] unsupported data format: %s' % data)
65
+ self.error(msg='unsupported data format: %s' % data)
65
66
  return None
66
67
  # OK
67
68
  docker.delegate = self.delegate
@@ -74,19 +75,26 @@ class FlexibleDocker(StarDocker, DeparturePacker):
74
75
  async def set_connection(self, conn: Optional[Connection]):
75
76
  await super().set_connection(conn=conn)
76
77
  docker = self.__docker
77
- if docker is not None:
78
+ if docker is None:
79
+ self.error(msg='docker not ready, failed to set connection: %s' % conn)
80
+ else:
78
81
  await docker.set_connection(conn=conn)
79
82
 
80
83
  # Override
81
84
  async def send_ship(self, ship: Departure) -> bool:
82
85
  docker = self.__docker
83
- if docker is not None:
86
+ if docker is None:
87
+ self.error(msg='docker not ready, failed to send ship: %s' % ship)
88
+ return False
89
+ else:
84
90
  return await docker.send_ship(ship=ship)
85
91
 
86
92
  # Override
87
93
  async def process_received(self, data: bytes):
88
94
  docker = self._get_docker(data=data)
89
- if docker is not None:
95
+ if docker is None:
96
+ self.error(msg='docker not ready, failed to process received: %s' % data)
97
+ else:
90
98
  return await docker.process_received(data=data)
91
99
 
92
100
  # Override
@@ -113,7 +121,9 @@ class FlexibleDocker(StarDocker, DeparturePacker):
113
121
  def purge(self, now: float = 0) -> int:
114
122
  cnt = super().purge(now=now)
115
123
  docker = self.__docker
116
- if docker is not None:
124
+ if docker is None:
125
+ self.warning(msg='docker not ready, failed to purge')
126
+ else:
117
127
  cnt += docker.purge(now=now)
118
128
  return cnt
119
129
 
@@ -128,14 +138,17 @@ class FlexibleDocker(StarDocker, DeparturePacker):
128
138
  # Override
129
139
  async def process(self) -> bool:
130
140
  docker = self.__docker
131
- if docker is not None:
141
+ if docker is None:
142
+ self.warning(msg='docker not ready, failed to process')
143
+ return False
144
+ else:
132
145
  return await docker.process()
133
146
 
134
147
  # Override
135
148
  async def send_data(self, payload: Union[bytes, bytearray]) -> bool:
136
149
  docker = self.__docker
137
150
  if docker is None:
138
- # docker not ready
151
+ self.error(msg='docker not ready, failed to send payload: %s' % payload)
139
152
  return False
140
153
  elif isinstance(docker, WSDocker):
141
154
  ship = docker.pack(payload=payload)
@@ -156,13 +169,16 @@ class FlexibleDocker(StarDocker, DeparturePacker):
156
169
  # Override
157
170
  async def heartbeat(self):
158
171
  docker = self.__docker
159
- if docker is not None:
172
+ if docker is None:
173
+ self.warning(msg='docker not ready, failed to heart bet')
174
+ else:
160
175
  await docker.heartbeat()
161
176
 
162
177
  # Override
163
178
  def pack(self, payload: bytes, priority: int = 0) -> Optional[Departure]:
164
179
  docker = self.__docker
165
180
  if docker is None:
181
+ self.error(msg='docker not ready, failed to pack: %s' % payload)
166
182
  return None
167
183
  else:
168
184
  assert isinstance(docker, DeparturePacker), 'docker error: %s' % docker
@@ -220,26 +220,6 @@ class GateKeeper(Runner, DockerDelegate, Logging):
220
220
  self.__last_active = when
221
221
  return True
222
222
 
223
- # @property # Override
224
- # def running(self) -> bool:
225
- # if super().running:
226
- # return self.gate.running
227
- #
228
- # # Override
229
- # async def stop(self):
230
- # await super().stop()
231
- # await self.gate.stop()
232
-
233
- # Override
234
- async def setup(self):
235
- # await self.gate.start()
236
- pass
237
-
238
- # Override
239
- async def finish(self):
240
- # await self.gate.stop()
241
- pass
242
-
243
223
  # Override
244
224
  async def process(self) -> bool:
245
225
  gate = self.gate
@@ -85,37 +85,37 @@ class Storage:
85
85
  return Path.join(self._public, template)
86
86
 
87
87
  @classmethod
88
- def read_text(cls, path: str) -> Optional[str]:
88
+ async def read_text(cls, path: str) -> Optional[str]:
89
89
  try:
90
- return TextFile(path=path).read()
90
+ return await TextFile(path=path).read()
91
91
  except Exception as error:
92
92
  Log.error(msg='Storage >\t%s' % error)
93
93
 
94
94
  @classmethod
95
- def read_json(cls, path: str) -> Union[dict, list, None]:
95
+ async def read_json(cls, path: str) -> Union[dict, list, None]:
96
96
  try:
97
- return JSONFile(path=path).read()
97
+ return await JSONFile(path=path).read()
98
98
  except Exception as error:
99
99
  Log.error(msg='Storage >\t%s' % error)
100
100
 
101
101
  @classmethod
102
- def write_text(cls, text: str, path: str) -> bool:
102
+ async def write_text(cls, text: str, path: str) -> bool:
103
103
  try:
104
- return TextFile(path=path).write(text=text)
104
+ return await TextFile(path=path).write(text=text)
105
105
  except Exception as error:
106
106
  Log.error(msg='Storage >\t%s' % error)
107
107
 
108
108
  @classmethod
109
- def write_json(cls, container: Union[dict, list], path: str) -> bool:
109
+ async def write_json(cls, container: Union[dict, list], path: str) -> bool:
110
110
  try:
111
- return JSONFile(path=path).write(container=container)
111
+ return await JSONFile(path=path).write(container=container)
112
112
  except Exception as error:
113
113
  Log.error(msg='Storage >\t%s' % error)
114
114
 
115
115
  @classmethod
116
- def append_text(cls, text: str, path: str) -> bool:
116
+ async def append_text(cls, text: str, path: str) -> bool:
117
117
  try:
118
- return TextFile(path=path).append(text=text)
118
+ return await TextFile(path=path).append(text=text)
119
119
  except Exception as error:
120
120
  Log.error(msg='Storage >\t%s' % error)
121
121
 
@@ -63,13 +63,13 @@ class DocumentStorage(Storage, DocumentDBI):
63
63
  for doc in documents:
64
64
  assert doc.identifier == identifier, 'document ID not matched: %s, %s' % (identifier, doc)
65
65
  array.append(doc.dictionary)
66
- return self.write_json(container=array, path=path)
66
+ return await self.write_json(container=array, path=path)
67
67
 
68
68
  async def load_documents(self, identifier: ID) -> Optional[List[Document]]:
69
69
  """ load documents from file """
70
70
  path = self.__all_path(identifier=identifier)
71
71
  self.info(msg='Loading documents from: %s' % path)
72
- array = self.read_json(path=path)
72
+ array = await self.read_json(path=path)
73
73
  if array is None:
74
74
  # file not found
75
75
  return None
@@ -86,7 +86,7 @@ class DocumentStorage(Storage, DocumentDBI):
86
86
  """ load document from file """
87
87
  path = self.__doc_path(identifier=identifier)
88
88
  self.info(msg='Loading document from: %s' % path)
89
- info = self.read_json(path=path)
89
+ info = await self.read_json(path=path)
90
90
  if info is not None:
91
91
  return parse_document(dictionary=info, identifier=identifier)
92
92
 
@@ -84,7 +84,7 @@ class GroupStorage(Storage, GroupDBI):
84
84
  """ load members from file """
85
85
  path = self.__members_path(identifier=group)
86
86
  self.info(msg='Loading members from: %s' % path)
87
- users = self.read_json(path=path)
87
+ users = await self.read_json(path=path)
88
88
  if users is None:
89
89
  # members not found
90
90
  return []
@@ -95,14 +95,14 @@ class GroupStorage(Storage, GroupDBI):
95
95
  """ save members into file """
96
96
  path = self.__members_path(identifier=group)
97
97
  self.info(msg='Saving members into: %s' % path)
98
- return self.write_json(container=ID.revert(array=members), path=path)
98
+ return await self.write_json(container=ID.revert(array=members), path=path)
99
99
 
100
100
  # Override
101
101
  async def get_assistants(self, group: ID) -> List[ID]:
102
102
  """ load assistants from file """
103
103
  path = self.__assistants_path(identifier=group)
104
104
  self.info(msg='Loading assistants from: %s' % path)
105
- bots = self.read_json(path=path)
105
+ bots = await self.read_json(path=path)
106
106
  if bots is None:
107
107
  # assistants not found
108
108
  return []
@@ -113,14 +113,14 @@ class GroupStorage(Storage, GroupDBI):
113
113
  """ save assistants into file """
114
114
  path = self.__assistants_path(identifier=group)
115
115
  self.info(msg='Saving assistants into: %s' % path)
116
- return self.write_json(container=ID.revert(array=assistants), path=path)
116
+ return await self.write_json(container=ID.revert(array=assistants), path=path)
117
117
 
118
118
  # Override
119
119
  async def get_administrators(self, group: ID) -> List[ID]:
120
120
  """ load administrators from file """
121
121
  path = self.__administrators_path(identifier=group)
122
122
  self.info(msg='Loading administrators from: %s' % path)
123
- users = self.read_json(path=path)
123
+ users = await self.read_json(path=path)
124
124
  if users is None:
125
125
  # administrators not found
126
126
  return []
@@ -131,4 +131,4 @@ class GroupStorage(Storage, GroupDBI):
131
131
  """ save administrators into file """
132
132
  path = self.__administrators_path(identifier=group)
133
133
  self.info(msg='Saving administrators into: %s' % path)
134
- return self.write_json(container=ID.revert(array=administrators), path=path)
134
+ return await self.write_json(container=ID.revert(array=administrators), path=path)
@@ -57,7 +57,7 @@ class GroupHistoryStorage(Storage, GroupHistoryDBI):
57
57
  async def load_group_histories(self, group: ID) -> List[Tuple[GroupCommand, ReliableMessage]]:
58
58
  path = self.__history_path(group=group)
59
59
  self.info(msg='Loading group history from: %s' % path)
60
- array = self.read_json(path=path)
60
+ array = await self.read_json(path=path)
61
61
  if array is None:
62
62
  # history not found
63
63
  return []
@@ -88,7 +88,7 @@ class GroupHistoryStorage(Storage, GroupHistoryDBI):
88
88
  array.append(item)
89
89
  path = self.__history_path(group=group)
90
90
  self.info(msg='Saving %d group history(ies) into: %s' % (len(histories), path))
91
- return self.write_json(container=array, path=path)
91
+ return await self.write_json(container=array, path=path)
92
92
 
93
93
  #
94
94
  # Group History DBI
@@ -61,11 +61,11 @@ class GroupKeysStorage(Storage, GroupKeysDBI):
61
61
  """ load group keys from file """
62
62
  path = self.__keys_path(group=group, sender=sender)
63
63
  self.info(msg='Loading group keys from: %s' % path)
64
- return self.read_json(path=path)
64
+ return await self.read_json(path=path)
65
65
 
66
66
  # Override
67
67
  async def save_group_keys(self, group: ID, sender: ID, keys: Dict[str, str]) -> bool:
68
68
  """ save group keys into file """
69
69
  path = self.__keys_path(group=group, sender=sender)
70
70
  self.info(msg='Saving group keys into: %s' % path)
71
- return self.write_json(container=keys, path=path)
71
+ return await self.write_json(container=keys, path=path)
@@ -60,7 +60,7 @@ class LoginStorage(Storage, LoginDBI):
60
60
  """ load login command from file """
61
61
  path = self.__login_path(identifier=user)
62
62
  self.info(msg='Loading login command from: %s' % path)
63
- info = self.read_json(path=path)
63
+ info = await self.read_json(path=path)
64
64
  if info is None:
65
65
  # command not found
66
66
  return None, None
@@ -79,4 +79,4 @@ class LoginStorage(Storage, LoginDBI):
79
79
  }
80
80
  path = self.__login_path(identifier=user)
81
81
  self.info(msg='Saving login command into: %s' % path)
82
- return self.write_json(container=info, path=path)
82
+ return await self.write_json(container=info, path=path)
@@ -58,13 +58,13 @@ class MetaStorage(Storage, MetaDBI):
58
58
  """ save meta into file """
59
59
  path = self.__meta_path(identifier=identifier)
60
60
  self.info(msg='Saving meta into: %s' % path)
61
- return self.write_json(container=meta.dictionary, path=path)
61
+ return await self.write_json(container=meta.dictionary, path=path)
62
62
 
63
63
  # Override
64
64
  async def get_meta(self, identifier: ID) -> Optional[Meta]:
65
65
  """ load meta from file """
66
66
  path = self.__meta_path(identifier=identifier)
67
67
  self.info(msg='Loading meta from: %s' % path)
68
- info = self.read_json(path=path)
68
+ info = await self.read_json(path=path)
69
69
  if info is not None:
70
70
  return Meta.parse(meta=info)
@@ -67,20 +67,20 @@ class PrivateKeyStorage(Storage, PrivateKeyDBI):
67
67
  path = self.private_path(self.msg_keys_path)
68
68
  return template_replace(path, key='ADDRESS', value=str(identifier.address))
69
69
 
70
- def _save_id_key(self, key: PrivateKey, identifier: ID) -> bool:
70
+ async def _save_id_key(self, key: PrivateKey, identifier: ID) -> bool:
71
71
  path = self.__id_key_path(identifier=identifier)
72
72
  self.info(msg='Saving identity private key into: %s' % path)
73
- return self.write_json(container=key.dictionary, path=path)
73
+ return await self.write_json(container=key.dictionary, path=path)
74
74
 
75
- def _load_id_key(self, identifier: ID) -> Optional[PrivateKey]:
75
+ async def _load_id_key(self, identifier: ID) -> Optional[PrivateKey]:
76
76
  path = self.__id_key_path(identifier=identifier)
77
77
  self.info(msg='Loading identity private key from: %s' % path)
78
- info = self.read_json(path=path)
78
+ info = await self.read_json(path=path)
79
79
  if info is not None:
80
80
  return PrivateKey.parse(key=info)
81
81
 
82
- def _save_msg_key(self, key: PrivateKey, identifier: ID) -> bool:
83
- private_keys = self._load_msg_keys(identifier=identifier)
82
+ async def _save_msg_key(self, key: PrivateKey, identifier: ID) -> bool:
83
+ private_keys = await self._load_msg_keys(identifier=identifier)
84
84
  private_keys = PrivateKeyDBI.insert(item=key, array=private_keys)
85
85
  if private_keys is None:
86
86
  # nothing changed
@@ -88,13 +88,13 @@ class PrivateKeyStorage(Storage, PrivateKeyDBI):
88
88
  plain = [item.dictionary for item in private_keys]
89
89
  path = self.__msg_keys_path(identifier=identifier)
90
90
  self.info(msg='Saving message private keys into: %s' % path)
91
- return self.write_json(container=plain, path=path)
91
+ return await self.write_json(container=plain, path=path)
92
92
 
93
- def _load_msg_keys(self, identifier: ID) -> List[PrivateKey]:
93
+ async def _load_msg_keys(self, identifier: ID) -> List[PrivateKey]:
94
94
  keys = []
95
95
  path = self.__msg_keys_path(identifier=identifier)
96
96
  self.info(msg='Loading message private keys from: %s' % path)
97
- array = self.read_json(path=path)
97
+ array = await self.read_json(path=path)
98
98
  if array is not None:
99
99
  for item in array:
100
100
  k = PrivateKey.parse(key=item)
@@ -110,17 +110,17 @@ class PrivateKeyStorage(Storage, PrivateKeyDBI):
110
110
  async def save_private_key(self, key: PrivateKey, user: ID, key_type: str = 'M') -> bool:
111
111
  if key_type == self.ID_KEY_TAG:
112
112
  # save private key for meta
113
- return self._save_id_key(key=key, identifier=user)
113
+ return await self._save_id_key(key=key, identifier=user)
114
114
  else:
115
115
  # save private key for visa
116
- return self._save_msg_key(key=key, identifier=user)
116
+ return await self._save_msg_key(key=key, identifier=user)
117
117
 
118
118
  # Override
119
119
  async def private_keys_for_decryption(self, user: ID) -> List[DecryptKey]:
120
- keys: list = self._load_msg_keys(identifier=user)
120
+ keys: list = await self._load_msg_keys(identifier=user)
121
121
  # the 'ID key' could be used for encrypting message too (RSA),
122
122
  # so we append it to the decrypt keys here
123
- id_key = self._load_id_key(identifier=user)
123
+ id_key = await self._load_id_key(identifier=user)
124
124
  if isinstance(id_key, DecryptKey) and PrivateKeyDBI.find(item=id_key, array=keys) < 0:
125
125
  keys.append(id_key)
126
126
  return keys
@@ -132,4 +132,4 @@ class PrivateKeyStorage(Storage, PrivateKeyDBI):
132
132
 
133
133
  # Override
134
134
  async def private_key_for_visa_signature(self, user: ID) -> Optional[SignKey]:
135
- return self._load_id_key(identifier=user)
135
+ return await self._load_id_key(identifier=user)
@@ -67,17 +67,17 @@ class StationStorage(Storage, ProviderDBI, StationDBI):
67
67
  """ load providers from file """
68
68
  path = self.__providers_path()
69
69
  self.info(msg='Loading providers from: %s' % path)
70
- providers = self.read_json(path=path)
70
+ providers = await self.read_json(path=path)
71
71
  if providers is None:
72
72
  # service providers not found
73
73
  return []
74
74
  return ProviderInfo.convert(array=providers)
75
75
 
76
- def _save_providers(self, providers: List[ProviderInfo]) -> bool:
76
+ async def _save_providers(self, providers: List[ProviderInfo]) -> bool:
77
77
  """ save providers into file """
78
78
  path = self.__providers_path()
79
79
  self.info(msg='Saving providers into: %s' % path)
80
- return self.write_json(container=ProviderInfo.revert(array=providers), path=path)
80
+ return await self.write_json(container=ProviderInfo.revert(array=providers), path=path)
81
81
 
82
82
  # Override
83
83
  async def add_provider(self, identifier: ID, chosen: int = 0) -> bool:
@@ -88,7 +88,7 @@ class StationStorage(Storage, ProviderDBI, StationDBI):
88
88
  self.warning(msg='provider exists: %s, %s' % (identifier, providers))
89
89
  return True
90
90
  providers.insert(0, ProviderInfo(identifier=identifier, chosen=chosen))
91
- return self._save_providers(providers=providers)
91
+ return await self._save_providers(providers=providers)
92
92
 
93
93
  # Override
94
94
  async def update_provider(self, identifier: ID, chosen: int) -> bool:
@@ -107,7 +107,7 @@ class StationStorage(Storage, ProviderDBI, StationDBI):
107
107
  providers.insert(0, info)
108
108
  else:
109
109
  info.chosen = chosen
110
- return self._save_providers(providers=providers)
110
+ return await self._save_providers(providers=providers)
111
111
 
112
112
  # Override
113
113
  async def remove_provider(self, identifier: ID) -> bool:
@@ -120,7 +120,7 @@ class StationStorage(Storage, ProviderDBI, StationDBI):
120
120
  break
121
121
  if info is not None:
122
122
  providers.remove(info)
123
- return self._save_providers(providers=providers)
123
+ return await self._save_providers(providers=providers)
124
124
 
125
125
  #
126
126
  # Station DBI
@@ -131,17 +131,17 @@ class StationStorage(Storage, ProviderDBI, StationDBI):
131
131
  """ load stations with SP ID """
132
132
  path = self.__stations_path(provider=provider)
133
133
  self.info(msg='Loading stations from: %s' % path)
134
- stations = self.read_json(path=path)
134
+ stations = await self.read_json(path=path)
135
135
  if stations is None:
136
136
  # stations not found
137
137
  return []
138
138
  return StationInfo.convert(array=stations)
139
139
 
140
- def _save_stations(self, stations: List[StationInfo], provider: ID) -> bool:
140
+ async def _save_stations(self, stations: List[StationInfo], provider: ID) -> bool:
141
141
  """ save stations into file """
142
142
  path = self.__stations_path(provider=provider)
143
143
  self.info(msg='Saving stations into: %s' % path)
144
- return self.write_json(container=StationInfo.revert(array=stations), path=path)
144
+ return await self.write_json(container=StationInfo.revert(array=stations), path=path)
145
145
 
146
146
  # Override
147
147
  async def add_station(self, identifier: Optional[ID], host: str, port: int, provider: ID, chosen: int = 0) -> bool:
@@ -152,7 +152,7 @@ class StationStorage(Storage, ProviderDBI, StationDBI):
152
152
  self.warning(msg='station exists: %s, %d, %s' % (host, port, stations))
153
153
  return True
154
154
  stations.insert(0, StationInfo(identifier=identifier, host=host, port=port, provider=provider, chosen=chosen))
155
- return self._save_stations(stations=stations, provider=provider)
155
+ return await self._save_stations(stations=stations, provider=provider)
156
156
 
157
157
  # Override
158
158
  async def update_station(self, identifier: Optional[ID], host: str, port: int,
@@ -174,7 +174,7 @@ class StationStorage(Storage, ProviderDBI, StationDBI):
174
174
  if not (identifier is None or identifier.is_broadcast):
175
175
  info.identifier = identifier
176
176
  info.chosen = chosen
177
- return self._save_stations(stations=stations, provider=provider)
177
+ return await self._save_stations(stations=stations, provider=provider)
178
178
 
179
179
  # Override
180
180
  async def remove_station(self, host: str, port: int, provider: ID) -> bool:
@@ -187,7 +187,7 @@ class StationStorage(Storage, ProviderDBI, StationDBI):
187
187
  break
188
188
  if info is not None:
189
189
  stations.remove(info)
190
- return self._save_stations(stations=stations, provider=provider)
190
+ return await self._save_stations(stations=stations, provider=provider)
191
191
 
192
192
  # Override
193
193
  async def remove_stations(self, provider: ID) -> bool:
@@ -196,4 +196,4 @@ class StationStorage(Storage, ProviderDBI, StationDBI):
196
196
  if len(stations) == 0:
197
197
  # already empty
198
198
  return True
199
- return self._save_stations(stations=[], provider=provider)
199
+ return await self._save_stations(stations=[], provider=provider)
@@ -71,7 +71,7 @@ class UserStorage(Storage, UserDBI, ContactDBI):
71
71
  """ load contacts from file """
72
72
  path = self.__contacts_path(identifier=user)
73
73
  self.info(msg='Loading contacts from: %s' % path)
74
- contacts = self.read_json(path=path)
74
+ contacts = await self.read_json(path=path)
75
75
  if contacts is None:
76
76
  # contacts not found
77
77
  return []
@@ -82,4 +82,4 @@ class UserStorage(Storage, UserDBI, ContactDBI):
82
82
  """ save contacts into file """
83
83
  path = self.__contacts_path(identifier=user)
84
84
  self.info(msg='Saving contacts into: %s' % path)
85
- return self.write_json(container=ID.revert(array=contacts), path=path)
85
+ return await self.write_json(container=ID.revert(array=contacts), path=path)
@@ -84,7 +84,7 @@ class MetaTable(MetaDBI):
84
84
  async def save_meta(self, meta: Meta, identifier: ID) -> bool:
85
85
  # assert Meta.match_id(meta=meta, identifier=identifier), 'meta invalid: %s, %s' % (identifier, meta)
86
86
  # 0. check old record
87
- old = self.get_meta(identifier=identifier)
87
+ old = await self.get_meta(identifier=identifier)
88
88
  if old is not None:
89
89
  # meta exists, no need to update it
90
90
  return True
@@ -142,14 +142,6 @@ class Octopus(Runner, Logging):
142
142
  # 3. stop runner
143
143
  await super().stop()
144
144
 
145
- # Override
146
- async def setup(self):
147
- pass
148
-
149
- # Override
150
- async def finish(self):
151
- pass
152
-
153
145
  # Override
154
146
  async def process(self) -> bool:
155
147
  # get all neighbor stations