udata 10.6.1.dev36110__py2.py3-none-any.whl → 10.6.1.dev36176__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/dataservices/api.py +1 -3
- udata/core/dataset/models.py +11 -6
- udata/core/dataset/preview.py +19 -72
- udata/core/organization/api.py +14 -0
- udata/settings.py +3 -0
- udata/static/chunks/{11.8a2f7828175824bcd74b.js → 11.51d706fb9521c16976bc.js} +3 -3
- udata/static/chunks/{11.8a2f7828175824bcd74b.js.map → 11.51d706fb9521c16976bc.js.map} +1 -1
- udata/static/chunks/{19.df16abde17a42033a7f8.js → 19.a348a5fff8fe2801e52a.js} +3 -3
- udata/static/chunks/{19.df16abde17a42033a7f8.js.map → 19.a348a5fff8fe2801e52a.js.map} +1 -1
- udata/static/chunks/{5.5660483641193b7f8295.js → 5.343ca020a2d38cec1a14.js} +3 -3
- udata/static/chunks/{5.5660483641193b7f8295.js.map → 5.343ca020a2d38cec1a14.js.map} +1 -1
- udata/static/chunks/{6.30dce49d17db07600b06.js → 6.a3b07de9dd2ca2d24e85.js} +3 -3
- udata/static/chunks/{6.30dce49d17db07600b06.js.map → 6.a3b07de9dd2ca2d24e85.js.map} +1 -1
- udata/static/chunks/{8.54e44b102164ae5e7a67.js → 8.462bb3029de008497675.js} +2 -2
- udata/static/chunks/{8.54e44b102164ae5e7a67.js.map → 8.462bb3029de008497675.js.map} +1 -1
- udata/static/common.js +1 -1
- udata/static/common.js.map +1 -1
- udata/tests/api/test_dataservices_api.py +8 -8
- udata/tests/api/test_datasets_api.py +18 -8
- udata/tests/api/test_organizations_api.py +23 -1
- udata/tests/api/test_reuses_api.py +12 -8
- udata/tests/dataset/test_resource_preview.py +47 -98
- {udata-10.6.1.dev36110.dist-info → udata-10.6.1.dev36176.dist-info}/METADATA +5 -1
- {udata-10.6.1.dev36110.dist-info → udata-10.6.1.dev36176.dist-info}/RECORD +28 -28
- {udata-10.6.1.dev36110.dist-info → udata-10.6.1.dev36176.dist-info}/LICENSE +0 -0
- {udata-10.6.1.dev36110.dist-info → udata-10.6.1.dev36176.dist-info}/WHEEL +0 -0
- {udata-10.6.1.dev36110.dist-info → udata-10.6.1.dev36176.dist-info}/entry_points.txt +0 -0
- {udata-10.6.1.dev36110.dist-info → udata-10.6.1.dev36176.dist-info}/top_level.txt +0 -0
udata/core/dataservices/api.py
CHANGED
|
@@ -63,9 +63,7 @@ class DataservicesAtomFeedAPI(API):
|
|
|
63
63
|
)
|
|
64
64
|
|
|
65
65
|
dataservices: List[Dataservice] = (
|
|
66
|
-
Dataservice.objects.visible()
|
|
67
|
-
.order_by("-created_at_internal")
|
|
68
|
-
.limit(current_site.feed_size)
|
|
66
|
+
Dataservice.objects.visible().order_by("-created_at").limit(current_site.feed_size)
|
|
69
67
|
)
|
|
70
68
|
for dataservice in dataservices:
|
|
71
69
|
author_name = None
|
udata/core/dataset/models.py
CHANGED
|
@@ -20,6 +20,7 @@ from udata.api_fields import field
|
|
|
20
20
|
from udata.app import cache
|
|
21
21
|
from udata.core import storages
|
|
22
22
|
from udata.core.activity.models import Auditable
|
|
23
|
+
from udata.core.dataset.preview import TabularAPIPreview
|
|
23
24
|
from udata.core.linkable import Linkable
|
|
24
25
|
from udata.core.metrics.helpers import get_stock_metrics
|
|
25
26
|
from udata.core.owned import Owned, OwnedQuerySet
|
|
@@ -47,7 +48,6 @@ from .exceptions import (
|
|
|
47
48
|
SchemasCacheUnavailableException,
|
|
48
49
|
SchemasCatalogNotFoundException,
|
|
49
50
|
)
|
|
50
|
-
from .preview import get_preview_url
|
|
51
51
|
|
|
52
52
|
__all__ = (
|
|
53
53
|
"License",
|
|
@@ -393,9 +393,9 @@ class ResourceMixin(object):
|
|
|
393
393
|
if not self.urlhash or "url" in self._get_changed_fields():
|
|
394
394
|
self.urlhash = hash_url(self.url)
|
|
395
395
|
|
|
396
|
-
@
|
|
396
|
+
@property
|
|
397
397
|
def preview_url(self):
|
|
398
|
-
return
|
|
398
|
+
return TabularAPIPreview().preview_url(self)
|
|
399
399
|
|
|
400
400
|
@property
|
|
401
401
|
def closed_or_no_format(self):
|
|
@@ -1156,12 +1156,17 @@ class ResourceSchema(object):
|
|
|
1156
1156
|
f"Schemas catalog does not exist at {endpoint}"
|
|
1157
1157
|
)
|
|
1158
1158
|
response.raise_for_status()
|
|
1159
|
-
|
|
1160
|
-
|
|
1159
|
+
data = response.json()
|
|
1160
|
+
except requests.exceptions.RequestException as err:
|
|
1161
|
+
log.exception(f"Error while getting schema catalog from {endpoint}: {err}")
|
|
1162
|
+
schemas = cache.get(cache_key)
|
|
1163
|
+
except requests.exceptions.JSONDecodeError as err:
|
|
1164
|
+
log.exception(f"Error while getting schema catalog from {endpoint}: {err}")
|
|
1161
1165
|
schemas = cache.get(cache_key)
|
|
1162
1166
|
else:
|
|
1163
|
-
schemas =
|
|
1167
|
+
schemas = data.get("schemas", [])
|
|
1164
1168
|
cache.set(cache_key, schemas)
|
|
1169
|
+
|
|
1165
1170
|
# no cached version or no content
|
|
1166
1171
|
if not schemas:
|
|
1167
1172
|
log.error("No content found inc. from cache for schema catalog")
|
udata/core/dataset/preview.py
CHANGED
|
@@ -1,84 +1,31 @@
|
|
|
1
|
-
import
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
2
3
|
from abc import ABC, abstractmethod
|
|
4
|
+
from typing import TYPE_CHECKING, Optional
|
|
3
5
|
|
|
4
6
|
from flask import current_app
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
from udata.
|
|
8
|
-
|
|
9
|
-
# Cache available plugins for a day
|
|
10
|
-
# Don't forget to flush cache on new configuration or plugin
|
|
11
|
-
CACHE_DURATION = 60 * 60 * 24
|
|
12
|
-
CACHE_KEY = "udata.preview.enabled_plugins"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class PreviewWarning(UserWarning):
|
|
16
|
-
pass
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class PreviewPlugin(ABC):
|
|
20
|
-
"""
|
|
21
|
-
An abstract preview plugin.
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from udata.models import Resource
|
|
22
10
|
|
|
23
|
-
In order to register a functionnal PreviewPlugin,
|
|
24
|
-
extension developpers need to:
|
|
25
|
-
- inherit this class
|
|
26
|
-
- implement abstract methods
|
|
27
|
-
- expose the class on the ``udata.preview`` endpoint
|
|
28
|
-
"""
|
|
29
|
-
|
|
30
|
-
#: Default previews are given only if no specific preview match.
|
|
31
|
-
#: Typically plugins only relying on mimetype or format
|
|
32
|
-
#: should have `fallback = True`
|
|
33
|
-
fallback = False
|
|
34
|
-
|
|
35
|
-
@abstractmethod
|
|
36
|
-
def can_preview(self, resource):
|
|
37
|
-
"""
|
|
38
|
-
Whether or not this plugin can provide a preview for the given resource
|
|
39
|
-
|
|
40
|
-
:param ResourceMixin resource: the (community) resource to preview
|
|
41
|
-
:return: ``True`` if this plugin can provide a preview
|
|
42
|
-
:rtype: bool
|
|
43
|
-
"""
|
|
44
|
-
pass
|
|
45
11
|
|
|
12
|
+
# Define an abstract class
|
|
13
|
+
class Preview(ABC):
|
|
46
14
|
@abstractmethod
|
|
47
|
-
def preview_url(self, resource):
|
|
48
|
-
|
|
49
|
-
Returns the absolute preview URL associated to the resource
|
|
50
|
-
|
|
51
|
-
:param ResourceMixin resource: the (community) resource to preview
|
|
52
|
-
:return: a preview url to be displayed into an iframe or a new window
|
|
53
|
-
:rtype: str
|
|
54
|
-
"""
|
|
55
|
-
pass
|
|
56
|
-
|
|
15
|
+
def preview_url(self, resource: Resource) -> Optional[str]:
|
|
16
|
+
return None
|
|
57
17
|
|
|
58
|
-
@cache.cached(timeout=CACHE_DURATION, key_prefix=CACHE_KEY)
|
|
59
|
-
def get_enabled_plugins():
|
|
60
|
-
"""
|
|
61
|
-
Returns enabled preview plugins.
|
|
62
18
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if plugin not in valid:
|
|
69
|
-
clsname = plugin.__name__
|
|
70
|
-
msg = "{0} is not a valid preview plugin".format(clsname)
|
|
71
|
-
warnings.warn(msg, PreviewWarning)
|
|
72
|
-
return [p() for p in sorted(valid, key=lambda p: 1 if p.fallback else 0)]
|
|
19
|
+
class TabularAPIPreview(Preview):
|
|
20
|
+
def preview_url(self, resource: Resource) -> Optional[str]:
|
|
21
|
+
preview_base_url = current_app.config["TABULAR_EXPLORE_URL"]
|
|
22
|
+
if not preview_base_url:
|
|
23
|
+
return None
|
|
73
24
|
|
|
25
|
+
if "analysis:parsing:parsing_table" not in resource.extras:
|
|
26
|
+
return None
|
|
74
27
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
Returns the most pertinent preview URL associated to the resource, if any.
|
|
28
|
+
if resource.filetype == "remote" and not current_app.config["TABULAR_ALLOW_REMOTE"]:
|
|
29
|
+
return None
|
|
78
30
|
|
|
79
|
-
|
|
80
|
-
:return: a preview url to be displayed into an iframe or a new window
|
|
81
|
-
:rtype: HttpResponse
|
|
82
|
-
"""
|
|
83
|
-
candidates = (p.preview_url(resource) for p in get_enabled_plugins() if p.can_preview(resource))
|
|
84
|
-
return next(iter(candidates), None)
|
|
31
|
+
return f"{preview_base_url}/resources/{resource.id}"
|
udata/core/organization/api.py
CHANGED
|
@@ -76,6 +76,16 @@ class OrgApiParser(ModelApiParser):
|
|
|
76
76
|
choices=list(Organization.__badges__),
|
|
77
77
|
location="args",
|
|
78
78
|
)
|
|
79
|
+
self.parser.add_argument(
|
|
80
|
+
"name",
|
|
81
|
+
type=str,
|
|
82
|
+
location="args",
|
|
83
|
+
)
|
|
84
|
+
self.parser.add_argument(
|
|
85
|
+
"business_number_id",
|
|
86
|
+
type=str,
|
|
87
|
+
location="args",
|
|
88
|
+
)
|
|
79
89
|
|
|
80
90
|
@staticmethod
|
|
81
91
|
def parse_filters(organizations, args):
|
|
@@ -88,6 +98,10 @@ class OrgApiParser(ModelApiParser):
|
|
|
88
98
|
organizations = organizations.search_text(phrase_query)
|
|
89
99
|
if args.get("badge"):
|
|
90
100
|
organizations = organizations.with_badge(args["badge"])
|
|
101
|
+
if args.get("name"):
|
|
102
|
+
organizations = organizations.filter(name=args["name"])
|
|
103
|
+
if args.get("business_number_id"):
|
|
104
|
+
organizations = organizations.filter(business_number_id=args["business_number_id"])
|
|
91
105
|
return organizations
|
|
92
106
|
|
|
93
107
|
|
udata/settings.py
CHANGED
|
@@ -582,6 +582,9 @@ class Defaults(object):
|
|
|
582
582
|
###########################################################################
|
|
583
583
|
TABULAR_API_DATASERVICE_ID = None
|
|
584
584
|
|
|
585
|
+
TABULAR_EXPLORE_URL = None
|
|
586
|
+
TABULAR_ALLOW_REMOTE = True
|
|
587
|
+
|
|
585
588
|
# JSON-LD settings
|
|
586
589
|
###########################################################################
|
|
587
590
|
MAX_RESOURCES_IN_JSON_LD = 20
|