dimp 2.1.0__tar.gz → 2.2.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.
- dimp-2.2.2/PKG-INFO +248 -0
- dimp-2.2.2/README.md +234 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/__init__.py +85 -45
- {dimp-2.1.0 → dimp-2.2.2}/dimp/crypto/__init__.py +8 -6
- {dimp-2.1.0 → dimp-2.2.2}/dimp/crypto/keys.py +16 -17
- {dimp-2.1.0 → dimp-2.2.2}/dimp/crypto/pnf.py +2 -2
- {dimp-2.1.0 → dimp-2.2.2}/dimp/crypto/ted.py +7 -5
- {dimp-2.1.0 → dimp-2.2.2}/dimp/dkd/__init__.py +33 -19
- {dimp-2.1.0 → dimp-2.2.2}/dimp/dkd/base.py +6 -6
- {dimp-2.1.0 → dimp-2.2.2}/dimp/dkd/contents.py +1 -1
- dimp-2.2.2/dimp/dkd/quote.py +140 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/dkd/receipt.py +0 -4
- dimp-2.1.0/dimp/mkm/delegate.py → dimp-2.2.2/dimp/mkm/__init__.py +38 -22
- {dimp-2.1.0 → dimp-2.2.2}/dimp/mkm/docs.py +9 -9
- {dimp-2.1.0 → dimp-2.2.2}/dimp/mkm/document.py +13 -13
- {dimp-2.1.0 → dimp-2.2.2}/dimp/mkm/meta.py +50 -79
- {dimp-2.1.0 → dimp-2.2.2}/dimp/msg/__init__.py +24 -5
- {dimp-2.1.0 → dimp-2.2.2}/dimp/msg/instant.py +5 -6
- {dimp-2.1.0/dimp/mkm → dimp-2.2.2/dimp/plugins}/__init__.py +40 -33
- dimp-2.1.0/dimp/protocol/customized.py → dimp-2.2.2/dimp/plugins/cmd.py +36 -33
- {dimp-2.1.0 → dimp-2.2.2}/dimp/protocol/__init__.py +31 -24
- {dimp-2.1.0 → dimp-2.2.2}/dimp/protocol/commands.py +38 -14
- {dimp-2.1.0 → dimp-2.2.2}/dimp/protocol/contents.py +5 -5
- dimp-2.2.2/dimp/protocol/helpers.py +41 -0
- dimp-2.2.2/dimp/protocol/quote.py +159 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/protocol/receipt.py +1 -1
- dimp-2.2.2/dimp.egg-info/PKG-INFO +248 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp.egg-info/SOURCES.txt +5 -12
- dimp-2.2.2/dimp.egg-info/requires.txt +2 -0
- {dimp-2.1.0 → dimp-2.2.2}/setup.py +3 -3
- dimp-2.1.0/PKG-INFO +0 -22
- dimp-2.1.0/README.md +0 -8
- dimp-2.1.0/dimp/barrack.py +0 -236
- dimp-2.1.0/dimp/dkd/customized.py +0 -85
- dimp-2.1.0/dimp/dkd/factory.py +0 -89
- dimp-2.1.0/dimp/mkm/entity.py +0 -188
- dimp-2.1.0/dimp/mkm/group.py +0 -191
- dimp-2.1.0/dimp/mkm/helper.py +0 -168
- dimp-2.1.0/dimp/mkm/user.py +0 -331
- dimp-2.1.0/dimp/packer.py +0 -108
- dimp-2.1.0/dimp/processor.py +0 -93
- dimp-2.1.0/dimp/transceiver.py +0 -218
- dimp-2.1.0/dimp.egg-info/PKG-INFO +0 -22
- dimp-2.1.0/dimp.egg-info/requires.txt +0 -2
- {dimp-2.1.0 → dimp-2.2.2}/dimp/dkd/commands.py +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/dkd/files.py +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/dkd/group_admins.py +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/dkd/groups.py +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/dkd/money.py +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/msg/base.py +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/msg/envelope.py +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/msg/reliable.py +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/msg/secure.py +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/protocol/docs.py +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/protocol/files.py +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/protocol/groups.py +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp/protocol/money.py +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp.egg-info/dependency_links.txt +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/dimp.egg-info/top_level.txt +0 -0
- {dimp-2.1.0 → dimp-2.2.2}/setup.cfg +0 -0
dimp-2.2.2/PKG-INFO
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: dimp
|
|
3
|
+
Version: 2.2.2
|
|
4
|
+
Summary: Decentralized Instant Messaging Protocol
|
|
5
|
+
Home-page: https://github.com/dimchat/core-py
|
|
6
|
+
Author: Albert Moky
|
|
7
|
+
Author-email: albert.moky@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Description: # Decentralized Instant Messaging Protocol (Python)
|
|
10
|
+
|
|
11
|
+
[](https://github.com/dimchat/core-py/blob/master/LICENSE)
|
|
12
|
+
[](https://github.com/dimchat/core-py/pulls)
|
|
13
|
+
[](https://github.com/dimchat/core-py/wiki)
|
|
14
|
+
[](https://github.com/dimchat/core-py/issues)
|
|
15
|
+
[](https://github.com/dimchat/core-py/archive/refs/heads/main.zip)
|
|
16
|
+
[](https://github.com/dimchat/core-py/tags)
|
|
17
|
+
[](https://pypi.org/project/dimp)
|
|
18
|
+
|
|
19
|
+
[](https://github.com/dimchat/core-py/watchers)
|
|
20
|
+
[](https://github.com/dimchat/core-py/forks)
|
|
21
|
+
[](https://github.com/dimchat/core-py/stargazers)
|
|
22
|
+
[](https://github.com/orgs/dimchat/followers)
|
|
23
|
+
|
|
24
|
+
## Dependencies
|
|
25
|
+
|
|
26
|
+
| Name | Version | Description |
|
|
27
|
+
|------|---------|-------------|
|
|
28
|
+
| [Ming Ke Ming (名可名)](https://github.com/dimchat/mkm-py) | [](https://pypi.org/project/mkm) | Decentralized User Identity Authentication |
|
|
29
|
+
| [Dao Ke Dao (道可道)](https://github.com/dimchat/dkd-py) | [](https://pypi.org/project/dkd) | Universal Message Module |
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
|
|
33
|
+
### extends Command
|
|
34
|
+
|
|
35
|
+
* _Handshake Command Protocol_
|
|
36
|
+
0. (C-S) handshake start
|
|
37
|
+
1. (S-C) handshake again with new session
|
|
38
|
+
2. (C-S) handshake restart with new session
|
|
39
|
+
3. (S-C) handshake success
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from enum import IntEnum
|
|
43
|
+
from typing import Optional, Any, Dict
|
|
44
|
+
|
|
45
|
+
from dimp import Command, BaseCommand
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class HandshakeState(IntEnum):
|
|
49
|
+
Start = 0 # C -> S, without session key(or session expired)
|
|
50
|
+
Again = 1 # S -> C, with new session key
|
|
51
|
+
Restart = 2 # C -> S, with new session key
|
|
52
|
+
Success = 3 # S -> C, handshake accepted
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class HandshakeCommand(BaseCommand):
|
|
56
|
+
"""
|
|
57
|
+
Handshake Command
|
|
58
|
+
~~~~~~~~~~~~~~~~~
|
|
59
|
+
|
|
60
|
+
data format: {
|
|
61
|
+
type : 0x88,
|
|
62
|
+
sn : 123,
|
|
63
|
+
|
|
64
|
+
command : "handshake", // command name
|
|
65
|
+
title : "Hello world!", // "DIM?", "DIM!"
|
|
66
|
+
session : "{SESSION_ID}", // session key
|
|
67
|
+
}
|
|
68
|
+
"""
|
|
69
|
+
HANDSHAKE = 'handshake'
|
|
70
|
+
|
|
71
|
+
def __init__(self, content: Dict[str, Any] = None, title: str = None, session: str = None):
|
|
72
|
+
if content is None:
|
|
73
|
+
# 1. new command with title & session key
|
|
74
|
+
assert title is not None, 'handshake command error: %s' % session
|
|
75
|
+
cmd = self.HANDSHAKE
|
|
76
|
+
super().__init__(cmd=cmd)
|
|
77
|
+
self['title'] = title
|
|
78
|
+
self['message'] = title # TODO: remove after all clients upgraded
|
|
79
|
+
if session is not None:
|
|
80
|
+
self['session'] = session
|
|
81
|
+
else:
|
|
82
|
+
# 2. command info from network
|
|
83
|
+
assert title is None and session is None, 'params error: %s, %s, %s' % (content, title, session)
|
|
84
|
+
super().__init__(content)
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def title(self) -> str:
|
|
88
|
+
# TODO: modify after all clients upgraded
|
|
89
|
+
text = self.get_str(key='title', default=None)
|
|
90
|
+
if text is None:
|
|
91
|
+
# compatible with v1.0
|
|
92
|
+
text = self.get_str(key='message', default='')
|
|
93
|
+
return text
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def session(self) -> Optional[str]:
|
|
97
|
+
return self.get_str(key='session', default=None)
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def state(self) -> HandshakeState:
|
|
101
|
+
return handshake_state(title=self.title, session=self.session)
|
|
102
|
+
|
|
103
|
+
@classmethod
|
|
104
|
+
def offer(cls, session: str = None) -> Command:
|
|
105
|
+
"""
|
|
106
|
+
Create client-station handshake offer
|
|
107
|
+
|
|
108
|
+
:param session: Old session key
|
|
109
|
+
:return: HandshakeCommand object
|
|
110
|
+
"""
|
|
111
|
+
return HandshakeCommand(title='Hello world!', session=session)
|
|
112
|
+
|
|
113
|
+
@classmethod
|
|
114
|
+
def ask(cls, session: str) -> Command:
|
|
115
|
+
"""
|
|
116
|
+
Create station-client handshake again with new session
|
|
117
|
+
|
|
118
|
+
:param session: New session key
|
|
119
|
+
:return: HandshakeCommand object
|
|
120
|
+
"""
|
|
121
|
+
return HandshakeCommand(title='DIM?', session=session)
|
|
122
|
+
|
|
123
|
+
@classmethod
|
|
124
|
+
def accepted(cls, session: str = None) -> Command:
|
|
125
|
+
"""
|
|
126
|
+
Create station-client handshake success notice
|
|
127
|
+
|
|
128
|
+
:return: HandshakeCommand object
|
|
129
|
+
"""
|
|
130
|
+
return HandshakeCommand(title='DIM!', session=session)
|
|
131
|
+
|
|
132
|
+
start = offer # (1. C->S) first handshake, without session
|
|
133
|
+
again = ask # (2. S->C) ask client to handshake with new session key
|
|
134
|
+
restart = offer # (3. C->S) handshake with new session key
|
|
135
|
+
success = accepted # (4. S->C) notice the client that handshake accepted
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def handshake_state(title: str, session: str = None) -> HandshakeState:
|
|
139
|
+
# Server -> Client
|
|
140
|
+
if title == 'DIM!': # or title == 'OK!':
|
|
141
|
+
return HandshakeState.Success
|
|
142
|
+
if title == 'DIM?':
|
|
143
|
+
return HandshakeState.Again
|
|
144
|
+
# Client -> Server: "Hello world!"
|
|
145
|
+
if session is None or len(session) == 0:
|
|
146
|
+
return HandshakeState.Start
|
|
147
|
+
else:
|
|
148
|
+
return HandshakeState.Restart
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### extends Content
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from abc import ABC, abstractmethod
|
|
155
|
+
from typing import Any, Dict
|
|
156
|
+
|
|
157
|
+
from dimp import ContentType
|
|
158
|
+
from dimp import Content
|
|
159
|
+
from dimp import BaseContent
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class CustomizedContent(Content, ABC):
|
|
163
|
+
"""
|
|
164
|
+
Application Customized message
|
|
165
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
166
|
+
|
|
167
|
+
data format: {
|
|
168
|
+
type : 0xCC,
|
|
169
|
+
sn : 123,
|
|
170
|
+
|
|
171
|
+
app : "{APP_ID}", // application (e.g.: "chat.dim.sechat")
|
|
172
|
+
mod : "{MODULE}", // module name (e.g.: "drift_bottle")
|
|
173
|
+
act : "{ACTION}", // action name (e.g.: "throw")
|
|
174
|
+
extra : info // action parameters
|
|
175
|
+
}
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
@property
|
|
179
|
+
@abstractmethod
|
|
180
|
+
def application(self) -> str:
|
|
181
|
+
""" App ID """
|
|
182
|
+
raise NotImplemented
|
|
183
|
+
|
|
184
|
+
@property
|
|
185
|
+
@abstractmethod
|
|
186
|
+
def module(self) -> str:
|
|
187
|
+
""" Module Name """
|
|
188
|
+
raise NotImplemented
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
@abstractmethod
|
|
192
|
+
def action(self) -> str:
|
|
193
|
+
""" Action Name """
|
|
194
|
+
raise NotImplemented
|
|
195
|
+
|
|
196
|
+
@classmethod
|
|
197
|
+
def create(cls, app: str, mod: str, act: str):
|
|
198
|
+
return AppCustomizedContent(app=app, mod=mod, act=act)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class AppCustomizedContent(BaseContent, CustomizedContent):
|
|
202
|
+
|
|
203
|
+
def __init__(self, content: Dict[str, Any] = None,
|
|
204
|
+
msg_type: int = None,
|
|
205
|
+
app: str = None, mod: str = None, act: str = None):
|
|
206
|
+
if content is None:
|
|
207
|
+
# 1. new content with type, application, module & action
|
|
208
|
+
assert app is not None and mod is not None and act is not None, \
|
|
209
|
+
'customized content error: %s, %s, %s, %s' % (msg_type, app, mod, act)
|
|
210
|
+
if msg_type is None:
|
|
211
|
+
msg_type = ContentType.CUSTOMIZED.value
|
|
212
|
+
super().__init__(None, msg_type)
|
|
213
|
+
self['app'] = app
|
|
214
|
+
self['mod'] = mod
|
|
215
|
+
self['act'] = act
|
|
216
|
+
else:
|
|
217
|
+
# 2. content info from network
|
|
218
|
+
assert msg_type is None and app is None and mod is None and act is None, \
|
|
219
|
+
'params error: %s, %s, %s, %s, %s' % (content, msg_type, app, mod, act)
|
|
220
|
+
super().__init__(content)
|
|
221
|
+
|
|
222
|
+
@property # Override
|
|
223
|
+
def application(self) -> str:
|
|
224
|
+
return self.get_str(key='app', default='')
|
|
225
|
+
|
|
226
|
+
@property # Override
|
|
227
|
+
def module(self) -> str:
|
|
228
|
+
return self.get_str(key='mod', default='')
|
|
229
|
+
|
|
230
|
+
@property # Override
|
|
231
|
+
def action(self) -> str:
|
|
232
|
+
return self.get_str(key='act', default='')
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### extends ID Address
|
|
236
|
+
|
|
237
|
+
* Examples in [dim plugins](https://pypi.org/project/dimplugins)
|
|
238
|
+
|
|
239
|
+
----
|
|
240
|
+
|
|
241
|
+
Copyright © 2018 Albert Moky
|
|
242
|
+
[](https://github.com/moky?tab=followers)
|
|
243
|
+
|
|
244
|
+
Platform: UNKNOWN
|
|
245
|
+
Classifier: Programming Language :: Python :: 3
|
|
246
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
247
|
+
Classifier: Operating System :: OS Independent
|
|
248
|
+
Description-Content-Type: text/markdown
|
dimp-2.2.2/README.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# Decentralized Instant Messaging Protocol (Python)
|
|
2
|
+
|
|
3
|
+
[](https://github.com/dimchat/core-py/blob/master/LICENSE)
|
|
4
|
+
[](https://github.com/dimchat/core-py/pulls)
|
|
5
|
+
[](https://github.com/dimchat/core-py/wiki)
|
|
6
|
+
[](https://github.com/dimchat/core-py/issues)
|
|
7
|
+
[](https://github.com/dimchat/core-py/archive/refs/heads/main.zip)
|
|
8
|
+
[](https://github.com/dimchat/core-py/tags)
|
|
9
|
+
[](https://pypi.org/project/dimp)
|
|
10
|
+
|
|
11
|
+
[](https://github.com/dimchat/core-py/watchers)
|
|
12
|
+
[](https://github.com/dimchat/core-py/forks)
|
|
13
|
+
[](https://github.com/dimchat/core-py/stargazers)
|
|
14
|
+
[](https://github.com/orgs/dimchat/followers)
|
|
15
|
+
|
|
16
|
+
## Dependencies
|
|
17
|
+
|
|
18
|
+
| Name | Version | Description |
|
|
19
|
+
|------|---------|-------------|
|
|
20
|
+
| [Ming Ke Ming (名可名)](https://github.com/dimchat/mkm-py) | [](https://pypi.org/project/mkm) | Decentralized User Identity Authentication |
|
|
21
|
+
| [Dao Ke Dao (道可道)](https://github.com/dimchat/dkd-py) | [](https://pypi.org/project/dkd) | Universal Message Module |
|
|
22
|
+
|
|
23
|
+
## Examples
|
|
24
|
+
|
|
25
|
+
### extends Command
|
|
26
|
+
|
|
27
|
+
* _Handshake Command Protocol_
|
|
28
|
+
0. (C-S) handshake start
|
|
29
|
+
1. (S-C) handshake again with new session
|
|
30
|
+
2. (C-S) handshake restart with new session
|
|
31
|
+
3. (S-C) handshake success
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from enum import IntEnum
|
|
35
|
+
from typing import Optional, Any, Dict
|
|
36
|
+
|
|
37
|
+
from dimp import Command, BaseCommand
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class HandshakeState(IntEnum):
|
|
41
|
+
Start = 0 # C -> S, without session key(or session expired)
|
|
42
|
+
Again = 1 # S -> C, with new session key
|
|
43
|
+
Restart = 2 # C -> S, with new session key
|
|
44
|
+
Success = 3 # S -> C, handshake accepted
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class HandshakeCommand(BaseCommand):
|
|
48
|
+
"""
|
|
49
|
+
Handshake Command
|
|
50
|
+
~~~~~~~~~~~~~~~~~
|
|
51
|
+
|
|
52
|
+
data format: {
|
|
53
|
+
type : 0x88,
|
|
54
|
+
sn : 123,
|
|
55
|
+
|
|
56
|
+
command : "handshake", // command name
|
|
57
|
+
title : "Hello world!", // "DIM?", "DIM!"
|
|
58
|
+
session : "{SESSION_ID}", // session key
|
|
59
|
+
}
|
|
60
|
+
"""
|
|
61
|
+
HANDSHAKE = 'handshake'
|
|
62
|
+
|
|
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
|
+
@property
|
|
79
|
+
def title(self) -> str:
|
|
80
|
+
# TODO: modify after all clients upgraded
|
|
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
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def session(self) -> Optional[str]:
|
|
89
|
+
return self.get_str(key='session', default=None)
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def state(self) -> HandshakeState:
|
|
93
|
+
return handshake_state(title=self.title, session=self.session)
|
|
94
|
+
|
|
95
|
+
@classmethod
|
|
96
|
+
def offer(cls, session: str = None) -> Command:
|
|
97
|
+
"""
|
|
98
|
+
Create client-station handshake offer
|
|
99
|
+
|
|
100
|
+
:param session: Old session key
|
|
101
|
+
:return: HandshakeCommand object
|
|
102
|
+
"""
|
|
103
|
+
return HandshakeCommand(title='Hello world!', session=session)
|
|
104
|
+
|
|
105
|
+
@classmethod
|
|
106
|
+
def ask(cls, session: str) -> Command:
|
|
107
|
+
"""
|
|
108
|
+
Create station-client handshake again with new session
|
|
109
|
+
|
|
110
|
+
:param session: New session key
|
|
111
|
+
:return: HandshakeCommand object
|
|
112
|
+
"""
|
|
113
|
+
return HandshakeCommand(title='DIM?', session=session)
|
|
114
|
+
|
|
115
|
+
@classmethod
|
|
116
|
+
def accepted(cls, session: str = None) -> Command:
|
|
117
|
+
"""
|
|
118
|
+
Create station-client handshake success notice
|
|
119
|
+
|
|
120
|
+
:return: HandshakeCommand object
|
|
121
|
+
"""
|
|
122
|
+
return HandshakeCommand(title='DIM!', session=session)
|
|
123
|
+
|
|
124
|
+
start = offer # (1. C->S) first handshake, without session
|
|
125
|
+
again = ask # (2. S->C) ask client to handshake with new session key
|
|
126
|
+
restart = offer # (3. C->S) handshake with new session key
|
|
127
|
+
success = accepted # (4. S->C) notice the client that handshake accepted
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def handshake_state(title: str, session: str = None) -> HandshakeState:
|
|
131
|
+
# Server -> Client
|
|
132
|
+
if title == 'DIM!': # or title == 'OK!':
|
|
133
|
+
return HandshakeState.Success
|
|
134
|
+
if title == 'DIM?':
|
|
135
|
+
return HandshakeState.Again
|
|
136
|
+
# Client -> Server: "Hello world!"
|
|
137
|
+
if session is None or len(session) == 0:
|
|
138
|
+
return HandshakeState.Start
|
|
139
|
+
else:
|
|
140
|
+
return HandshakeState.Restart
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### extends Content
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
from abc import ABC, abstractmethod
|
|
147
|
+
from typing import Any, Dict
|
|
148
|
+
|
|
149
|
+
from dimp import ContentType
|
|
150
|
+
from dimp import Content
|
|
151
|
+
from dimp import BaseContent
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class CustomizedContent(Content, ABC):
|
|
155
|
+
"""
|
|
156
|
+
Application Customized message
|
|
157
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
158
|
+
|
|
159
|
+
data format: {
|
|
160
|
+
type : 0xCC,
|
|
161
|
+
sn : 123,
|
|
162
|
+
|
|
163
|
+
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
|
+
extra : info // action parameters
|
|
167
|
+
}
|
|
168
|
+
"""
|
|
169
|
+
|
|
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
|
+
def __init__(self, content: Dict[str, Any] = None,
|
|
196
|
+
msg_type: int = None,
|
|
197
|
+
app: str = None, mod: str = None, act: str = None):
|
|
198
|
+
if content is None:
|
|
199
|
+
# 1. new content with type, application, module & action
|
|
200
|
+
assert app is not None and mod is not None and act is not None, \
|
|
201
|
+
'customized content error: %s, %s, %s, %s' % (msg_type, app, mod, act)
|
|
202
|
+
if msg_type is None:
|
|
203
|
+
msg_type = ContentType.CUSTOMIZED.value
|
|
204
|
+
super().__init__(None, msg_type)
|
|
205
|
+
self['app'] = app
|
|
206
|
+
self['mod'] = mod
|
|
207
|
+
self['act'] = act
|
|
208
|
+
else:
|
|
209
|
+
# 2. content info from network
|
|
210
|
+
assert msg_type is None and app is None and mod is None and act is None, \
|
|
211
|
+
'params error: %s, %s, %s, %s, %s' % (content, msg_type, app, mod, act)
|
|
212
|
+
super().__init__(content)
|
|
213
|
+
|
|
214
|
+
@property # Override
|
|
215
|
+
def application(self) -> str:
|
|
216
|
+
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
|
+
```
|
|
226
|
+
|
|
227
|
+
### extends ID Address
|
|
228
|
+
|
|
229
|
+
* Examples in [dim plugins](https://pypi.org/project/dimplugins)
|
|
230
|
+
|
|
231
|
+
----
|
|
232
|
+
|
|
233
|
+
Copyright © 2018 Albert Moky
|
|
234
|
+
[](https://github.com/moky?tab=followers)
|
|
@@ -28,16 +28,19 @@
|
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
|
+
from mkm.types import *
|
|
32
|
+
from mkm.format import *
|
|
33
|
+
from mkm.crypto import *
|
|
34
|
+
from mkm import *
|
|
35
|
+
from dkd import *
|
|
36
|
+
|
|
37
|
+
from .protocol.commands import CommandFactory
|
|
31
38
|
from .protocol import *
|
|
32
39
|
from .crypto import *
|
|
33
40
|
from .mkm import *
|
|
34
41
|
from .dkd import *
|
|
35
42
|
from .msg import *
|
|
36
43
|
|
|
37
|
-
from .barrack import Barrack
|
|
38
|
-
from .transceiver import Transceiver
|
|
39
|
-
from .packer import Packer
|
|
40
|
-
from .processor import Processor
|
|
41
44
|
|
|
42
45
|
name = "DIMP"
|
|
43
46
|
|
|
@@ -45,19 +48,53 @@ __author__ = 'Albert Moky'
|
|
|
45
48
|
|
|
46
49
|
__all__ = [
|
|
47
50
|
|
|
51
|
+
'Singleton',
|
|
52
|
+
|
|
48
53
|
'URI', 'DateTime',
|
|
49
|
-
|
|
54
|
+
|
|
55
|
+
'Converter', 'Copier',
|
|
56
|
+
'Wrapper', 'Stringer', 'Mapper',
|
|
57
|
+
'ConstantString', # 'String',
|
|
58
|
+
'Dictionary',
|
|
59
|
+
|
|
60
|
+
#
|
|
61
|
+
# Format
|
|
62
|
+
#
|
|
63
|
+
|
|
64
|
+
'DataCoder', 'Hex', 'Base58', 'Base64',
|
|
65
|
+
'ObjectCoder', 'JSON',
|
|
66
|
+
'MapCoder', 'JSONMap',
|
|
67
|
+
'ListCoder', 'JSONList',
|
|
68
|
+
'StringCoder', 'UTF8',
|
|
69
|
+
|
|
70
|
+
'hex_encode', 'hex_decode',
|
|
71
|
+
'base58_encode', 'base58_decode',
|
|
72
|
+
'base64_encode', 'base64_decode',
|
|
73
|
+
'json_encode', 'json_decode',
|
|
74
|
+
'utf8_encode', 'utf8_decode',
|
|
75
|
+
|
|
76
|
+
'TransportableData', 'TransportableDataFactory',
|
|
77
|
+
'PortableNetworkFile', 'PortableNetworkFileFactory',
|
|
78
|
+
|
|
79
|
+
#
|
|
80
|
+
# Digest
|
|
81
|
+
#
|
|
82
|
+
|
|
83
|
+
'DataDigester',
|
|
84
|
+
'MD5', 'SHA1', 'SHA256', 'KECCAK256', 'RIPEMD160',
|
|
85
|
+
|
|
86
|
+
'md5', 'sha1', 'sha256', 'keccak256', 'ripemd160',
|
|
50
87
|
|
|
51
88
|
#
|
|
52
89
|
# Crypto
|
|
53
90
|
#
|
|
54
91
|
|
|
55
|
-
'CryptographyKey',
|
|
56
|
-
'
|
|
57
|
-
'SymmetricKey', '
|
|
58
|
-
'
|
|
59
|
-
|
|
60
|
-
'
|
|
92
|
+
'CryptographyKey',
|
|
93
|
+
'EncryptKey', 'DecryptKey', 'SignKey', 'VerifyKey',
|
|
94
|
+
'SymmetricKey', 'AsymmetricKey',
|
|
95
|
+
'PrivateKey', 'PublicKey',
|
|
96
|
+
|
|
97
|
+
'SymmetricKeyFactory', 'PrivateKeyFactory', 'PublicKeyFactory',
|
|
61
98
|
|
|
62
99
|
'BaseKey', 'BaseSymmetricKey',
|
|
63
100
|
'BaseAsymmetricKey', 'BasePublicKey', 'BasePrivateKey',
|
|
@@ -69,79 +106,82 @@ __all__ = [
|
|
|
69
106
|
# MingKeMing
|
|
70
107
|
#
|
|
71
108
|
|
|
72
|
-
'EntityType',
|
|
73
|
-
'Address',
|
|
74
|
-
'ID',
|
|
75
|
-
'Meta',
|
|
76
|
-
'Document', '
|
|
77
|
-
'Visa', 'Bulletin',
|
|
109
|
+
'EntityType',
|
|
110
|
+
'Address',
|
|
111
|
+
'ID',
|
|
112
|
+
'Meta',
|
|
113
|
+
'Document', 'Visa', 'Bulletin',
|
|
78
114
|
|
|
79
|
-
'
|
|
80
|
-
'
|
|
81
|
-
'
|
|
82
|
-
'
|
|
83
|
-
'BaseMeta', 'MetaHelper',
|
|
84
|
-
'BaseDocument', 'BaseVisa', 'BaseBulletin',
|
|
115
|
+
'AddressFactory',
|
|
116
|
+
'IDFactory',
|
|
117
|
+
'MetaFactory',
|
|
118
|
+
'DocumentFactory',
|
|
85
119
|
|
|
86
|
-
'
|
|
87
|
-
'
|
|
88
|
-
'
|
|
89
|
-
|
|
120
|
+
'Identifier',
|
|
121
|
+
'ANYONE', 'EVERYONE', 'FOUNDER',
|
|
122
|
+
'ANYWHERE', 'EVERYWHERE',
|
|
123
|
+
# 'BroadcastAddress',
|
|
90
124
|
|
|
91
|
-
'
|
|
125
|
+
'BaseMeta',
|
|
126
|
+
'BaseDocument', 'BaseVisa', 'BaseBulletin',
|
|
92
127
|
|
|
93
128
|
#
|
|
94
129
|
# DaoKeDao
|
|
95
130
|
#
|
|
96
131
|
|
|
97
|
-
'ContentType',
|
|
98
|
-
'
|
|
132
|
+
'ContentType',
|
|
133
|
+
'Content',
|
|
134
|
+
'Envelope',
|
|
99
135
|
'Message',
|
|
100
|
-
'InstantMessage', '
|
|
101
|
-
'SecureMessage', 'SecureMessageFactory',
|
|
102
|
-
'ReliableMessage', 'ReliableMessageFactory',
|
|
103
|
-
|
|
104
|
-
'InstantMessageDelegate', 'SecureMessageDelegate', 'ReliableMessageDelegate',
|
|
105
|
-
'MessageGeneralFactory', 'MessageFactoryManager',
|
|
136
|
+
'InstantMessage', 'SecureMessage', 'ReliableMessage',
|
|
106
137
|
|
|
138
|
+
# contents
|
|
107
139
|
'TextContent', 'ArrayContent', 'ForwardContent',
|
|
108
140
|
'PageContent', 'NameCard',
|
|
109
141
|
'FileContent', 'ImageContent', 'AudioContent', 'VideoContent',
|
|
110
142
|
'MoneyContent', 'TransferContent',
|
|
111
|
-
'
|
|
143
|
+
'QuoteContent', 'CombineContent',
|
|
112
144
|
|
|
113
|
-
|
|
145
|
+
# commands
|
|
146
|
+
'Command',
|
|
114
147
|
'MetaCommand', 'DocumentCommand',
|
|
115
148
|
'ReceiptCommand',
|
|
116
149
|
|
|
150
|
+
# group history
|
|
117
151
|
'HistoryCommand', 'GroupCommand',
|
|
118
152
|
'InviteCommand', 'ExpelCommand', 'JoinCommand', 'QuitCommand', 'QueryCommand', 'ResetCommand',
|
|
119
153
|
'HireCommand', 'FireCommand', 'ResignCommand',
|
|
120
154
|
|
|
155
|
+
# extend contents
|
|
121
156
|
'BaseContent',
|
|
122
157
|
'BaseTextContent', 'ListContent', 'SecretContent',
|
|
123
158
|
'WebPageContent', 'NameCardContent',
|
|
124
159
|
'BaseFileContent', 'ImageFileContent', 'AudioFileContent', 'VideoFileContent',
|
|
125
160
|
'BaseMoneyContent', 'TransferMoneyContent',
|
|
126
|
-
'
|
|
161
|
+
'BaseQuoteContent', 'CombineForwardContent',
|
|
127
162
|
|
|
163
|
+
# extend commands
|
|
128
164
|
'BaseCommand',
|
|
129
165
|
'BaseMetaCommand', 'BaseDocumentCommand',
|
|
130
166
|
'BaseReceiptCommand',
|
|
131
167
|
|
|
168
|
+
# extend group history
|
|
132
169
|
'BaseHistoryCommand', 'BaseGroupCommand',
|
|
133
170
|
'InviteGroupCommand', 'ExpelGroupCommand', 'JoinGroupCommand',
|
|
134
171
|
'QuitGroupCommand', 'QueryGroupCommand', 'ResetGroupCommand',
|
|
135
172
|
'HireGroupCommand', 'FireGroupCommand', 'ResignGroupCommand',
|
|
136
173
|
|
|
137
|
-
|
|
174
|
+
#
|
|
175
|
+
# Message
|
|
176
|
+
#
|
|
138
177
|
|
|
139
|
-
'MessageEnvelope',
|
|
178
|
+
'MessageEnvelope',
|
|
179
|
+
'BaseMessage',
|
|
140
180
|
'PlainMessage', 'EncryptedMessage', 'NetworkMessage',
|
|
141
181
|
|
|
142
|
-
#
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
'
|
|
182
|
+
# factories
|
|
183
|
+
'ContentFactory', 'CommandFactory',
|
|
184
|
+
'EnvelopeFactory',
|
|
185
|
+
'InstantMessageFactory', 'SecureMessageFactory', 'ReliableMessageFactory',
|
|
146
186
|
|
|
147
187
|
]
|