dimp 2.4.2__tar.gz → 2.4.3__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.4.2 → dimp-2.4.3}/PKG-INFO +6 -5
- {dimp-2.4.2 → dimp-2.4.3}/README.md +5 -4
- {dimp-2.4.2 → dimp-2.4.3}/dimp/__init__.py +6 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp/crypto/algorithms.py +4 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp/dkd/base.py +7 -6
- {dimp-2.4.2 → dimp-2.4.3}/dimp/dkd/envelope.py +5 -3
- {dimp-2.4.2 → dimp-2.4.3}/dimp/dkd/instant.py +9 -7
- {dimp-2.4.2 → dimp-2.4.3}/dimp/dkd/reliable.py +5 -3
- {dimp-2.4.2 → dimp-2.4.3}/dimp/dkd/secure.py +9 -7
- {dimp-2.4.2 → dimp-2.4.3}/dimp/format/__init__.py +6 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp/format/data.py +2 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp/format/duri.py +7 -6
- {dimp-2.4.2 → dimp-2.4.3}/dimp/format/embed.py +6 -5
- {dimp-2.4.2 → dimp-2.4.3}/dimp/format/file.py +7 -5
- {dimp-2.4.2 → dimp-2.4.3}/dimp/format/file_wrapper.py +7 -5
- {dimp-2.4.2 → dimp-2.4.3}/dimp/format/pnf.py +12 -9
- {dimp-2.4.2 → dimp-2.4.3}/dimp/format/pnf_wrapper.py +12 -9
- {dimp-2.4.2 → dimp-2.4.3}/dimp/mkm/docs.py +7 -5
- {dimp-2.4.2 → dimp-2.4.3}/dimp/mkm/document.py +10 -6
- {dimp-2.4.2 → dimp-2.4.3}/dimp/mkm/meta.py +9 -7
- {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/assets.py +5 -3
- {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/base.py +9 -7
- {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/commands.py +7 -4
- {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/contents.py +10 -8
- {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/files.py +15 -13
- {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/forward.py +11 -9
- {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/groups.py +9 -8
- {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/quote.py +12 -9
- {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/receipt.py +6 -4
- {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/types.py +3 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/version.py +4 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp.egg-info/PKG-INFO +6 -5
- dimp-2.4.3/dimp.egg-info/requires.txt +2 -0
- {dimp-2.4.2 → dimp-2.4.3}/setup.py +3 -3
- dimp-2.4.2/dimp.egg-info/requires.txt +0 -2
- {dimp-2.4.2 → dimp-2.4.3}/LICENSE +0 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp/crypto/__init__.py +0 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp/dkd/__init__.py +0 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp/ext/__init__.py +0 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp/format/base.py +0 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp/mkm/__init__.py +0 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/__init__.py +0 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/docs.py +0 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp.egg-info/SOURCES.txt +0 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp.egg-info/dependency_links.txt +0 -0
- {dimp-2.4.2 → dimp-2.4.3}/dimp.egg-info/top_level.txt +0 -0
- {dimp-2.4.2 → dimp-2.4.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dimp
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.3
|
|
4
4
|
Summary: Decentralized Instant Messaging Protocol
|
|
5
5
|
Home-page: https://github.com/dimchat/core-py
|
|
6
6
|
Author: Albert Moky
|
|
@@ -47,7 +47,8 @@ License-File: LICENSE
|
|
|
47
47
|
```python
|
|
48
48
|
from abc import ABC, abstractmethod
|
|
49
49
|
from enum import IntEnum
|
|
50
|
-
from
|
|
50
|
+
from collections.abc import Mapping
|
|
51
|
+
from typing import Optional
|
|
51
52
|
|
|
52
53
|
from dimp import *
|
|
53
54
|
|
|
@@ -150,7 +151,7 @@ class HandshakeCommand(Command, ABC):
|
|
|
150
151
|
|
|
151
152
|
class BaseHandshakeCommand(BaseCommand, HandshakeCommand):
|
|
152
153
|
|
|
153
|
-
def __init__(self, content:
|
|
154
|
+
def __init__(self, content: Mapping = None, title: str = None, session: str = None):
|
|
154
155
|
if content is None:
|
|
155
156
|
# 1. new command with title & session key
|
|
156
157
|
assert title is not None, 'handshake command error: %s' % session
|
|
@@ -250,14 +251,14 @@ class CustomizedContent(Content, ABC):
|
|
|
250
251
|
```
|
|
251
252
|
|
|
252
253
|
```python
|
|
253
|
-
from
|
|
254
|
+
from collections.abc import Mapping
|
|
254
255
|
|
|
255
256
|
from dimp import *
|
|
256
257
|
|
|
257
258
|
|
|
258
259
|
class AppCustomizedContent(BaseContent, AppContent, CustomizedContent):
|
|
259
260
|
|
|
260
|
-
def __init__(self, content:
|
|
261
|
+
def __init__(self, content: Mapping = None,
|
|
261
262
|
msg_type: str = None,
|
|
262
263
|
app: str = None, mod: str = None, act: str = None):
|
|
263
264
|
if content is None:
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
```python
|
|
34
34
|
from abc import ABC, abstractmethod
|
|
35
35
|
from enum import IntEnum
|
|
36
|
-
from
|
|
36
|
+
from collections.abc import Mapping
|
|
37
|
+
from typing import Optional
|
|
37
38
|
|
|
38
39
|
from dimp import *
|
|
39
40
|
|
|
@@ -136,7 +137,7 @@ class HandshakeCommand(Command, ABC):
|
|
|
136
137
|
|
|
137
138
|
class BaseHandshakeCommand(BaseCommand, HandshakeCommand):
|
|
138
139
|
|
|
139
|
-
def __init__(self, content:
|
|
140
|
+
def __init__(self, content: Mapping = None, title: str = None, session: str = None):
|
|
140
141
|
if content is None:
|
|
141
142
|
# 1. new command with title & session key
|
|
142
143
|
assert title is not None, 'handshake command error: %s' % session
|
|
@@ -236,14 +237,14 @@ class CustomizedContent(Content, ABC):
|
|
|
236
237
|
```
|
|
237
238
|
|
|
238
239
|
```python
|
|
239
|
-
from
|
|
240
|
+
from collections.abc import Mapping
|
|
240
241
|
|
|
241
242
|
from dimp import *
|
|
242
243
|
|
|
243
244
|
|
|
244
245
|
class AppCustomizedContent(BaseContent, AppContent, CustomizedContent):
|
|
245
246
|
|
|
246
|
-
def __init__(self, content:
|
|
247
|
+
def __init__(self, content: Mapping = None,
|
|
247
248
|
msg_type: str = None,
|
|
248
249
|
app: str = None, mod: str = None, act: str = None):
|
|
249
250
|
if content is None:
|
|
@@ -23,7 +23,10 @@
|
|
|
23
23
|
# SOFTWARE.
|
|
24
24
|
# ==============================================================================
|
|
25
25
|
|
|
26
|
+
from mkm.types import final
|
|
26
27
|
|
|
28
|
+
|
|
29
|
+
@final
|
|
27
30
|
class AsymmetricAlgorithms:
|
|
28
31
|
""" Algorithms for Asymmetric Key """
|
|
29
32
|
|
|
@@ -31,6 +34,7 @@ class AsymmetricAlgorithms:
|
|
|
31
34
|
ECC = 'ECC'
|
|
32
35
|
|
|
33
36
|
|
|
37
|
+
@final
|
|
34
38
|
class SymmetricAlgorithms:
|
|
35
39
|
""" Algorithms for Symmetric Key """
|
|
36
40
|
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
| time | | time | | time |
|
|
41
41
|
| | | | | |
|
|
42
42
|
| content | | data | | data |
|
|
43
|
-
+-------------+ |
|
|
43
|
+
+-------------+ | keys | | keys |
|
|
44
44
|
+------------+ | signature |
|
|
45
45
|
+--------------+
|
|
46
46
|
Algorithm:
|
|
@@ -49,22 +49,23 @@
|
|
|
49
49
|
signature = sender.private_key.sign(data)
|
|
50
50
|
"""
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
from typing import Optional, Dict
|
|
52
|
+
from typing import Optional
|
|
54
53
|
|
|
55
54
|
from mkm.types import DateTime
|
|
55
|
+
from mkm.types import StrMap
|
|
56
56
|
from mkm.types import Dictionary
|
|
57
|
+
|
|
57
58
|
from mkm.protocol import ID
|
|
58
59
|
from dkd.protocol import Envelope, Message
|
|
59
60
|
|
|
60
61
|
|
|
61
62
|
class BaseMessage(Dictionary, Message):
|
|
62
63
|
|
|
63
|
-
def __init__(self, msg:
|
|
64
|
+
def __init__(self, msg: StrMap = None, head: Envelope = None):
|
|
64
65
|
if msg is None:
|
|
65
66
|
# 1. new message with envelope
|
|
66
67
|
assert head is not None, 'message envelope should not be empty'
|
|
67
|
-
msg = head.
|
|
68
|
+
msg = head.to_map()
|
|
68
69
|
else:
|
|
69
70
|
# 2. message info from network
|
|
70
71
|
assert head is None, f'params error: {msg}, {head}'
|
|
@@ -77,7 +78,7 @@ class BaseMessage(Dictionary, Message):
|
|
|
77
78
|
env = self.__envelope
|
|
78
79
|
if env is None:
|
|
79
80
|
# let envelope share the same dictionary with message
|
|
80
|
-
env = Envelope.parse(envelope=super().
|
|
81
|
+
env = Envelope.parse(envelope=super().to_map())
|
|
81
82
|
self.__envelope = env
|
|
82
83
|
return env
|
|
83
84
|
|
|
@@ -28,10 +28,12 @@
|
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
|
-
from typing import Optional
|
|
31
|
+
from typing import Optional
|
|
32
32
|
|
|
33
33
|
from mkm.types import DateTime
|
|
34
|
+
from mkm.types import StrMap
|
|
34
35
|
from mkm.types import Dictionary
|
|
36
|
+
|
|
35
37
|
from mkm.protocol import ID, ANYONE
|
|
36
38
|
from dkd.protocol import Envelope
|
|
37
39
|
|
|
@@ -52,7 +54,7 @@ from dkd.protocol import Envelope
|
|
|
52
54
|
|
|
53
55
|
class MessageEnvelope(Dictionary, Envelope):
|
|
54
56
|
|
|
55
|
-
def __init__(self, envelope:
|
|
57
|
+
def __init__(self, envelope: StrMap = None,
|
|
56
58
|
sender: ID = None, receiver: Optional[ID] = None, time: Optional[DateTime] = None):
|
|
57
59
|
if envelope is None:
|
|
58
60
|
# 1. new envelope with sender, receiver & time
|
|
@@ -83,7 +85,7 @@ class MessageEnvelope(Dictionary, Envelope):
|
|
|
83
85
|
if did is None:
|
|
84
86
|
did = self.get('sender')
|
|
85
87
|
did = ID.parse(identifier=did)
|
|
86
|
-
assert did is not None, 'message sender error: %s' % super().
|
|
88
|
+
assert did is not None, 'message sender error: %s' % super().to_map()
|
|
87
89
|
self.__sender = did
|
|
88
90
|
return did
|
|
89
91
|
|
|
@@ -28,9 +28,11 @@
|
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
|
-
from typing import Optional
|
|
31
|
+
from typing import Optional
|
|
32
32
|
|
|
33
33
|
from mkm.types import DateTime
|
|
34
|
+
from mkm.types import StrMap, MutableStrMap
|
|
35
|
+
|
|
34
36
|
from mkm.protocol import ID
|
|
35
37
|
from dkd.protocol import Content
|
|
36
38
|
from dkd.protocol import Envelope
|
|
@@ -57,13 +59,13 @@ from .base import BaseMessage
|
|
|
57
59
|
|
|
58
60
|
class PlainMessage(BaseMessage, InstantMessage):
|
|
59
61
|
|
|
60
|
-
def __init__(self, msg:
|
|
62
|
+
def __init__(self, msg: StrMap = None,
|
|
61
63
|
head: Envelope = None, body: Content = None):
|
|
62
64
|
if msg is None:
|
|
63
65
|
# 1. new instant message with envelope & content
|
|
64
66
|
assert head is not None and body is not None, f'instant message error: {head}, {body}'
|
|
65
67
|
super().__init__(None, head)
|
|
66
|
-
# self['content'] = body.
|
|
68
|
+
# self['content'] = body.to_map()
|
|
67
69
|
else:
|
|
68
70
|
# 2. message info from network
|
|
69
71
|
assert head is None and body is None, f'params error: {msg}, {head}, {body}'
|
|
@@ -93,7 +95,7 @@ class PlainMessage(BaseMessage, InstantMessage):
|
|
|
93
95
|
if body is None:
|
|
94
96
|
info = self.get('content')
|
|
95
97
|
body = Content.parse(content=info)
|
|
96
|
-
assert body is not None, f'message content error: {self.
|
|
98
|
+
assert body is not None, f'message content error: {self.to_map()}'
|
|
97
99
|
self.__content = body
|
|
98
100
|
return body
|
|
99
101
|
|
|
@@ -104,10 +106,10 @@ class PlainMessage(BaseMessage, InstantMessage):
|
|
|
104
106
|
self.__content = value
|
|
105
107
|
|
|
106
108
|
# Override
|
|
107
|
-
def
|
|
109
|
+
def to_map(self) -> MutableStrMap:
|
|
108
110
|
# serialize 'content'
|
|
109
111
|
body = self.__content
|
|
110
112
|
if body is not None and self.get('content') is None:
|
|
111
|
-
self['content'] = body.
|
|
113
|
+
self['content'] = body.to_map()
|
|
112
114
|
# OK
|
|
113
|
-
return super().
|
|
115
|
+
return super().to_map()
|
|
@@ -28,9 +28,11 @@
|
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
|
-
from typing import Optional
|
|
31
|
+
from typing import Optional
|
|
32
32
|
|
|
33
|
+
from mkm.types import StrMap
|
|
33
34
|
from mkm.format import TransportableData
|
|
35
|
+
|
|
34
36
|
from dkd.protocol import ReliableMessage
|
|
35
37
|
|
|
36
38
|
from .secure import EncryptedMessage
|
|
@@ -48,7 +50,7 @@ from .secure import EncryptedMessage
|
|
|
48
50
|
"receiver" : "hulk@yyy",
|
|
49
51
|
"time" : 123.45,
|
|
50
52
|
|
|
51
|
-
//-- content data and
|
|
53
|
+
//-- content data and keys
|
|
52
54
|
"data" : "...", // base64_encode( symmetric_encrypt(content))
|
|
53
55
|
"keys" : {
|
|
54
56
|
"ID1" : "key1", // base64_encode(asymmetric_encrypt(password))
|
|
@@ -62,7 +64,7 @@ from .secure import EncryptedMessage
|
|
|
62
64
|
|
|
63
65
|
class NetworkMessage(EncryptedMessage, ReliableMessage):
|
|
64
66
|
|
|
65
|
-
def __init__(self, msg:
|
|
67
|
+
def __init__(self, msg: StrMap):
|
|
66
68
|
super().__init__(msg=msg)
|
|
67
69
|
# lazy
|
|
68
70
|
self.__signature: Optional[TransportableData] = None
|
|
@@ -28,9 +28,11 @@
|
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
|
-
from typing import Optional
|
|
31
|
+
from typing import Optional
|
|
32
32
|
|
|
33
|
+
from mkm.types import Mapping, StrMap
|
|
33
34
|
from mkm.format import TransportableData
|
|
35
|
+
|
|
34
36
|
from dkd.protocol import SecureMessage
|
|
35
37
|
|
|
36
38
|
from ..format import PlainData
|
|
@@ -49,7 +51,7 @@ from .base import BaseMessage
|
|
|
49
51
|
"receiver" : "hulk@yyy",
|
|
50
52
|
"time" : 123.45,
|
|
51
53
|
|
|
52
|
-
//-- content data and
|
|
54
|
+
//-- content data and keys
|
|
53
55
|
"data" : "...", // base64_encode( symmetric_encrypt(content))
|
|
54
56
|
"keys" : {
|
|
55
57
|
"ID1" : "key1", // base64_encode(asymmetric_encrypt(password))
|
|
@@ -61,11 +63,11 @@ from .base import BaseMessage
|
|
|
61
63
|
|
|
62
64
|
class EncryptedMessage(BaseMessage, SecureMessage):
|
|
63
65
|
|
|
64
|
-
def __init__(self, msg:
|
|
66
|
+
def __init__(self, msg: StrMap):
|
|
65
67
|
super().__init__(msg=msg)
|
|
66
68
|
# lazy
|
|
67
69
|
self.__data: Optional[TransportableData] = None
|
|
68
|
-
self.__keys: Optional[
|
|
70
|
+
self.__keys: Optional[StrMap] = None
|
|
69
71
|
|
|
70
72
|
@property # Override
|
|
71
73
|
def data(self) -> TransportableData:
|
|
@@ -73,7 +75,7 @@ class EncryptedMessage(BaseMessage, SecureMessage):
|
|
|
73
75
|
if ted is None:
|
|
74
76
|
text = self.get('data')
|
|
75
77
|
if text is None:
|
|
76
|
-
assert False, 'message data not found: %s' % super().
|
|
78
|
+
assert False, 'message data not found: %s' % super().to_map()
|
|
77
79
|
elif not BaseMessage.is_broadcast(msg=self):
|
|
78
80
|
# message content had been encrypted by a symmetric key,
|
|
79
81
|
# so the data should be encoded here (with algorithm 'base64' as default).
|
|
@@ -89,11 +91,11 @@ class EncryptedMessage(BaseMessage, SecureMessage):
|
|
|
89
91
|
return ted
|
|
90
92
|
|
|
91
93
|
@property # Override
|
|
92
|
-
def encrypted_keys(self) -> Optional[
|
|
94
|
+
def encrypted_keys(self) -> Optional[StrMap]:
|
|
93
95
|
keys = self.__keys
|
|
94
96
|
if keys is None:
|
|
95
97
|
keys = self.get('keys')
|
|
96
|
-
if isinstance(keys,
|
|
98
|
+
if isinstance(keys, Mapping):
|
|
97
99
|
self.__keys = keys
|
|
98
100
|
else:
|
|
99
101
|
assert keys is None, f'message keys error: {keys}'
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
from typing import Optional
|
|
27
27
|
|
|
28
|
+
from mkm.types import final
|
|
28
29
|
from mkm.format import base64_encode, base64_decode
|
|
29
30
|
from mkm.format import utf8_encode, utf8_decode
|
|
30
31
|
|
|
@@ -70,6 +71,7 @@ class Base64Data(BaseData):
|
|
|
70
71
|
return Base64Data(string=string, binary=binary)
|
|
71
72
|
|
|
72
73
|
|
|
74
|
+
@final
|
|
73
75
|
class PlainData(BaseData):
|
|
74
76
|
""" UTF-8 encoding """
|
|
75
77
|
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
# SOFTWARE.
|
|
24
24
|
# ==============================================================================
|
|
25
25
|
|
|
26
|
-
from typing import Optional
|
|
26
|
+
from typing import Optional
|
|
27
|
+
from typing import Mapping, MutableMapping
|
|
27
28
|
|
|
28
29
|
from mkm.format import base64_decode, utf8_encode
|
|
29
30
|
|
|
@@ -39,7 +40,7 @@ from mkm.format import base64_decode, utf8_encode
|
|
|
39
40
|
|
|
40
41
|
class Header:
|
|
41
42
|
|
|
42
|
-
def __init__(self, mime_type: str, encoding: str = None, extra:
|
|
43
|
+
def __init__(self, mime_type: str, encoding: str = None, extra: Mapping[str, str] = None):
|
|
43
44
|
super().__init__()
|
|
44
45
|
self.__mime_type = mime_type
|
|
45
46
|
self.__encoding = encoding
|
|
@@ -58,7 +59,7 @@ class Header:
|
|
|
58
59
|
return self.__encoding
|
|
59
60
|
|
|
60
61
|
@property
|
|
61
|
-
def extra(self) -> Optional[
|
|
62
|
+
def extra(self) -> Optional[Mapping[str, str]]:
|
|
62
63
|
""" extra parameters """
|
|
63
64
|
return self.__extra
|
|
64
65
|
|
|
@@ -78,7 +79,7 @@ class Header:
|
|
|
78
79
|
else:
|
|
79
80
|
name = name.lower()
|
|
80
81
|
# get value by name in lowercase
|
|
81
|
-
return extra
|
|
82
|
+
return extra.get(name)
|
|
82
83
|
|
|
83
84
|
# Override
|
|
84
85
|
def __str__(self) -> str:
|
|
@@ -145,7 +146,7 @@ class Header:
|
|
|
145
146
|
mime_type: str = None
|
|
146
147
|
encoding: str = None
|
|
147
148
|
# split extra info
|
|
148
|
-
extra:
|
|
149
|
+
extra: MutableMapping[str, str] = None
|
|
149
150
|
for item in array:
|
|
150
151
|
if len(item) == 0:
|
|
151
152
|
# assert False, f'header error: {uri}'
|
|
@@ -202,7 +203,7 @@ class DataURI:
|
|
|
202
203
|
return self.__body
|
|
203
204
|
|
|
204
205
|
@property
|
|
205
|
-
def parameters(self) -> Optional[
|
|
206
|
+
def parameters(self) -> Optional[Mapping[str, str]]:
|
|
206
207
|
""" extra parameters """
|
|
207
208
|
return self.head.extra
|
|
208
209
|
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
# SOFTWARE.
|
|
24
24
|
# ==============================================================================
|
|
25
25
|
|
|
26
|
-
from typing import Optional
|
|
26
|
+
from typing import Optional
|
|
27
|
+
from typing import Mapping
|
|
27
28
|
|
|
28
29
|
from mkm.format import base64_encode
|
|
29
30
|
|
|
@@ -46,7 +47,7 @@ class EmbedData(BaseData):
|
|
|
46
47
|
# lazy load
|
|
47
48
|
self.__data_uri: Optional[DataURI] = None
|
|
48
49
|
self.__mime_type: Optional[str] = None # default is "text/plain"
|
|
49
|
-
self.__parameters: Optional[
|
|
50
|
+
self.__parameters: Optional[Mapping[str, str]] = None
|
|
50
51
|
|
|
51
52
|
@property
|
|
52
53
|
def encoding(self) -> Optional[str]:
|
|
@@ -84,7 +85,7 @@ class EmbedData(BaseData):
|
|
|
84
85
|
def header_value(self, name: str) -> Optional[str]:
|
|
85
86
|
extra = self.parameters
|
|
86
87
|
if extra is not None:
|
|
87
|
-
value = extra
|
|
88
|
+
value = extra.get(name)
|
|
88
89
|
if value is not None:
|
|
89
90
|
# charset
|
|
90
91
|
# filename
|
|
@@ -98,7 +99,7 @@ class EmbedData(BaseData):
|
|
|
98
99
|
# return self.encoding
|
|
99
100
|
|
|
100
101
|
@property
|
|
101
|
-
def parameters(self) -> Optional[
|
|
102
|
+
def parameters(self) -> Optional[Mapping[str, str]]:
|
|
102
103
|
extra = self.__parameters
|
|
103
104
|
if extra is not None:
|
|
104
105
|
return extra
|
|
@@ -171,7 +172,7 @@ class EmbedData(BaseData):
|
|
|
171
172
|
|
|
172
173
|
@classmethod
|
|
173
174
|
def new(cls, string: Optional[str], binary: Optional[bytes],
|
|
174
|
-
uri: DataURI = None, mime_type: str = None, parameters:
|
|
175
|
+
uri: DataURI = None, mime_type: str = None, parameters: Mapping[str, str] = None):
|
|
175
176
|
if parameters is None and uri is not None:
|
|
176
177
|
parameters = uri.parameters
|
|
177
178
|
embed = EmbedData(string=string, binary=binary)
|
|
@@ -24,10 +24,12 @@
|
|
|
24
24
|
# ==============================================================================
|
|
25
25
|
|
|
26
26
|
from abc import ABC, abstractmethod
|
|
27
|
-
from typing import Optional, Union, Any
|
|
27
|
+
from typing import Optional, Union, Any
|
|
28
28
|
|
|
29
|
+
from mkm.types import StrMap, MutableStrMap
|
|
29
30
|
from mkm.types import Mapper
|
|
30
31
|
from mkm.types import URI
|
|
32
|
+
|
|
31
33
|
from mkm.crypto import DecryptKey
|
|
32
34
|
from mkm.format import TransportableResource
|
|
33
35
|
from mkm.format import TransportableData
|
|
@@ -145,15 +147,15 @@ class TransportableFile(Mapper, TransportableResource, ABC):
|
|
|
145
147
|
|
|
146
148
|
# Override
|
|
147
149
|
@abstractmethod
|
|
148
|
-
def
|
|
150
|
+
def to_map(self) -> MutableStrMap:
|
|
149
151
|
""" Serialize to map """
|
|
150
152
|
raise NotImplementedError(
|
|
151
|
-
f'Not implemented: {type(self).__module__}.{type(self).__name__}.
|
|
153
|
+
f'Not implemented: {type(self).__module__}.{type(self).__name__}.to_map()'
|
|
152
154
|
)
|
|
153
155
|
|
|
154
156
|
# Override
|
|
155
157
|
@abstractmethod
|
|
156
|
-
def serialize(self) -> Union[str,
|
|
158
|
+
def serialize(self) -> Union[str, StrMap]:
|
|
157
159
|
"""
|
|
158
160
|
Serializes this PNF to a URL string or a map.
|
|
159
161
|
|
|
@@ -217,7 +219,7 @@ class TransportableFileFactory(ABC):
|
|
|
217
219
|
)
|
|
218
220
|
|
|
219
221
|
@abstractmethod
|
|
220
|
-
def parse_transportable_file(self, pnf:
|
|
222
|
+
def parse_transportable_file(self, pnf: StrMap) -> Optional[TransportableFile]:
|
|
221
223
|
"""
|
|
222
224
|
Parse map object to PNF
|
|
223
225
|
|
|
@@ -24,9 +24,11 @@
|
|
|
24
24
|
# ==============================================================================
|
|
25
25
|
|
|
26
26
|
from abc import ABC, abstractmethod
|
|
27
|
-
from typing import Optional
|
|
27
|
+
from typing import Optional
|
|
28
28
|
|
|
29
29
|
from mkm.types import URI
|
|
30
|
+
from mkm.types import StrMap, MutableStrMap
|
|
31
|
+
|
|
30
32
|
from mkm.crypto import DecryptKey
|
|
31
33
|
from mkm.format import TransportableData
|
|
32
34
|
from mkm.ext import shared_format_extensions
|
|
@@ -35,10 +37,10 @@ from mkm.ext import shared_format_extensions
|
|
|
35
37
|
class TransportableFileWrapper(ABC):
|
|
36
38
|
|
|
37
39
|
@abstractmethod
|
|
38
|
-
def
|
|
40
|
+
def to_map(self) -> MutableStrMap:
|
|
39
41
|
""" Serialize to map """
|
|
40
42
|
raise NotImplementedError(
|
|
41
|
-
f'Not implemented: {type(self).__module__}.{type(self).__name__}.
|
|
43
|
+
f'Not implemented: {type(self).__module__}.{type(self).__name__}.to_map()'
|
|
42
44
|
)
|
|
43
45
|
|
|
44
46
|
#
|
|
@@ -126,7 +128,7 @@ class TransportableFileWrapper(ABC):
|
|
|
126
128
|
#
|
|
127
129
|
|
|
128
130
|
@classmethod
|
|
129
|
-
def create(cls, content:
|
|
131
|
+
def create(cls, content: StrMap,
|
|
130
132
|
data: Optional[TransportableData] = None, filename: Optional[str] = None,
|
|
131
133
|
url: Optional[URI] = None, password: Optional[DecryptKey] = None):
|
|
132
134
|
factory = wrapper_factory()
|
|
@@ -139,7 +141,7 @@ class TransportableFileWrapperFactory(ABC):
|
|
|
139
141
|
""" Wrapper factory """
|
|
140
142
|
|
|
141
143
|
@abstractmethod
|
|
142
|
-
def create_transportable_file_wrapper(self, content:
|
|
144
|
+
def create_transportable_file_wrapper(self, content: StrMap,
|
|
143
145
|
data: Optional[TransportableData],
|
|
144
146
|
filename: Optional[str],
|
|
145
147
|
url: Optional[URI],
|
|
@@ -23,10 +23,12 @@
|
|
|
23
23
|
# SOFTWARE.
|
|
24
24
|
# ==============================================================================
|
|
25
25
|
|
|
26
|
-
from typing import Optional, Union
|
|
26
|
+
from typing import Optional, Union
|
|
27
27
|
|
|
28
28
|
from mkm.types import URI
|
|
29
|
+
from mkm.types import StrMap, MutableStrMap
|
|
29
30
|
from mkm.types import Dictionary
|
|
31
|
+
|
|
30
32
|
from mkm.crypto import DecryptKey
|
|
31
33
|
from mkm.format import TransportableData
|
|
32
34
|
from mkm.format import json_encode
|
|
@@ -37,13 +39,13 @@ from .file_wrapper import TransportableFileWrapper
|
|
|
37
39
|
|
|
38
40
|
class PortableNetworkFile(Dictionary, TransportableFile):
|
|
39
41
|
|
|
40
|
-
def __init__(self, dictionary: Optional[
|
|
42
|
+
def __init__(self, dictionary: Optional[StrMap],
|
|
41
43
|
data: Optional[TransportableData] = None, filename: Optional[str] = None,
|
|
42
44
|
url: Optional[URI] = None, password: Optional[DecryptKey] = None,
|
|
43
45
|
wrapper: Optional[TransportableFileWrapper] = None):
|
|
44
46
|
super().__init__(dictionary=dictionary)
|
|
45
47
|
if wrapper is None:
|
|
46
|
-
wrapper = TransportableFileWrapper.create(super().
|
|
48
|
+
wrapper = TransportableFileWrapper.create(super().to_map(),
|
|
47
49
|
data=data, filename=filename,
|
|
48
50
|
url=url, password=password)
|
|
49
51
|
self.__wrapper = wrapper
|
|
@@ -53,7 +55,7 @@ class PortableNetworkFile(Dictionary, TransportableFile):
|
|
|
53
55
|
def uri_string(self) -> Optional[str]:
|
|
54
56
|
# serialize
|
|
55
57
|
wrapper = self.__wrapper
|
|
56
|
-
info = wrapper.
|
|
58
|
+
info = wrapper.to_map()
|
|
57
59
|
# check 'URL'
|
|
58
60
|
remote = self.url
|
|
59
61
|
if remote is not None and len(remote) > 0:
|
|
@@ -98,24 +100,25 @@ class PortableNetworkFile(Dictionary, TransportableFile):
|
|
|
98
100
|
return uri_string
|
|
99
101
|
# return JSON string
|
|
100
102
|
wrapper = self.__wrapper
|
|
101
|
-
info = wrapper.
|
|
103
|
+
info = wrapper.to_map()
|
|
102
104
|
return json_encode(info)
|
|
103
105
|
|
|
104
106
|
# Override
|
|
105
|
-
def
|
|
107
|
+
def to_map(self) -> MutableStrMap:
|
|
106
108
|
""" call wrapper to serialize 'data' & 'key" """
|
|
107
109
|
wrapper = self.__wrapper
|
|
108
|
-
return wrapper.
|
|
110
|
+
return wrapper.to_map()
|
|
109
111
|
# return self.__dictionary
|
|
110
112
|
|
|
111
113
|
# Override
|
|
112
|
-
def serialize(self) -> Union[str,
|
|
114
|
+
def serialize(self) -> Union[str, StrMap]:
|
|
113
115
|
uri_string = self.uri_string
|
|
114
116
|
if uri_string is not None:
|
|
115
117
|
return uri_string
|
|
116
118
|
# return inner map
|
|
117
119
|
wrapper = self.__wrapper
|
|
118
|
-
|
|
120
|
+
info = wrapper.to_map()
|
|
121
|
+
return dict(info)
|
|
119
122
|
|
|
120
123
|
#
|
|
121
124
|
# File data
|