dimples 1.5.1__tar.gz → 1.5.2__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.
- {dimples-1.5.1 → dimples-1.5.2}/PKG-INFO +1 -1
- {dimples-1.5.1 → dimples-1.5.2}/dimples/__init__.py +0 -2
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/__init__.py +4 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/facebook.py +11 -7
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/messenger.py +2 -1
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/packer.py +3 -3
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/processor.py +3 -4
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/__init__.py +0 -2
- dimples-1.5.2/dimples/common/archivist.py +223 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/checker.py +5 -4
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/compat/__init__.py +6 -2
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/compat/compatible.py +36 -28
- dimples-1.5.2/dimples/common/compat/compressor.py +68 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/compat/loader.py +15 -15
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/facebook.py +39 -148
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/messenger.py +14 -44
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/packer.py +28 -4
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/protocol/__init__.py +0 -4
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/protocol/ans.py +1 -1
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/protocol/handshake.py +1 -1
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/protocol/login.py +1 -1
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/protocol/report.py +2 -1
- {dimples-1.5.1 → dimples-1.5.2}/dimples/edge/shared.py +4 -3
- {dimples-1.5.1 → dimples-1.5.2}/dimples/group/delegate.py +2 -1
- {dimples-1.5.1 → dimples-1.5.2}/dimples/register/shared.py +2 -2
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/messenger.py +4 -1
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/processor.py +4 -1
- {dimples-1.5.1 → dimples-1.5.2}/dimples/station/shared.py +4 -3
- {dimples-1.5.1 → dimples-1.5.2}/dimples/utils/thanos.py +4 -1
- {dimples-1.5.1 → dimples-1.5.2}/dimples.egg-info/PKG-INFO +1 -1
- {dimples-1.5.1 → dimples-1.5.2}/dimples.egg-info/SOURCES.txt +1 -1
- {dimples-1.5.1 → dimples-1.5.2}/dimples.egg-info/requires.txt +2 -3
- {dimples-1.5.1 → dimples-1.5.2}/setup.py +6 -6
- dimples-1.5.1/dimples/common/archivist.py +0 -106
- dimples-1.5.1/dimples/common/protocol/group.py +0 -96
- {dimples-1.5.1 → dimples-1.5.2}/LICENSE +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/README.md +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/checker.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/checkpoint.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/cpu/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/cpu/commands.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/cpu/creator.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/cpu/customized.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/cpu/group.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/cpu/grp_expel.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/cpu/grp_invite.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/cpu/grp_join.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/cpu/grp_query.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/cpu/grp_quit.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/cpu/grp_reset.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/cpu/grp_resign.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/cpu/handshake.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/network/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/network/session.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/network/state.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/network/transition.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/client/terminal.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/anonymous.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/ans.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/compat/address.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/compat/entity.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/compat/meta.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/compat/network.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/dbi/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/dbi/account.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/dbi/message.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/dbi/session.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/processer.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/protocol/block.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/protocol/customized.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/protocol/mute.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/protocol/password.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/protocol/roles.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/protocol/utils.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/protocol/version.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/queue.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/register.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/common/session.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/conn/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/conn/flexible.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/conn/gate.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/conn/gatekeeper.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/conn/mars.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/conn/mtp.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/conn/protocol/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/conn/protocol/mars.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/conn/protocol/ws.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/conn/queue.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/conn/seeker.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/conn/session.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/conn/ws.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/account.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/dos/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/dos/base.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/dos/document.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/dos/group.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/dos/group_history.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/dos/group_keys.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/dos/login.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/dos/meta.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/dos/private.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/dos/station.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/dos/user.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/message.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/redis/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/redis/base.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/redis/document.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/redis/group.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/redis/grp_history.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/redis/grp_keys.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/redis/login.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/redis/message.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/redis/meta.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/redis/station.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/redis/user.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/session.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/t_base.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/t_cipherkey.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/t_document.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/t_group.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/t_group_history.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/t_group_keys.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/t_login.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/t_message.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/t_meta.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/t_private.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/t_station.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/database/t_user.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/edge/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/edge/messenger.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/edge/octopus.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/edge/start.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/emitter.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/group/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/group/admin.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/group/builder.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/group/emitter.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/group/helper.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/group/manager.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/group/packer.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/group/shared.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/register/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/register/base.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/register/ext.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/register/run.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/checker.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/cpu/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/cpu/ans.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/cpu/creator.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/cpu/document.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/cpu/handshake.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/cpu/login.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/cpu/report.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/deliver.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/dis_roamer.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/dispatcher.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/facebook.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/packer.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/push.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/session.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/session_center.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/server/trace.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/station/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/station/handler.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/station/start.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/utils/__init__.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/utils/cache.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/utils/checker.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/utils/config.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/utils/http.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples/utils/log.py +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples.egg-info/dependency_links.txt +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples.egg-info/entry_points.txt +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/dimples.egg-info/top_level.txt +0 -0
- {dimples-1.5.1 → dimples-1.5.2}/setup.cfg +0 -0
|
@@ -35,7 +35,9 @@ from .network import SessionState
|
|
|
35
35
|
from .checkpoint import Checkpoint
|
|
36
36
|
from .checker import ClientChecker
|
|
37
37
|
|
|
38
|
+
from .facebook import ClientArchivist
|
|
38
39
|
from .facebook import ClientFacebook
|
|
40
|
+
|
|
39
41
|
from .messenger import ClientMessenger
|
|
40
42
|
from .packer import ClientMessagePacker
|
|
41
43
|
from .processor import ClientMessageProcessor
|
|
@@ -58,7 +60,9 @@ __all__ = [
|
|
|
58
60
|
'Checkpoint',
|
|
59
61
|
'ClientChecker',
|
|
60
62
|
|
|
63
|
+
'ClientArchivist',
|
|
61
64
|
'ClientFacebook',
|
|
65
|
+
|
|
62
66
|
'ClientMessenger',
|
|
63
67
|
'ClientMessagePacker',
|
|
64
68
|
'ClientMessageProcessor',
|
|
@@ -39,17 +39,16 @@ from dimsdk import Group
|
|
|
39
39
|
from ..utils import Runner
|
|
40
40
|
from ..common import BroadcastUtils
|
|
41
41
|
from ..common import CommonFacebook
|
|
42
|
+
from ..common import CommonArchivist
|
|
42
43
|
from ..group import SharedGroupManager
|
|
43
44
|
|
|
44
45
|
|
|
45
|
-
class
|
|
46
|
+
class ClientArchivist(CommonArchivist):
|
|
46
47
|
|
|
47
48
|
# Override
|
|
48
|
-
|
|
49
|
-
group =
|
|
50
|
-
|
|
51
|
-
group.data_source = SharedGroupManager()
|
|
52
|
-
return group
|
|
49
|
+
def cache_group(self, group: Group):
|
|
50
|
+
group.data_source = SharedGroupManager()
|
|
51
|
+
super().cache_group(group=group)
|
|
53
52
|
|
|
54
53
|
# Override
|
|
55
54
|
async def save_document(self, document: Document) -> bool:
|
|
@@ -61,9 +60,14 @@ class ClientFacebook(CommonFacebook):
|
|
|
61
60
|
group = document.identifier
|
|
62
61
|
assert group.is_group, 'group ID error: %s' % group
|
|
63
62
|
admins = ID.convert(array=array)
|
|
64
|
-
|
|
63
|
+
db = self.database
|
|
64
|
+
ok = await db.save_administrators(administrators=admins, group=group)
|
|
65
65
|
return ok
|
|
66
66
|
|
|
67
|
+
|
|
68
|
+
class ClientFacebook(CommonFacebook):
|
|
69
|
+
""" Client Facebook with Address Name Service """
|
|
70
|
+
|
|
67
71
|
#
|
|
68
72
|
# Group DataSource
|
|
69
73
|
#
|
|
@@ -167,6 +167,7 @@ class ClientMessenger(CommonMessenger):
|
|
|
167
167
|
|
|
168
168
|
async def _update_visa(self) -> Optional[Visa]:
|
|
169
169
|
facebook = self.facebook
|
|
170
|
+
archivist = facebook.archivist
|
|
170
171
|
user = await facebook.current_user
|
|
171
172
|
assert user is not None, 'current user not found'
|
|
172
173
|
# 1. get sign key for current user
|
|
@@ -189,7 +190,7 @@ class ClientMessenger(CommonMessenger):
|
|
|
189
190
|
})
|
|
190
191
|
if visa.sign(private_key=pri_key) is None:
|
|
191
192
|
self.error(msg='failed to sign visa: %s, private key: %s' % (visa, pri_key))
|
|
192
|
-
elif await
|
|
193
|
+
elif await archivist.save_document(document=visa):
|
|
193
194
|
self.info(msg='visa updated: %s' % visa)
|
|
194
195
|
return visa
|
|
195
196
|
else:
|
|
@@ -73,7 +73,7 @@ class ClientMessagePacker(CommonMessagePacker):
|
|
|
73
73
|
'message': 'group not ready',
|
|
74
74
|
'group': str(receiver),
|
|
75
75
|
}
|
|
76
|
-
self.
|
|
76
|
+
self.suspend_instant_message(msg=msg, error=error)
|
|
77
77
|
return False
|
|
78
78
|
#
|
|
79
79
|
# check group members' visa key
|
|
@@ -92,7 +92,7 @@ class ClientMessagePacker(CommonMessagePacker):
|
|
|
92
92
|
'group': str(receiver),
|
|
93
93
|
'members': ID.revert(identifiers=waiting),
|
|
94
94
|
}
|
|
95
|
-
self.
|
|
95
|
+
self.suspend_instant_message(msg=msg, error=error)
|
|
96
96
|
# perhaps some members have already disappeared,
|
|
97
97
|
# although the packer will query document when the member's visa key is not found,
|
|
98
98
|
# but the station will never respond with the right document,
|
|
@@ -129,7 +129,7 @@ class ClientMessagePacker(CommonMessagePacker):
|
|
|
129
129
|
'message': 'group not ready',
|
|
130
130
|
'group': str(receiver),
|
|
131
131
|
}
|
|
132
|
-
self.
|
|
132
|
+
self.suspend_reliable_message(msg=msg, error=error) # msg['error'] = error
|
|
133
133
|
return False
|
|
134
134
|
|
|
135
135
|
# Override
|
|
@@ -114,11 +114,10 @@ class ClientMessageProcessor(CommonMessageProcessor):
|
|
|
114
114
|
return responses
|
|
115
115
|
sender = r_msg.sender
|
|
116
116
|
receiver = r_msg.receiver
|
|
117
|
-
|
|
118
|
-
if
|
|
117
|
+
me = await self.facebook.select_local_user(receiver=receiver)
|
|
118
|
+
if me is None:
|
|
119
119
|
# assert False, 'receiver error: %s' % receiver
|
|
120
120
|
return responses
|
|
121
|
-
receiver = user.identifier
|
|
122
121
|
messenger = self.messenger
|
|
123
122
|
# check responses
|
|
124
123
|
from_bots = sender.type == EntityType.STATION or sender.type == EntityType.BOT
|
|
@@ -137,6 +136,6 @@ class ClientMessageProcessor(CommonMessageProcessor):
|
|
|
137
136
|
self.info(msg='drop text to %s, origin time=[%s], text=%s' % (sender, r_msg.time, res.text))
|
|
138
137
|
continue
|
|
139
138
|
# normal response
|
|
140
|
-
await messenger.send_content(sender=
|
|
139
|
+
await messenger.send_content(sender=me, receiver=sender, content=res, priority=1)
|
|
141
140
|
# DON'T respond to station directly
|
|
142
141
|
return []
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# DIM-SDK : Decentralized Instant Messaging Software Development Kit
|
|
4
|
+
#
|
|
5
|
+
# Written in 2023 by Moky <albert.moky@gmail.com>
|
|
6
|
+
#
|
|
7
|
+
# ==============================================================================
|
|
8
|
+
# MIT License
|
|
9
|
+
#
|
|
10
|
+
# Copyright (c) 2023 Albert Moky
|
|
11
|
+
#
|
|
12
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
# in the Software without restriction, including without limitation the rights
|
|
15
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
# furnished to do so, subject to the following conditions:
|
|
18
|
+
#
|
|
19
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
# copies or substantial portions of the Software.
|
|
21
|
+
#
|
|
22
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
# SOFTWARE.
|
|
29
|
+
# ==============================================================================
|
|
30
|
+
|
|
31
|
+
import weakref
|
|
32
|
+
from typing import Optional, List
|
|
33
|
+
|
|
34
|
+
from dimsdk import DateTime
|
|
35
|
+
from dimsdk import VerifyKey, EncryptKey
|
|
36
|
+
from dimsdk import ID, Meta, Document
|
|
37
|
+
from dimsdk import MetaUtils, DocumentUtils
|
|
38
|
+
from dimsdk import User, Group
|
|
39
|
+
from dimsdk import Facebook
|
|
40
|
+
from dimsdk import Archivist
|
|
41
|
+
from dimsdk import Barrack
|
|
42
|
+
|
|
43
|
+
from ..utils import Logging
|
|
44
|
+
from ..utils import MemoryCache, ThanosCache
|
|
45
|
+
|
|
46
|
+
from .dbi import AccountDBI
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class CommonArchivist(Barrack, Archivist, Logging):
|
|
50
|
+
|
|
51
|
+
def __init__(self, facebook: Facebook, database: AccountDBI):
|
|
52
|
+
super().__init__()
|
|
53
|
+
self.__facebook = weakref.ref(facebook)
|
|
54
|
+
self.__database = database
|
|
55
|
+
# memory caches
|
|
56
|
+
self.__user_cache = self._create_user_cache()
|
|
57
|
+
self.__group_cache = self._create_group_cache()
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def facebook(self) -> Optional[Facebook]:
|
|
61
|
+
return self.__facebook()
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def database(self) -> AccountDBI:
|
|
65
|
+
return self.__database
|
|
66
|
+
|
|
67
|
+
# noinspection PyMethodMayBeStatic
|
|
68
|
+
def _create_user_cache(self) -> MemoryCache[ID, User]:
|
|
69
|
+
return ThanosCache()
|
|
70
|
+
|
|
71
|
+
# noinspection PyMethodMayBeStatic
|
|
72
|
+
def _create_group_cache(self) -> MemoryCache[ID, Group]:
|
|
73
|
+
return ThanosCache()
|
|
74
|
+
|
|
75
|
+
def reduce_memory(self):
|
|
76
|
+
"""
|
|
77
|
+
Call it when received 'UIApplicationDidReceiveMemoryWarningNotification',
|
|
78
|
+
this will remove 50% of cached objects
|
|
79
|
+
|
|
80
|
+
:return: number of survivors
|
|
81
|
+
"""
|
|
82
|
+
cnt1 = self.__user_cache.reduce_memory()
|
|
83
|
+
cnt2 = self.__group_cache.reduce_memory()
|
|
84
|
+
return cnt1 + cnt2
|
|
85
|
+
|
|
86
|
+
#
|
|
87
|
+
# Barrack
|
|
88
|
+
#
|
|
89
|
+
|
|
90
|
+
# Override
|
|
91
|
+
def cache_user(self, user: User):
|
|
92
|
+
if user.data_source is None:
|
|
93
|
+
user.data_source = self.facebook
|
|
94
|
+
self.__user_cache.put(key=user.identifier, value=user)
|
|
95
|
+
|
|
96
|
+
# Override
|
|
97
|
+
def cache_group(self, group: Group):
|
|
98
|
+
if group.data_source is None:
|
|
99
|
+
group.data_source = self.facebook
|
|
100
|
+
self.__group_cache.put(key=group.identifier, value=group)
|
|
101
|
+
|
|
102
|
+
# Override
|
|
103
|
+
def get_user(self, identifier: ID):
|
|
104
|
+
return self.__user_cache.get(key=identifier)
|
|
105
|
+
|
|
106
|
+
# Override
|
|
107
|
+
def get_group(self, identifier: ID):
|
|
108
|
+
return self.__group_cache.get(key=identifier)
|
|
109
|
+
|
|
110
|
+
#
|
|
111
|
+
# Archivist
|
|
112
|
+
#
|
|
113
|
+
|
|
114
|
+
# Override
|
|
115
|
+
async def save_meta(self, meta: Meta, identifier: ID) -> bool:
|
|
116
|
+
#
|
|
117
|
+
# 1. check valid
|
|
118
|
+
#
|
|
119
|
+
if not self.check_meta(meta=meta, identifier=identifier):
|
|
120
|
+
self.warning(msg='meta not valid: %s' % identifier)
|
|
121
|
+
return False
|
|
122
|
+
#
|
|
123
|
+
# 2. check duplicated
|
|
124
|
+
#
|
|
125
|
+
old = await self.facebook.get_meta(identifier=identifier)
|
|
126
|
+
if old is not None:
|
|
127
|
+
self.debug(msg='meta duplicated: %s' % identifier)
|
|
128
|
+
return True
|
|
129
|
+
#
|
|
130
|
+
# 3. save into database
|
|
131
|
+
#
|
|
132
|
+
db = self.database
|
|
133
|
+
return await db.save_meta(meta=meta, identifier=identifier)
|
|
134
|
+
|
|
135
|
+
# protected
|
|
136
|
+
def check_meta(self, meta: Meta, identifier: ID) -> bool:
|
|
137
|
+
if meta.valid:
|
|
138
|
+
return MetaUtils.match_identifier(identifier=identifier, meta=meta)
|
|
139
|
+
else:
|
|
140
|
+
self.warning(msg='meta error: %s -> %s' % (meta, identifier))
|
|
141
|
+
|
|
142
|
+
# Override
|
|
143
|
+
async def save_document(self, document: Document) -> bool:
|
|
144
|
+
#
|
|
145
|
+
# 1. check valid
|
|
146
|
+
#
|
|
147
|
+
valid = await self.check_document(document=document)
|
|
148
|
+
if not valid:
|
|
149
|
+
self.warning(msg='meta not valid: %s' % document.identifier)
|
|
150
|
+
return False
|
|
151
|
+
#
|
|
152
|
+
# 2. check expired
|
|
153
|
+
#
|
|
154
|
+
expired = await self.is_document_expired(document=document)
|
|
155
|
+
if expired:
|
|
156
|
+
self.info(msg='drop expired document: %s' % document)
|
|
157
|
+
return False
|
|
158
|
+
#
|
|
159
|
+
# 3. save into database
|
|
160
|
+
#
|
|
161
|
+
db = self.database
|
|
162
|
+
return await db.save_document(document=document)
|
|
163
|
+
|
|
164
|
+
# protected
|
|
165
|
+
async def check_document(self, document: Document) -> bool:
|
|
166
|
+
identifier = document.identifier
|
|
167
|
+
doc_time = document.time
|
|
168
|
+
# check document time
|
|
169
|
+
if doc_time is None:
|
|
170
|
+
self.warning(msg='document without time: %s' % identifier)
|
|
171
|
+
else:
|
|
172
|
+
# calibrate the clock
|
|
173
|
+
# make sure the document time is not in the far future
|
|
174
|
+
near_future = DateTime.current_timestamp() + 30 * 60
|
|
175
|
+
if doc_time > near_future:
|
|
176
|
+
self.error(msg='document time error: %s, %s' % (doc_time, identifier))
|
|
177
|
+
return False
|
|
178
|
+
# check valid
|
|
179
|
+
return await self.verify_document(document=document)
|
|
180
|
+
|
|
181
|
+
# protected
|
|
182
|
+
async def verify_document(self, document: Document) -> bool:
|
|
183
|
+
if document.valid:
|
|
184
|
+
return True
|
|
185
|
+
else:
|
|
186
|
+
identifier = document.identifier
|
|
187
|
+
meta = await self.facebook.get_meta(identifier=identifier)
|
|
188
|
+
if meta is None:
|
|
189
|
+
self.warning(msg='failed to get meta: %s' % identifier)
|
|
190
|
+
else:
|
|
191
|
+
return document.verify(public_key=meta.public_key)
|
|
192
|
+
|
|
193
|
+
# protected
|
|
194
|
+
async def is_document_expired(self, document: Document) -> bool:
|
|
195
|
+
identifier = document.identifier
|
|
196
|
+
doc_type = DocumentUtils.get_document_type(document=document)
|
|
197
|
+
if doc_type is None:
|
|
198
|
+
doc_type = '*'
|
|
199
|
+
# check old documents with type
|
|
200
|
+
docs = await self.facebook.get_documents(identifier=identifier)
|
|
201
|
+
if docs is None or len(docs) == 0:
|
|
202
|
+
return False
|
|
203
|
+
old = DocumentUtils.last_document(documents=docs, doc_type=doc_type)
|
|
204
|
+
return old is not None and DocumentUtils.is_expired(this_doc=document, old_doc=old)
|
|
205
|
+
|
|
206
|
+
# Override
|
|
207
|
+
async def get_meta_key(self, identifier: ID) -> Optional[VerifyKey]:
|
|
208
|
+
meta = await self.facebook.get_meta(identifier=identifier)
|
|
209
|
+
if meta is not None:
|
|
210
|
+
return meta.public_key
|
|
211
|
+
|
|
212
|
+
# Override
|
|
213
|
+
async def get_visa_key(self, identifier: ID) -> Optional[EncryptKey]:
|
|
214
|
+
docs = await self.facebook.get_documents(identifier=identifier)
|
|
215
|
+
if docs is None or len(docs) == 0:
|
|
216
|
+
return None
|
|
217
|
+
visa = DocumentUtils.last_visa(documents=docs)
|
|
218
|
+
if visa is not None:
|
|
219
|
+
return visa.public_key
|
|
220
|
+
|
|
221
|
+
# Override
|
|
222
|
+
async def local_users(self) -> List[ID]:
|
|
223
|
+
return await self.database.get_local_users()
|
|
@@ -34,12 +34,13 @@ from typing import Optional, List, Dict
|
|
|
34
34
|
from dimsdk import DateTime
|
|
35
35
|
from dimsdk import ID, Meta, Document, Visa
|
|
36
36
|
|
|
37
|
+
from ..utils import Logging
|
|
37
38
|
from ..utils import FrequencyChecker, RecentTimeChecker
|
|
38
39
|
|
|
39
40
|
from .dbi import AccountDBI
|
|
40
41
|
|
|
41
42
|
|
|
42
|
-
class EntityChecker(ABC):
|
|
43
|
+
class EntityChecker(Logging, ABC):
|
|
43
44
|
|
|
44
45
|
# each query will be expired after 10 minutes
|
|
45
46
|
QUERY_EXPIRES = 10 * 60
|
|
@@ -174,7 +175,7 @@ class EntityChecker(ABC):
|
|
|
174
175
|
doc_time = doc.time
|
|
175
176
|
if doc_time is None:
|
|
176
177
|
# assert False, 'document error: %s' % doc
|
|
177
|
-
|
|
178
|
+
self.warning(msg='document time error: %s' % doc)
|
|
178
179
|
elif last_time is None or last_time < doc_time:
|
|
179
180
|
last_time = doc_time
|
|
180
181
|
# OK
|
|
@@ -221,8 +222,8 @@ class EntityChecker(ABC):
|
|
|
221
222
|
for cmd, _ in array:
|
|
222
223
|
his_time = cmd.time
|
|
223
224
|
if his_time is None:
|
|
224
|
-
assert False, 'group command error: %s' % cmd
|
|
225
|
-
|
|
225
|
+
# assert False, 'group command error: %s' % cmd
|
|
226
|
+
self.warning(msg='group command time error: %s' % cmd)
|
|
226
227
|
elif last_time is None or last_time < his_time:
|
|
227
228
|
last_time = his_time
|
|
228
229
|
# OK
|
|
@@ -38,9 +38,11 @@ from .address import UnknownAddress
|
|
|
38
38
|
|
|
39
39
|
from .meta import CompatibleMetaFactory
|
|
40
40
|
|
|
41
|
-
from .loader import
|
|
41
|
+
from .loader import CommonExtensionLoader
|
|
42
42
|
from .loader import CommonPluginLoader
|
|
43
|
+
from .loader import LibraryLoader
|
|
43
44
|
|
|
45
|
+
from .compressor import CompatibleCompressor # , CompatibleShortener
|
|
44
46
|
from .compatible import Compatible, CompatibleIncoming, CompatibleOutgoing
|
|
45
47
|
|
|
46
48
|
|
|
@@ -56,9 +58,11 @@ __all__ = [
|
|
|
56
58
|
|
|
57
59
|
'CompatibleMetaFactory',
|
|
58
60
|
|
|
59
|
-
'
|
|
61
|
+
'CommonExtensionLoader',
|
|
60
62
|
'CommonPluginLoader',
|
|
63
|
+
'LibraryLoader',
|
|
61
64
|
|
|
65
|
+
'CompatibleCompressor', # 'CompatibleShortener',
|
|
62
66
|
'Compatible', 'CompatibleIncoming', 'CompatibleOutgoing',
|
|
63
67
|
|
|
64
68
|
]
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Ming-Ke-Ming : Decentralized User Identity Authentication
|
|
4
|
-
#
|
|
5
|
-
# Written in 2022 by Moky <albert.moky@gmail.com>
|
|
6
|
-
#
|
|
7
2
|
# ==============================================================================
|
|
8
3
|
# MIT License
|
|
9
4
|
#
|
|
@@ -57,7 +52,7 @@ class Compatible:
|
|
|
57
52
|
def fix_meta_attachment(cls, msg: ReliableMessage):
|
|
58
53
|
meta = msg.get('meta')
|
|
59
54
|
if meta is not None:
|
|
60
|
-
|
|
55
|
+
_fix_meta_version(meta=meta)
|
|
61
56
|
|
|
62
57
|
@classmethod
|
|
63
58
|
def fix_meta_version(cls, meta: Dict[str, Any]):
|
|
@@ -67,7 +62,7 @@ class Compatible:
|
|
|
67
62
|
def fix_visa_attachment(cls, msg: ReliableMessage):
|
|
68
63
|
visa = msg.get('visa')
|
|
69
64
|
if visa is not None:
|
|
70
|
-
|
|
65
|
+
_fix_doc_id(document=visa)
|
|
71
66
|
|
|
72
67
|
@classmethod
|
|
73
68
|
def fix_document_id(cls, document: Dict[str, Any]):
|
|
@@ -76,32 +71,40 @@ class Compatible:
|
|
|
76
71
|
|
|
77
72
|
def _fix_cmd(content: Dict[str, Any]):
|
|
78
73
|
cmd = content.get('command')
|
|
79
|
-
if cmd is
|
|
80
|
-
# command
|
|
81
|
-
if 'cmd' not in content:
|
|
82
|
-
content['cmd'] = cmd
|
|
83
|
-
else:
|
|
84
|
-
# cmd to command
|
|
74
|
+
if cmd is None:
|
|
75
|
+
# 'command' not exists, copy the value from 'cmd'
|
|
85
76
|
cmd = content.get('cmd')
|
|
86
77
|
if cmd is not None:
|
|
87
78
|
content['command'] = cmd
|
|
79
|
+
else:
|
|
80
|
+
assert False, 'command error: %s' % content
|
|
81
|
+
elif 'cmd' in content:
|
|
82
|
+
# these two values must be equal
|
|
83
|
+
assert content.get('cmd') == cmd, 'command error: %s' % content
|
|
84
|
+
else:
|
|
85
|
+
# copy value from 'command' to 'cmd'
|
|
86
|
+
content['cmd'] = cmd
|
|
88
87
|
|
|
89
88
|
|
|
90
89
|
def _fix_did(content: Dict[str, Any]):
|
|
91
90
|
did = content.get('did')
|
|
92
|
-
if did is
|
|
93
|
-
# did
|
|
94
|
-
if 'ID' not in content:
|
|
95
|
-
content['ID'] = did
|
|
96
|
-
else:
|
|
97
|
-
# ID to did
|
|
91
|
+
if did is None:
|
|
92
|
+
# 'did' not exists, copy the value from 'ID'
|
|
98
93
|
did = content.get('ID')
|
|
99
94
|
if did is not None:
|
|
100
95
|
content['did'] = did
|
|
96
|
+
# else:
|
|
97
|
+
# assert False, 'did not exists: %s' % content
|
|
98
|
+
elif 'ID' in content:
|
|
99
|
+
# these two values must be equal
|
|
100
|
+
assert content.get('ID') == did, 'did error: %s' % content
|
|
101
|
+
else:
|
|
102
|
+
# copy value from 'did' to 'ID'
|
|
103
|
+
content['ID'] = did
|
|
101
104
|
|
|
102
105
|
|
|
103
106
|
def _fix_doc_id(document: Dict[str, Any]):
|
|
104
|
-
# 'ID' <-> 'did
|
|
107
|
+
# 'ID' <-> 'did'
|
|
105
108
|
_fix_did(document)
|
|
106
109
|
return document
|
|
107
110
|
|
|
@@ -133,7 +136,14 @@ def _fix_file_content(content: Dict[str, Any]):
|
|
|
133
136
|
pwd = content.get('password')
|
|
134
137
|
if pwd is not None:
|
|
135
138
|
content['key'] = pwd
|
|
136
|
-
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
_file_types = [
|
|
142
|
+
ContentType.FILE, 'file',
|
|
143
|
+
ContentType.IMAGE, 'image',
|
|
144
|
+
ContentType.AUDIO, 'audio',
|
|
145
|
+
ContentType.VIDEO, 'video',
|
|
146
|
+
]
|
|
137
147
|
|
|
138
148
|
|
|
139
149
|
# TODO: remove after all server/client upgraded
|
|
@@ -145,10 +155,7 @@ class CompatibleIncoming:
|
|
|
145
155
|
msg_type = content.get('type')
|
|
146
156
|
msg_type = Converter.get_str(value=msg_type, default='')
|
|
147
157
|
|
|
148
|
-
if msg_type
|
|
149
|
-
msg_type == ContentType.IMAGE or msg_type == 'image' or \
|
|
150
|
-
msg_type == ContentType.AUDIO or msg_type == 'audio' or \
|
|
151
|
-
msg_type == ContentType.VIDEO or msg_type == 'video':
|
|
158
|
+
if msg_type in _file_types:
|
|
152
159
|
# 1. 'key' <-> 'password'
|
|
153
160
|
_fix_file_content(content=content)
|
|
154
161
|
return
|
|
@@ -174,12 +181,13 @@ class CompatibleIncoming:
|
|
|
174
181
|
|
|
175
182
|
if cmd == LoginCommand.LOGIN:
|
|
176
183
|
# 2. 'ID' <-> 'did'
|
|
177
|
-
|
|
184
|
+
_fix_did(content=content)
|
|
178
185
|
return
|
|
179
186
|
|
|
180
187
|
if cmd == Command.DOCUMENTS or cmd == 'document':
|
|
181
|
-
# 2.
|
|
188
|
+
# 2. cmd: 'document' -> 'documents'
|
|
182
189
|
cls._fix_docs(content=content)
|
|
190
|
+
|
|
183
191
|
if cmd == Command.META or cmd == Command.DOCUMENTS or cmd == 'document':
|
|
184
192
|
# 3. 'ID' <-> 'did'
|
|
185
193
|
_fix_did(content=content)
|
|
@@ -197,7 +205,7 @@ class CompatibleIncoming:
|
|
|
197
205
|
# 'document' -> 'documents'
|
|
198
206
|
doc = content.get('document')
|
|
199
207
|
if doc is not None:
|
|
200
|
-
content['documents'] = [
|
|
208
|
+
content['documents'] = [_fix_doc_id(document=doc)]
|
|
201
209
|
content.pop('document', None)
|
|
202
210
|
|
|
203
211
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# ==============================================================================
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2025 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 typing import Optional, Dict
|
|
27
|
+
|
|
28
|
+
from dimsdk import MessageCompressor
|
|
29
|
+
from dimsdk import MessageShortener
|
|
30
|
+
|
|
31
|
+
from .compatible import CompatibleIncoming
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class CompatibleCompressor(MessageCompressor):
|
|
35
|
+
|
|
36
|
+
# Override
|
|
37
|
+
def _create_shortener(self) -> MessageShortener:
|
|
38
|
+
return CompatibleShortener()
|
|
39
|
+
|
|
40
|
+
# Override
|
|
41
|
+
def compress_content(self, content: Dict, key: Dict) -> bytes:
|
|
42
|
+
# CompatibleOutgoing.fix_content(content=content);
|
|
43
|
+
return super().compress_content(content=content, key=key)
|
|
44
|
+
|
|
45
|
+
# Override
|
|
46
|
+
def extract_content(self, data: bytes, key: Dict) -> Optional[Dict]:
|
|
47
|
+
content = super().extract_content(data=data, key=key)
|
|
48
|
+
if content is not None:
|
|
49
|
+
CompatibleIncoming.fix_content(content=content)
|
|
50
|
+
return content
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class CompatibleShortener(MessageShortener):
|
|
54
|
+
|
|
55
|
+
# Override
|
|
56
|
+
def compress_content(self, content: Dict) -> Dict:
|
|
57
|
+
# DON'T COMPRESS NOW
|
|
58
|
+
return content
|
|
59
|
+
|
|
60
|
+
# Override
|
|
61
|
+
def compress_symmetric_key(self, key: Dict) -> Dict:
|
|
62
|
+
# DON'T COMPRESS NOW
|
|
63
|
+
return key
|
|
64
|
+
|
|
65
|
+
# Override
|
|
66
|
+
def compress_reliable_message(self, msg: Dict) -> Dict:
|
|
67
|
+
# DON'T COMPRESS NOW
|
|
68
|
+
return msg
|