dimples 0.5.7__tar.gz → 1.0.0__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 (144) hide show
  1. {dimples-0.5.7 → dimples-1.0.0}/PKG-INFO +1 -1
  2. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/archivist.py +23 -23
  3. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/cpu/commands.py +1 -1
  4. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/cpu/group.py +27 -26
  5. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/cpu/grp_expel.py +1 -1
  6. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/cpu/grp_invite.py +8 -8
  7. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/cpu/grp_join.py +6 -6
  8. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/cpu/grp_query.py +6 -6
  9. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/cpu/grp_quit.py +6 -6
  10. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/cpu/grp_reset.py +7 -7
  11. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/cpu/grp_resign.py +6 -6
  12. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/cpu/handshake.py +3 -3
  13. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/facebook.py +24 -24
  14. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/messenger.py +41 -31
  15. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/network/session.py +32 -24
  16. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/network/state.py +33 -11
  17. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/packer.py +24 -24
  18. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/processor.py +8 -8
  19. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/terminal.py +20 -27
  20. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/archivist.py +56 -40
  21. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/dbi/account.py +25 -25
  22. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/dbi/message.py +5 -5
  23. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/dbi/session.py +11 -11
  24. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/facebook.py +37 -37
  25. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/messenger.py +25 -23
  26. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/packer.py +22 -22
  27. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/processer.py +5 -5
  28. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/register.py +10 -10
  29. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/session.py +5 -5
  30. {dimples-0.5.7 → dimples-1.0.0}/dimples/conn/gate.py +28 -25
  31. {dimples-0.5.7 → dimples-1.0.0}/dimples/conn/gatekeeper.py +37 -29
  32. {dimples-0.5.7 → dimples-1.0.0}/dimples/conn/mars.py +7 -7
  33. {dimples-0.5.7 → dimples-1.0.0}/dimples/conn/mtp.py +4 -4
  34. {dimples-0.5.7 → dimples-1.0.0}/dimples/conn/session.py +9 -9
  35. {dimples-0.5.7 → dimples-1.0.0}/dimples/conn/ws.py +7 -6
  36. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/account.py +52 -52
  37. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/dos/document.py +9 -9
  38. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/dos/group.py +8 -8
  39. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/dos/group_history.py +15 -15
  40. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/dos/group_keys.py +2 -2
  41. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/dos/login.py +2 -2
  42. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/dos/meta.py +2 -2
  43. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/dos/private.py +5 -5
  44. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/dos/station.py +17 -16
  45. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/dos/user.py +4 -4
  46. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/message.py +14 -14
  47. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/session.py +26 -24
  48. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/t_cipherkey.py +2 -2
  49. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/t_document.py +5 -5
  50. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/t_group.py +14 -14
  51. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/t_group_history.py +13 -13
  52. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/t_group_keys.py +7 -7
  53. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/t_login.py +7 -7
  54. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/t_message.py +3 -3
  55. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/t_meta.py +5 -5
  56. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/t_private.py +10 -10
  57. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/t_station.py +22 -18
  58. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/t_user.py +8 -8
  59. {dimples-0.5.7 → dimples-1.0.0}/dimples/edge/octopus.py +48 -49
  60. {dimples-0.5.7 → dimples-1.0.0}/dimples/edge/shared.py +8 -8
  61. {dimples-0.5.7 → dimples-1.0.0}/dimples/edge/start.py +8 -7
  62. {dimples-0.5.7 → dimples-1.0.0}/dimples/group/admin.py +13 -13
  63. {dimples-0.5.7 → dimples-1.0.0}/dimples/group/builder.py +17 -17
  64. {dimples-0.5.7 → dimples-1.0.0}/dimples/group/delegate.py +38 -38
  65. {dimples-0.5.7 → dimples-1.0.0}/dimples/group/emitter.py +20 -20
  66. {dimples-0.5.7 → dimples-1.0.0}/dimples/group/helper.py +14 -14
  67. {dimples-0.5.7 → dimples-1.0.0}/dimples/group/manager.py +45 -45
  68. {dimples-0.5.7 → dimples-1.0.0}/dimples/group/packer.py +5 -5
  69. {dimples-0.5.7 → dimples-1.0.0}/dimples/register/base.py +8 -8
  70. {dimples-0.5.7 → dimples-1.0.0}/dimples/register/ext.py +16 -16
  71. {dimples-0.5.7 → dimples-1.0.0}/dimples/register/run.py +6 -6
  72. {dimples-0.5.7 → dimples-1.0.0}/dimples/register/shared.py +6 -6
  73. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/archivist.py +16 -16
  74. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/cpu/ans.py +1 -1
  75. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/cpu/document.py +7 -7
  76. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/cpu/handshake.py +4 -4
  77. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/cpu/login.py +2 -2
  78. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/cpu/report.py +1 -1
  79. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/dispatcher.py +57 -53
  80. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/messenger.py +14 -12
  81. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/packer.py +6 -6
  82. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/processor.py +26 -25
  83. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/push.py +6 -8
  84. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/session.py +34 -31
  85. {dimples-0.5.7 → dimples-1.0.0}/dimples/station/handler.py +24 -39
  86. {dimples-0.5.7 → dimples-1.0.0}/dimples/station/shared.py +8 -8
  87. {dimples-0.5.7 → dimples-1.0.0}/dimples/station/start.py +5 -6
  88. {dimples-0.5.7 → dimples-1.0.0}/dimples/utils/__init__.py +2 -2
  89. {dimples-0.5.7 → dimples-1.0.0}/dimples/utils/cache.py +11 -10
  90. {dimples-0.5.7 → dimples-1.0.0}/dimples.egg-info/PKG-INFO +1 -1
  91. dimples-1.0.0/dimples.egg-info/requires.txt +8 -0
  92. {dimples-0.5.7 → dimples-1.0.0}/setup.py +9 -9
  93. dimples-0.5.7/dimples.egg-info/requires.txt +0 -8
  94. {dimples-0.5.7 → dimples-1.0.0}/README.md +0 -0
  95. {dimples-0.5.7 → dimples-1.0.0}/dimples/__init__.py +0 -0
  96. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/__init__.py +0 -0
  97. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/checkpoint.py +0 -0
  98. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/cpu/__init__.py +0 -0
  99. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/cpu/creator.py +0 -0
  100. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/network/__init__.py +0 -0
  101. {dimples-0.5.7 → dimples-1.0.0}/dimples/client/network/transition.py +0 -0
  102. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/__init__.py +0 -0
  103. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/anonymous.py +0 -0
  104. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/ans.py +0 -0
  105. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/compat/__init__.py +0 -0
  106. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/compat/btc.py +0 -0
  107. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/compat/compatible.py +0 -0
  108. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/compat/entity.py +0 -0
  109. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/compat/meta.py +0 -0
  110. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/compat/network.py +0 -0
  111. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/dbi/__init__.py +0 -0
  112. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/protocol/__init__.py +0 -0
  113. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/protocol/ans.py +0 -0
  114. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/protocol/block.py +0 -0
  115. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/protocol/handshake.py +0 -0
  116. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/protocol/login.py +0 -0
  117. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/protocol/mute.py +0 -0
  118. {dimples-0.5.7 → dimples-1.0.0}/dimples/common/protocol/report.py +0 -0
  119. {dimples-0.5.7 → dimples-1.0.0}/dimples/conn/__init__.py +0 -0
  120. {dimples-0.5.7 → dimples-1.0.0}/dimples/conn/protocol/__init__.py +0 -0
  121. {dimples-0.5.7 → dimples-1.0.0}/dimples/conn/protocol/mars.py +0 -0
  122. {dimples-0.5.7 → dimples-1.0.0}/dimples/conn/protocol/ws.py +0 -0
  123. {dimples-0.5.7 → dimples-1.0.0}/dimples/conn/queue.py +0 -0
  124. {dimples-0.5.7 → dimples-1.0.0}/dimples/conn/seeker.py +0 -0
  125. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/__init__.py +0 -0
  126. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/dos/__init__.py +0 -0
  127. {dimples-0.5.7 → dimples-1.0.0}/dimples/database/dos/base.py +0 -0
  128. {dimples-0.5.7 → dimples-1.0.0}/dimples/edge/__init__.py +0 -0
  129. {dimples-0.5.7 → dimples-1.0.0}/dimples/group/__init__.py +0 -0
  130. {dimples-0.5.7 → dimples-1.0.0}/dimples/register/__init__.py +0 -0
  131. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/__init__.py +0 -0
  132. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/cpu/__init__.py +0 -0
  133. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/session_center.py +0 -0
  134. {dimples-0.5.7 → dimples-1.0.0}/dimples/server/trace.py +0 -0
  135. {dimples-0.5.7 → dimples-1.0.0}/dimples/station/__init__.py +0 -0
  136. {dimples-0.5.7 → dimples-1.0.0}/dimples/utils/config.py +0 -0
  137. {dimples-0.5.7 → dimples-1.0.0}/dimples/utils/dos.py +0 -0
  138. {dimples-0.5.7 → dimples-1.0.0}/dimples/utils/log.py +0 -0
  139. {dimples-0.5.7 → dimples-1.0.0}/dimples/utils/singleton.py +0 -0
  140. {dimples-0.5.7 → dimples-1.0.0}/dimples.egg-info/SOURCES.txt +0 -0
  141. {dimples-0.5.7 → dimples-1.0.0}/dimples.egg-info/dependency_links.txt +0 -0
  142. {dimples-0.5.7 → dimples-1.0.0}/dimples.egg-info/entry_points.txt +0 -0
  143. {dimples-0.5.7 → dimples-1.0.0}/dimples.egg-info/top_level.txt +0 -0
  144. {dimples-0.5.7 → dimples-1.0.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dimples
3
- Version: 0.5.7
3
+ Version: 1.0.0
4
4
  Summary: DIMP Library for Edges and Stations
5
5
  Home-page: https://github.com/dimchat/demo-py
6
6
  Author: Albert Moky
@@ -75,7 +75,7 @@ class ClientArchivist(CommonArchivist, ABC):
75
75
  self.__last_active_members[group] = member
76
76
 
77
77
  # Override
78
- def query_meta(self, identifier: ID) -> bool:
78
+ async def query_meta(self, identifier: ID) -> bool:
79
79
  if not self.is_meta_query_expired(identifier=identifier):
80
80
  # query not expired yet
81
81
  self.info(msg='meta query not expired yet: %s' % identifier)
@@ -86,11 +86,11 @@ class ClientArchivist(CommonArchivist, ABC):
86
86
  return False
87
87
  self.info(msg='querying meta for: %s' % identifier)
88
88
  command = MetaCommand.query(identifier=identifier)
89
- _, r_msg = messenger.send_content(sender=None, receiver=Station.ANY, content=command, priority=1)
89
+ _, r_msg = await messenger.send_content(sender=None, receiver=Station.ANY, content=command, priority=1)
90
90
  return r_msg is not None
91
91
 
92
92
  # Override
93
- def query_documents(self, identifier: ID, documents: List[Document]) -> bool:
93
+ async def query_documents(self, identifier: ID, documents: List[Document]) -> bool:
94
94
  if not self.is_documents_query_expired(identifier=identifier):
95
95
  # query not expired yet
96
96
  self.info(msg='document query not expired yet: %s' % identifier)
@@ -99,14 +99,14 @@ class ClientArchivist(CommonArchivist, ABC):
99
99
  if messenger is None:
100
100
  self.warning(msg='messenger not ready yet')
101
101
  return False
102
- last_time = self.get_last_document_time(identifier=identifier, documents=documents)
102
+ last_time = await self.get_last_document_time(identifier=identifier, documents=documents)
103
103
  self.info(msg='querying document for: %s, last time: %s' % (identifier, last_time))
104
104
  command = DocumentCommand.query(identifier=identifier, last_time=last_time)
105
- _, r_msg = messenger.send_content(sender=None, receiver=Station.ANY, content=command, priority=1)
105
+ _, r_msg = await messenger.send_content(sender=None, receiver=Station.ANY, content=command, priority=1)
106
106
  return r_msg is not None
107
107
 
108
108
  # Override
109
- def query_members(self, group: ID, members: List[ID]) -> bool:
109
+ async def query_members(self, group: ID, members: List[ID]) -> bool:
110
110
  if not self.is_members_query_expired(group=group):
111
111
  # query not expired yet
112
112
  self.info('members query not expired yet: %s' % group)
@@ -121,20 +121,20 @@ class ClientArchivist(CommonArchivist, ABC):
121
121
  self.error(msg='failed to get current user')
122
122
  return False
123
123
  me = user.identifier
124
- last_time = self.get_last_group_history_time(group=group)
124
+ last_time = await self.get_last_group_history_time(group=group)
125
125
  self.info(msg='querying members for group: %s, last time: %s' % (group, last_time))
126
126
  # build query command for group members
127
127
  command = GroupCommand.query(group=group, last_time=last_time)
128
128
  # 1. check group bots
129
- ok = self.query_members_from_assistants(command=command, sender=me, group=group)
129
+ ok = await self.query_members_from_assistants(command=command, sender=me, group=group)
130
130
  if ok:
131
131
  return True
132
132
  # 2. check administrators
133
- ok = self.query_members_from_administrators(command=command, sender=me, group=group)
133
+ ok = await self.query_members_from_administrators(command=command, sender=me, group=group)
134
134
  if ok:
135
135
  return True
136
136
  # 3. check group owner
137
- ok = self.query_members_from_owner(command=command, sender=me, group=group)
137
+ ok = await self.query_members_from_owner(command=command, sender=me, group=group)
138
138
  if ok:
139
139
  return True
140
140
  # all failed, try last active member
@@ -143,18 +143,18 @@ class ClientArchivist(CommonArchivist, ABC):
143
143
  r_msg = None
144
144
  else:
145
145
  self.info(msg='querying members from: %s, group: %s' % (last_member, group))
146
- _, r_msg = messenger.send_content(sender=me, receiver=last_member, content=command, priority=1)
146
+ _, r_msg = await messenger.send_content(sender=me, receiver=last_member, content=command, priority=1)
147
147
  self.error(msg='group not ready: %s' % group)
148
148
  return r_msg is not None
149
149
 
150
150
  # protected
151
- def query_members_from_assistants(self, command: QueryCommand, sender: ID, group: ID) -> bool:
151
+ async def query_members_from_assistants(self, command: QueryCommand, sender: ID, group: ID) -> bool:
152
152
  facebook = get_facebook(archivist=self)
153
153
  messenger = get_messenger(archivist=self)
154
154
  if facebook is None or messenger is None:
155
155
  self.warning(msg='facebook messenger not ready yet')
156
156
  return False
157
- bots = facebook.assistants(group)
157
+ bots = await facebook.get_assistants(group)
158
158
  if len(bots) == 0:
159
159
  self.warning(msg='assistants not designated for group: %s' % group)
160
160
  return False
@@ -165,7 +165,7 @@ class ClientArchivist(CommonArchivist, ABC):
165
165
  if receiver == sender:
166
166
  self.warning(msg='ignore cycled querying: %s, group: %s' % (receiver, group))
167
167
  continue
168
- _, r_msg = messenger.send_content(sender=sender, receiver=receiver, content=command, priority=1)
168
+ _, r_msg = await messenger.send_content(sender=sender, receiver=receiver, content=command, priority=1)
169
169
  if r_msg is not None:
170
170
  success += 1
171
171
  if success == 0:
@@ -177,17 +177,17 @@ class ClientArchivist(CommonArchivist, ABC):
177
177
  pass
178
178
  else:
179
179
  self.info(msg='querying members from: %s, group: %s' % (last_member, group))
180
- messenger.send_content(sender=sender, receiver=last_member, content=command, priority=1)
180
+ await messenger.send_content(sender=sender, receiver=last_member, content=command, priority=1)
181
181
  return True
182
182
 
183
183
  # protected
184
- def query_members_from_administrators(self, command: QueryCommand, sender: ID, group: ID) -> bool:
184
+ async def query_members_from_administrators(self, command: QueryCommand, sender: ID, group: ID) -> bool:
185
185
  facebook = get_facebook(archivist=self)
186
186
  messenger = get_messenger(archivist=self)
187
187
  if facebook is None or messenger is None:
188
188
  self.warning(msg='facebook messenger not ready yet')
189
189
  return False
190
- admins = facebook.administrators(group)
190
+ admins = await facebook.get_administrators(group)
191
191
  if len(admins) == 0:
192
192
  self.warning(msg='administrators not found for group: %s' % group)
193
193
  return False
@@ -198,7 +198,7 @@ class ClientArchivist(CommonArchivist, ABC):
198
198
  if receiver == sender:
199
199
  self.warning(msg='ignore cycled querying: %s, group: %s' % (receiver, group))
200
200
  continue
201
- _, r_msg = messenger.send_content(sender=sender, receiver=receiver, content=command, priority=1)
201
+ _, r_msg = await messenger.send_content(sender=sender, receiver=receiver, content=command, priority=1)
202
202
  if r_msg is not None:
203
203
  success += 1
204
204
  if success == 0:
@@ -210,17 +210,17 @@ class ClientArchivist(CommonArchivist, ABC):
210
210
  pass
211
211
  else:
212
212
  self.info(msg='querying members from: %s, group: %s' % (last_member, group))
213
- messenger.send_content(sender=sender, receiver=last_member, content=command, priority=1)
213
+ await messenger.send_content(sender=sender, receiver=last_member, content=command, priority=1)
214
214
  return True
215
215
 
216
216
  # protected
217
- def query_members_from_owner(self, command: QueryCommand, sender: ID, group: ID) -> bool:
217
+ async def query_members_from_owner(self, command: QueryCommand, sender: ID, group: ID) -> bool:
218
218
  facebook = get_facebook(archivist=self)
219
219
  messenger = get_messenger(archivist=self)
220
220
  if facebook is None or messenger is None:
221
221
  self.warning(msg='facebook messenger not ready yet')
222
222
  return False
223
- owner = facebook.owner(group)
223
+ owner = await facebook.get_owner(group)
224
224
  if owner is None:
225
225
  self.warning(msg='owner not found for group: %s' % group)
226
226
  return False
@@ -229,7 +229,7 @@ class ClientArchivist(CommonArchivist, ABC):
229
229
  return False
230
230
  # querying members from owner
231
231
  self.info(msg='querying members from owner: %s, group: %s' % (owner, group))
232
- _, r_msg = messenger.send_content(sender=sender, receiver=owner, content=command, priority=1)
232
+ _, r_msg = await messenger.send_content(sender=sender, receiver=owner, content=command, priority=1)
233
233
  if r_msg is None:
234
234
  # failed
235
235
  return False
@@ -239,5 +239,5 @@ class ClientArchivist(CommonArchivist, ABC):
239
239
  pass
240
240
  else:
241
241
  self.info(msg='querying members from: %s, group: %s' % (last_member, group))
242
- messenger.send_content(sender=sender, receiver=last_member, content=command, priority=1)
242
+ await messenger.send_content(sender=sender, receiver=last_member, content=command, priority=1)
243
243
  return True
@@ -43,7 +43,7 @@ from ...common import LoginCommand
43
43
  class LoginCommandProcessor(BaseCommandProcessor):
44
44
 
45
45
  # Override
46
- def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
46
+ async def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
47
47
  assert isinstance(content, LoginCommand), 'login command error: %s' % content
48
48
  # return ReceiptCommand.new(message='Login received')
49
49
  return []
@@ -73,7 +73,7 @@ class HistoryCommandProcessor(BaseCommandProcessor, Logging):
73
73
  return transceiver
74
74
 
75
75
  # Override
76
- def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
76
+ async def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
77
77
  assert isinstance(content, Command), 'history command error: %s' % content
78
78
  text = 'Command not support.'
79
79
  return self._respond_receipt(text=text, content=content, envelope=r_msg.envelope, extra={
@@ -123,36 +123,36 @@ class HistoryCommandProcessor(BaseCommandProcessor, Logging):
123
123
 
124
124
  class GroupCommandProcessor(HistoryCommandProcessor):
125
125
 
126
- def _owner(self, group: ID) -> Optional[ID]:
126
+ async def _owner(self, group: ID) -> Optional[ID]:
127
127
  delegate = self.delegate
128
- return delegate.owner(identifier=group)
128
+ return await delegate.get_owner(identifier=group)
129
129
 
130
- def _assistants(self, group: ID) -> List[ID]:
130
+ async def _assistants(self, group: ID) -> List[ID]:
131
131
  delegate = self.delegate
132
- return delegate.assistants(identifier=group)
132
+ return await delegate.get_assistants(identifier=group)
133
133
 
134
- def _administrators(self, group: ID) -> List[ID]:
134
+ async def _administrators(self, group: ID) -> List[ID]:
135
135
  delegate = self.delegate
136
- return delegate.administrators(group=group)
136
+ return await delegate.get_administrators(group=group)
137
137
 
138
- def _save_administrators(self, administrators: List[ID], group: ID) -> bool:
138
+ async def _save_administrators(self, administrators: List[ID], group: ID) -> bool:
139
139
  delegate = self.delegate
140
- return delegate.save_administrators(administrators=administrators, group=group)
140
+ return await delegate.save_administrators(administrators=administrators, group=group)
141
141
 
142
- def _members(self, group: ID) -> List[ID]:
142
+ async def _members(self, group: ID) -> List[ID]:
143
143
  delegate = self.delegate
144
- return delegate.members(identifier=group)
144
+ return await delegate.get_members(identifier=group)
145
145
 
146
- def _save_members(self, members: List[ID], group: ID) -> bool:
146
+ async def _save_members(self, members: List[ID], group: ID) -> bool:
147
147
  delegate = self.delegate
148
- return delegate.save_members(members=members, group=group)
148
+ return await delegate.save_members(members=members, group=group)
149
149
 
150
- def _save_group_history(self, group: ID, content: GroupCommand, r_msg: ReliableMessage) -> bool:
150
+ async def _save_group_history(self, group: ID, content: GroupCommand, r_msg: ReliableMessage) -> bool:
151
151
  delegate = self.helper
152
- return delegate.save_group_history(group=group, content=content, message=r_msg)
152
+ return await delegate.save_group_history(group=group, content=content, message=r_msg)
153
153
 
154
154
  # Override
155
- def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
155
+ async def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
156
156
  assert isinstance(content, GroupCommand), 'group command error: %s' % content
157
157
  text = 'Command not support.'
158
158
  return self._respond_receipt(text=text, content=content, envelope=r_msg.envelope, extra={
@@ -162,10 +162,10 @@ class GroupCommandProcessor(HistoryCommandProcessor):
162
162
  }
163
163
  })
164
164
 
165
- def _check_expired(self, content: GroupCommand, r_msg: ReliableMessage) -> Tuple[Optional[ID], List[Content]]:
165
+ async def _check_expired(self, content: GroupCommand, r_msg: ReliableMessage) -> Tuple[Optional[ID], List[Content]]:
166
166
  group = content.group
167
167
  assert group is not None, 'group command error: %s' % content
168
- expired = self.helper.is_expired(content=content)
168
+ expired = await self.helper.is_expired(content=content)
169
169
  if expired:
170
170
  text = 'Command expired.'
171
171
  errors = self._respond_receipt(text=text, content=content, envelope=r_msg.envelope, extra={
@@ -181,7 +181,8 @@ class GroupCommandProcessor(HistoryCommandProcessor):
181
181
  errors = None
182
182
  return group, errors
183
183
 
184
- def _check_command_members(self, content: GroupCommand, r_msg: ReliableMessage) -> Tuple[List[ID], List[Content]]:
184
+ async def _check_command_members(self, content: GroupCommand, r_msg: ReliableMessage
185
+ ) -> Tuple[List[ID], List[Content]]:
185
186
  group = content.group
186
187
  assert group is not None, 'group command error: %s' % content
187
188
  members = self.helper.members_from_command(content=content)
@@ -198,12 +199,12 @@ class GroupCommandProcessor(HistoryCommandProcessor):
198
199
  errors = None
199
200
  return members, errors
200
201
 
201
- def _check_group_members(self, content: GroupCommand,
202
- r_msg: ReliableMessage) -> Tuple[Optional[ID], List[ID], List[Content]]:
202
+ async def _check_group_members(self, content: GroupCommand, r_msg: ReliableMessage
203
+ ) -> Tuple[Optional[ID], List[ID], List[Content]]:
203
204
  group = content.group
204
205
  assert group is not None, 'group command error: %s' % content
205
- owner = self._owner(group=group)
206
- members = self._members(group=group)
206
+ owner = await self._owner(group=group)
207
+ members = await self._members(group=group)
207
208
  if owner is None or len(members) == 0:
208
209
  # TODO: query group members?
209
210
  text = 'Group empty.'
@@ -219,11 +220,11 @@ class GroupCommandProcessor(HistoryCommandProcessor):
219
220
  return owner, members, errors
220
221
 
221
222
  # protected
222
- def send_group_histories(self, group: ID, receiver: ID) -> bool:
223
- messages = self.builder.build_group_histories(group=group)
223
+ async def send_group_histories(self, group: ID, receiver: ID) -> bool:
224
+ messages = await self.builder.build_group_histories(group=group)
224
225
  if len(messages) == 0:
225
226
  self.warning(msg='failed to build history for group: %s' % group)
226
227
  return False
227
228
  content = ForwardContent.create(messages=messages)
228
- _, r_msg = self.messenger.send_content(sender=None, receiver=receiver, content=content, priority=1)
229
+ _, r_msg = await self.messenger.send_content(sender=None, receiver=receiver, content=content, priority=1)
229
230
  return r_msg is not None
@@ -49,7 +49,7 @@ from .group import GroupCommandProcessor
49
49
  class ExpelCommandProcessor(GroupCommandProcessor, Logging):
50
50
 
51
51
  # Override
52
- def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
52
+ async def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
53
53
  assert isinstance(content, ExpelCommand), 'expel command error: %s' % content
54
54
 
55
55
  self.warning(msg='"expel" group command is deprecated, use "reset" instead.')
@@ -50,21 +50,21 @@ from .group import GroupCommandProcessor
50
50
  class InviteCommandProcessor(GroupCommandProcessor):
51
51
 
52
52
  # Override
53
- def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
53
+ async def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
54
54
  assert isinstance(content, InviteCommand), 'invite command error: %s' % content
55
55
 
56
56
  # 0. check command
57
- group, errors = self._check_expired(content=content, r_msg=r_msg)
57
+ group, errors = await self._check_expired(content=content, r_msg=r_msg)
58
58
  if group is None:
59
59
  # ignore expired command
60
60
  return errors
61
- invite_list, errors = self._check_command_members(content=content, r_msg=r_msg)
61
+ invite_list, errors = await self._check_command_members(content=content, r_msg=r_msg)
62
62
  if len(invite_list) == 0:
63
63
  # command error
64
64
  return errors
65
65
 
66
66
  # 1. check group
67
- trip = self._check_group_members(content=content, r_msg=r_msg)
67
+ trip = await self._check_group_members(content=content, r_msg=r_msg)
68
68
  owner = trip[0]
69
69
  members = trip[1]
70
70
  errors = trip[2]
@@ -72,7 +72,7 @@ class InviteCommandProcessor(GroupCommandProcessor):
72
72
  return errors
73
73
 
74
74
  sender = r_msg.sender
75
- admins = self._administrators(group=group)
75
+ admins = await self._administrators(group=group)
76
76
  is_owner = sender == owner
77
77
  is_admin = sender in admins
78
78
  is_member = sender in members
@@ -100,9 +100,9 @@ class InviteCommandProcessor(GroupCommandProcessor):
100
100
  # the sender cannot reset the group, means it's an ordinary member now,
101
101
  # and if I am the owner, then send the group history commands
102
102
  # to update the sender's memory.
103
- ok = self.send_group_histories(group=group, receiver=sender)
103
+ ok = await self.send_group_histories(group=group, receiver=sender)
104
104
  assert ok, 'failed to send history for group: %s => %s' % (group, sender)
105
- elif not self._save_group_history(group=group, content=content, r_msg=r_msg):
105
+ elif not await self._save_group_history(group=group, content=content, r_msg=r_msg):
106
106
  # here try to append the 'invite' command to local storage as group history
107
107
  # it should not failed unless the command is expired
108
108
  self.error(msg='failed to save "invite" command for group: %s' % group)
@@ -110,7 +110,7 @@ class InviteCommandProcessor(GroupCommandProcessor):
110
110
  # the sender cannot reset the group, means it's invited by ordinary member,
111
111
  # and the 'invite' command was saved, now waiting for review.
112
112
  self.info(msg='"invite" command saved, waiting review now')
113
- elif self._save_members(members=new_members, group=group):
113
+ elif await self._save_members(members=new_members, group=group):
114
114
  # FIXME: this sender has permission to reset the group,
115
115
  # means it must be the owner or an administrator,
116
116
  # usually it should send a 'reset' command instead;
@@ -48,22 +48,22 @@ from .group import GroupCommandProcessor
48
48
  class JoinCommandProcessor(GroupCommandProcessor):
49
49
 
50
50
  # Override
51
- def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
51
+ async def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
52
52
  assert isinstance(content, JoinCommand), 'join command error: %s' % content
53
53
 
54
54
  # 0. check command
55
- group, errors = self._check_expired(content=content, r_msg=r_msg)
55
+ group, errors = await self._check_expired(content=content, r_msg=r_msg)
56
56
  if group is None:
57
57
  # ignore expired command
58
58
  return errors
59
59
 
60
60
  # 1. check group
61
- owner, members, errors = self._check_group_members(content=content, r_msg=r_msg)
61
+ owner, members, errors = await self._check_group_members(content=content, r_msg=r_msg)
62
62
  if owner is None or len(members) == 0:
63
63
  return errors
64
64
 
65
65
  sender = r_msg.sender
66
- admins = self._administrators(group=group)
66
+ admins = await self._administrators(group=group)
67
67
  is_owner = sender == owner
68
68
  is_admin = sender in admins
69
69
  is_member = sender in members
@@ -80,9 +80,9 @@ class JoinCommandProcessor(GroupCommandProcessor):
80
80
  # the sender cannot reset the group, means it's an ordinary member now,
81
81
  # and if I am the owner, then send the group history commands
82
82
  # to update the sender's memory.
83
- ok = self.send_group_histories(group=group, receiver=sender)
83
+ ok = await self.send_group_histories(group=group, receiver=sender)
84
84
  assert ok, 'failed to send history for group: %s => %s' % (group, sender)
85
- elif not self._save_group_history(group=group, content=content, r_msg=r_msg):
85
+ elif not await self._save_group_history(group=group, content=content, r_msg=r_msg):
86
86
  # here try to append the 'join' command to local storage as group history
87
87
  # it should not failed unless the command is expired
88
88
  self.error(msg='failed to save "join" command for group: %s' % group)
@@ -48,22 +48,22 @@ from .group import GroupCommandProcessor
48
48
  class QueryCommandProcessor(GroupCommandProcessor):
49
49
 
50
50
  # Override
51
- def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
51
+ async def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
52
52
  assert isinstance(content, QueryCommand), 'query command error: %s' % content
53
53
 
54
54
  # 0. check command
55
- group, errors = self._check_expired(content=content, r_msg=r_msg)
55
+ group, errors = await self._check_expired(content=content, r_msg=r_msg)
56
56
  if group is None:
57
57
  # ignore expired command
58
58
  return errors
59
59
 
60
60
  # 1. check group
61
- owner, members, errors = self._check_group_members(content=content, r_msg=r_msg)
61
+ owner, members, errors = await self._check_group_members(content=content, r_msg=r_msg)
62
62
  if owner is None or len(members) == 0:
63
63
  return errors
64
64
 
65
65
  sender = r_msg.sender
66
- bots = self._assistants(group=group)
66
+ bots = await self._assistants(group=group)
67
67
  is_member = sender in members
68
68
  is_bot = sender in bots
69
69
  can_query = is_member or is_bot
@@ -83,7 +83,7 @@ class QueryCommandProcessor(GroupCommandProcessor):
83
83
  if query_time is not None:
84
84
  # check last group history time
85
85
  archivist = self.facebook.archivist
86
- last_time = archivist.get_last_group_history_time(group=group)
86
+ last_time = await archivist.get_last_group_history_time(group=group)
87
87
  if last_time is None:
88
88
  self.error(msg='group history error: %s' % group)
89
89
  elif not last_time.after(query_time):
@@ -98,7 +98,7 @@ class QueryCommandProcessor(GroupCommandProcessor):
98
98
  })
99
99
 
100
100
  # 3. send newest group history commands
101
- ok = self.send_group_histories(group=group, receiver=sender)
101
+ ok = await self.send_group_histories(group=group, receiver=sender)
102
102
  assert ok, 'failed to send history for group: %s => %s' % (group, sender)
103
103
 
104
104
  # no need to response this group command
@@ -48,22 +48,22 @@ from .group import GroupCommandProcessor
48
48
  class QuitCommandProcessor(GroupCommandProcessor):
49
49
 
50
50
  # Override
51
- def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
51
+ async def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
52
52
  assert isinstance(content, QuitCommand), 'quit command error: %s' % content
53
53
 
54
54
  # 0. check command
55
- group, errors = self._check_expired(content=content, r_msg=r_msg)
55
+ group, errors = await self._check_expired(content=content, r_msg=r_msg)
56
56
  if group is None:
57
57
  # ignore expired command
58
58
  return errors
59
59
 
60
60
  # 1. check group
61
- owner, members, errors = self._check_group_members(content=content, r_msg=r_msg)
61
+ owner, members, errors = await self._check_group_members(content=content, r_msg=r_msg)
62
62
  if owner is None or len(members) == 0:
63
63
  return errors
64
64
 
65
65
  sender = r_msg.sender
66
- admins = self._administrators(group=group)
66
+ admins = await self._administrators(group=group)
67
67
  is_owner = sender == owner
68
68
  is_admin = sender in admins
69
69
  is_member = sender in members
@@ -95,11 +95,11 @@ class QuitCommandProcessor(GroupCommandProcessor):
95
95
  # the sender is not a member now,
96
96
  # shall we notify the sender that the member list was updated?
97
97
  self.warning(msg='not a member now: %s, %s' % (sender, group))
98
- elif not self._save_group_history(group=group, content=content, r_msg=r_msg):
98
+ elif not await self._save_group_history(group=group, content=content, r_msg=r_msg):
99
99
  # here try to append the 'quit' command to local storage as group history
100
100
  # it should not failed unless the command is expired
101
101
  self.error(msg='failed to save "quit" command for group: %s' % group)
102
- elif self._save_members(members=members, group=group):
102
+ elif await self._save_members(members=members, group=group):
103
103
  # here try to remove the sender from member list
104
104
  content['removed'] = [str(sender)]
105
105
  else:
@@ -49,26 +49,26 @@ from .group import GroupCommandProcessor
49
49
  class ResetCommandProcessor(GroupCommandProcessor):
50
50
 
51
51
  # Override
52
- def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
52
+ async def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
53
53
  assert isinstance(content, ResetCommand), 'group cmd error: %s' % content
54
54
 
55
55
  # 0. check command
56
- group, errors = self._check_expired(content=content, r_msg=r_msg)
56
+ group, errors = await self._check_expired(content=content, r_msg=r_msg)
57
57
  if group is None:
58
58
  # ignore expired command
59
59
  return errors
60
- new_members, errors = self._check_command_members(content=content, r_msg=r_msg)
60
+ new_members, errors = await self._check_command_members(content=content, r_msg=r_msg)
61
61
  if len(new_members) == 0:
62
62
  # command error
63
63
  return errors
64
64
 
65
65
  # 1. check group
66
- owner, members, errors = self._check_group_members(content=content, r_msg=r_msg)
66
+ owner, members, errors = await self._check_group_members(content=content, r_msg=r_msg)
67
67
  if owner is None or len(members) == 0:
68
68
  return errors
69
69
 
70
70
  sender = r_msg.sender
71
- administrators = self._administrators(group=group)
71
+ administrators = await self._administrators(group=group)
72
72
  is_owner = sender == owner
73
73
  is_admin = sender in administrators
74
74
 
@@ -108,14 +108,14 @@ class ResetCommandProcessor(GroupCommandProcessor):
108
108
 
109
109
  # 3. do reset
110
110
  add_list, remove_list = calculate_reset(old_members=members, new_members=new_members)
111
- if not self._save_group_history(group=group, content=content, r_msg=r_msg):
111
+ if not await self._save_group_history(group=group, content=content, r_msg=r_msg):
112
112
  # here try to save the 'reset' command to local storage as group history
113
113
  # it should not failed unless the command is expired
114
114
  self.error(msg='failed to save "reset" command for group: %s' % group)
115
115
  elif len(add_list) == 0 and len(remove_list) == 0:
116
116
  # nothing changed
117
117
  self.warning(msg='nothing changed for group members: %d, %s' % (len(members), group))
118
- elif self._save_members(members=new_members, group=group):
118
+ elif await self._save_members(members=new_members, group=group):
119
119
  self.info(msg='new members saved in group: %s' % group)
120
120
  if len(add_list) > 0:
121
121
  content['added'] = ID.revert(add_list)
@@ -48,22 +48,22 @@ from .group import GroupCommandProcessor
48
48
  class ResignCommandProcessor(GroupCommandProcessor):
49
49
 
50
50
  # Override
51
- def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
51
+ async def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
52
52
  assert isinstance(content, ResignCommand), 'resign command error: %s' % content
53
53
 
54
54
  # 0. check command
55
- group, errors = self._check_expired(content=content, r_msg=r_msg)
55
+ group, errors = await self._check_expired(content=content, r_msg=r_msg)
56
56
  if group is None:
57
57
  # ignore expired command
58
58
  return errors
59
59
 
60
60
  # 1. check group
61
- owner, members, errors = self._check_group_members(content=content, r_msg=r_msg)
61
+ owner, members, errors = await self._check_group_members(content=content, r_msg=r_msg)
62
62
  if owner is None or len(members) == 0:
63
63
  return errors
64
64
 
65
65
  sender = r_msg.sender
66
- admins = self._administrators(group=group)
66
+ admins = await self._administrators(group=group)
67
67
  is_owner = sender == owner
68
68
  is_admin = sender in admins
69
69
 
@@ -86,11 +86,11 @@ class ResignCommandProcessor(GroupCommandProcessor):
86
86
  # the sender is not an administrator now,
87
87
  # shall we notify the sender that the administrators list was updated?
88
88
  self.warning(msg='not an administrator now: %s, %s' % (sender, group))
89
- elif not self._save_group_history(group=group, content=content, r_msg=r_msg):
89
+ elif not await self._save_group_history(group=group, content=content, r_msg=r_msg):
90
90
  # here try to append the 'resign' command to local storage as group history
91
91
  # it should not failed unless the command is expired
92
92
  self.error(msg='failed to save "resign" command for group: %s' % group)
93
- elif self._save_administrators(administrators=admins, group=group):
93
+ elif await self._save_administrators(administrators=admins, group=group):
94
94
  # here try to remove the sender from admin list
95
95
  content['removed'] = [str(sender)]
96
96
  else:
@@ -44,7 +44,7 @@ from ...common import HandshakeCommand
44
44
  class HandshakeCommandProcessor(BaseCommandProcessor, Logging):
45
45
 
46
46
  # Override
47
- def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
47
+ async def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
48
48
  assert isinstance(content, HandshakeCommand), 'handshake command error: %s' % content
49
49
  messenger = get_client_messenger(cpu=self)
50
50
  client_session = get_client_session(messenger=messenger)
@@ -68,12 +68,12 @@ class HandshakeCommandProcessor(BaseCommandProcessor, Logging):
68
68
  # clear client session key while handshake again
69
69
  if old_sess_key is None:
70
70
  # first handshake response with new session key,
71
- messenger.handshake(session_key=new_sess_key)
71
+ await messenger.handshake(session_key=new_sess_key)
72
72
  elif old_sess_key == new_sess_key:
73
73
  # duplicated handshake response?
74
74
  # or session expired and the station ask to handshake again?
75
75
  self.warning(msg='session key already set: %s => %s' % (old_sess_key, new_sess_key))
76
- messenger.handshake(session_key=new_sess_key)
76
+ await messenger.handshake(session_key=new_sess_key)
77
77
  else:
78
78
  # connection changed?
79
79
  self.error(msg='session key from %s not match: %s => %s' % (sender, old_sess_key, new_sess_key))