Skip to content

Commit 1ac45ef

Browse files
committed
feat(dev): validation support cont.;
- Moved logic into util method. - Added new config options for empty resource schemas. - Renamed some things to make them clearer.
1 parent b5231a4 commit 1ac45ef

File tree

3 files changed

+82
-50
lines changed

3 files changed

+82
-50
lines changed

ckanext/xloader/config_declaration.yaml

+14-1
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,26 @@ groups:
119119
to True.
120120
type: bool
121121
required: false
122-
- key: ckanext.xloader.requires_validation
122+
- key: ckanext.xloader.validation.requiredSoWaitForReport
123123
default: False
124124
example: True
125125
description: |
126126
Resources are required to pass validation from the ckanext-validation
127127
plugin to be able to get xloadered.
128128
type: bool
129129
required: false
130+
- key: ckanext.xloader.validation.enforceDefaultsIfSchemaMissing
131+
default: True
132+
example: False
133+
description: |
134+
Resources are required to have a Schema including the field `validation_status`.
135+
136+
If this option is set to `False`, Resources that do not have a `validation_status` field will
137+
always be submitted to XLoader.
138+
139+
See https://github.com/frictionlessdata/ckanext-validation?tab=readme-ov-file#changes-in-the-metadata-schema
140+
for more details.
141+
type: bool
142+
required: false
130143

131144

ckanext/xloader/plugin.py

+15-20
Original file line numberDiff line numberDiff line change
@@ -82,22 +82,6 @@ def notify(self, entity, operation):
8282
or not isinstance(entity, Resource):
8383
return
8484

85-
# If the resource requires validation, stop here if validation
86-
# has not been performed or did not succeed. The Validation
87-
# extension will call resource_patch and this method should
88-
# be called again. However, url_changed will not be in the entity
89-
# once Validation does the patch.
90-
if utils.is_validation_plugin_loaded() and \
91-
toolkit.asbool(toolkit.config.get('ckanext.xloader.requires_validation')):
92-
93-
if entity.__dict__.get('extras', {}).get('validation_status', None) != 'success':
94-
log.debug("Skipping xloading resource %s because the "
95-
"resource did not pass validation yet.", entity.id)
96-
return
97-
98-
elif not getattr(entity, 'url_changed', False):
99-
return
100-
10185
context = {
10286
"ignore_auth": True,
10387
}
@@ -107,15 +91,26 @@ def notify(self, entity, operation):
10791
"id": entity.id,
10892
},
10993
)
94+
95+
if utils.awaiting_validation(resource_dict):
96+
# If the resource requires validation, stop here if validation
97+
# has not been performed or did not succeed. The Validation
98+
# extension will call resource_patch and this method should
99+
# be called again. However, url_changed will not be in the entity
100+
# once Validation does the patch.
101+
log.debug("Skipping xloading resource %s because the "
102+
"resource did not pass validation yet.", resource_dict.get('id'))
103+
return
104+
elif not getattr(entity, 'url_changed', False):
105+
# do not submit to xloader if the url has not changed.
106+
return
107+
110108
self._submit_to_xloader(resource_dict)
111109

112110
# IResourceController
113111

114112
def after_resource_create(self, context, resource_dict):
115-
if utils.is_validation_plugin_loaded() and \
116-
toolkit.asbool(toolkit.config.get('ckanext.xloader.requires_validation')) and \
117-
resource_dict.get('validation_status', None) != 'success':
118-
113+
if utils.awaiting_validation(resource_dict):
119114
log.debug("Skipping xloading resource %s because the "
120115
"resource did not pass validation yet.", resource_dict.get('id'))
121116
return

ckanext/xloader/utils.py

+53-29
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,63 @@ def is_it_an_xloader_format(cls, format_):
4141
return format_.lower() in cls._formats
4242

4343

44+
def awaiting_validation(res_dict):
45+
"""
46+
Checks the existence of a logic action from the ckanext-validation
47+
plugin, thus supporting any extending of the Validation Plugin class.
48+
49+
Checks ckanext.xloader.validation.requiredSoWaitForReport config
50+
option value.
51+
52+
Checks ckanext.xloader.validation.enforceDefaultsIfSchemaMissing config
53+
option value. Then checks the Resource's Schema for the `validation_status` field.
54+
"""
55+
try:
56+
p.toolkit.get_action('resource_validation_show')
57+
is_validation_plugin_loaded = True
58+
except KeyError:
59+
is_validation_plugin_loaded = False
60+
61+
if not is_validation_plugin_loaded or \
62+
not p.toolkit.asbool(p.toolkit.config.get('ckanext.xloader.validation.requiredSoWaitForReport', False)):
63+
# the validation plugin is not loaded or the validation.requiredSoWaitForReport is turned off
64+
return False
65+
66+
if p.toolkit.asbool(p.toolkit.config.get('ckanext.xloader.validation.enforceDefaultsIfSchemaMissing', True)):
67+
# validation.enforceDefaultsIfSchemaMissing is turned on, so we will expect Resources to have `validation_status`
68+
if res_dict.get('validation_status', None) != 'success':
69+
return True
70+
else:
71+
return False
72+
else:
73+
# TODO: check the Resource's schema to see if there is no `validation_status`,
74+
# if there is not, then return False, otherwise check if it is `success` or not.
75+
return True
76+
77+
return True
78+
79+
4480
def resource_data(id, resource_id, rows=None):
4581

4682
if p.toolkit.request.method == "POST":
47-
if is_validation_plugin_loaded() and \
48-
p.toolkit.asbool(p.toolkit.config.get('ckanext.xloader.requires_validation')):
49-
50-
context = {
51-
"ignore_auth": True,
52-
}
53-
resource_dict = p.toolkit.get_action("resource_show")(
54-
context,
55-
{
56-
"id": resource_id,
57-
},
83+
84+
context = {
85+
"ignore_auth": True,
86+
}
87+
resource_dict = p.toolkit.get_action("resource_show")(
88+
context,
89+
{
90+
"id": resource_id,
91+
},
92+
)
93+
94+
if awaiting_validation(resource_dict):
95+
h.flash_error(_("Cannot upload resource %s to the DataStore "
96+
"because the resource did not pass validation yet.") % resource_id)
97+
return p.toolkit.redirect_to(
98+
"xloader.resource_data", id=id, resource_id=resource_id
5899
)
59-
if resource_dict.get('validation_status', None) != 'success':
60-
h.flash_error(_("Cannot upload resource %s to the DataStore "
61-
"because the resource did not pass validation yet.") % resource_id)
62-
return p.toolkit.redirect_to(
63-
"xloader.resource_data", id=id, resource_id=resource_id
64-
)
100+
65101
try:
66102
p.toolkit.get_action("xloader_submit")(
67103
None,
@@ -274,15 +310,3 @@ def datastore_resource_exists(resource_id):
274310
except p.toolkit.ObjectNotFound:
275311
return False
276312
return response or {'fields': []}
277-
278-
279-
def is_validation_plugin_loaded():
280-
"""
281-
Checks the existence of a logic action from the ckanext-validation
282-
plugin, thus supporting any extending of the Validation Plugin class.
283-
"""
284-
try:
285-
p.toolkit.get_action('resource_validation_show')
286-
return True
287-
except KeyError:
288-
return False

0 commit comments

Comments
 (0)