dimples 1.2.4__tar.gz → 1.2.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. dimples-1.2.5/PKG-INFO +22 -0
  2. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/processor.py +2 -5
  3. {dimples-1.2.4 → dimples-1.2.5}/dimples/conn/flexible.py +2 -2
  4. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/__init__.py +16 -0
  5. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/account.py +41 -40
  6. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/dos/document.py +9 -27
  7. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/message.py +15 -14
  8. dimples-1.2.5/dimples/database/redis/__init__.py +59 -0
  9. dimples-1.2.5/dimples/database/redis/base.py +105 -0
  10. dimples-1.2.5/dimples/database/redis/document.py +90 -0
  11. dimples-1.2.5/dimples/database/redis/group.py +119 -0
  12. dimples-1.2.5/dimples/database/redis/grp_history.py +97 -0
  13. dimples-1.2.5/dimples/database/redis/grp_keys.py +72 -0
  14. dimples-1.2.5/dimples/database/redis/login.py +194 -0
  15. dimples-1.2.5/dimples/database/redis/message.py +119 -0
  16. dimples-1.2.5/dimples/database/redis/meta.py +73 -0
  17. dimples-1.2.5/dimples/database/redis/station.py +193 -0
  18. dimples-1.2.5/dimples/database/redis/user.py +72 -0
  19. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/session.py +19 -18
  20. dimples-1.2.5/dimples/database/t_base.py +175 -0
  21. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/t_cipherkey.py +36 -13
  22. dimples-1.2.5/dimples/database/t_document.py +141 -0
  23. dimples-1.2.5/dimples/database/t_group.py +220 -0
  24. dimples-1.2.5/dimples/database/t_group_history.py +189 -0
  25. dimples-1.2.5/dimples/database/t_group_keys.py +139 -0
  26. dimples-1.2.5/dimples/database/t_login.py +155 -0
  27. dimples-1.2.5/dimples/database/t_message.py +124 -0
  28. dimples-1.2.5/dimples/database/t_meta.py +115 -0
  29. dimples-1.2.5/dimples/database/t_private.py +169 -0
  30. dimples-1.2.5/dimples/database/t_station.py +255 -0
  31. dimples-1.2.5/dimples/database/t_user.py +123 -0
  32. {dimples-1.2.4 → dimples-1.2.5}/dimples/edge/shared.py +22 -3
  33. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/cpu/document.py +6 -2
  34. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/cpu/login.py +8 -4
  35. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/dispatcher.py +6 -3
  36. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/processor.py +2 -5
  37. {dimples-1.2.4 → dimples-1.2.5}/dimples/station/shared.py +22 -3
  38. {dimples-1.2.4 → dimples-1.2.5}/dimples/utils/__init__.py +2 -2
  39. dimples-1.2.5/dimples/utils/cache.py +83 -0
  40. dimples-1.2.5/dimples.egg-info/PKG-INFO +22 -0
  41. {dimples-1.2.4 → dimples-1.2.5}/dimples.egg-info/SOURCES.txt +12 -1
  42. {dimples-1.2.4 → dimples-1.2.5}/dimples.egg-info/entry_points.txt +1 -0
  43. {dimples-1.2.4 → dimples-1.2.5}/dimples.egg-info/requires.txt +4 -4
  44. {dimples-1.2.4 → dimples-1.2.5}/setup.py +5 -5
  45. dimples-1.2.4/LICENSE +0 -21
  46. dimples-1.2.4/PKG-INFO +0 -31
  47. dimples-1.2.4/dimples/database/t_document.py +0 -99
  48. dimples-1.2.4/dimples/database/t_group.py +0 -157
  49. dimples-1.2.4/dimples/database/t_group_history.py +0 -145
  50. dimples-1.2.4/dimples/database/t_group_keys.py +0 -107
  51. dimples-1.2.4/dimples/database/t_login.py +0 -103
  52. dimples-1.2.4/dimples/database/t_message.py +0 -116
  53. dimples-1.2.4/dimples/database/t_meta.py +0 -94
  54. dimples-1.2.4/dimples/database/t_private.py +0 -138
  55. dimples-1.2.4/dimples/database/t_station.py +0 -165
  56. dimples-1.2.4/dimples/database/t_user.py +0 -97
  57. dimples-1.2.4/dimples/utils/cache.py +0 -178
  58. dimples-1.2.4/dimples.egg-info/PKG-INFO +0 -31
  59. {dimples-1.2.4 → dimples-1.2.5}/README.md +0 -0
  60. {dimples-1.2.4 → dimples-1.2.5}/dimples/__init__.py +0 -0
  61. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/__init__.py +0 -0
  62. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/archivist.py +0 -0
  63. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/checkpoint.py +0 -0
  64. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/cpu/__init__.py +0 -0
  65. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/cpu/commands.py +0 -0
  66. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/cpu/creator.py +0 -0
  67. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/cpu/group.py +0 -0
  68. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/cpu/grp_expel.py +0 -0
  69. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/cpu/grp_invite.py +0 -0
  70. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/cpu/grp_join.py +0 -0
  71. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/cpu/grp_query.py +0 -0
  72. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/cpu/grp_quit.py +0 -0
  73. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/cpu/grp_reset.py +0 -0
  74. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/cpu/grp_resign.py +0 -0
  75. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/cpu/handshake.py +0 -0
  76. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/facebook.py +0 -0
  77. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/messenger.py +0 -0
  78. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/network/__init__.py +0 -0
  79. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/network/session.py +0 -0
  80. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/network/state.py +0 -0
  81. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/network/transition.py +0 -0
  82. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/packer.py +0 -0
  83. {dimples-1.2.4 → dimples-1.2.5}/dimples/client/terminal.py +0 -0
  84. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/__init__.py +0 -0
  85. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/anonymous.py +0 -0
  86. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/ans.py +0 -0
  87. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/archivist.py +0 -0
  88. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/compat/__init__.py +0 -0
  89. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/compat/btc.py +0 -0
  90. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/compat/compatible.py +0 -0
  91. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/compat/entity.py +0 -0
  92. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/compat/meta.py +0 -0
  93. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/compat/network.py +0 -0
  94. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/dbi/__init__.py +0 -0
  95. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/dbi/account.py +0 -0
  96. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/dbi/message.py +0 -0
  97. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/dbi/session.py +0 -0
  98. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/facebook.py +0 -0
  99. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/messenger.py +0 -0
  100. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/packer.py +0 -0
  101. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/processer.py +0 -0
  102. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/protocol/__init__.py +0 -0
  103. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/protocol/ans.py +0 -0
  104. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/protocol/block.py +0 -0
  105. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/protocol/handshake.py +0 -0
  106. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/protocol/login.py +0 -0
  107. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/protocol/mute.py +0 -0
  108. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/protocol/report.py +0 -0
  109. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/register.py +0 -0
  110. {dimples-1.2.4 → dimples-1.2.5}/dimples/common/session.py +0 -0
  111. {dimples-1.2.4 → dimples-1.2.5}/dimples/conn/__init__.py +0 -0
  112. {dimples-1.2.4 → dimples-1.2.5}/dimples/conn/gate.py +0 -0
  113. {dimples-1.2.4 → dimples-1.2.5}/dimples/conn/gatekeeper.py +0 -0
  114. {dimples-1.2.4 → dimples-1.2.5}/dimples/conn/mars.py +0 -0
  115. {dimples-1.2.4 → dimples-1.2.5}/dimples/conn/mtp.py +0 -0
  116. {dimples-1.2.4 → dimples-1.2.5}/dimples/conn/protocol/__init__.py +0 -0
  117. {dimples-1.2.4 → dimples-1.2.5}/dimples/conn/protocol/mars.py +0 -0
  118. {dimples-1.2.4 → dimples-1.2.5}/dimples/conn/protocol/ws.py +0 -0
  119. {dimples-1.2.4 → dimples-1.2.5}/dimples/conn/queue.py +0 -0
  120. {dimples-1.2.4 → dimples-1.2.5}/dimples/conn/seeker.py +0 -0
  121. {dimples-1.2.4 → dimples-1.2.5}/dimples/conn/session.py +0 -0
  122. {dimples-1.2.4 → dimples-1.2.5}/dimples/conn/ws.py +0 -0
  123. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/dos/__init__.py +0 -0
  124. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/dos/base.py +0 -0
  125. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/dos/group.py +0 -0
  126. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/dos/group_history.py +0 -0
  127. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/dos/group_keys.py +0 -0
  128. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/dos/login.py +0 -0
  129. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/dos/meta.py +0 -0
  130. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/dos/private.py +0 -0
  131. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/dos/station.py +0 -0
  132. {dimples-1.2.4 → dimples-1.2.5}/dimples/database/dos/user.py +0 -0
  133. {dimples-1.2.4 → dimples-1.2.5}/dimples/edge/__init__.py +0 -0
  134. {dimples-1.2.4 → dimples-1.2.5}/dimples/edge/octopus.py +0 -0
  135. {dimples-1.2.4 → dimples-1.2.5}/dimples/edge/start.py +0 -0
  136. {dimples-1.2.4 → dimples-1.2.5}/dimples/group/__init__.py +0 -0
  137. {dimples-1.2.4 → dimples-1.2.5}/dimples/group/admin.py +0 -0
  138. {dimples-1.2.4 → dimples-1.2.5}/dimples/group/builder.py +0 -0
  139. {dimples-1.2.4 → dimples-1.2.5}/dimples/group/delegate.py +0 -0
  140. {dimples-1.2.4 → dimples-1.2.5}/dimples/group/emitter.py +0 -0
  141. {dimples-1.2.4 → dimples-1.2.5}/dimples/group/helper.py +0 -0
  142. {dimples-1.2.4 → dimples-1.2.5}/dimples/group/manager.py +0 -0
  143. {dimples-1.2.4 → dimples-1.2.5}/dimples/group/packer.py +0 -0
  144. {dimples-1.2.4 → dimples-1.2.5}/dimples/register/__init__.py +0 -0
  145. {dimples-1.2.4 → dimples-1.2.5}/dimples/register/base.py +0 -0
  146. {dimples-1.2.4 → dimples-1.2.5}/dimples/register/ext.py +0 -0
  147. {dimples-1.2.4 → dimples-1.2.5}/dimples/register/run.py +0 -0
  148. {dimples-1.2.4 → dimples-1.2.5}/dimples/register/shared.py +0 -0
  149. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/__init__.py +0 -0
  150. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/archivist.py +0 -0
  151. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/cpu/__init__.py +0 -0
  152. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/cpu/ans.py +0 -0
  153. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/cpu/handshake.py +0 -0
  154. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/cpu/report.py +0 -0
  155. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/messenger.py +0 -0
  156. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/packer.py +0 -0
  157. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/push.py +0 -0
  158. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/session.py +0 -0
  159. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/session_center.py +0 -0
  160. {dimples-1.2.4 → dimples-1.2.5}/dimples/server/trace.py +0 -0
  161. {dimples-1.2.4 → dimples-1.2.5}/dimples/station/__init__.py +0 -0
  162. {dimples-1.2.4 → dimples-1.2.5}/dimples/station/handler.py +0 -0
  163. {dimples-1.2.4 → dimples-1.2.5}/dimples/station/start.py +0 -0
  164. {dimples-1.2.4 → dimples-1.2.5}/dimples/utils/config.py +0 -0
  165. {dimples-1.2.4 → dimples-1.2.5}/dimples/utils/log.py +0 -0
  166. {dimples-1.2.4 → dimples-1.2.5}/dimples/utils/runner.py +0 -0
  167. {dimples-1.2.4 → dimples-1.2.5}/dimples.egg-info/dependency_links.txt +0 -0
  168. {dimples-1.2.4 → dimples-1.2.5}/dimples.egg-info/top_level.txt +0 -0
  169. {dimples-1.2.4 → dimples-1.2.5}/setup.cfg +0 -0
dimples-1.2.5/PKG-INFO ADDED
@@ -0,0 +1,22 @@
1
+ Metadata-Version: 2.1
2
+ Name: dimples
3
+ Version: 1.2.5
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
+ Description: # DIMP Library for Edges and Stations (Python version)
10
+
11
+ [![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/dimchat/demo-py/blob/master/LICENSE)
12
+ [![Version](https://img.shields.io/badge/alpha-0.1.0-red.svg)](https://github.com/dimchat/demo-py/wiki)
13
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/dimchat/demo-py/pulls)
14
+ [![Platform](https://img.shields.io/badge/Platform-Python%203-brightgreen.svg)](https://github.com/dimchat/demo-py/wiki)
15
+
16
+ Copyright © 2018-2022 Albert Moky
17
+
18
+ Platform: UNKNOWN
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: License :: OSI Approved :: MIT License
21
+ Classifier: Operating System :: OS Independent
22
+ Description-Content-Type: text/markdown
@@ -28,7 +28,6 @@
28
28
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
29
29
  """
30
30
 
31
- import time
32
31
  from typing import List
33
32
 
34
33
  from dimsdk import DateTime
@@ -120,14 +119,12 @@ class ClientMessageProcessor(CommonMessageProcessor):
120
119
  elif isinstance(res, ReceiptCommand):
121
120
  if sender.type == EntityType.STATION or sender.type == EntityType.BOT:
122
121
  # no need to respond receipt to station
123
- when = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(r_msg.time))
124
- self.info(msg='drop receipt responding to %s, origin msg time=[%s]' % (sender, when))
122
+ self.info(msg='drop receipt to %s, origin msg time=[%s]' % (sender, r_msg.time))
125
123
  continue
126
124
  elif isinstance(res, TextContent):
127
125
  if sender.type == EntityType.STATION or sender.type == EntityType.BOT:
128
126
  # no need to respond text message to station
129
- when = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(r_msg.time))
130
- self.info(msg='drop text responding to %s, origin time=[%s], text=%s' % (sender, when, res.text))
127
+ self.info(msg='drop text to %s, origin time=[%s], text=%s' % (sender, r_msg.time, res.text))
131
128
  continue
132
129
  # normal response
133
130
  await messenger.send_content(sender=receiver, receiver=sender, content=res)
@@ -122,7 +122,7 @@ class FlexibleDocker(StarDocker, DeparturePacker, Logging):
122
122
  cnt = super().purge(now=now)
123
123
  docker = self.__docker
124
124
  if docker is None:
125
- self.warning(msg='docker not ready, failed to purge')
125
+ self.debug(msg='docker not ready, failed to purge')
126
126
  else:
127
127
  cnt += docker.purge(now=now)
128
128
  return cnt
@@ -139,7 +139,7 @@ class FlexibleDocker(StarDocker, DeparturePacker, Logging):
139
139
  async def process(self) -> bool:
140
140
  docker = self.__docker
141
141
  if docker is None:
142
- self.warning(msg='docker not ready, failed to process')
142
+ self.debug(msg='docker not ready, failed to process')
143
143
  return False
144
144
  else:
145
145
  return await docker.process()
@@ -32,6 +32,9 @@
32
32
  from ..common.dbi import *
33
33
 
34
34
  from .dos import *
35
+ from .redis import *
36
+
37
+ from .t_base import DbInfo, DbTask
35
38
 
36
39
  from .t_private import PrivateKeyTable
37
40
  from .t_meta import MetaTable
@@ -78,9 +81,22 @@ __all__ = [
78
81
  'LoginStorage',
79
82
  'StationStorage',
80
83
 
84
+ #
85
+ # Redis
86
+ #
87
+ 'RedisConnector', 'RedisCache',
88
+
89
+ 'MetaCache', 'DocumentCache',
90
+ 'UserCache', 'LoginCache',
91
+ 'GroupCache', 'GroupHistoryCache', 'GroupKeysCache',
92
+ 'MessageCache',
93
+ 'StationCache',
94
+
81
95
  #
82
96
  # Table
83
97
  #
98
+ 'DbInfo', 'DbTask',
99
+
84
100
  'PrivateKeyTable', 'MetaTable', 'DocumentTable',
85
101
  'UserTable', 'GroupTable', 'GroupHistoryTable',
86
102
  'GroupKeysTable',
@@ -32,6 +32,7 @@ from dimsdk import ReliableMessage
32
32
 
33
33
  from ..common import AccountDBI
34
34
 
35
+ from .t_base import DbInfo
35
36
  from .t_private import PrivateKeyTable
36
37
  from .t_meta import MetaTable
37
38
  from .t_document import DocumentTable
@@ -46,22 +47,22 @@ class AccountDatabase(AccountDBI):
46
47
  ~~~~~~~~~~~~~~~~~~~~~~~
47
48
  """
48
49
 
49
- def __init__(self, root: str = None, public: str = None, private: str = None):
50
+ def __init__(self, info: DbInfo):
50
51
  super().__init__()
51
- self.__private_table = PrivateKeyTable(root=root, public=public, private=private)
52
- self.__meta_table = MetaTable(root=root, public=public, private=private)
53
- self.__doc_table = DocumentTable(root=root, public=public, private=private)
54
- self.__user_table = UserTable(root=root, public=public, private=private)
55
- self.__group_table = GroupTable(root=root, public=public, private=private)
56
- self.__history_table = GroupHistoryTable(root=root, public=public, private=private)
52
+ self._private_table = PrivateKeyTable(info=info)
53
+ self._meta_table = MetaTable(info=info)
54
+ self._doc_table = DocumentTable(info=info)
55
+ self._user_table = UserTable(info=info)
56
+ self._group_table = GroupTable(info=info)
57
+ self._history_table = GroupHistoryTable(info=info)
57
58
 
58
59
  def show_info(self):
59
- self.__private_table.show_info()
60
- self.__meta_table.show_info()
61
- self.__doc_table.show_info()
62
- self.__user_table.show_info()
63
- self.__group_table.show_info()
64
- self.__history_table.show_info()
60
+ self._private_table.show_info()
61
+ self._meta_table.show_info()
62
+ self._doc_table.show_info()
63
+ self._user_table.show_info()
64
+ self._group_table.show_info()
65
+ self._history_table.show_info()
65
66
 
66
67
  #
67
68
  # PrivateKey DBI
@@ -69,19 +70,19 @@ class AccountDatabase(AccountDBI):
69
70
 
70
71
  # Override
71
72
  async def save_private_key(self, key: PrivateKey, user: ID, key_type: str = 'M') -> bool:
72
- return await self.__private_table.save_private_key(key=key, user=user, key_type=key_type)
73
+ return await self._private_table.save_private_key(key=key, user=user, key_type=key_type)
73
74
 
74
75
  # Override
75
76
  async def private_keys_for_decryption(self, user: ID) -> List[DecryptKey]:
76
- return await self.__private_table.private_keys_for_decryption(user=user)
77
+ return await self._private_table.private_keys_for_decryption(user=user)
77
78
 
78
79
  # Override
79
80
  async def private_key_for_signature(self, user: ID) -> Optional[SignKey]:
80
- return await self.__private_table.private_key_for_signature(user=user)
81
+ return await self._private_table.private_key_for_signature(user=user)
81
82
 
82
83
  # Override
83
84
  async def private_key_for_visa_signature(self, user: ID) -> Optional[SignKey]:
84
- return await self.__private_table.private_key_for_visa_signature(user=user)
85
+ return await self._private_table.private_key_for_visa_signature(user=user)
85
86
 
86
87
  #
87
88
  # Meta DBI
@@ -92,11 +93,11 @@ class AccountDatabase(AccountDBI):
92
93
  # check meta with ID
93
94
  if not meta.match_identifier(identifier=identifier):
94
95
  raise ValueError('meta not match: %s => %s' % (identifier, meta))
95
- return await self.__meta_table.save_meta(meta=meta, identifier=identifier)
96
+ return await self._meta_table.save_meta(meta=meta, identifier=identifier)
96
97
 
97
98
  # Override
98
99
  async def get_meta(self, identifier: ID) -> Optional[Meta]:
99
- return await self.__meta_table.get_meta(identifier=identifier)
100
+ return await self._meta_table.get_meta(identifier=identifier)
100
101
 
101
102
  #
102
103
  # Document DBI
@@ -105,7 +106,7 @@ class AccountDatabase(AccountDBI):
105
106
  # Override
106
107
  async def save_document(self, document: Document) -> bool:
107
108
  # check meta first
108
- meta = await self.__meta_table.get_meta(identifier=document.identifier)
109
+ meta = await self._meta_table.get_meta(identifier=document.identifier)
109
110
  if meta is None:
110
111
  raise LookupError('meta not exists: %s' % document.identifier)
111
112
  # check document valid before saving it
@@ -115,15 +116,15 @@ class AccountDatabase(AccountDBI):
115
116
  if isinstance(document, Bulletin):
116
117
  founder = document.founder
117
118
  if founder is not None:
118
- f_meta = await self.__meta_table.get_meta(identifier=founder)
119
+ f_meta = await self._meta_table.get_meta(identifier=founder)
119
120
  if f_meta is None or meta.public_key != meta.public_key:
120
121
  raise ValueError('founder error: %s, group: %s' % (founder, document.identifier))
121
122
  # document ok, try to save it
122
- return await self.__doc_table.save_document(document=document)
123
+ return await self._doc_table.save_document(document=document)
123
124
 
124
125
  # Override
125
126
  async def get_documents(self, identifier: ID) -> List[Document]:
126
- return await self.__doc_table.get_documents(identifier=identifier)
127
+ return await self._doc_table.get_documents(identifier=identifier)
127
128
 
128
129
  #
129
130
  # User DBI
@@ -131,19 +132,19 @@ class AccountDatabase(AccountDBI):
131
132
 
132
133
  # Override
133
134
  async def get_local_users(self) -> List[ID]:
134
- return await self.__user_table.get_local_users()
135
+ return await self._user_table.get_local_users()
135
136
 
136
137
  # Override
137
138
  async def save_local_users(self, users: List[ID]) -> bool:
138
- return await self.__user_table.save_local_users(users=users)
139
+ return await self._user_table.save_local_users(users=users)
139
140
 
140
141
  # Override
141
142
  async def get_contacts(self, user: ID) -> List[ID]:
142
- return await self.__user_table.get_contacts(user=user)
143
+ return await self._user_table.get_contacts(user=user)
143
144
 
144
145
  # Override
145
146
  async def save_contacts(self, contacts: List[ID], user: ID) -> bool:
146
- return await self.__user_table.save_contacts(contacts=contacts, user=user)
147
+ return await self._user_table.save_contacts(contacts=contacts, user=user)
147
148
 
148
149
  #
149
150
  # Group DBI
@@ -151,35 +152,35 @@ class AccountDatabase(AccountDBI):
151
152
 
152
153
  # Override
153
154
  async def get_founder(self, group: ID) -> Optional[ID]:
154
- return await self.__group_table.get_founder(group=group)
155
+ return await self._group_table.get_founder(group=group)
155
156
 
156
157
  # Override
157
158
  async def get_owner(self, group: ID) -> Optional[ID]:
158
- return await self.__group_table.get_owner(group=group)
159
+ return await self._group_table.get_owner(group=group)
159
160
 
160
161
  # Override
161
162
  async def get_members(self, group: ID) -> List[ID]:
162
- return await self.__group_table.get_members(group=group)
163
+ return await self._group_table.get_members(group=group)
163
164
 
164
165
  # Override
165
166
  async def save_members(self, members: List[ID], group: ID) -> bool:
166
- return await self.__group_table.save_members(members=members, group=group)
167
+ return await self._group_table.save_members(members=members, group=group)
167
168
 
168
169
  # Override
169
170
  async def get_assistants(self, group: ID) -> List[ID]:
170
- return await self.__group_table.get_assistants(group=group)
171
+ return await self._group_table.get_assistants(group=group)
171
172
 
172
173
  # Override
173
174
  async def save_assistants(self, assistants: List[ID], group: ID) -> bool:
174
- return await self.__group_table.save_assistants(assistants=assistants, group=group)
175
+ return await self._group_table.save_assistants(assistants=assistants, group=group)
175
176
 
176
177
  # Override
177
178
  async def get_administrators(self, group: ID) -> List[ID]:
178
- return await self.__group_table.get_administrators(group=group)
179
+ return await self._group_table.get_administrators(group=group)
179
180
 
180
181
  # Override
181
182
  async def save_administrators(self, administrators: List[ID], group: ID) -> bool:
182
- return await self.__group_table.save_administrators(administrators=administrators, group=group)
183
+ return await self._group_table.save_administrators(administrators=administrators, group=group)
183
184
 
184
185
  #
185
186
  # Group History DBI
@@ -187,20 +188,20 @@ class AccountDatabase(AccountDBI):
187
188
 
188
189
  # Override
189
190
  async def save_group_history(self, group: ID, content: GroupCommand, message: ReliableMessage) -> bool:
190
- return await self.__history_table.save_group_history(group=group, content=content, message=message)
191
+ return await self._history_table.save_group_history(group=group, content=content, message=message)
191
192
 
192
193
  # Override
193
194
  async def get_group_histories(self, group: ID) -> List[Tuple[GroupCommand, ReliableMessage]]:
194
- return await self.__history_table.get_group_histories(group=group)
195
+ return await self._history_table.get_group_histories(group=group)
195
196
 
196
197
  # Override
197
198
  async def get_reset_command_message(self, group: ID) -> Tuple[Optional[ResetCommand], Optional[ReliableMessage]]:
198
- return await self.__history_table.get_reset_command_message(group=group)
199
+ return await self._history_table.get_reset_command_message(group=group)
199
200
 
200
201
  # Override
201
202
  async def clear_group_member_histories(self, group: ID) -> bool:
202
- return await self.__history_table.clear_group_member_histories(group=group)
203
+ return await self._history_table.clear_group_member_histories(group=group)
203
204
 
204
205
  # Override
205
206
  async def clear_group_admin_histories(self, group: ID) -> bool:
206
- return await self.__history_table.clear_group_admin_histories(group=group)
207
+ return await self._history_table.clear_group_admin_histories(group=group)
@@ -40,24 +40,19 @@ class DocumentStorage(Storage, DocumentDBI):
40
40
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41
41
  file path: '.dim/public/{ADDRESS}/documents.js'
42
42
  """
43
- doc_path = '{PUBLIC}/{ADDRESS}/document.js'
44
- all_path = '{PUBLIC}/{ADDRESS}/documents.js'
43
+ docs_path = '{PUBLIC}/{ADDRESS}/documents.js'
45
44
 
46
45
  def show_info(self):
47
- path = self.public_path(self.all_path)
46
+ path = self.public_path(self.docs_path)
48
47
  print('!!! documents path: %s' % path)
49
48
 
50
- def __doc_path(self, identifier: ID) -> str:
51
- path = self.public_path(self.doc_path)
52
- return template_replace(path, key='ADDRESS', value=str(identifier.address))
53
-
54
- def __all_path(self, identifier: ID) -> str:
55
- path = self.public_path(self.all_path)
49
+ def __docs_path(self, identifier: ID) -> str:
50
+ path = self.public_path(self.docs_path)
56
51
  return template_replace(path, key='ADDRESS', value=str(identifier.address))
57
52
 
58
53
  async def save_documents(self, documents: List[Document], identifier: ID) -> bool:
59
54
  """ save documents into file """
60
- path = self.__all_path(identifier=identifier)
55
+ path = self.__docs_path(identifier=identifier)
61
56
  self.info(msg='Saving %d document(s) into: %s' % (len(documents), path))
62
57
  array = []
63
58
  for doc in documents:
@@ -67,7 +62,7 @@ class DocumentStorage(Storage, DocumentDBI):
67
62
 
68
63
  async def load_documents(self, identifier: ID) -> Optional[List[Document]]:
69
64
  """ load documents from file """
70
- path = self.__all_path(identifier=identifier)
65
+ path = self.__docs_path(identifier=identifier)
71
66
  self.info(msg='Loading documents from: %s' % path)
72
67
  array = await self.read_json(path=path)
73
68
  if array is None:
@@ -76,20 +71,11 @@ class DocumentStorage(Storage, DocumentDBI):
76
71
  documents = []
77
72
  for info in array:
78
73
  doc = parse_document(dictionary=info, identifier=identifier)
79
- if info is None:
80
- assert False, 'document error: %s, %s' % (identifier, info)
74
+ assert doc is not None, 'document error: %s, %s' % (identifier, info)
81
75
  documents.append(doc)
82
76
  self.info(msg='Loaded %d documents from: %s' % (len(documents), path))
83
77
  return documents
84
78
 
85
- async def load_document(self, identifier: ID) -> Optional[Document]:
86
- """ load document from file """
87
- path = self.__doc_path(identifier=identifier)
88
- self.info(msg='Loading document from: %s' % path)
89
- info = await self.read_json(path=path)
90
- if info is not None:
91
- return parse_document(dictionary=info, identifier=identifier)
92
-
93
79
  #
94
80
  # Document DBI
95
81
  #
@@ -116,12 +102,8 @@ class DocumentStorage(Storage, DocumentDBI):
116
102
  # Override
117
103
  async def get_documents(self, identifier: ID) -> List[Document]:
118
104
  """ load documents from file """
119
- all_documents = await self.load_documents(identifier=identifier)
120
- if all_documents is not None:
121
- return all_documents
122
- # try old file
123
- doc = await self.load_document(identifier=identifier)
124
- return [] if doc is None else [doc]
105
+ docs = await self.load_documents(identifier=identifier)
106
+ return [] if docs is None else docs
125
107
 
126
108
 
127
109
  def parse_document(dictionary: dict, identifier: ID = None, doc_type: str = '*') -> Optional[Document]:
@@ -31,6 +31,7 @@ from dimsdk import ReliableMessage
31
31
 
32
32
  from ..common import MessageDBI
33
33
 
34
+ from .t_base import DbInfo
34
35
  from .t_group_keys import GroupKeysTable
35
36
  from .t_cipherkey import CipherKeyTable
36
37
  from .t_message import ReliableMessageTable
@@ -42,27 +43,27 @@ class MessageDatabase(MessageDBI):
42
43
  ~~~~~~~~~~~~~~~~~~~~~
43
44
  """
44
45
 
45
- def __init__(self, root: str = None, public: str = None, private: str = None):
46
+ def __init__(self, info: DbInfo):
46
47
  super().__init__()
47
- self.__group_keys_table = GroupKeysTable(root=root, public=public, private=private)
48
- self.__cipher_table = CipherKeyTable(root=root, public=public, private=private)
49
- self.__msg_table = ReliableMessageTable(root=root, public=public, private=private)
48
+ self._group_keys_table = GroupKeysTable(info=info)
49
+ self._cipher_table = CipherKeyTable(info=info)
50
+ self._msg_table = ReliableMessageTable(info=info)
50
51
 
51
52
  def show_info(self):
52
- self.__group_keys_table.show_info()
53
- self.__cipher_table.show_info()
54
- self.__msg_table.show_info()
53
+ self._group_keys_table.show_info()
54
+ self._cipher_table.show_info()
55
+ self._msg_table.show_info()
55
56
 
56
57
  #
57
58
  # GroupKeys DBI
58
59
 
59
60
  # Override
60
61
  async def get_group_keys(self, group: ID, sender: ID) -> Optional[Dict[str, str]]:
61
- return await self.__group_keys_table.get_group_keys(group=group, sender=sender)
62
+ return await self._group_keys_table.get_group_keys(group=group, sender=sender)
62
63
 
63
64
  # Override
64
65
  async def save_group_keys(self, group: ID, sender: ID, keys: Dict[str, str]) -> bool:
65
- return await self.__group_keys_table.save_group_keys(group=group, sender=sender, keys=keys)
66
+ return await self._group_keys_table.save_group_keys(group=group, sender=sender, keys=keys)
66
67
 
67
68
  #
68
69
  # CipherKey DBI
@@ -70,11 +71,11 @@ class MessageDatabase(MessageDBI):
70
71
 
71
72
  # Override
72
73
  async def get_cipher_key(self, sender: ID, receiver: ID, generate: bool = False) -> Optional[SymmetricKey]:
73
- return await self.__cipher_table.get_cipher_key(sender=sender, receiver=receiver, generate=generate)
74
+ return await self._cipher_table.get_cipher_key(sender=sender, receiver=receiver, generate=generate)
74
75
 
75
76
  # Override
76
77
  async def cache_cipher_key(self, key: SymmetricKey, sender: ID, receiver: ID):
77
- return await self.__cipher_table.cache_cipher_key(key=key, sender=sender, receiver=receiver)
78
+ return await self._cipher_table.cache_cipher_key(key=key, sender=sender, receiver=receiver)
78
79
 
79
80
  #
80
81
  # ReliableMessage DBI
@@ -82,12 +83,12 @@ class MessageDatabase(MessageDBI):
82
83
 
83
84
  # Override
84
85
  async def get_reliable_messages(self, receiver: ID, limit: int = 1024) -> List[ReliableMessage]:
85
- return await self.__msg_table.get_reliable_messages(receiver=receiver, limit=limit)
86
+ return await self._msg_table.get_reliable_messages(receiver=receiver, limit=limit)
86
87
 
87
88
  # Override
88
89
  async def cache_reliable_message(self, msg: ReliableMessage, receiver: ID) -> bool:
89
- return await self.__msg_table.cache_reliable_message(msg=msg, receiver=receiver)
90
+ return await self._msg_table.cache_reliable_message(msg=msg, receiver=receiver)
90
91
 
91
92
  # Override
92
93
  async def remove_reliable_message(self, msg: ReliableMessage, receiver: ID) -> bool:
93
- return await self.__msg_table.remove_reliable_message(msg=msg, receiver=receiver)
94
+ return await self._msg_table.remove_reliable_message(msg=msg, receiver=receiver)
@@ -0,0 +1,59 @@
1
+ # -*- coding: utf-8 -*-
2
+ # ==============================================================================
3
+ # MIT License
4
+ #
5
+ # Copyright (c) 2021 Albert Moky
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ # ==============================================================================
25
+
26
+ """
27
+ Database module
28
+ ~~~~~~~~~~~~~~~
29
+ Redis Client
30
+ """
31
+
32
+ from .base import RedisConnector
33
+ from .base import Cache as RedisCache
34
+
35
+ from .meta import MetaCache
36
+ from .document import DocumentCache
37
+ from .user import UserCache
38
+ from .login import LoginCache
39
+ from .group import GroupCache
40
+ from .grp_history import GroupHistoryCache
41
+ from .grp_keys import GroupKeysCache
42
+ from .message import MessageCache
43
+ from .station import StationCache
44
+
45
+
46
+ __all__ = [
47
+
48
+ 'RedisConnector',
49
+ 'RedisCache',
50
+
51
+ 'MetaCache',
52
+ 'DocumentCache',
53
+ 'UserCache', 'LoginCache',
54
+ 'GroupCache', 'GroupHistoryCache',
55
+ 'GroupKeysCache',
56
+ 'MessageCache',
57
+ 'StationCache',
58
+
59
+ ]
@@ -0,0 +1,105 @@
1
+ # -*- coding: utf-8 -*-
2
+ # ==============================================================================
3
+ # MIT License
4
+ #
5
+ # Copyright (c) 2021 Albert Moky
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ # ==============================================================================
25
+
26
+ from abc import ABC, abstractmethod
27
+ from typing import Optional
28
+
29
+ from aiou import Redis
30
+ from aiou import RedisClient
31
+ from aiou import RedisConnector
32
+
33
+
34
+ class Cache(RedisClient, ABC):
35
+
36
+ @property
37
+ @abstractmethod
38
+ def db_name(self) -> Optional[str]:
39
+ """ database name for redis """
40
+ raise NotImplemented
41
+
42
+ @property
43
+ @abstractmethod
44
+ def tbl_name(self) -> str:
45
+ """ table name for redis """
46
+ raise NotImplemented
47
+
48
+ # protected
49
+ def get_redis(self, name: str) -> Optional[Redis]:
50
+ """ Get Redis with name
51
+
52
+ 0 - default
53
+ 1 - mkm.meta
54
+ 2 - mkm.document
55
+ 3 - mkm.user
56
+ 4 - mkm.group
57
+ 5
58
+ 6
59
+ 7 - mkm.session
60
+ 8 - dkd.msg
61
+ 9 - dkd.key
62
+ """
63
+ connector = self.connector
64
+ if connector is None:
65
+ return None
66
+ else:
67
+ assert isinstance(connector, RedisConnector)
68
+ if name == 'default':
69
+ return connector.connect(db=0)
70
+ #
71
+ # MingKeMing
72
+ #
73
+ elif name == 'mkm.meta':
74
+ return connector.connect(db=1)
75
+ elif name == 'mkm.document':
76
+ return connector.connect(db=2)
77
+ elif name == 'mkm.user':
78
+ return connector.connect(db=3)
79
+ elif name == 'mkm.group':
80
+ return connector.connect(db=4)
81
+ #
82
+ # Session
83
+ #
84
+ elif name == 'mkm.session':
85
+ return connector.connect(db=7)
86
+ #
87
+ # DaoKeDao
88
+ #
89
+ elif name == 'dkd.msg':
90
+ return connector.connect(db=8)
91
+ elif name == 'dkd.key':
92
+ return connector.connect(db=9)
93
+
94
+ @property # Override
95
+ def redis(self) -> Optional[Redis]:
96
+ db_name = self.db_name
97
+ tbl_name = self.tbl_name
98
+ db = None
99
+ if db_name is not None:
100
+ db = self.get_redis(name='%s.%s' % (db_name, tbl_name))
101
+ if db is None:
102
+ db = self.get_redis(name=tbl_name)
103
+ if db is None:
104
+ db = super().redis
105
+ return db