dimp 2.3.2__tar.gz → 2.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dimp-2.3.2 → dimp-2.3.4}/PKG-INFO +71 -96
- {dimp-2.3.2 → dimp-2.3.4}/README.md +70 -95
- {dimp-2.3.2 → dimp-2.3.4}/dimp/__init__.py +16 -16
- {dimp-2.3.2 → dimp-2.3.4}/dimp/crypto/__init__.py +4 -4
- {dimp-2.3.2 → dimp-2.3.4}/dimp/crypto/keys.py +12 -12
- {dimp-2.3.2 → dimp-2.3.4}/dimp/crypto/pnf.py +3 -3
- {dimp-2.3.2 → dimp-2.3.4}/dimp/crypto/ted.py +5 -5
- {dimp-2.3.2 → dimp-2.3.4}/dimp/dkd/__init__.py +15 -12
- {dimp-2.3.2/dimp/plugins → dimp-2.3.4/dimp/ext}/__init__.py +2 -2
- {dimp-2.3.2 → dimp-2.3.4}/dimp/mkm/document.py +3 -3
- {dimp-2.3.2 → dimp-2.3.4}/dimp/mkm/meta.py +1 -1
- {dimp-2.3.2 → dimp-2.3.4}/dimp/msg/envelope.py +6 -6
- {dimp-2.3.2 → dimp-2.3.4}/dimp/protocol/__init__.py +5 -3
- dimp-2.3.4/dimp/protocol/app.py +135 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/protocol/base.py +2 -2
- {dimp-2.3.2 → dimp-2.3.4}/dimp/protocol/commands.py +2 -5
- {dimp-2.3.2 → dimp-2.3.4}/dimp/protocol/contents.py +5 -8
- {dimp-2.3.2 → dimp-2.3.4}/dimp/protocol/files.py +3 -3
- {dimp-2.3.2 → dimp-2.3.4}/dimp/protocol/groups.py +3 -35
- {dimp-2.3.2 → dimp-2.3.4}/dimp.egg-info/PKG-INFO +71 -96
- {dimp-2.3.2 → dimp-2.3.4}/dimp.egg-info/SOURCES.txt +3 -2
- dimp-2.3.4/dimp.egg-info/requires.txt +2 -0
- {dimp-2.3.2 → dimp-2.3.4}/setup.py +3 -3
- dimp-2.3.2/dimp.egg-info/requires.txt +0 -2
- {dimp-2.3.2 → dimp-2.3.4}/LICENSE +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/crypto/algorithms.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/mkm/__init__.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/mkm/docs.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/msg/__init__.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/msg/base.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/msg/instant.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/msg/reliable.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/msg/secure.py +0 -0
- /dimp-2.3.2/dimp/protocol/money.py → /dimp-2.3.4/dimp/protocol/assets.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/protocol/docs.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/protocol/forward.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/protocol/helpers.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/protocol/quote.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/protocol/receipt.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp/protocol/types.py +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp.egg-info/dependency_links.txt +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/dimp.egg-info/top_level.txt +0 -0
- {dimp-2.3.2 → dimp-2.3.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dimp
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.4
|
|
4
4
|
Summary: Decentralized Instant Messaging Protocol
|
|
5
5
|
Home-page: https://github.com/dimchat/core-py
|
|
6
6
|
Author: Albert Moky
|
|
@@ -18,7 +18,7 @@ License-File: LICENSE
|
|
|
18
18
|
[](https://github.com/dimchat/core-py/pulls)
|
|
19
19
|
[](https://github.com/dimchat/core-py/wiki)
|
|
20
20
|
[](https://github.com/dimchat/core-py/issues)
|
|
21
|
-
[](https://github.com/dimchat/core-py/archive/refs/heads/
|
|
21
|
+
[](https://github.com/dimchat/core-py/archive/refs/heads/master.zip)
|
|
22
22
|
[](https://github.com/dimchat/core-py/tags)
|
|
23
23
|
[](https://pypi.org/project/dimp)
|
|
24
24
|
|
|
@@ -36,7 +36,7 @@ License-File: LICENSE
|
|
|
36
36
|
|
|
37
37
|
## Examples
|
|
38
38
|
|
|
39
|
-
###
|
|
39
|
+
### Extends Command
|
|
40
40
|
|
|
41
41
|
* _Handshake Command Protocol_
|
|
42
42
|
0. (C-S) handshake start
|
|
@@ -45,8 +45,9 @@ License-File: LICENSE
|
|
|
45
45
|
3. (S-C) handshake success
|
|
46
46
|
|
|
47
47
|
```python
|
|
48
|
+
from abc import ABC, abstractmethod
|
|
48
49
|
from enum import IntEnum
|
|
49
|
-
from typing import Optional,
|
|
50
|
+
from typing import Optional, Dict
|
|
50
51
|
|
|
51
52
|
from dimp import Command, BaseCommand
|
|
52
53
|
|
|
@@ -58,7 +59,20 @@ class HandshakeState(IntEnum):
|
|
|
58
59
|
Success = 3 # S -> C, handshake accepted
|
|
59
60
|
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
def handshake_state(title: str, session: str = None) -> HandshakeState:
|
|
63
|
+
# Server -> Client
|
|
64
|
+
if title == 'DIM!': # or title == 'OK!':
|
|
65
|
+
return HandshakeState.Success
|
|
66
|
+
if title == 'DIM?':
|
|
67
|
+
return HandshakeState.Again
|
|
68
|
+
# Client -> Server: "Hello world!"
|
|
69
|
+
if session is None or len(session) == 0:
|
|
70
|
+
return HandshakeState.Start
|
|
71
|
+
else:
|
|
72
|
+
return HandshakeState.Restart
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class HandshakeCommand(Command, ABC):
|
|
62
76
|
"""
|
|
63
77
|
Handshake Command
|
|
64
78
|
~~~~~~~~~~~~~~~~~
|
|
@@ -74,37 +88,24 @@ class HandshakeCommand(BaseCommand):
|
|
|
74
88
|
"""
|
|
75
89
|
HANDSHAKE = 'handshake'
|
|
76
90
|
|
|
77
|
-
def __init__(self, content: Dict[str, Any] = None, title: str = None, session: str = None):
|
|
78
|
-
if content is None:
|
|
79
|
-
# 1. new command with title & session key
|
|
80
|
-
assert title is not None, 'handshake command error: %s' % session
|
|
81
|
-
cmd = self.HANDSHAKE
|
|
82
|
-
super().__init__(cmd=cmd)
|
|
83
|
-
self['title'] = title
|
|
84
|
-
self['message'] = title # TODO: remove after all clients upgraded
|
|
85
|
-
if session is not None:
|
|
86
|
-
self['session'] = session
|
|
87
|
-
else:
|
|
88
|
-
# 2. command info from network
|
|
89
|
-
assert title is None and session is None, 'params error: %s, %s, %s' % (content, title, session)
|
|
90
|
-
super().__init__(content)
|
|
91
|
-
|
|
92
91
|
@property
|
|
92
|
+
@abstractmethod
|
|
93
93
|
def title(self) -> str:
|
|
94
|
-
|
|
95
|
-
text = self.get_str(key='title', default=None)
|
|
96
|
-
if text is None:
|
|
97
|
-
# compatible with v1.0
|
|
98
|
-
text = self.get_str(key='message', default='')
|
|
99
|
-
return text
|
|
94
|
+
raise NotImplemented
|
|
100
95
|
|
|
101
96
|
@property
|
|
97
|
+
@abstractmethod
|
|
102
98
|
def session(self) -> Optional[str]:
|
|
103
|
-
|
|
99
|
+
raise NotImplemented
|
|
104
100
|
|
|
105
101
|
@property
|
|
102
|
+
@abstractmethod
|
|
106
103
|
def state(self) -> HandshakeState:
|
|
107
|
-
|
|
104
|
+
raise NotImplemented
|
|
105
|
+
|
|
106
|
+
#
|
|
107
|
+
# Factories
|
|
108
|
+
#
|
|
108
109
|
|
|
109
110
|
@classmethod
|
|
110
111
|
def offer(cls, session: str = None) -> Command:
|
|
@@ -114,7 +115,7 @@ class HandshakeCommand(BaseCommand):
|
|
|
114
115
|
:param session: Old session key
|
|
115
116
|
:return: HandshakeCommand object
|
|
116
117
|
"""
|
|
117
|
-
return
|
|
118
|
+
return BaseHandshakeCommand(title='Hello world!', session=session)
|
|
118
119
|
|
|
119
120
|
@classmethod
|
|
120
121
|
def ask(cls, session: str) -> Command:
|
|
@@ -124,7 +125,7 @@ class HandshakeCommand(BaseCommand):
|
|
|
124
125
|
:param session: New session key
|
|
125
126
|
:return: HandshakeCommand object
|
|
126
127
|
"""
|
|
127
|
-
return
|
|
128
|
+
return BaseHandshakeCommand(title='DIM?', session=session)
|
|
128
129
|
|
|
129
130
|
@classmethod
|
|
130
131
|
def accepted(cls, session: str = None) -> Command:
|
|
@@ -133,7 +134,7 @@ class HandshakeCommand(BaseCommand):
|
|
|
133
134
|
|
|
134
135
|
:return: HandshakeCommand object
|
|
135
136
|
"""
|
|
136
|
-
return
|
|
137
|
+
return BaseHandshakeCommand(title='DIM!', session=session)
|
|
137
138
|
|
|
138
139
|
start = offer # (1. C->S) first handshake, without session
|
|
139
140
|
again = ask # (2. S->C) ask client to handshake with new session key
|
|
@@ -141,108 +142,82 @@ class HandshakeCommand(BaseCommand):
|
|
|
141
142
|
success = accepted # (4. S->C) notice the client that handshake accepted
|
|
142
143
|
|
|
143
144
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
145
|
+
class BaseHandshakeCommand(BaseCommand, HandshakeCommand):
|
|
146
|
+
|
|
147
|
+
def __init__(self, content: Dict = None, title: str = None, session: str = None):
|
|
148
|
+
if content is None:
|
|
149
|
+
# 1. new command with title & session key
|
|
150
|
+
assert title is not None, 'handshake command error: %s' % session
|
|
151
|
+
cmd = self.HANDSHAKE
|
|
152
|
+
super().__init__(cmd=cmd)
|
|
153
|
+
self['title'] = title
|
|
154
|
+
self['message'] = title # TODO: remove after all clients upgraded
|
|
155
|
+
if session is not None:
|
|
156
|
+
self['session'] = session
|
|
157
|
+
else:
|
|
158
|
+
# 2. command info from network
|
|
159
|
+
assert title is None and session is None, 'params error: %s, %s, %s' % (content, title, session)
|
|
160
|
+
super().__init__(content)
|
|
161
|
+
|
|
162
|
+
@property
|
|
163
|
+
def title(self) -> str:
|
|
164
|
+
return self.get_str(key='title', default='')
|
|
165
|
+
|
|
166
|
+
@property
|
|
167
|
+
def session(self) -> Optional[str]:
|
|
168
|
+
return self.get_str(key='session')
|
|
169
|
+
|
|
170
|
+
@property
|
|
171
|
+
def state(self) -> HandshakeState:
|
|
172
|
+
return handshake_state(title=self.title, session=self.session)
|
|
155
173
|
```
|
|
156
174
|
|
|
157
|
-
###
|
|
175
|
+
### Extends Content
|
|
158
176
|
|
|
159
177
|
```python
|
|
160
|
-
from abc import ABC, abstractmethod
|
|
161
178
|
from typing import Any, Dict
|
|
162
179
|
|
|
163
|
-
from dimp import
|
|
164
|
-
from dimp import Content
|
|
165
|
-
from dimp import BaseContent
|
|
180
|
+
from dimp import *
|
|
166
181
|
|
|
167
182
|
|
|
168
|
-
class
|
|
183
|
+
class ApplicationContent(BaseContent, AppContent):
|
|
169
184
|
"""
|
|
170
185
|
Application Customized message
|
|
171
186
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
172
187
|
|
|
173
188
|
data format: {
|
|
174
|
-
type :
|
|
189
|
+
type : i2s(0xA0),
|
|
175
190
|
sn : 123,
|
|
176
191
|
|
|
177
192
|
app : "{APP_ID}", // application (e.g.: "chat.dim.sechat")
|
|
178
|
-
mod : "{MODULE}", // module name (e.g.: "drift_bottle")
|
|
179
|
-
act : "{ACTION}", // action name (e.g.: "throw")
|
|
180
193
|
extra : info // action parameters
|
|
181
194
|
}
|
|
182
195
|
"""
|
|
183
196
|
|
|
184
|
-
@property
|
|
185
|
-
@abstractmethod
|
|
186
|
-
def application(self) -> str:
|
|
187
|
-
""" App ID """
|
|
188
|
-
raise NotImplemented
|
|
189
|
-
|
|
190
|
-
@property
|
|
191
|
-
@abstractmethod
|
|
192
|
-
def module(self) -> str:
|
|
193
|
-
""" Module Name """
|
|
194
|
-
raise NotImplemented
|
|
195
|
-
|
|
196
|
-
@property
|
|
197
|
-
@abstractmethod
|
|
198
|
-
def action(self) -> str:
|
|
199
|
-
""" Action Name """
|
|
200
|
-
raise NotImplemented
|
|
201
|
-
|
|
202
|
-
@classmethod
|
|
203
|
-
def create(cls, app: str, mod: str, act: str):
|
|
204
|
-
return AppCustomizedContent(app=app, mod=mod, act=act)
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
class AppCustomizedContent(BaseContent, CustomizedContent):
|
|
208
|
-
|
|
209
197
|
def __init__(self, content: Dict[str, Any] = None,
|
|
210
|
-
msg_type:
|
|
211
|
-
app: str = None, mod: str = None, act: str = None):
|
|
198
|
+
msg_type: str = None, app: str = None):
|
|
212
199
|
if content is None:
|
|
213
|
-
# 1. new content with type,
|
|
214
|
-
assert app is not None
|
|
215
|
-
'customized content error: %s, %s, %s, %s' % (msg_type, app, mod, act)
|
|
200
|
+
# 1. new content with type, app_id
|
|
201
|
+
assert app is not None, 'customized content error: %s, %s' % (msg_type, app)
|
|
216
202
|
if msg_type is None:
|
|
217
|
-
msg_type = ContentType.
|
|
203
|
+
msg_type = ContentType.APPLICATION
|
|
218
204
|
super().__init__(None, msg_type)
|
|
219
205
|
self['app'] = app
|
|
220
|
-
self['mod'] = mod
|
|
221
|
-
self['act'] = act
|
|
222
206
|
else:
|
|
223
207
|
# 2. content info from network
|
|
224
|
-
assert msg_type is None and app is None
|
|
225
|
-
'params error: %s, %s, %s, %s, %s' % (content, msg_type, app, mod, act)
|
|
208
|
+
assert msg_type is None and app is None, 'params error: %s, %s, %s' % (content, msg_type, app)
|
|
226
209
|
super().__init__(content)
|
|
227
210
|
|
|
228
211
|
@property # Override
|
|
229
212
|
def application(self) -> str:
|
|
230
213
|
return self.get_str(key='app', default='')
|
|
231
|
-
|
|
232
|
-
@property # Override
|
|
233
|
-
def module(self) -> str:
|
|
234
|
-
return self.get_str(key='mod', default='')
|
|
235
|
-
|
|
236
|
-
@property # Override
|
|
237
|
-
def action(self) -> str:
|
|
238
|
-
return self.get_str(key='act', default='')
|
|
239
214
|
```
|
|
240
215
|
|
|
241
|
-
###
|
|
216
|
+
### Extends ID Address
|
|
242
217
|
|
|
243
218
|
* Examples in [dim plugins](https://pypi.org/project/dimplugins)
|
|
244
219
|
|
|
245
220
|
----
|
|
246
221
|
|
|
247
|
-
Copyright © 2018 Albert Moky
|
|
222
|
+
Copyright © 2018-2025 Albert Moky
|
|
248
223
|
[](https://github.com/moky?tab=followers)
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://github.com/dimchat/core-py/pulls)
|
|
5
5
|
[](https://github.com/dimchat/core-py/wiki)
|
|
6
6
|
[](https://github.com/dimchat/core-py/issues)
|
|
7
|
-
[](https://github.com/dimchat/core-py/archive/refs/heads/
|
|
7
|
+
[](https://github.com/dimchat/core-py/archive/refs/heads/master.zip)
|
|
8
8
|
[](https://github.com/dimchat/core-py/tags)
|
|
9
9
|
[](https://pypi.org/project/dimp)
|
|
10
10
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
## Examples
|
|
24
24
|
|
|
25
|
-
###
|
|
25
|
+
### Extends Command
|
|
26
26
|
|
|
27
27
|
* _Handshake Command Protocol_
|
|
28
28
|
0. (C-S) handshake start
|
|
@@ -31,8 +31,9 @@
|
|
|
31
31
|
3. (S-C) handshake success
|
|
32
32
|
|
|
33
33
|
```python
|
|
34
|
+
from abc import ABC, abstractmethod
|
|
34
35
|
from enum import IntEnum
|
|
35
|
-
from typing import Optional,
|
|
36
|
+
from typing import Optional, Dict
|
|
36
37
|
|
|
37
38
|
from dimp import Command, BaseCommand
|
|
38
39
|
|
|
@@ -44,7 +45,20 @@ class HandshakeState(IntEnum):
|
|
|
44
45
|
Success = 3 # S -> C, handshake accepted
|
|
45
46
|
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
def handshake_state(title: str, session: str = None) -> HandshakeState:
|
|
49
|
+
# Server -> Client
|
|
50
|
+
if title == 'DIM!': # or title == 'OK!':
|
|
51
|
+
return HandshakeState.Success
|
|
52
|
+
if title == 'DIM?':
|
|
53
|
+
return HandshakeState.Again
|
|
54
|
+
# Client -> Server: "Hello world!"
|
|
55
|
+
if session is None or len(session) == 0:
|
|
56
|
+
return HandshakeState.Start
|
|
57
|
+
else:
|
|
58
|
+
return HandshakeState.Restart
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class HandshakeCommand(Command, ABC):
|
|
48
62
|
"""
|
|
49
63
|
Handshake Command
|
|
50
64
|
~~~~~~~~~~~~~~~~~
|
|
@@ -60,37 +74,24 @@ class HandshakeCommand(BaseCommand):
|
|
|
60
74
|
"""
|
|
61
75
|
HANDSHAKE = 'handshake'
|
|
62
76
|
|
|
63
|
-
def __init__(self, content: Dict[str, Any] = None, title: str = None, session: str = None):
|
|
64
|
-
if content is None:
|
|
65
|
-
# 1. new command with title & session key
|
|
66
|
-
assert title is not None, 'handshake command error: %s' % session
|
|
67
|
-
cmd = self.HANDSHAKE
|
|
68
|
-
super().__init__(cmd=cmd)
|
|
69
|
-
self['title'] = title
|
|
70
|
-
self['message'] = title # TODO: remove after all clients upgraded
|
|
71
|
-
if session is not None:
|
|
72
|
-
self['session'] = session
|
|
73
|
-
else:
|
|
74
|
-
# 2. command info from network
|
|
75
|
-
assert title is None and session is None, 'params error: %s, %s, %s' % (content, title, session)
|
|
76
|
-
super().__init__(content)
|
|
77
|
-
|
|
78
77
|
@property
|
|
78
|
+
@abstractmethod
|
|
79
79
|
def title(self) -> str:
|
|
80
|
-
|
|
81
|
-
text = self.get_str(key='title', default=None)
|
|
82
|
-
if text is None:
|
|
83
|
-
# compatible with v1.0
|
|
84
|
-
text = self.get_str(key='message', default='')
|
|
85
|
-
return text
|
|
80
|
+
raise NotImplemented
|
|
86
81
|
|
|
87
82
|
@property
|
|
83
|
+
@abstractmethod
|
|
88
84
|
def session(self) -> Optional[str]:
|
|
89
|
-
|
|
85
|
+
raise NotImplemented
|
|
90
86
|
|
|
91
87
|
@property
|
|
88
|
+
@abstractmethod
|
|
92
89
|
def state(self) -> HandshakeState:
|
|
93
|
-
|
|
90
|
+
raise NotImplemented
|
|
91
|
+
|
|
92
|
+
#
|
|
93
|
+
# Factories
|
|
94
|
+
#
|
|
94
95
|
|
|
95
96
|
@classmethod
|
|
96
97
|
def offer(cls, session: str = None) -> Command:
|
|
@@ -100,7 +101,7 @@ class HandshakeCommand(BaseCommand):
|
|
|
100
101
|
:param session: Old session key
|
|
101
102
|
:return: HandshakeCommand object
|
|
102
103
|
"""
|
|
103
|
-
return
|
|
104
|
+
return BaseHandshakeCommand(title='Hello world!', session=session)
|
|
104
105
|
|
|
105
106
|
@classmethod
|
|
106
107
|
def ask(cls, session: str) -> Command:
|
|
@@ -110,7 +111,7 @@ class HandshakeCommand(BaseCommand):
|
|
|
110
111
|
:param session: New session key
|
|
111
112
|
:return: HandshakeCommand object
|
|
112
113
|
"""
|
|
113
|
-
return
|
|
114
|
+
return BaseHandshakeCommand(title='DIM?', session=session)
|
|
114
115
|
|
|
115
116
|
@classmethod
|
|
116
117
|
def accepted(cls, session: str = None) -> Command:
|
|
@@ -119,7 +120,7 @@ class HandshakeCommand(BaseCommand):
|
|
|
119
120
|
|
|
120
121
|
:return: HandshakeCommand object
|
|
121
122
|
"""
|
|
122
|
-
return
|
|
123
|
+
return BaseHandshakeCommand(title='DIM!', session=session)
|
|
123
124
|
|
|
124
125
|
start = offer # (1. C->S) first handshake, without session
|
|
125
126
|
again = ask # (2. S->C) ask client to handshake with new session key
|
|
@@ -127,108 +128,82 @@ class HandshakeCommand(BaseCommand):
|
|
|
127
128
|
success = accepted # (4. S->C) notice the client that handshake accepted
|
|
128
129
|
|
|
129
130
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
131
|
+
class BaseHandshakeCommand(BaseCommand, HandshakeCommand):
|
|
132
|
+
|
|
133
|
+
def __init__(self, content: Dict = None, title: str = None, session: str = None):
|
|
134
|
+
if content is None:
|
|
135
|
+
# 1. new command with title & session key
|
|
136
|
+
assert title is not None, 'handshake command error: %s' % session
|
|
137
|
+
cmd = self.HANDSHAKE
|
|
138
|
+
super().__init__(cmd=cmd)
|
|
139
|
+
self['title'] = title
|
|
140
|
+
self['message'] = title # TODO: remove after all clients upgraded
|
|
141
|
+
if session is not None:
|
|
142
|
+
self['session'] = session
|
|
143
|
+
else:
|
|
144
|
+
# 2. command info from network
|
|
145
|
+
assert title is None and session is None, 'params error: %s, %s, %s' % (content, title, session)
|
|
146
|
+
super().__init__(content)
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def title(self) -> str:
|
|
150
|
+
return self.get_str(key='title', default='')
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
def session(self) -> Optional[str]:
|
|
154
|
+
return self.get_str(key='session')
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def state(self) -> HandshakeState:
|
|
158
|
+
return handshake_state(title=self.title, session=self.session)
|
|
141
159
|
```
|
|
142
160
|
|
|
143
|
-
###
|
|
161
|
+
### Extends Content
|
|
144
162
|
|
|
145
163
|
```python
|
|
146
|
-
from abc import ABC, abstractmethod
|
|
147
164
|
from typing import Any, Dict
|
|
148
165
|
|
|
149
|
-
from dimp import
|
|
150
|
-
from dimp import Content
|
|
151
|
-
from dimp import BaseContent
|
|
166
|
+
from dimp import *
|
|
152
167
|
|
|
153
168
|
|
|
154
|
-
class
|
|
169
|
+
class ApplicationContent(BaseContent, AppContent):
|
|
155
170
|
"""
|
|
156
171
|
Application Customized message
|
|
157
172
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
158
173
|
|
|
159
174
|
data format: {
|
|
160
|
-
type :
|
|
175
|
+
type : i2s(0xA0),
|
|
161
176
|
sn : 123,
|
|
162
177
|
|
|
163
178
|
app : "{APP_ID}", // application (e.g.: "chat.dim.sechat")
|
|
164
|
-
mod : "{MODULE}", // module name (e.g.: "drift_bottle")
|
|
165
|
-
act : "{ACTION}", // action name (e.g.: "throw")
|
|
166
179
|
extra : info // action parameters
|
|
167
180
|
}
|
|
168
181
|
"""
|
|
169
182
|
|
|
170
|
-
@property
|
|
171
|
-
@abstractmethod
|
|
172
|
-
def application(self) -> str:
|
|
173
|
-
""" App ID """
|
|
174
|
-
raise NotImplemented
|
|
175
|
-
|
|
176
|
-
@property
|
|
177
|
-
@abstractmethod
|
|
178
|
-
def module(self) -> str:
|
|
179
|
-
""" Module Name """
|
|
180
|
-
raise NotImplemented
|
|
181
|
-
|
|
182
|
-
@property
|
|
183
|
-
@abstractmethod
|
|
184
|
-
def action(self) -> str:
|
|
185
|
-
""" Action Name """
|
|
186
|
-
raise NotImplemented
|
|
187
|
-
|
|
188
|
-
@classmethod
|
|
189
|
-
def create(cls, app: str, mod: str, act: str):
|
|
190
|
-
return AppCustomizedContent(app=app, mod=mod, act=act)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
class AppCustomizedContent(BaseContent, CustomizedContent):
|
|
194
|
-
|
|
195
183
|
def __init__(self, content: Dict[str, Any] = None,
|
|
196
|
-
msg_type:
|
|
197
|
-
app: str = None, mod: str = None, act: str = None):
|
|
184
|
+
msg_type: str = None, app: str = None):
|
|
198
185
|
if content is None:
|
|
199
|
-
# 1. new content with type,
|
|
200
|
-
assert app is not None
|
|
201
|
-
'customized content error: %s, %s, %s, %s' % (msg_type, app, mod, act)
|
|
186
|
+
# 1. new content with type, app_id
|
|
187
|
+
assert app is not None, 'customized content error: %s, %s' % (msg_type, app)
|
|
202
188
|
if msg_type is None:
|
|
203
|
-
msg_type = ContentType.
|
|
189
|
+
msg_type = ContentType.APPLICATION
|
|
204
190
|
super().__init__(None, msg_type)
|
|
205
191
|
self['app'] = app
|
|
206
|
-
self['mod'] = mod
|
|
207
|
-
self['act'] = act
|
|
208
192
|
else:
|
|
209
193
|
# 2. content info from network
|
|
210
|
-
assert msg_type is None and app is None
|
|
211
|
-
'params error: %s, %s, %s, %s, %s' % (content, msg_type, app, mod, act)
|
|
194
|
+
assert msg_type is None and app is None, 'params error: %s, %s, %s' % (content, msg_type, app)
|
|
212
195
|
super().__init__(content)
|
|
213
196
|
|
|
214
197
|
@property # Override
|
|
215
198
|
def application(self) -> str:
|
|
216
199
|
return self.get_str(key='app', default='')
|
|
217
|
-
|
|
218
|
-
@property # Override
|
|
219
|
-
def module(self) -> str:
|
|
220
|
-
return self.get_str(key='mod', default='')
|
|
221
|
-
|
|
222
|
-
@property # Override
|
|
223
|
-
def action(self) -> str:
|
|
224
|
-
return self.get_str(key='act', default='')
|
|
225
200
|
```
|
|
226
201
|
|
|
227
|
-
###
|
|
202
|
+
### Extends ID Address
|
|
228
203
|
|
|
229
204
|
* Examples in [dim plugins](https://pypi.org/project/dimplugins)
|
|
230
205
|
|
|
231
206
|
----
|
|
232
207
|
|
|
233
|
-
Copyright © 2018 Albert Moky
|
|
208
|
+
Copyright © 2018-2025 Albert Moky
|
|
234
209
|
[](https://github.com/moky?tab=followers)
|
|
@@ -65,7 +65,6 @@ __all__ = [
|
|
|
65
65
|
'DataCoder', 'Hex', 'Base58', 'Base64',
|
|
66
66
|
'ObjectCoder', 'JSON',
|
|
67
67
|
'MapCoder', 'JSONMap',
|
|
68
|
-
'ListCoder', 'JSONList',
|
|
69
68
|
'StringCoder', 'UTF8',
|
|
70
69
|
|
|
71
70
|
'hex_encode', 'hex_decode',
|
|
@@ -81,10 +80,9 @@ __all__ = [
|
|
|
81
80
|
# Digest
|
|
82
81
|
#
|
|
83
82
|
|
|
84
|
-
'
|
|
85
|
-
'
|
|
86
|
-
|
|
87
|
-
'md5', 'sha1', 'sha256', 'keccak256', 'ripemd160',
|
|
83
|
+
'MessageDigester',
|
|
84
|
+
'SHA256', 'KECCAK256', 'RIPEMD160',
|
|
85
|
+
'sha256', 'keccak256', 'ripemd160',
|
|
88
86
|
|
|
89
87
|
#
|
|
90
88
|
# Crypto
|
|
@@ -119,6 +117,8 @@ __all__ = [
|
|
|
119
117
|
'Meta',
|
|
120
118
|
'Document', 'Visa', 'Bulletin',
|
|
121
119
|
|
|
120
|
+
'MetaType', 'DocumentType',
|
|
121
|
+
|
|
122
122
|
'AddressFactory',
|
|
123
123
|
'IDFactory',
|
|
124
124
|
'MetaFactory',
|
|
@@ -132,8 +132,6 @@ __all__ = [
|
|
|
132
132
|
'BaseMeta',
|
|
133
133
|
'BaseDocument', 'BaseVisa', 'BaseBulletin',
|
|
134
134
|
|
|
135
|
-
'MetaType', 'DocumentType',
|
|
136
|
-
|
|
137
135
|
#
|
|
138
136
|
# DaoKeDao
|
|
139
137
|
#
|
|
@@ -145,11 +143,12 @@ __all__ = [
|
|
|
145
143
|
'InstantMessage', 'SecureMessage', 'ReliableMessage',
|
|
146
144
|
|
|
147
145
|
# contents
|
|
148
|
-
'TextContent', '
|
|
149
|
-
'
|
|
146
|
+
'TextContent', 'PageContent', 'NameCard',
|
|
147
|
+
'ForwardContent', 'CombineContent', 'ArrayContent',
|
|
150
148
|
'FileContent', 'ImageContent', 'AudioContent', 'VideoContent',
|
|
151
149
|
'MoneyContent', 'TransferContent',
|
|
152
|
-
'QuoteContent',
|
|
150
|
+
'QuoteContent',
|
|
151
|
+
'CustomizedContent',
|
|
153
152
|
|
|
154
153
|
# commands
|
|
155
154
|
'Command',
|
|
@@ -158,16 +157,17 @@ __all__ = [
|
|
|
158
157
|
|
|
159
158
|
# group history
|
|
160
159
|
'HistoryCommand', 'GroupCommand',
|
|
161
|
-
'InviteCommand', 'ExpelCommand', 'JoinCommand', 'QuitCommand', '
|
|
160
|
+
'InviteCommand', 'ExpelCommand', 'JoinCommand', 'QuitCommand', 'ResetCommand',
|
|
162
161
|
'HireCommand', 'FireCommand', 'ResignCommand',
|
|
163
162
|
|
|
164
163
|
# extend contents
|
|
165
164
|
'BaseContent',
|
|
166
|
-
'BaseTextContent', '
|
|
167
|
-
'
|
|
165
|
+
'BaseTextContent', 'WebPageContent', 'NameCardContent',
|
|
166
|
+
'SecretContent', 'CombineForwardContent', 'ListContent',
|
|
168
167
|
'BaseFileContent', 'ImageFileContent', 'AudioFileContent', 'VideoFileContent',
|
|
169
168
|
'BaseMoneyContent', 'TransferMoneyContent',
|
|
170
|
-
'BaseQuoteContent',
|
|
169
|
+
'BaseQuoteContent',
|
|
170
|
+
'AppCustomizedContent',
|
|
171
171
|
|
|
172
172
|
# extend commands
|
|
173
173
|
'BaseCommand',
|
|
@@ -176,8 +176,8 @@ __all__ = [
|
|
|
176
176
|
|
|
177
177
|
# extend group history
|
|
178
178
|
'BaseHistoryCommand', 'BaseGroupCommand',
|
|
179
|
-
'InviteGroupCommand', 'ExpelGroupCommand',
|
|
180
|
-
'
|
|
179
|
+
'InviteGroupCommand', 'ExpelGroupCommand',
|
|
180
|
+
'JoinGroupCommand', 'QuitGroupCommand', 'ResetGroupCommand',
|
|
181
181
|
'HireGroupCommand', 'FireGroupCommand', 'ResignGroupCommand',
|
|
182
182
|
|
|
183
183
|
#
|
|
@@ -42,12 +42,12 @@ from .pnf import BaseFileWrapper
|
|
|
42
42
|
__all__ = [
|
|
43
43
|
|
|
44
44
|
#
|
|
45
|
-
#
|
|
45
|
+
# Digest
|
|
46
46
|
#
|
|
47
47
|
|
|
48
|
-
'
|
|
49
|
-
'
|
|
50
|
-
'
|
|
48
|
+
'MessageDigester',
|
|
49
|
+
'SHA256', 'KECCAK256', 'RIPEMD160',
|
|
50
|
+
'sha256', 'keccak256', 'ripemd160',
|
|
51
51
|
|
|
52
52
|
#
|
|
53
53
|
# Crypto
|