muninn 6.4__tar.gz → 6.4.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.
- {muninn-6.4 → muninn-6.4.2}/CHANGES +11 -0
- {muninn-6.4 → muninn-6.4.2}/PKG-INFO +3 -1
- {muninn-6.4 → muninn-6.4.2}/muninn/__init__.py +1 -1
- {muninn-6.4 → muninn-6.4.2}/muninn/_compat.py +9 -2
- {muninn-6.4 → muninn-6.4.2}/muninn/archive.py +1 -1
- {muninn-6.4 → muninn-6.4.2}/muninn/database/postgresql.py +6 -4
- {muninn-6.4 → muninn-6.4.2}/muninn/database/sqlite.py +30 -6
- {muninn-6.4 → muninn-6.4.2}/muninn/language.py +3 -3
- {muninn-6.4 → muninn-6.4.2}/muninn/schema.py +5 -2
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/ingest.py +1 -1
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/update.py +2 -5
- {muninn-6.4 → muninn-6.4.2}/muninn.egg-info/PKG-INFO +3 -1
- {muninn-6.4 → muninn-6.4.2}/setup.py +3 -1
- {muninn-6.4 → muninn-6.4.2}/test/test.py +12 -1
- {muninn-6.4 → muninn-6.4.2}/DEVELOPER.md +0 -0
- {muninn-6.4 → muninn-6.4.2}/LICENSE +0 -0
- {muninn-6.4 → muninn-6.4.2}/MANIFEST.in +0 -0
- {muninn-6.4 → muninn-6.4.2}/README.md +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/config.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/core.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/database/__init__.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/database/base.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/database/blobgeometry.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/database/ewkb.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/database/sql.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/enum.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/exceptions.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/extension.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/function.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/geometry.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/remote.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/storage/__init__.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/storage/base.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/storage/fs.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/storage/s3.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/storage/swift.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/struct.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/__init__.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/attach.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/destroy.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/export.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/hash.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/info.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/list_tags.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/prepare.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/pull.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/remove.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/retrieve.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/search.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/strip.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/summary.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/tag.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/untag.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/tools/utils.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/util.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn/visitor.py +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn.egg-info/SOURCES.txt +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn.egg-info/dependency_links.txt +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn.egg-info/entry_points.txt +0 -0
- {muninn-6.4 → muninn-6.4.2}/muninn.egg-info/top_level.txt +0 -0
- {muninn-6.4 → muninn-6.4.2}/setup.cfg +0 -0
- {muninn-6.4 → muninn-6.4.2}/test/coverage.sh +0 -0
- {muninn-6.4 → muninn-6.4.2}/test/data/README +0 -0
- {muninn-6.4 → muninn-6.4.2}/test/data/multi/1.txt +0 -0
- {muninn-6.4 → muninn-6.4.2}/test/data/multi/2.txt +0 -0
- {muninn-6.4 → muninn-6.4.2}/test/data/pi.txt +0 -0
- {muninn-6.4 → muninn-6.4.2}/test/product_type.py.template +0 -0
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
6.4.2 2025-02-24
|
|
2
|
+
~~~~~~~~~~~~~~~~
|
|
3
|
+
|
|
4
|
+
* Fixed issue with loading spatialite for versions of sqlite that were
|
|
5
|
+
build to disallow DQS (double-quoted string literals).
|
|
6
|
+
|
|
7
|
+
6.4.1 2024-08-14
|
|
8
|
+
~~~~~~~~~~~~~~~~
|
|
9
|
+
|
|
10
|
+
* Fixed issue where only 'dict' values could be stored as a JSON property.
|
|
11
|
+
|
|
1
12
|
6.4 2024-03-14
|
|
2
13
|
~~~~~~~~~~~~~~
|
|
3
14
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 1.2
|
|
2
2
|
Name: muninn
|
|
3
|
-
Version: 6.4
|
|
3
|
+
Version: 6.4.2
|
|
4
4
|
Summary: Data product catalogue and archive system
|
|
5
5
|
Home-page: https://github.com/stcorp/muninn
|
|
6
6
|
Author: S[&]T
|
|
@@ -17,6 +17,8 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
22
|
Classifier: License :: OSI Approved :: BSD License
|
|
21
23
|
Classifier: Operating System :: OS Independent
|
|
22
24
|
Classifier: Topic :: Scientific/Engineering
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import absolute_import, division, print_function
|
|
6
6
|
|
|
7
|
-
__version__ = "6.4"
|
|
7
|
+
__version__ = "6.4.2"
|
|
8
8
|
__copyright__ = "Copyright (C) 2014-2024 S[&]T, The Netherlands."
|
|
9
9
|
|
|
10
10
|
__all__ = ["Error", "InternalError", "Struct", "Archive", "open", "config_path"]
|
|
@@ -5,6 +5,7 @@ Inspired by six, future, and jinja2
|
|
|
5
5
|
'''
|
|
6
6
|
import sys
|
|
7
7
|
import operator
|
|
8
|
+
import datetime
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
PY3 = sys.version_info[0] == 3
|
|
@@ -33,6 +34,9 @@ if PY3:
|
|
|
33
34
|
def decode(s):
|
|
34
35
|
return s.decode('utf-8')
|
|
35
36
|
|
|
37
|
+
def utcnow():
|
|
38
|
+
return datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
|
|
39
|
+
|
|
36
40
|
itervalues = operator.methodcaller("values")
|
|
37
41
|
|
|
38
42
|
imap = map
|
|
@@ -55,12 +59,15 @@ else:
|
|
|
55
59
|
def path_utf8(path):
|
|
56
60
|
return path.decode(sys.getfilesystemencoding()).encode('utf-8')
|
|
57
61
|
|
|
58
|
-
def
|
|
62
|
+
def encode(s):
|
|
59
63
|
return s
|
|
60
64
|
|
|
61
|
-
def
|
|
65
|
+
def decode(s):
|
|
62
66
|
return s
|
|
63
67
|
|
|
68
|
+
def utcnow():
|
|
69
|
+
return datetime.datetime.utcnow()
|
|
70
|
+
|
|
64
71
|
dictkeys = operator.methodcaller("keys")
|
|
65
72
|
dictvalues = operator.methodcaller("values")
|
|
66
73
|
itervalues = operator.methodcaller("itervalues")
|
|
@@ -413,7 +413,7 @@ class Archive(object):
|
|
|
413
413
|
if len(set(basenames)) < len(basenames):
|
|
414
414
|
raise Error("basename of each part should be unique for multi-part products")
|
|
415
415
|
|
|
416
|
-
return [path.replace('\\', '/') for path in paths]
|
|
416
|
+
return sorted([path.replace('\\', '/') for path in paths])
|
|
417
417
|
|
|
418
418
|
def _extract_hash_type(self, hash_value):
|
|
419
419
|
prefix, middle, _ = hash_value.partition(':')
|
|
@@ -481,8 +481,9 @@ class PostgresqlBackend(DatabaseBackend):
|
|
|
481
481
|
fields.append("uuid")
|
|
482
482
|
parameters.append(uuid)
|
|
483
483
|
|
|
484
|
-
|
|
485
|
-
parameters = [json.dumps(p) if
|
|
484
|
+
schema = self._namespace_schema(name)
|
|
485
|
+
parameters = [json.dumps(p) if f != "uuid" and issubclass(schema[f], JSON) else p for f, p in
|
|
486
|
+
zip(fields, parameters)]
|
|
486
487
|
|
|
487
488
|
# Build and execute INSERT query.
|
|
488
489
|
query = "INSERT INTO %s (%s) VALUES (%s)" % (self._table_name(name), ", ".join(fields),
|
|
@@ -775,11 +776,12 @@ class PostgresqlBackend(DatabaseBackend):
|
|
|
775
776
|
del fields[uuid_index]
|
|
776
777
|
del parameters[uuid_index]
|
|
777
778
|
|
|
779
|
+
schema = self._namespace_schema(name)
|
|
780
|
+
parameters = [json.dumps(p) if issubclass(schema[f], JSON) else p for f, p in zip(fields, parameters)]
|
|
781
|
+
|
|
778
782
|
# Append the uuid (value) at the end of the list of parameters (will be used in the WHERE clause).
|
|
779
783
|
parameters.append(uuid)
|
|
780
784
|
|
|
781
|
-
parameters = [json.dumps(p) if isinstance(p, dict) else p for p in parameters]
|
|
782
|
-
|
|
783
785
|
# Build and execute UPDATE query.
|
|
784
786
|
set_clause = ", ".join(["%s = %s" % (field, self._placeholder()) for field in fields])
|
|
785
787
|
query = "UPDATE %s SET %s WHERE uuid = %s" % (self._table_name(name), set_clause, self._placeholder())
|
|
@@ -13,7 +13,7 @@ import uuid
|
|
|
13
13
|
|
|
14
14
|
from .base import DatabaseBackend
|
|
15
15
|
|
|
16
|
-
from muninn._compat import dictkeys, dictvalues
|
|
16
|
+
from muninn._compat import decode, dictkeys, dictvalues, utcnow
|
|
17
17
|
|
|
18
18
|
# Select a version of dbapi2 that's available.
|
|
19
19
|
# Since we need the spatialite module, we need a version of sqlite3 that supports extensions.
|
|
@@ -96,6 +96,24 @@ def _cast_geometry(blob):
|
|
|
96
96
|
return blobgeometry.decode_blob_geometry(blob)
|
|
97
97
|
|
|
98
98
|
|
|
99
|
+
def _adapt_datetime(val):
|
|
100
|
+
return val.isoformat(" ")
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _cast_datetime(val):
|
|
104
|
+
datepart, timepart = decode(val).split(" ")
|
|
105
|
+
year, month, day = map(int, datepart.split("-"))
|
|
106
|
+
timepart_full = timepart.split(".")
|
|
107
|
+
hours, minutes, seconds = map(int, timepart_full[0].split(":"))
|
|
108
|
+
if len(timepart_full) == 2:
|
|
109
|
+
microseconds = int('{:0<6.6}'.format(timepart_full[1]))
|
|
110
|
+
else:
|
|
111
|
+
microseconds = 0
|
|
112
|
+
|
|
113
|
+
val = datetime.datetime(year, month, day, hours, minutes, seconds, microseconds)
|
|
114
|
+
return val
|
|
115
|
+
|
|
116
|
+
|
|
99
117
|
class SQLiteConnection(object):
|
|
100
118
|
"""Wrapper for a sqlite database connection that defers (re)connection until an attempt is made to use the
|
|
101
119
|
connection.
|
|
@@ -150,7 +168,7 @@ class SQLiteConnection(object):
|
|
|
150
168
|
# load the spatialite extension
|
|
151
169
|
try:
|
|
152
170
|
self._connection.enable_load_extension(True)
|
|
153
|
-
self._connection.execute("select load_extension(
|
|
171
|
+
self._connection.execute("select load_extension('%s');" % (self._mod_spatialite))
|
|
154
172
|
except Exception as e:
|
|
155
173
|
raise Error("loading mod_spatialite extension failed (mod_spatialite_path='%s'): %s" %
|
|
156
174
|
(self._mod_spatialite, str(e)))
|
|
@@ -222,6 +240,9 @@ class SQLiteBackend(object):
|
|
|
222
240
|
dbapi2.register_adapter(geometry.MultiLineString, _adapt_geometry)
|
|
223
241
|
dbapi2.register_adapter(geometry.MultiPolygon, _adapt_geometry)
|
|
224
242
|
|
|
243
|
+
dbapi2.register_converter("TIMESTAMP", _cast_datetime)
|
|
244
|
+
dbapi2.register_adapter(datetime.datetime, _adapt_datetime)
|
|
245
|
+
|
|
225
246
|
self._connection_string = connection_string
|
|
226
247
|
self._connection = SQLiteConnection(connection_string, mod_spatialite_path, self)
|
|
227
248
|
|
|
@@ -438,7 +459,9 @@ class SQLiteBackend(object):
|
|
|
438
459
|
fields.append("uuid")
|
|
439
460
|
parameters.append(uuid)
|
|
440
461
|
|
|
441
|
-
|
|
462
|
+
schema = self._namespace_schema(name)
|
|
463
|
+
parameters = [json.dumps(p) if f != "uuid" and issubclass(schema[f], JSON) else p for f, p in
|
|
464
|
+
zip(fields, parameters)]
|
|
442
465
|
|
|
443
466
|
# Build and execute INSERT query.
|
|
444
467
|
query = "INSERT INTO %s (%s) VALUES (%s)" % (self._table_name(name), ", ".join(fields),
|
|
@@ -733,11 +756,12 @@ class SQLiteBackend(object):
|
|
|
733
756
|
del fields[uuid_index]
|
|
734
757
|
del parameters[uuid_index]
|
|
735
758
|
|
|
759
|
+
schema = self._namespace_schema(name)
|
|
760
|
+
parameters = [json.dumps(p) if issubclass(schema[f], JSON) else p for f, p in zip(fields, parameters)]
|
|
761
|
+
|
|
736
762
|
# Append the uuid (value) at the end of the list of parameters (will be used in the WHERE clause).
|
|
737
763
|
parameters.append(uuid)
|
|
738
764
|
|
|
739
|
-
parameters = [json.dumps(p) if isinstance(p, dict) else p for p in parameters]
|
|
740
|
-
|
|
741
765
|
# Build and execute UPDATE query.
|
|
742
766
|
set_clause = ", ".join(["%s = %s" % (field, self._placeholder()) for field in fields])
|
|
743
767
|
query = "UPDATE %s SET %s WHERE uuid = %s" % (self._table_name(name), set_clause, self._placeholder())
|
|
@@ -875,7 +899,7 @@ class SQLiteBackend(object):
|
|
|
875
899
|
|
|
876
900
|
@translate_sqlite_errors
|
|
877
901
|
def server_time_utc(self):
|
|
878
|
-
return
|
|
902
|
+
return utcnow()
|
|
879
903
|
|
|
880
904
|
@translate_sqlite_errors
|
|
881
905
|
def source_products(self, uuid):
|
|
@@ -613,7 +613,7 @@ def _literal_type(literal):
|
|
|
613
613
|
else:
|
|
614
614
|
return type
|
|
615
615
|
|
|
616
|
-
raise Error("unable to determine type of literal value: %r" % literal)
|
|
616
|
+
raise Error("unable to determine type of literal value: %r" % (literal,))
|
|
617
617
|
|
|
618
618
|
|
|
619
619
|
class SemanticAnalysis(Visitor):
|
|
@@ -788,7 +788,7 @@ class Identifier(object):
|
|
|
788
788
|
self.muninn_type = Long
|
|
789
789
|
|
|
790
790
|
elif not re.match(r'[\w]+\.[\w.]+', canonical_identifier):
|
|
791
|
-
raise Error("cannot resolve identifier: %r" % canonical_identifier)
|
|
791
|
+
raise Error("cannot resolve identifier: %r" % (canonical_identifier,))
|
|
792
792
|
|
|
793
793
|
else:
|
|
794
794
|
segments = canonical_identifier.split('.')
|
|
@@ -808,7 +808,7 @@ class Identifier(object):
|
|
|
808
808
|
self.namespace, self.identifier, self.subscript = segments
|
|
809
809
|
|
|
810
810
|
else:
|
|
811
|
-
raise Error("cannot resolve identifier: %r" % canonical_identifier)
|
|
811
|
+
raise Error("cannot resolve identifier: %r" % (canonical_identifier,))
|
|
812
812
|
|
|
813
813
|
# check if namespace is valid
|
|
814
814
|
if self.namespace not in namespace_schemas:
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
from __future__ import absolute_import, division, print_function
|
|
6
6
|
|
|
7
7
|
import datetime
|
|
8
|
+
import json
|
|
9
|
+
import uuid
|
|
8
10
|
from muninn._compat import long
|
|
9
11
|
from muninn._compat import string_types as basestring
|
|
10
|
-
import uuid
|
|
11
12
|
|
|
12
13
|
from muninn import geometry
|
|
13
14
|
|
|
@@ -96,7 +97,9 @@ class Timestamp(Type):
|
|
|
96
97
|
class JSON(Type):
|
|
97
98
|
@classmethod
|
|
98
99
|
def validate(cls, value):
|
|
99
|
-
|
|
100
|
+
try:
|
|
101
|
+
json.dumps(value)
|
|
102
|
+
except Exception:
|
|
100
103
|
raise ValueError("invalid value %r for type %r" % (value, cls.name()))
|
|
101
104
|
|
|
102
105
|
|
|
@@ -31,7 +31,7 @@ class CheckProductListAction(argparse.Action):
|
|
|
31
31
|
|
|
32
32
|
def expand_stem(stem):
|
|
33
33
|
try:
|
|
34
|
-
return glob.glob(stem + "*")
|
|
34
|
+
return sorted(glob.glob(stem + "*"))
|
|
35
35
|
except EnvironmentError as error:
|
|
36
36
|
raise Error("unable to expand stem \"%s\" [%s]" % (stem, error))
|
|
37
37
|
|
|
@@ -75,11 +75,8 @@ def update(args):
|
|
|
75
75
|
|
|
76
76
|
processor = UpdateProcessor(args)
|
|
77
77
|
with muninn.open(args.archive) as archive:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
products = archive.search(expression, property_names=['uuid', 'product_name'])
|
|
81
|
-
else:
|
|
82
|
-
products = archive.search(expression, namespaces=archive.namespaces())
|
|
78
|
+
# we only need the uuid and the product_name
|
|
79
|
+
products = archive.search(expression, property_names=['uuid', 'product_name'])
|
|
83
80
|
if args.parallel:
|
|
84
81
|
if args.processes is not None:
|
|
85
82
|
pool = multiprocessing.Pool(args.processes)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 1.2
|
|
2
2
|
Name: muninn
|
|
3
|
-
Version: 6.4
|
|
3
|
+
Version: 6.4.2
|
|
4
4
|
Summary: Data product catalogue and archive system
|
|
5
5
|
Home-page: https://github.com/stcorp/muninn
|
|
6
6
|
Author: S[&]T
|
|
@@ -17,6 +17,8 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
22
|
Classifier: License :: OSI Approved :: BSD License
|
|
21
23
|
Classifier: Operating System :: OS Independent
|
|
22
24
|
Classifier: Topic :: Scientific/Engineering
|
|
@@ -15,7 +15,7 @@ requirements = []
|
|
|
15
15
|
|
|
16
16
|
setup(
|
|
17
17
|
name="muninn",
|
|
18
|
-
version="6.4",
|
|
18
|
+
version="6.4.2",
|
|
19
19
|
description="Data product catalogue and archive system",
|
|
20
20
|
url="https://github.com/stcorp/muninn",
|
|
21
21
|
author="S[&]T",
|
|
@@ -51,6 +51,8 @@ setup(
|
|
|
51
51
|
"Programming Language :: Python :: 3.9",
|
|
52
52
|
"Programming Language :: Python :: 3.10",
|
|
53
53
|
"Programming Language :: Python :: 3.11",
|
|
54
|
+
"Programming Language :: Python :: 3.12",
|
|
55
|
+
"Programming Language :: Python :: 3.13",
|
|
54
56
|
"License :: OSI Approved :: BSD License",
|
|
55
57
|
"Operating System :: OS Independent",
|
|
56
58
|
"Topic :: Scientific/Engineering",
|
|
@@ -26,7 +26,11 @@ import botocore
|
|
|
26
26
|
logging.getLogger("boto3").setLevel(logging.CRITICAL)
|
|
27
27
|
|
|
28
28
|
warnings.filterwarnings('ignore', 'distutils version classes', DeprecationWarning, 'swiftclient.client')
|
|
29
|
-
|
|
29
|
+
try:
|
|
30
|
+
import swiftclient
|
|
31
|
+
except ImportError:
|
|
32
|
+
# allow to run tests where the swift backend is not enabled
|
|
33
|
+
pass
|
|
30
34
|
logging.getLogger("swiftclient").setLevel(logging.CRITICAL)
|
|
31
35
|
|
|
32
36
|
sys.path.insert(0, '..')
|
|
@@ -1233,6 +1237,13 @@ class TestArchive:
|
|
|
1233
1237
|
assert myjson['bla'] == 14
|
|
1234
1238
|
assert myjson['mylist'] == [1, 2, 3]
|
|
1235
1239
|
|
|
1240
|
+
# also test that we can store other json objects than 'dict'
|
|
1241
|
+
props = muninn.Struct({'mynamespace': {'myjson': [1, 2, 3]}})
|
|
1242
|
+
archive.update_properties(props, product.core.uuid)
|
|
1243
|
+
props = archive.retrieve_properties(uuid=product.core.uuid, namespaces=['mynamespace'])
|
|
1244
|
+
myjson = props.mynamespace.myjson
|
|
1245
|
+
assert myjson == [1, 2, 3]
|
|
1246
|
+
|
|
1236
1247
|
def test_verify_hash(self, archive):
|
|
1237
1248
|
product = self._ingest_file(archive)
|
|
1238
1249
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|