muninn 7.0__tar.gz → 7.0.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-7.0 → muninn-7.0.2}/CHANGES +16 -0
- {muninn-7.0 → muninn-7.0.2}/PKG-INFO +2 -1
- {muninn-7.0 → muninn-7.0.2}/muninn/__init__.py +1 -1
- {muninn-7.0 → muninn-7.0.2}/muninn/archive.py +5 -2
- {muninn-7.0 → muninn-7.0.2}/muninn/geometry.py +10 -5
- {muninn-7.0 → muninn-7.0.2}/muninn/language.py +1 -1
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/search.py +2 -2
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/summary.py +1 -1
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/sync.py +8 -7
- {muninn-7.0 → muninn-7.0.2}/muninn.egg-info/PKG-INFO +2 -1
- {muninn-7.0 → muninn-7.0.2}/setup.py +2 -1
- {muninn-7.0 → muninn-7.0.2}/test/test.py +1 -1
- {muninn-7.0 → muninn-7.0.2}/DEVELOPER.md +0 -0
- {muninn-7.0 → muninn-7.0.2}/LICENSE +0 -0
- {muninn-7.0 → muninn-7.0.2}/MANIFEST.in +0 -0
- {muninn-7.0 → muninn-7.0.2}/README.md +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/_compat.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/config.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/core.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/database/__init__.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/database/base.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/database/blobgeometry.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/database/ewkb.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/database/postgresql.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/database/sql.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/database/sqlite.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/enum.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/exceptions.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/extension.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/function.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/remote.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/schema.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/storage/__init__.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/storage/base.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/storage/fs.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/storage/s3.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/storage/swift.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/struct.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/__init__.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/attach.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/destroy.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/export.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/hash.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/info.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/ingest.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/list_tags.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/prepare.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/pull.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/remove.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/retrieve.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/strip.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/tag.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/untag.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/update.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/tools/utils.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/util.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn/visitor.py +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn.egg-info/SOURCES.txt +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn.egg-info/dependency_links.txt +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn.egg-info/entry_points.txt +0 -0
- {muninn-7.0 → muninn-7.0.2}/muninn.egg-info/top_level.txt +0 -0
- {muninn-7.0 → muninn-7.0.2}/setup.cfg +0 -0
- {muninn-7.0 → muninn-7.0.2}/test/coverage.sh +0 -0
- {muninn-7.0 → muninn-7.0.2}/test/data/README +0 -0
- {muninn-7.0 → muninn-7.0.2}/test/data/multi/1.txt +0 -0
- {muninn-7.0 → muninn-7.0.2}/test/data/multi/2.txt +0 -0
- {muninn-7.0 → muninn-7.0.2}/test/data/pi.txt +0 -0
- {muninn-7.0 → muninn-7.0.2}/test/product_type.py.template +0 -0
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
7.0.2 2025-10-10
|
|
2
|
+
~~~~~~~~~~~~~~~~
|
|
3
|
+
|
|
4
|
+
* Fixed issue where a Geometry Linearring could not be closed or had a
|
|
5
|
+
duplicate closing point.
|
|
6
|
+
|
|
7
|
+
7.0.1 2025-08-25
|
|
8
|
+
~~~~~~~~~~~~~~~~
|
|
9
|
+
|
|
10
|
+
* Fixed incorrect unit of sizes >= Petabyte for the -H command line option.
|
|
11
|
+
|
|
12
|
+
* 'muninn-search --path' now shows the content of remote_url if a product
|
|
13
|
+
is not in the archive. A leading file:// in the remote_url is then omitted.
|
|
14
|
+
|
|
15
|
+
* Allow muninn-sync start/end arguments to be a date+time argument.
|
|
16
|
+
|
|
1
17
|
7.0 2025-08-14
|
|
2
18
|
~~~~~~~~~~~~~~
|
|
3
19
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 1.2
|
|
2
2
|
Name: muninn
|
|
3
|
-
Version: 7.0
|
|
3
|
+
Version: 7.0.2
|
|
4
4
|
Summary: Data product catalogue and archive system
|
|
5
5
|
Home-page: https://github.com/stcorp/muninn
|
|
6
6
|
Author: S[&]T
|
|
@@ -19,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
23
|
Classifier: License :: OSI Approved :: BSD License
|
|
23
24
|
Classifier: Operating System :: OS Independent
|
|
24
25
|
Classifier: Topic :: Scientific/Engineering
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import absolute_import, division, print_function
|
|
6
6
|
|
|
7
|
-
__version__ = "7.0.
|
|
7
|
+
__version__ = "7.0.2"
|
|
8
8
|
__copyright__ = "Copyright (C) 2014-2025 S[&]T, The Netherlands."
|
|
9
9
|
|
|
10
10
|
__all__ = ["Error", "InternalError", "Struct", "Archive", "open", "config_path"]
|
|
@@ -96,7 +96,7 @@ def _load_synchronizer_module(name):
|
|
|
96
96
|
try:
|
|
97
97
|
__import__(name)
|
|
98
98
|
except ImportError as e:
|
|
99
|
-
raise Error("import of
|
|
99
|
+
raise Error("import of synchronizer %r failed (%s)" % (name, e))
|
|
100
100
|
|
|
101
101
|
return sys.modules[name]
|
|
102
102
|
|
|
@@ -1314,8 +1314,11 @@ class Archive(object):
|
|
|
1314
1314
|
if archive_path is not None and self._storage is not None:
|
|
1315
1315
|
product_path = self._product_path(product)
|
|
1316
1316
|
return os.path.join(self._storage.global_prefix, product_path)
|
|
1317
|
-
|
|
1317
|
+
if remote_url is not None:
|
|
1318
|
+
if remote_url.startswith('file://'):
|
|
1319
|
+
return remote_url[7:]
|
|
1318
1320
|
return remote_url
|
|
1321
|
+
return None
|
|
1319
1322
|
|
|
1320
1323
|
def pull(self, where="", parameters={}, verify_hash=False, verify_hash_download=False):
|
|
1321
1324
|
"""Pull one or more remote products into the archive.
|
|
@@ -284,10 +284,15 @@ class LineString(GeometrySequence):
|
|
|
284
284
|
|
|
285
285
|
class LinearRing(GeometrySequence):
|
|
286
286
|
def __init__(self, geometries=[]):
|
|
287
|
+
geometries = list(geometries)
|
|
288
|
+
if len(geometries) > 1 and geometries[0] != geometries[-1]:
|
|
289
|
+
# close the ring
|
|
290
|
+
geometries.append(geometries[0])
|
|
291
|
+
|
|
287
292
|
super(LinearRing, self).__init__(geometries)
|
|
288
293
|
|
|
289
|
-
if self and len(self) <
|
|
290
|
-
raise ValueError("linear ring should be empty or should contain >=
|
|
294
|
+
if self and len(self) < 4:
|
|
295
|
+
raise ValueError("linear ring should be empty or should contain >= 4 points")
|
|
291
296
|
|
|
292
297
|
def point(self, index):
|
|
293
298
|
return self[index]
|
|
@@ -296,8 +301,7 @@ class LinearRing(GeometrySequence):
|
|
|
296
301
|
if not self:
|
|
297
302
|
wkt = "EMPTY"
|
|
298
303
|
else:
|
|
299
|
-
wkt = "(
|
|
300
|
-
self.point(0).y)
|
|
304
|
+
wkt = "(" + ", ".join(["%f %f" % (point.x, point.y) for point in self]) + ")"
|
|
301
305
|
return "LINESTRING " + wkt if tagged else wkt
|
|
302
306
|
|
|
303
307
|
def __repr__(self):
|
|
@@ -421,7 +425,8 @@ class Polygon(GeometrySequence):
|
|
|
421
425
|
del crossing_lat[min_index]
|
|
422
426
|
for pts in pts_set:
|
|
423
427
|
# close ring
|
|
424
|
-
pts
|
|
428
|
+
if pts[0] != pts[-1]:
|
|
429
|
+
pts.append(pts[0])
|
|
425
430
|
if len(pts_set) == 1:
|
|
426
431
|
return Polygon([LinearRing(pts)])
|
|
427
432
|
else:
|
|
@@ -485,7 +485,7 @@ def parse_linear_ring(stream):
|
|
|
485
485
|
if points[-1] != points[0]:
|
|
486
486
|
raise Error("char %d: linear ring should be closed" % stream.token_start_position)
|
|
487
487
|
|
|
488
|
-
return geometry.LinearRing(points
|
|
488
|
+
return geometry.LinearRing(points)
|
|
489
489
|
|
|
490
490
|
|
|
491
491
|
def parse_polygon(stream):
|
|
@@ -121,12 +121,12 @@ def uuid(args):
|
|
|
121
121
|
def paths(args):
|
|
122
122
|
with muninn.open(args.archive) as archive:
|
|
123
123
|
# Collect possibly multiple sort order specifier lists into a single list.
|
|
124
|
-
order_by_default = ['+core.archive_path', '+core.physical_name']
|
|
124
|
+
order_by_default = ['+core.archive_path', '+core.physical_name', '+core.remote_url']
|
|
125
125
|
order_by = order_by_default if not args.order_by else sum(args.order_by, []) + order_by_default
|
|
126
126
|
|
|
127
127
|
# Find products using the search expression and print the paths of the products found.
|
|
128
128
|
products = archive.search(args.expression, order_by, args.limit,
|
|
129
|
-
property_names=['archive_path', 'physical_name'])
|
|
129
|
+
property_names=['archive_path', 'physical_name', 'remote_url'])
|
|
130
130
|
for product in products:
|
|
131
131
|
product_path = archive.product_path(product)
|
|
132
132
|
if product_path is not None:
|
|
@@ -34,7 +34,7 @@ def ceil(size):
|
|
|
34
34
|
return integer_size + 1 if size > integer_size else integer_size
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
def human_readable_size(size, base=1024, powers=["Bi", "Ki", "Mi", "Gi", "Ti", "Ei"]):
|
|
37
|
+
def human_readable_size(size, base=1024, powers=["Bi", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]):
|
|
38
38
|
if len(powers) == 0:
|
|
39
39
|
return str(size)
|
|
40
40
|
|
|
@@ -5,19 +5,20 @@
|
|
|
5
5
|
from __future__ import absolute_import, division, print_function
|
|
6
6
|
|
|
7
7
|
import argparse
|
|
8
|
-
|
|
8
|
+
import datetime
|
|
9
9
|
|
|
10
10
|
import muninn
|
|
11
11
|
|
|
12
12
|
from muninn.tools.utils import create_parser, parse_args_and_run
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
def valid_date(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
def valid_date(arg: str) -> datetime:
|
|
16
|
+
for format_string in ("%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%dT%H:%M:%S.%f"):
|
|
17
|
+
try:
|
|
18
|
+
return datetime.datetime.strptime(arg, format_string)
|
|
19
|
+
except ValueError:
|
|
20
|
+
pass
|
|
21
|
+
raise argparse.ArgumentTypeError(f"invalid datetime: {arg} (expected 'YYYY-MM-DD(THH:MM:SS(.ffffff))')")
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
def run(args):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 1.2
|
|
2
2
|
Name: muninn
|
|
3
|
-
Version: 7.0
|
|
3
|
+
Version: 7.0.2
|
|
4
4
|
Summary: Data product catalogue and archive system
|
|
5
5
|
Home-page: https://github.com/stcorp/muninn
|
|
6
6
|
Author: S[&]T
|
|
@@ -19,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
23
|
Classifier: License :: OSI Approved :: BSD License
|
|
23
24
|
Classifier: Operating System :: OS Independent
|
|
24
25
|
Classifier: Topic :: Scientific/Engineering
|
|
@@ -15,7 +15,7 @@ requirements = []
|
|
|
15
15
|
|
|
16
16
|
setup(
|
|
17
17
|
name="muninn",
|
|
18
|
-
version="7.0",
|
|
18
|
+
version="7.0.2",
|
|
19
19
|
description="Data product catalogue and archive system",
|
|
20
20
|
url="https://github.com/stcorp/muninn",
|
|
21
21
|
author="S[&]T",
|
|
@@ -54,6 +54,7 @@ setup(
|
|
|
54
54
|
"Programming Language :: Python :: 3.11",
|
|
55
55
|
"Programming Language :: Python :: 3.12",
|
|
56
56
|
"Programming Language :: Python :: 3.13",
|
|
57
|
+
"Programming Language :: Python :: 3.14",
|
|
57
58
|
"License :: OSI Approved :: BSD License",
|
|
58
59
|
"Operating System :: OS Independent",
|
|
59
60
|
"Topic :: Scientific/Engineering",
|
|
@@ -1370,7 +1370,7 @@ class TestArchivePureCatalogue: # TODO merge with TestArchive?
|
|
|
1370
1370
|
assert properties.core.remote_url == 'file://' + os.path.realpath('data/a.txt').replace('\\', '/')
|
|
1371
1371
|
assert len(archive_pure.search()) == 1
|
|
1372
1372
|
|
|
1373
|
-
assert archive_pure.product_path(properties).startswith('
|
|
1373
|
+
assert archive_pure.product_path(properties).startswith('/')
|
|
1374
1374
|
|
|
1375
1375
|
def test_remove(self, archive_pure):
|
|
1376
1376
|
properties = archive_pure.ingest(
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|