2020-04-22 09:51:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
"""Compile Kasten elements into a packed (msgpack) sequence.
|
|
|
|
|
|
|
|
KastenPacked sequences are prepared sequences used by Kasten instances and
|
|
|
|
their generators to apply rules and validation to Kasten.
|
|
|
|
|
|
|
|
Note that encryption and signing are not handled by anything in kasten, only
|
|
|
|
hash authentication is dependending on the generator used.
|
|
|
|
|
|
|
|
Packed bytes structure:
|
2020-04-11 07:48:28 +00:00
|
|
|
0: type: str: 4bytesmax
|
2020-12-27 03:30:13 +00:00
|
|
|
1. Timestamp: int
|
2020-04-11 07:48:28 +00:00
|
|
|
encrypted with specified mode:
|
2020-12-27 03:30:13 +00:00
|
|
|
3. app_metadata: arbitrary JSON
|
2020-04-11 07:48:28 +00:00
|
|
|
\n
|
|
|
|
data: bytes
|
|
|
|
"""
|
2020-04-14 09:33:17 +00:00
|
|
|
from math import floor
|
|
|
|
from time import time
|
|
|
|
|
2020-04-11 07:48:28 +00:00
|
|
|
from msgpack import packb
|
|
|
|
|
2020-04-14 09:33:17 +00:00
|
|
|
from kasten import exceptions
|
|
|
|
|
|
|
|
from kasten.types import KastenPacked
|
2020-04-22 09:51:28 +00:00
|
|
|
"""
|
|
|
|
Copyright (C) <2020> Kevin Froman
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
"""
|
2020-04-11 07:48:28 +00:00
|
|
|
|
|
|
|
|
2020-12-11 03:27:52 +00:00
|
|
|
def pack(data: bytes, data_type: str,
|
2020-04-14 09:33:17 +00:00
|
|
|
app_metadata: 'KastenSerializeableDict' = None,
|
|
|
|
timestamp: int = None
|
2020-12-11 03:27:52 +00:00
|
|
|
) -> KastenPacked:
|
2020-04-22 09:51:28 +00:00
|
|
|
"""Create KastenPacked bytes sequence but do not ID or run through generator"""
|
2020-04-11 07:48:28 +00:00
|
|
|
|
2020-12-11 03:27:52 +00:00
|
|
|
|
|
|
|
# Final data will be:
|
2020-12-27 03:30:13 +00:00
|
|
|
# msgpack.packb([data_type, timestamp, {app_metadata}]) \
|
2020-12-11 03:27:52 +00:00
|
|
|
# + b'\n' + data
|
2020-04-11 07:48:28 +00:00
|
|
|
# Ensure data type does not exceed 4 characters
|
|
|
|
if not data_type or len(data_type) > 4:
|
|
|
|
raise exceptions.InvalidKastenTypeLength
|
|
|
|
|
2020-12-11 03:27:52 +00:00
|
|
|
try:
|
|
|
|
data_type = data_type.decode('utf8')
|
|
|
|
except AttributeError:
|
|
|
|
pass
|
|
|
|
|
2020-04-11 07:48:28 +00:00
|
|
|
try:
|
|
|
|
data = data.encode('utf8')
|
|
|
|
except AttributeError:
|
|
|
|
pass
|
2020-04-14 09:33:17 +00:00
|
|
|
if timestamp is None:
|
|
|
|
timestamp = floor(time())
|
2020-04-16 07:07:05 +00:00
|
|
|
timestamp = int(timestamp)
|
2020-04-11 07:48:28 +00:00
|
|
|
|
2020-12-27 03:30:13 +00:00
|
|
|
kasten_header = [data_type, timestamp, app_metadata]
|
2020-04-11 07:48:28 +00:00
|
|
|
|
2020-04-16 07:07:05 +00:00
|
|
|
kasten_header = packb(kasten_header) + b'\n'
|
2020-04-11 07:48:28 +00:00
|
|
|
return kasten_header + data
|