From 1080ac0c5e32cc459dc6aeabdd6a99a154613231 Mon Sep 17 00:00:00 2001 From: John Glover Date: Wed, 6 Nov 2013 18:15:34 +0100 Subject: [PATCH] [#1251] Updating Recline views for new IResourceView interface. The only view options that are currently supported are row offset and limit (so the graph in particular is not usable at the moment). --- ckanext/reclinepreview/plugin.py | 80 ++++++++-- .../theme/public/preview_recline.js | 146 +++++------------- .../theme/templates/recline_graph_form.html | 4 + .../theme/templates/recline_grid_form.html | 4 + .../theme/templates/recline_map_form.html | 5 + .../{recline.html => recline_view.html} | 14 +- setup.py | 4 +- 7 files changed, 133 insertions(+), 124 deletions(-) create mode 100644 ckanext/reclinepreview/theme/templates/recline_graph_form.html create mode 100644 ckanext/reclinepreview/theme/templates/recline_grid_form.html create mode 100644 ckanext/reclinepreview/theme/templates/recline_map_form.html rename ckanext/reclinepreview/theme/templates/{recline.html => recline_view.html} (52%) diff --git a/ckanext/reclinepreview/plugin.py b/ckanext/reclinepreview/plugin.py index 826227b1d16..21f695eb0e3 100644 --- a/ckanext/reclinepreview/plugin.py +++ b/ckanext/reclinepreview/plugin.py @@ -1,36 +1,84 @@ from logging import getLogger +from ckan.common import json import ckan.plugins as p import ckan.plugins.toolkit as toolkit log = getLogger(__name__) +ignore_missing = p.toolkit.get_validator('ignore_missing') +natural_number_validator = p.toolkit.get_validator('natural_number_validator') -class ReclinePreview(p.SingletonPlugin): - """This extension previews resources using recline - - This extension implements two interfaces - - - ``IConfigurer`` allows to modify the configuration - - ``IResourcePreview`` allows to add previews - """ +class ReclineView(p.SingletonPlugin): + ''' + This base class for the Recline view extensions. + ''' p.implements(p.IConfigurer, inherit=True) - p.implements(p.IResourcePreview, inherit=True) + p.implements(p.IResourceView, inherit=True) + + # schema fields that apply to all Recline views + schema = {'offset': [ignore_missing, natural_number_validator], + 'limit': [ignore_missing, natural_number_validator]} def update_config(self, config): - ''' Set up the resource library, public directory and + ''' + Set up the resource library, public directory and template directory for the preview ''' toolkit.add_public_directory(config, 'theme/public') toolkit.add_template_directory(config, 'theme/templates') toolkit.add_resource('theme/public', 'ckanext-reclinepreview') - def can_preview(self, data_dict): - # if the resource is in the datastore then we can preview it with recline + def can_view(self, data_dict): if data_dict['resource'].get('datastore_active'): return True - format_lower = data_dict['resource']['format'].lower() - return format_lower in ['csv', 'xls', 'tsv'] + return False + + def setup_template_variables(self, context, data_dict): + return {'resource_json': json.dumps(data_dict['resource']), + 'resource_view_json': json.dumps(data_dict['resource_view'])} + + def view_template(self, context, data_dict): + return 'recline_view.html' + + +class ReclineGrid(ReclineView): + ''' + This extension views resources using a Recline grid. + ''' + + def info(self): + return {'name': 'recline_grid', + 'title': 'Grid', + 'schema': self.schema} + + def form_template(self, context, data_dict): + return 'recline_grid_form.html' + + +class ReclineGraph(ReclineView): + ''' + This extension views resources using a Recline graph. + ''' + + def info(self): + return {'name': 'recline_graph', + 'title': 'Graph', + 'schema': self.schema} + + def form_template(self, context, data_dict): + return 'recline_graph_form.html' + + +class ReclineMap(ReclineView): + ''' + This extension views resources using a Recline map. + ''' + + def info(self): + return {'name': 'recline_map', + 'title': 'Map', + 'schema': self.schema} - def preview_template(self, context, data_dict): - return 'recline.html' + def form_template(self, context, data_dict): + return 'recline_map_form.html' diff --git a/ckanext/reclinepreview/theme/public/preview_recline.js b/ckanext/reclinepreview/theme/public/preview_recline.js index 2f291469fed..6e8071c2314 100644 --- a/ckanext/reclinepreview/theme/public/preview_recline.js +++ b/ckanext/reclinepreview/theme/public/preview_recline.js @@ -3,10 +3,10 @@ this.ckan.module('reclinepreview', function (jQuery, _) { return { options: { i18n: { - errorLoadingPreview: "Could not load preview", + errorLoadingPreview: "Could not load view", errorDataProxy: "DataProxy returned an error", errorDataStore: "DataStore returned an error", - previewNotAvailableForDataType: "Preview not available for data type: " + previewNotAvailableForDataType: "View not available for data type: " }, site_url: "" }, @@ -19,19 +19,10 @@ this.ckan.module('reclinepreview', function (jQuery, _) { }, _onReady: function() { - this.loadPreviewDialog(preload_resource); + this.loadView(preload_resource, preload_resource_view); }, - // **Public: Loads a data preview** - // - // Fetches the preview data object from the link provided and loads the - // parsed data from the webstore displaying it in the most appropriate - // manner. - // - // link - Preview button. - // - // Returns nothing. - loadPreviewDialog: function (resourceData) { + loadView: function (resourceData, reclineView) { var self = this; function showError(msg){ @@ -39,15 +30,6 @@ this.ckan.module('reclinepreview', function (jQuery, _) { window.parent.ckan.pubsub.publish('data-viewer-error', msg); } - recline.Backend.DataProxy.timeout = 10000; - // will no be necessary any more with https://github.com/okfn/recline/pull/345 - recline.Backend.DataProxy.dataproxy_url = '//jsonpdataproxy.appspot.com'; - - // 2 situations - // a) something was posted to the datastore - need to check for this - // b) csv or xls (but not datastore) - resourceData.formatNormalized = this.normalizeFormat(resourceData.format); - resourceData.url = this.normalizeUrl(resourceData.url); if (resourceData.formatNormalized === '') { var tmp = resourceData.url.split('/'); @@ -62,96 +44,50 @@ this.ckan.module('reclinepreview', function (jQuery, _) { var errorMsg, dataset; - if (resourceData.datastore_active) { - resourceData.backend = 'ckan'; - // Set endpoint of the resource to the datastore api (so it can locate - // CKAN DataStore) - resourceData.endpoint = jQuery('body').data('site-root') + 'api'; - dataset = new recline.Model.Dataset(resourceData); - errorMsg = this.options.i18n.errorLoadingPreview + ': ' + this.options.i18n.errorDataStore; - dataset.fetch() - .done(function(dataset){ - self.initializeDataExplorer(dataset); - }) - .fail(function(error){ - if (error.message) errorMsg += ' (' + error.message + ')'; - showError(errorMsg); - }); + resourceData.backend = 'ckan'; + resourceData.endpoint = jQuery('body').data('site-root') + 'api'; - } else if (resourceData.formatNormalized in {'csv': '', 'xls': ''}) { - // set format as this is used by Recline in setting format for DataProxy - resourceData.format = resourceData.formatNormalized; - resourceData.backend = 'dataproxy'; - dataset = new recline.Model.Dataset(resourceData); - errorMsg = this.options.i18n.errorLoadingPreview + ': ' +this.options.i18n.errorDataProxy; - dataset.fetch() - .done(function(dataset){ - dataset.bind('query:fail', function (error) { - jQuery('.data-view-container', self.el).hide(); - jQuery('.header', self.el).hide(); - }); + dataset = new recline.Model.Dataset(resourceData); + dataset.query({ + "from": reclineView.offset || 0, + "size": reclineView.limit || 100 + }); - self.initializeDataExplorer(dataset); - }) - .fail(function(error){ - if (error.message) errorMsg += ' (' + error.message + ')'; - showError(errorMsg); - }); - } + errorMsg = this.options.i18n.errorLoadingPreview + ': ' + this.options.i18n.errorDataStore; + dataset.fetch() + .done(function(dataset){ + self.initializeView(dataset, reclineView); + }) + .fail(function(error){ + if (error.message) errorMsg += ' (' + error.message + ')'; + showError(errorMsg); + }); }, - initializeDataExplorer: function (dataset) { - var views = [ - { - id: 'grid', - label: 'Grid', - view: new recline.View.SlickGrid({ - model: dataset - }) - }, - { - id: 'graph', - label: 'Graph', - view: new recline.View.Graph({ - model: dataset - }) - }, - { - id: 'map', - label: 'Map', - view: new recline.View.Map({ - model: dataset - }) - } - ]; - - var sidebarViews = [ - { - id: 'valueFilter', - label: 'Filters', - view: new recline.View.ValueFilter({ - model: dataset - }) - } - ]; + initializeView: function (dataset, reclineView) { + var view; - var dataExplorer = new recline.View.MultiView({ - el: this.el, - model: dataset, - views: views, - sidebarViews: sidebarViews, - config: { - readOnly: true - } - }); + if(reclineView.view_type === "recline_graph") { + view = new recline.View.Graph({ + model: dataset, + el: this.el + }); + } else if(reclineView.view_type == "recline_map") { + view = new recline.View.Map({ + model: dataset, + el: this.el + }); + } else { + view = new recline.View.SlickGrid({ + model: dataset, + el: this.el + }); + } + view.visible = true; + view.render(); }, - normalizeFormat: function (format) { - var out = format.toLowerCase(); - out = out.split('/'); - out = out[out.length-1]; - return out; - }, + normalizeUrl: function (url) { if (url.indexOf('https') === 0) { return 'http' + url.slice(5); diff --git a/ckanext/reclinepreview/theme/templates/recline_graph_form.html b/ckanext/reclinepreview/theme/templates/recline_graph_form.html new file mode 100644 index 00000000000..d4fb0bd9429 --- /dev/null +++ b/ckanext/reclinepreview/theme/templates/recline_graph_form.html @@ -0,0 +1,4 @@ +{% import 'macros/form.html' as form %} + +{{ form.input('offset', id='field-offset', label=_('Row offset'), placeholder=_('eg: 0'), value=data.offset, error=errors.offset, classes=['control-medium']) }} +{{ form.input('limit', id='field-limit', label=_('Number of rows'), placeholder=_('eg: 100'), value=data.limit, error=errors.limit, classes=['control-medium']) }} diff --git a/ckanext/reclinepreview/theme/templates/recline_grid_form.html b/ckanext/reclinepreview/theme/templates/recline_grid_form.html new file mode 100644 index 00000000000..d4fb0bd9429 --- /dev/null +++ b/ckanext/reclinepreview/theme/templates/recline_grid_form.html @@ -0,0 +1,4 @@ +{% import 'macros/form.html' as form %} + +{{ form.input('offset', id='field-offset', label=_('Row offset'), placeholder=_('eg: 0'), value=data.offset, error=errors.offset, classes=['control-medium']) }} +{{ form.input('limit', id='field-limit', label=_('Number of rows'), placeholder=_('eg: 100'), value=data.limit, error=errors.limit, classes=['control-medium']) }} diff --git a/ckanext/reclinepreview/theme/templates/recline_map_form.html b/ckanext/reclinepreview/theme/templates/recline_map_form.html new file mode 100644 index 00000000000..82925d69c7b --- /dev/null +++ b/ckanext/reclinepreview/theme/templates/recline_map_form.html @@ -0,0 +1,5 @@ +{% import 'macros/form.html' as form %} + +{{ form.input('offset', id='field-offset', label=_('Row offset'), placeholder=_('eg: 0'), value=data.offset, error=errors.offset, classes=['control-medium']) }} +{{ form.input('limit', id='field-limit', label=_('Number of rows'), placeholder=_('eg: 100'), value=data.limit, error=errors.limit, classes=['control-medium']) }} + diff --git a/ckanext/reclinepreview/theme/templates/recline.html b/ckanext/reclinepreview/theme/templates/recline_view.html similarity index 52% rename from ckanext/reclinepreview/theme/templates/recline.html rename to ckanext/reclinepreview/theme/templates/recline_view.html index 852b6936b01..59f02539f6c 100644 --- a/ckanext/reclinepreview/theme/templates/recline.html +++ b/ckanext/reclinepreview/theme/templates/recline_view.html @@ -1,4 +1,4 @@ -{% extends "dataviewer/base.html" %} +{% extends "base.html" %} {% block page %}
@@ -9,4 +9,14 @@

{% resource 'ckanext-reclinepreview/main' %} -{% endblock %} \ No newline at end of file +{% endblock %} + +{% block scripts %} + +{% endblock %} + +{% block styles %}{% endblock %} +{% block custom_styles %}{% endblock %} diff --git a/setup.py b/setup.py index 77e6b92c60b..50f9b097e58 100644 --- a/setup.py +++ b/setup.py @@ -120,7 +120,9 @@ resource_proxy=ckanext.resourceproxy.plugin:ResourceProxy text_preview=ckanext.textpreview.plugin:TextPreview pdf_preview=ckanext.pdfpreview.plugin:PdfPreview - recline_preview=ckanext.reclinepreview.plugin:ReclinePreview + recline_grid=ckanext.reclinepreview.plugin:ReclineGrid + recline_graph=ckanext.reclinepreview.plugin:ReclineGraph + recline_map=ckanext.reclinepreview.plugin:ReclineMap example_itemplatehelpers=ckanext.example_itemplatehelpers.plugin:ExampleITemplateHelpersPlugin example_idatasetform=ckanext.example_idatasetform.plugin:ExampleIDatasetFormPlugin example_iauthfunctions_v1=ckanext.example_iauthfunctions.plugin_v1:ExampleIAuthFunctionsPlugin