udata 7.0.5.dev27829__py2.py3-none-any.whl → 7.0.5.dev27885__py2.py3-none-any.whl
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.
Potentially problematic release.
This version of udata might be problematic. Click here for more details.
- udata/core/dataset/rdf.py +45 -1
- udata/forms/fields.py +10 -0
- udata/harvest/tests/dcat/bnodes.xml +16 -2
- udata/harvest/tests/test_dcat_backend.py +18 -0
- udata/tests/api/test_datasets_api.py +27 -0
- {udata-7.0.5.dev27829.dist-info → udata-7.0.5.dev27885.dist-info}/METADATA +5 -1
- {udata-7.0.5.dev27829.dist-info → udata-7.0.5.dev27885.dist-info}/RECORD +11 -11
- {udata-7.0.5.dev27829.dist-info → udata-7.0.5.dev27885.dist-info}/LICENSE +0 -0
- {udata-7.0.5.dev27829.dist-info → udata-7.0.5.dev27885.dist-info}/WHEEL +0 -0
- {udata-7.0.5.dev27829.dist-info → udata-7.0.5.dev27885.dist-info}/entry_points.txt +0 -0
- {udata-7.0.5.dev27829.dist-info → udata-7.0.5.dev27885.dist-info}/top_level.txt +0 -0
udata/core/dataset/rdf.py
CHANGED
|
@@ -2,17 +2,21 @@
|
|
|
2
2
|
This module centralize dataset helpers for RDF/DCAT serialization and parsing
|
|
3
3
|
'''
|
|
4
4
|
import calendar
|
|
5
|
+
import json
|
|
5
6
|
import logging
|
|
6
7
|
|
|
7
8
|
from datetime import date
|
|
8
9
|
from html.parser import HTMLParser
|
|
9
10
|
from dateutil.parser import parse as parse_dt
|
|
10
11
|
from flask import current_app
|
|
12
|
+
from geomet import wkt
|
|
11
13
|
from rdflib import Graph, URIRef, Literal, BNode
|
|
12
14
|
from rdflib.resource import Resource as RdfResource
|
|
13
15
|
from rdflib.namespace import RDF
|
|
16
|
+
from mongoengine.errors import ValidationError
|
|
14
17
|
|
|
15
18
|
from udata import i18n, uris
|
|
19
|
+
from udata.core.spatial.models import SpatialCoverage
|
|
16
20
|
from udata.frontend.markdown import parse_html
|
|
17
21
|
from udata.core.dataset.models import HarvestDatasetMetadata, HarvestResourceMetadata
|
|
18
22
|
from udata.models import db, ContactPoint
|
|
@@ -334,6 +338,42 @@ def contact_point_from_rdf(rdf, dataset):
|
|
|
334
338
|
ContactPoint(name=name, email=email, owner=dataset.owner).save())
|
|
335
339
|
|
|
336
340
|
|
|
341
|
+
def spatial_from_rdf(term):
|
|
342
|
+
if term is None:
|
|
343
|
+
return None
|
|
344
|
+
|
|
345
|
+
for object in term.objects():
|
|
346
|
+
if isinstance(object, Literal):
|
|
347
|
+
if object.datatype.__str__() == 'https://www.iana.org/assignments/media-types/application/vnd.geo+json':
|
|
348
|
+
try:
|
|
349
|
+
geojson = json.loads(object.toPython())
|
|
350
|
+
except ValueError as e:
|
|
351
|
+
log.warning(f"Invalid JSON in spatial GeoJSON {object.toPython()} {e}")
|
|
352
|
+
continue
|
|
353
|
+
elif object.datatype.__str__() == 'http://www.opengis.net/rdf#wktLiteral':
|
|
354
|
+
try:
|
|
355
|
+
# .upper() si here because geomet doesn't support Polygon but only POLYGON
|
|
356
|
+
geojson = wkt.loads(object.toPython().strip().upper())
|
|
357
|
+
except ValueError as e:
|
|
358
|
+
log.warning(f"Invalid JSON in spatial WKT {object.toPython()} {e}")
|
|
359
|
+
continue
|
|
360
|
+
else:
|
|
361
|
+
continue
|
|
362
|
+
|
|
363
|
+
if geojson['type'] == 'Polygon':
|
|
364
|
+
geojson['type'] = 'MultiPolygon'
|
|
365
|
+
geojson['coordinates'] = [geojson['coordinates']]
|
|
366
|
+
|
|
367
|
+
spatial_coverage = SpatialCoverage(geom=geojson)
|
|
368
|
+
|
|
369
|
+
try:
|
|
370
|
+
spatial_coverage.clean()
|
|
371
|
+
return spatial_coverage
|
|
372
|
+
except ValidationError:
|
|
373
|
+
return None
|
|
374
|
+
|
|
375
|
+
return None
|
|
376
|
+
|
|
337
377
|
def frequency_from_rdf(term):
|
|
338
378
|
if isinstance(term, str):
|
|
339
379
|
try:
|
|
@@ -488,7 +528,7 @@ def resource_from_rdf(graph_or_distrib, dataset=None, is_additionnal=False):
|
|
|
488
528
|
return resource
|
|
489
529
|
|
|
490
530
|
|
|
491
|
-
def dataset_from_rdf(graph, dataset=None, node=None):
|
|
531
|
+
def dataset_from_rdf(graph: Graph, dataset=None, node=None):
|
|
492
532
|
'''
|
|
493
533
|
Create or update a dataset from a RDF/DCAT graph
|
|
494
534
|
'''
|
|
@@ -509,6 +549,10 @@ def dataset_from_rdf(graph, dataset=None, node=None):
|
|
|
509
549
|
if schema:
|
|
510
550
|
dataset.schema = schema
|
|
511
551
|
|
|
552
|
+
spatial_coverage = spatial_from_rdf(d.value(DCT.spatial))
|
|
553
|
+
if spatial_coverage:
|
|
554
|
+
dataset.spatial = spatial_coverage
|
|
555
|
+
|
|
512
556
|
acronym = rdf_value(d, SKOS.altLabel)
|
|
513
557
|
if acronym:
|
|
514
558
|
dataset.acronym = acronym
|
udata/forms/fields.py
CHANGED
|
@@ -180,6 +180,16 @@ class BooleanField(FieldHelper, fields.BooleanField):
|
|
|
180
180
|
self.stacked = kwargs.pop('stacked', False)
|
|
181
181
|
super(BooleanField, self).__init__(*args, **kwargs)
|
|
182
182
|
|
|
183
|
+
def process_formdata(self, valuelist):
|
|
184
|
+
# We override this so that when no value is provided
|
|
185
|
+
# the form doesn't think the value is `False` instead
|
|
186
|
+
# the value is not present and the model can keep the
|
|
187
|
+
# existing value
|
|
188
|
+
if not valuelist:
|
|
189
|
+
return
|
|
190
|
+
|
|
191
|
+
super().process_formdata(valuelist)
|
|
192
|
+
|
|
183
193
|
|
|
184
194
|
class RadioField(FieldHelper, fields.RadioField):
|
|
185
195
|
def __init__(self, *args, **kwargs):
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
6
6
|
xmlns:dcat="http://www.w3.org/ns/dcat#"
|
|
7
7
|
xmlns:dct="http://purl.org/dc/terms/"
|
|
8
|
+
xmlns:ogc="http://www.opengis.net/ogc"
|
|
9
|
+
xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
|
|
8
10
|
xmlns:dcterms="http://purl.org/dc/terms/"
|
|
9
11
|
xmlns:vcard="http://www.w3.org/2006/vcard/ns#"
|
|
10
12
|
xmlns:schema="http://schema.org/"
|
|
@@ -54,7 +56,13 @@
|
|
|
54
56
|
<owl:versionInfo>1.0</owl:versionInfo>
|
|
55
57
|
<dcat:distribution rdf:resource="http://data.test.org/datasets/1/resources/2"/>
|
|
56
58
|
<dcat:keyword>Tag 4</dcat:keyword>
|
|
57
|
-
<
|
|
59
|
+
<dct:spatial>
|
|
60
|
+
<ogc:Polygon>
|
|
61
|
+
<geo:asWKT rdf:datatype="http://www.opengis.net/rdf#wktLiteral">
|
|
62
|
+
wrong wkt
|
|
63
|
+
</geo:asWKT>
|
|
64
|
+
</ogc:Polygon>
|
|
65
|
+
</dct:spatial>
|
|
58
66
|
<dcterms:modified rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2016-12-14T19:01:24.184120</dcterms:modified>
|
|
59
67
|
<dcat:keyword>Tag 2</dcat:keyword>
|
|
60
68
|
<dcat:keyword>Tag 1</dcat:keyword>
|
|
@@ -79,7 +87,13 @@
|
|
|
79
87
|
<dcat:keyword>Tag 3</dcat:keyword>
|
|
80
88
|
<dcat:distribution rdf:resource="http://data.test.org/datasets/2/resources/2"/>
|
|
81
89
|
<dcterms:title>Dataset 2</dcterms:title>
|
|
82
|
-
<
|
|
90
|
+
<dct:spatial>
|
|
91
|
+
<ogc:Polygon>
|
|
92
|
+
<geo:asWKT rdf:datatype="http://www.opengis.net/rdf#wktLiteral">
|
|
93
|
+
Polygon((4.44641288 45.54214467, 4.44641288 46.01316963, 4.75655252 46.01316963, 4.75655252 45.54214467, 4.44641288 45.54214467))
|
|
94
|
+
</geo:asWKT>
|
|
95
|
+
</ogc:Polygon>
|
|
96
|
+
</dct:spatial>
|
|
83
97
|
<dcterms:identifier>2</dcterms:identifier>
|
|
84
98
|
<dct:conformsTo rdf:resource="https://www.ecologie.gouv.fr/sites/default/files/R%C3%A9glementation%20IRVE.pdf" />
|
|
85
99
|
</dcat:Dataset>
|
|
@@ -156,6 +156,24 @@ class DcatBackendTest:
|
|
|
156
156
|
assert len(datasets['1'].resources) == 2
|
|
157
157
|
assert len(datasets['2'].resources) == 2
|
|
158
158
|
|
|
159
|
+
|
|
160
|
+
@pytest.mark.options(SCHEMA_CATALOG_URL='https://example.com/schemas')
|
|
161
|
+
def test_harvest_spatial(self, rmock):
|
|
162
|
+
rmock.get('https://example.com/schemas', json=ResourceSchemaMockData.get_mock_data())
|
|
163
|
+
|
|
164
|
+
filename = 'bnodes.xml'
|
|
165
|
+
url = mock_dcat(rmock, filename)
|
|
166
|
+
org = OrganizationFactory()
|
|
167
|
+
source = HarvestSourceFactory(backend='dcat', url=url, organization=org)
|
|
168
|
+
|
|
169
|
+
actions.run(source.slug)
|
|
170
|
+
|
|
171
|
+
datasets = {d.harvest.dct_identifier: d for d in Dataset.objects}
|
|
172
|
+
|
|
173
|
+
assert datasets['1'].spatial == None
|
|
174
|
+
assert datasets['2'].spatial.geom == {'type': 'MultiPolygon', 'coordinates': [[[[4.44641288, 45.54214467], [4.44641288, 46.01316963], [4.75655252, 46.01316963], [4.75655252, 45.54214467], [4.44641288, 45.54214467]]]]}
|
|
175
|
+
assert datasets['3'].spatial == None
|
|
176
|
+
|
|
159
177
|
@pytest.mark.options(SCHEMA_CATALOG_URL='https://example.com/schemas')
|
|
160
178
|
def test_harvest_schemas(self, rmock):
|
|
161
179
|
rmock.get('https://example.com/schemas', json=ResourceSchemaMockData.get_mock_data())
|
|
@@ -462,6 +462,33 @@ class DatasetAPITest(APITestCase):
|
|
|
462
462
|
dataset = Dataset.objects.first()
|
|
463
463
|
self.assertEqual(len(dataset.resources), initial_length + 1)
|
|
464
464
|
|
|
465
|
+
def test_dataset_api_update_private(self):
|
|
466
|
+
user = self.login()
|
|
467
|
+
dataset = DatasetFactory(owner=user, private=True)
|
|
468
|
+
data = dataset.to_dict()
|
|
469
|
+
data['description'] = 'new description'
|
|
470
|
+
del data['private']
|
|
471
|
+
|
|
472
|
+
response = self.put(url_for('api.dataset', dataset=dataset), data)
|
|
473
|
+
self.assert200(response)
|
|
474
|
+
dataset.reload()
|
|
475
|
+
self.assertEqual(dataset.description, 'new description')
|
|
476
|
+
self.assertEqual(dataset.private, True)
|
|
477
|
+
|
|
478
|
+
data['private'] = None
|
|
479
|
+
response = self.put(url_for('api.dataset', dataset=dataset), data)
|
|
480
|
+
self.assert200(response)
|
|
481
|
+
dataset.reload()
|
|
482
|
+
self.assertEqual(dataset.private, False)
|
|
483
|
+
|
|
484
|
+
data['private'] = True
|
|
485
|
+
response = self.put(url_for('api.dataset', dataset=dataset), data)
|
|
486
|
+
self.assert200(response)
|
|
487
|
+
dataset.reload()
|
|
488
|
+
self.assertEqual(dataset.private, True)
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
|
|
465
492
|
def test_dataset_api_update_new_resource_with_extras(self):
|
|
466
493
|
'''It should update a dataset with a new resource with extras'''
|
|
467
494
|
user = self.login()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: udata
|
|
3
|
-
Version: 7.0.5.
|
|
3
|
+
Version: 7.0.5.dev27885
|
|
4
4
|
Summary: Open data portal
|
|
5
5
|
Home-page: https://github.com/opendatateam/udata
|
|
6
6
|
Author: Opendata Team
|
|
@@ -41,6 +41,7 @@ Requires-Dist: certifi ==2021.5.30
|
|
|
41
41
|
Requires-Dist: cffi ==1.14.6
|
|
42
42
|
Requires-Dist: chardet ==3.0.4
|
|
43
43
|
Requires-Dist: click ==8.0.0
|
|
44
|
+
Requires-Dist: colorama ==0.4.6
|
|
44
45
|
Requires-Dist: cryptography ==2.8
|
|
45
46
|
Requires-Dist: dnspython ==2.1.0
|
|
46
47
|
Requires-Dist: email-validator ==1.1.3
|
|
@@ -63,6 +64,7 @@ Requires-Dist: flask-sitemap ==0.3.0
|
|
|
63
64
|
Requires-Dist: flask-storage ==1.3.2
|
|
64
65
|
Requires-Dist: flask-wtf ==1.0.1
|
|
65
66
|
Requires-Dist: geojson ==2.5.0
|
|
67
|
+
Requires-Dist: geomet ==1.1.0
|
|
66
68
|
Requires-Dist: html2text ==2019.9.26
|
|
67
69
|
Requires-Dist: idna ==2.10
|
|
68
70
|
Requires-Dist: importlib-metadata ==6.0.0
|
|
@@ -136,6 +138,8 @@ It is collectively taken care of by members of the
|
|
|
136
138
|
|
|
137
139
|
## Current (in progress)
|
|
138
140
|
|
|
141
|
+
- Add spatial coverage harvesting [#2959](https://github.com/opendatateam/udata/pull/2959)
|
|
142
|
+
- Fix: updating a dataset without `private` do not reset `private` to `False`, the previous saved value is kept [#2955](https://github.com/opendatateam/udata/pull/2955)
|
|
139
143
|
- Fix: return the correct error when no `Content-Type` is sent instead of 500 [#2967](https://github.com/opendatateam/udata/pull/2967)
|
|
140
144
|
- Improve documentation for API errors [#2952](https://github.com/opendatateam/udata/pull/2965)
|
|
141
145
|
|
|
@@ -90,7 +90,7 @@ udata/core/dataset/forms.py,sha256=auVYxLrPMdtvf2uhgEpJviHiQOSfLpBJdpZ3dXwcjNs,6
|
|
|
90
90
|
udata/core/dataset/models.py,sha256=SK16LJP_vlSkeGrLJTFbHFNc9iHWwM6_A6DOT0SX5D4,39609
|
|
91
91
|
udata/core/dataset/permissions.py,sha256=3F2J7le3_rEYNhh88o3hSRWHAAt01_yHJM6RPmvCrRo,1090
|
|
92
92
|
udata/core/dataset/preview.py,sha256=puPKT3fBD7ezAcT6owh0JK1_rGNDFZOqgT223qGn3LY,2597
|
|
93
|
-
udata/core/dataset/rdf.py,sha256=
|
|
93
|
+
udata/core/dataset/rdf.py,sha256=7IguXzHgNcmbGY9FtiqjZ1Ju8wDxD6ahdvTj-5OzNgA,21476
|
|
94
94
|
udata/core/dataset/search.py,sha256=LOHtOJYZJDPJ5S_Ch7QmmvInpw8aysmNlzbAWbMq9d0,5329
|
|
95
95
|
udata/core/dataset/signals.py,sha256=TK6dfrOUitZZkGGOh6XmhYqYvIjzZpI70JTLV4k-JRM,161
|
|
96
96
|
udata/core/dataset/tasks.py,sha256=VB1sQ6Fwbax46IRLGyZUDPGgGOWBYrzAlKzV3npDCyM,8412
|
|
@@ -243,7 +243,7 @@ udata/features/transfer/models.py,sha256=YjX0O53DQS8jUU9pb6hFCsBx-eo8g8DOAD7EHZM
|
|
|
243
243
|
udata/features/transfer/notifications.py,sha256=oh_uP0XlEEeT7747A292WkjAjAyO4d0YK28oBICN24Y,1003
|
|
244
244
|
udata/features/transfer/permissions.py,sha256=-iEgQkIfLYDGarhDVp3TMas4ABl_Pc4KJTSP8pcewws,953
|
|
245
245
|
udata/forms/__init__.py,sha256=ZxakXdJMwsM_YFT96Z2X24J5YpbpnP_VZ_VEh15gK3w,820
|
|
246
|
-
udata/forms/fields.py,sha256=
|
|
246
|
+
udata/forms/fields.py,sha256=WTCAc4KVPS6EanpUPuan_reDM9gwx4K2wdvJBxu_pTY,29129
|
|
247
247
|
udata/forms/validators.py,sha256=EqCJloDOR3BonrR34N_ZaMGBXr0iuliDc82khc98e20,2816
|
|
248
248
|
udata/forms/widgets.py,sha256=P-D3uYfNH5OhAa-SqNoXROg_DuDlnpv_DaO_e4LcJ5I,1380
|
|
249
249
|
udata/frontend/__init__.py,sha256=Xc71TI6a8b_QR_wqEOc1tty2y1CwHVbV4tS04nElme0,3494
|
|
@@ -269,7 +269,7 @@ udata/harvest/tests/factories.py,sha256=CbQORC1OJ1_Agtv_3LjCXysNumjMYlROwZPSEAHo
|
|
|
269
269
|
udata/harvest/tests/test_actions.py,sha256=7xSpouCAcf5p_bd38zHCyPN7sKWUUZXA7IlpI-yNVrQ,27603
|
|
270
270
|
udata/harvest/tests/test_api.py,sha256=QXhseHfnkBEmMbIJzroMdDYGLDj6Njal1s-2sn0xhEM,14888
|
|
271
271
|
udata/harvest/tests/test_base_backend.py,sha256=JA8Df1Eu-lEPLZfxyK81bsmT6exOjV_3PtKHJekAp5g,12092
|
|
272
|
-
udata/harvest/tests/test_dcat_backend.py,sha256=
|
|
272
|
+
udata/harvest/tests/test_dcat_backend.py,sha256=8bdpPMh9WsnUDpO19ZoMHfUnU1_fe8Zl_hLSntFwXwI,24761
|
|
273
273
|
udata/harvest/tests/test_filters.py,sha256=V2HFZlexIJa6r1DX6g2ktvIgjg4gSY11QPfPOd3_Oug,2370
|
|
274
274
|
udata/harvest/tests/test_models.py,sha256=p2VazyrPXSArBuf8Kf19TGPcQ86SnOGCGmvjcMOw0s0,924
|
|
275
275
|
udata/harvest/tests/test_notifications.py,sha256=ZwtwioittW3XcZc0x6zbHjs1dVaAxPytlVymnJa5w0E,817
|
|
@@ -278,7 +278,7 @@ udata/harvest/tests/csw_dcat/geonetworkv4-page-1.xml,sha256=k2pKidlQvJpoltGFm9HN
|
|
|
278
278
|
udata/harvest/tests/csw_dcat/geonetworkv4-page-3.xml,sha256=fsN0E4TVd_ts-sYA612yBP-gRAwpyQWqJdNm7ohczbs,20945
|
|
279
279
|
udata/harvest/tests/csw_dcat/geonetworkv4-page-5.xml,sha256=0VmPp1kspik7YAmOFyr-3yJLzWGA6kuQp_x_w-W385o,21213
|
|
280
280
|
udata/harvest/tests/dcat/bnodes.jsonld,sha256=Leqny-ccp30564yojQYYckw_HKbhR0f5qUCaavc2ruE,7964
|
|
281
|
-
udata/harvest/tests/dcat/bnodes.xml,sha256=
|
|
281
|
+
udata/harvest/tests/dcat/bnodes.xml,sha256=KHrVtHiHrWLIT7vxSK7xpYlClCWSWvczeOp-QzzBZVc,9128
|
|
282
282
|
udata/harvest/tests/dcat/catalog.xml,sha256=pBVSNZzA4gkgxHCttrjuBBVSumLFgXgvtSgnHr0ybk4,9239
|
|
283
283
|
udata/harvest/tests/dcat/flat.jsonld,sha256=BAw08MDhtW9Px3q6RAoTIqO_OwJmAwBS9EpC8BY_x98,8459
|
|
284
284
|
udata/harvest/tests/dcat/geonetwork.xml,sha256=9_pksE74Zzkbgs9okj6hEbo8CJS0FZjEnIdvopKfm7k,7928
|
|
@@ -557,7 +557,7 @@ udata/tests/api/__init__.py,sha256=Tz_WigHLDlnJNKOKzEAnJswkKiLtHlIpCE54-wgocgM,9
|
|
|
557
557
|
udata/tests/api/test_auth_api.py,sha256=3Zhn2A29poZIcCJ_R9_-LkR3xOFUTw1aTquiZVXQ2F0,20306
|
|
558
558
|
udata/tests/api/test_base_api.py,sha256=DRX5nuFIj51GFmMIAxUzoW1yiq1apNgr1vS4U4agzeg,2319
|
|
559
559
|
udata/tests/api/test_contact_points.py,sha256=MJm8B06iaUqIZCqxll3NViFwUCxwqZZ4u9e9s1h8MgU,1056
|
|
560
|
-
udata/tests/api/test_datasets_api.py,sha256=
|
|
560
|
+
udata/tests/api/test_datasets_api.py,sha256=kCl55lyWgDxCwkYTa1HVMNlR3GBJiAcwOCkvh1BQzXw,81372
|
|
561
561
|
udata/tests/api/test_fields.py,sha256=OW85Z5MES5HeWOpapeem8OvR1cIcrqW-xMWpdZO4LZ8,1033
|
|
562
562
|
udata/tests/api/test_follow_api.py,sha256=0h54P_Dfbo07u6tg0Rbai1WWgWb19ZLN2HGv4oLCWfg,3383
|
|
563
563
|
udata/tests/api/test_me_api.py,sha256=-JskdyxcbREceC1PxMj9NUs6QBE3YzKa5TXhHIaPy-o,14275
|
|
@@ -649,9 +649,9 @@ udata/translations/pt/LC_MESSAGES/udata.mo,sha256=dXTr2zzGPgclSMzAJo4qhOEVHYWYP7
|
|
|
649
649
|
udata/translations/pt/LC_MESSAGES/udata.po,sha256=G-MNwE4Gih-4w-xNAjp7PAvQOeW1uyM-27Z6O08_SCc,42104
|
|
650
650
|
udata/translations/sr/LC_MESSAGES/udata.mo,sha256=5bvKeJp9nqk76tZsgbGC2qnbpJws5lODdMcezr6LKbQ,28553
|
|
651
651
|
udata/translations/sr/LC_MESSAGES/udata.po,sha256=d_uBu93oIsmeewv8QzrB2Z8tmkUXn8juwT5OiySALog,48684
|
|
652
|
-
udata-7.0.5.
|
|
653
|
-
udata-7.0.5.
|
|
654
|
-
udata-7.0.5.
|
|
655
|
-
udata-7.0.5.
|
|
656
|
-
udata-7.0.5.
|
|
657
|
-
udata-7.0.5.
|
|
652
|
+
udata-7.0.5.dev27885.dist-info/LICENSE,sha256=V8j_M8nAz8PvAOZQocyRDX7keai8UJ9skgmnwqETmdY,34520
|
|
653
|
+
udata-7.0.5.dev27885.dist-info/METADATA,sha256=kcy_O4ue_mJRqxGZ2UdLKoxeigd80IF9igrM5DCOfxI,118247
|
|
654
|
+
udata-7.0.5.dev27885.dist-info/WHEEL,sha256=-G_t0oGuE7UD0DrSpVZnq1hHMBV9DD2XkS5v7XpmTnk,110
|
|
655
|
+
udata-7.0.5.dev27885.dist-info/entry_points.txt,sha256=ZqIUHhOth0MMQvMIeuhODbUCDwjR-Hvo7PaKrMwTKuQ,384
|
|
656
|
+
udata-7.0.5.dev27885.dist-info/top_level.txt,sha256=39OCg-VWFWOq4gCKnjKNu-s3OwFlZIu_dVH8Gl6ndHw,12
|
|
657
|
+
udata-7.0.5.dev27885.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|