diff --git a/ckanext/xloader/command.py b/ckanext/xloader/command.py index 7f2c000a..64b79754 100644 --- a/ckanext/xloader/command.py +++ b/ckanext/xloader/command.py @@ -3,6 +3,7 @@ import sys import logging import ckan.plugins.toolkit as tk +from ckanext.xloader.utils import XLoaderFormats class XloaderCmd: @@ -84,8 +85,6 @@ def _submit_resource(self, resource, user, indent=0): '''resource: resource dictionary ''' indentation = ' ' * indent - # import here, so that that loggers are setup - from ckanext.xloader.plugin import XLoaderFormats if not XLoaderFormats.is_it_an_xloader_format(resource['format']): print(indentation diff --git a/ckanext/xloader/helpers.py b/ckanext/xloader/helpers.py index 8c94387a..6c4b8b9b 100644 --- a/ckanext/xloader/helpers.py +++ b/ckanext/xloader/helpers.py @@ -1,4 +1,5 @@ import ckan.plugins.toolkit as toolkit +from ckanext.xloader.utils import XLoaderFormats def xloader_status(resource_id): @@ -25,3 +26,15 @@ def xloader_status_description(status): return captions.get(status['status'], status['status'].capitalize()) else: return _('Not Uploaded Yet') + + +def is_resource_supported_by_xloader(res_dict, check_access = True): + is_supported_format = XLoaderFormats.is_it_an_xloader_format(res_dict.get('format')) + is_datastore_active = res_dict.get('datastore_active', False) + user_has_access = not check_access or toolkit.h.check_access('package_update', + {'id':res_dict.get('package_id')}) + try: + is_supported_url_type = res_dict.get('url_type') not in toolkit.h.datastore_rw_resource_url_types() + except AttributeError: + is_supported_url_type = (res_dict.get('url_type') == 'upload' or not res_dict.get('url_type')) + return (is_supported_format or is_datastore_active) and user_has_access and is_supported_url_type diff --git a/ckanext/xloader/plugin.py b/ckanext/xloader/plugin.py index b21bce5d..392b1cf5 100644 --- a/ckanext/xloader/plugin.py +++ b/ckanext/xloader/plugin.py @@ -9,6 +9,7 @@ from ckan.model.resource import Resource from . import action, auth, helpers as xloader_helpers, utils +from ckanext.xloader.utils import XLoaderFormats try: config_declarations = toolkit.blanket.config_declarations @@ -21,36 +22,6 @@ def config_declarations(cls): log = logging.getLogger(__name__) -# resource.formats accepted by ckanext-xloader. Must be lowercase here. -DEFAULT_FORMATS = [ - "csv", - "application/csv", - "xls", - "xlsx", - "tsv", - "application/vnd.ms-excel", - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - "ods", - "application/vnd.oasis.opendocument.spreadsheet", -] - - -class XLoaderFormats(object): - formats = None - - @classmethod - def is_it_an_xloader_format(cls, format_): - if cls.formats is None: - cls._formats = toolkit.config.get("ckanext.xloader.formats") - if cls._formats is not None: - cls._formats = cls._formats.lower().split() - else: - cls._formats = DEFAULT_FORMATS - if not format_: - return False - return format_.lower() in cls._formats - - @config_declarations class xloaderPlugin(plugins.SingletonPlugin): plugins.implements(plugins.IConfigurer) @@ -224,4 +195,5 @@ def get_helpers(self): return { "xloader_status": xloader_helpers.xloader_status, "xloader_status_description": xloader_helpers.xloader_status_description, + "is_resource_supported_by_xloader": xloader_helpers.is_resource_supported_by_xloader, } diff --git a/ckanext/xloader/templates/package/resource_edit_base.html b/ckanext/xloader/templates/package/resource_edit_base.html index 34403521..5c02815a 100644 --- a/ckanext/xloader/templates/package/resource_edit_base.html +++ b/ckanext/xloader/templates/package/resource_edit_base.html @@ -2,5 +2,7 @@ {% block inner_primary_nav %} {{ super() }} - {{ h.build_nav_icon('xloader.resource_data', _('DataStore'), id=pkg.name, resource_id=res.id) }} + {% if h.is_resource_supported_by_xloader(res) %} + {{ h.build_nav_icon('xloader.resource_data', _('DataStore'), id=pkg.name, resource_id=res.id, icon='cloud-upload') }} + {% endif %} {% endblock %} diff --git a/ckanext/xloader/templates/package/resource_read.html b/ckanext/xloader/templates/package/resource_read.html new file mode 100644 index 00000000..3ab1476e --- /dev/null +++ b/ckanext/xloader/templates/package/resource_read.html @@ -0,0 +1,15 @@ +{% ckan_extends %} + +{% block action_manage_inner %} + {{ super() }} + {% if h.is_resource_supported_by_xloader(res) %} +
  • {% link_for _('DataStore'), named_route='xloader.resource_data', id=pkg.name, resource_id=res.id, class_='btn btn-light', icon='cloud-upload' %}
  • + {% endif %} +{% endblock %} + +{% block resource_actions_inner %} + {% if h.check_ckan_version(max_version='2.10') and h.is_resource_supported_by_xloader(res) %} +
  • {% link_for _('DataStore'), named_route='xloader.resource_data', id=pkg.name, resource_id=res.id, class_='btn btn-light', icon='cloud-upload' %}
  • + {% endif %} + {{ super() }} +{% endblock %} diff --git a/ckanext/xloader/templates/package/snippets/resource_item.html b/ckanext/xloader/templates/package/snippets/resource_item.html new file mode 100644 index 00000000..70bf99c4 --- /dev/null +++ b/ckanext/xloader/templates/package/snippets/resource_item.html @@ -0,0 +1,15 @@ +{% ckan_extends %} + +{% block resource_item_explore_inner %} + {{ super() }} + {% if h.is_resource_supported_by_xloader(res) %} +
  • {% link_for _('DataStore'), named_route='xloader.resource_data', id=pkg.name, resource_id=res.id, class_='dropdown-item', icon='cloud-upload' %}
  • + {% endif %} +{% endblock %} + +{% block resource_item_explore_links %} + {% if h.check_ckan_version(max_version='2.10') and h.is_resource_supported_by_xloader(res) %} +
  • {% link_for _('DataStore'), named_route='xloader.resource_data', id=pkg.name, resource_id=res.id, class_='dropdown-item', icon='cloud-upload' %}
  • + {% endif %} + {{ super() }} +{% endblock %} diff --git a/ckanext/xloader/templates/package/snippets/resources.html b/ckanext/xloader/templates/package/snippets/resources.html new file mode 100644 index 00000000..e04dde4d --- /dev/null +++ b/ckanext/xloader/templates/package/snippets/resources.html @@ -0,0 +1,8 @@ +{% ckan_extends %} + +{% block resources_list_edit_dropdown_inner %} + {{ super() }} + {% if h.is_resource_supported_by_xloader(resource) %} +
  • {% link_for _('DataStore'), named_route='xloader.resource_data', id=pkg.name, resource_id=resource.id, class_='dropdown-item', icon='cloud-upload' %}
  • + {% endif %} +{% endblock %} diff --git a/ckanext/xloader/utils.py b/ckanext/xloader/utils.py index ec8e4bbd..99284bff 100644 --- a/ckanext/xloader/utils.py +++ b/ckanext/xloader/utils.py @@ -9,6 +9,37 @@ from decimal import Decimal import ckan.plugins as p +from ckan.plugins.toolkit import config + +# resource.formats accepted by ckanext-xloader. Must be lowercase here. +DEFAULT_FORMATS = [ + "csv", + "application/csv", + "xls", + "xlsx", + "tsv", + "application/vnd.ms-excel", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "ods", + "application/vnd.oasis.opendocument.spreadsheet", +] + + +class XLoaderFormats(object): + formats = None + + @classmethod + def is_it_an_xloader_format(cls, format_): + if cls.formats is None: + cls._formats = config.get("ckanext.xloader.formats") + if cls._formats is not None: + # use config value. preserves empty list as well. + cls._formats = cls._formats.lower().split() + else: + cls._formats = DEFAULT_FORMATS + if not format_: + return False + return format_.lower() in cls._formats def resource_data(id, resource_id, rows=None):