-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathdecoder.py
More file actions
91 lines (68 loc) · 1.97 KB
/
decoder.py
File metadata and controls
91 lines (68 loc) · 1.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
""" Stream Decoder """
import gzip
import json
from hashlib import blake2b
import yaml
# -------------
# Conversion
# -------------
TYPE_ERR = "Expect a serialization of a mapping type."
def to_yaml(stream):
try:
data = yaml.load(stream, Loader=yaml.CSafeLoader)
except (yaml.scanner.ScannerError, yaml.parser.ParserError) as err:
raise ValueError(str(err)) from err
if not isinstance(data, dict):
raise TypeError(TYPE_ERR)
return data
def to_json(stream):
try:
data = json.loads(stream)
except json.JSONDecodeError as err:
raise ValueError(str(err)) from err
if not isinstance(data, dict):
raise TypeError(TYPE_ERR)
return data
def to_dict(stream, ext=None, ctype=None):
"""
Load a string or bytes to a dict.
If extension or content-type is specified,
only parse stream as the specified format.
"""
ext = ext.lower() if isinstance(ext, str) else ""
ctype = ctype.lower() if isinstance(ctype, str) else ""
# by extension
if "json" in ext:
return to_json(stream)
if ext in ("yaml", "yml"):
return to_yaml(stream)
# by content-type
if "json" in ctype:
return to_json(stream)
if "yaml" in ctype:
return to_yaml(stream)
# javascript files
if isinstance(stream, bytes):
try:
stream = stream.decode()
except UnicodeDecodeError:
pass
if isinstance(stream, str):
if stream.startswith("export default "):
stream = stream[len("export default "):]
# brute force
return to_yaml(stream)
# -------------
# Compression
# -------------
def compress(stream):
return gzip.compress(stream) if stream else None
def decompress(stream):
return gzip.decompress(stream) if stream else None
# -------------
# Hashed _id
# -------------
def get_id(url):
_bytes = str(url).encode("utf8")
_hash = blake2b(_bytes, digest_size=16)
return _hash.hexdigest()