diff --git a/ckan/controllers/package.py b/ckan/controllers/package.py index c7082617732..4106f7ee611 100644 --- a/ckan/controllers/package.py +++ b/ckan/controllers/package.py @@ -30,6 +30,7 @@ import ckan.rating import ckan.misc import ckan.lib.accept as accept +import ckan.lib.helpers as helpers from home import CACHE_PARAMETERS from ckan.lib.plugins import lookup_package_plugin @@ -1335,15 +1336,18 @@ def resource_datapreview(self, id, resource_id): {'id': resource_id}) c.package = get_action('package_show')(context, {'id': id}) + data_dict = {'resource': c.resource, 'package': c.package} + data_dict = helpers._add_whether_on_same_domain(data_dict) + plugins = ckanplugins.PluginImplementations(ckanplugins.IResourcePreview) - plugins_that_can_preview = [p for p in plugins if p.can_preview(c.resource)] + plugins_that_can_preview = [p for p in plugins if p.can_preview(data_dict)] if len(plugins_that_can_preview) == 0: abort(409, _('No preview has been defined.')) if len(plugins_that_can_preview) > 1: log.warn('Multiple previews are possible. {0}'.format(plugins_that_can_preview)) plugin = plugins_that_can_preview[0] - plugin.setup_template_variables(context, {'resource': c.resource, 'package': c.package}) + plugin.setup_template_variables(context, data_dict) c.resource_json = json.dumps(c.resource) diff --git a/ckan/lib/helpers.py b/ckan/lib/helpers.py index ff411d96deb..859658eb3e3 100644 --- a/ckan/lib/helpers.py +++ b/ckan/lib/helpers.py @@ -1265,23 +1265,29 @@ def format_resource_items(items): return sorted(output, key=lambda x: x[0]) -def _can_be_previewed(resource): - ''' - Determines whether there is an extension that can preview the resource. +def _add_whether_on_same_domain(data_dict): + ''' sets the ``on_same_domain`` flag to a resource dictionary ''' # compare CKAN domain and resource URL import ckan.plugins.toolkit as toolkit ckan_domain = toolkit.request.environ['HTTP_HOST'].lower() request_protocol = toolkit.request.environ['SERVER_PROTOCOL'].lower() - parsed = urlparse.urlparse(resource['url']) + parsed = urlparse.urlparse(data_dict['resource']['url']) resource_domain = (parsed.hostname + ':' + str(parsed.port)).lower() - resource['on_same_domain'] = (ckan_domain == resource_domain + data_dict['resource']['on_same_domain'] = (ckan_domain == resource_domain and parsed.scheme.lower() in request_protocol) + return data_dict + +def _can_be_previewed(data_dict): + ''' + Determines whether there is an extension that can preview the resource. + ''' + data_dict = _add_whether_on_same_domain(data_dict) plugins = ckanplugins.PluginImplementations(ckanplugins.IResourcePreview) - return any(plugin.can_preview(resource) for plugin in plugins) + return any(plugin.can_preview(data_dict) for plugin in plugins) def resource_preview(resource, pkg_id): @@ -1302,7 +1308,9 @@ def resource_preview(resource, pkg_id): directly = False url = '' - if _can_be_previewed(resource): + data_dict = {'resource': resource, 'package': None} + + if _can_be_previewed(data_dict): url = url = url_for(controller='package', action='resource_datapreview', resource_id=resource['id'], id=pkg_id, qualified=True) elif format_lower in DIRECT_EMBEDS: diff --git a/ckan/plugins/interfaces.py b/ckan/plugins/interfaces.py index b067b41b181..fcaeea39d0c 100644 --- a/ckan/plugins/interfaces.py +++ b/ckan/plugins/interfaces.py @@ -198,9 +198,10 @@ class IResourcePreview(Interface): create custom previews for example for xml files. """ - def can_preview(self, resource): + def can_preview(self, data_dict): ''' - Return True if the extension can preview the resource. + Return True if the extension can preview the resource. The ``data_dict`` + contains the resource and the package. Make sure you also make sure to ckeck the ``on_same_domain`` value of the resource or the url if your preview requires the resource to be on @@ -210,6 +211,7 @@ def can_preview(self, resource): def setup_template_variables(self, context, data_dict): ''' Add variables to c just prior to the template being rendered. + The ``data_dict`` contains the resource and the package. Change the url to a proxied domain if necessary. '''