We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
DataStore Map and Explorer not displaying map tiles since 11 July 2016
Direct tile access to MapQuest maps has been discontinued as of 11 July 2016 and the DataStore Map and Explorer previews no longer display map tiles. 

The issue actually lies with recline.js and it has been logged https://github.com/okfn/recline/issues/500  and there is a referenced patch to replace MapQuest with Open Street Map frodrigo/recline@3df0c2a2bb8897124bdbbca715b2be1fd99cb08f

Thought it would be useful to have a record here and request the packaged recline.js should be updated.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ckanext/reclineview/plugin.py`
Content:
```
1 # encoding: utf-8
2 
3 from logging import getLogger
4 
5 from ckan.common import json
6 import ckan.plugins as p
7 import ckan.plugins.toolkit as toolkit
8 
9 log = getLogger(__name__)
10 ignore_empty = p.toolkit.get_validator('ignore_empty')
11 natural_number_validator = p.toolkit.get_validator('natural_number_validator')
12 Invalid = p.toolkit.Invalid
13 
14 
15 def in_list(list_possible_values):
16     '''
17     Validator that checks that the input value is one of the given
18     possible values.
19 
20     :param list_possible_values: function that returns list of possible values
21         for validated field
22     :type possible_values: function
23     '''
24     def validate(key, data, errors, context):
25         if not data[key] in list_possible_values():
26             raise Invalid('"{0}" is not a valid parameter'.format(data[key]))
27     return validate
28 
29 
30 def datastore_fields(resource, valid_field_types):
31     '''
32     Return a list of all datastore fields for a given resource, as long as
33     the datastore field type is in valid_field_types.
34 
35     :param resource: resource dict
36     :type resource: dict
37     :param valid_field_types: field types to include in returned list
38     :type valid_field_types: list of strings
39     '''
40     data = {'resource_id': resource['id'], 'limit': 0}
41     fields = toolkit.get_action('datastore_search')({}, data)['fields']
42     return [{'value': f['id'], 'text': f['id']} for f in fields
43             if f['type'] in valid_field_types]
44 
45 
46 class ReclineViewBase(p.SingletonPlugin):
47     '''
48     This base class for the Recline view extensions.
49     '''
50     p.implements(p.IConfigurer, inherit=True)
51     p.implements(p.IResourceView, inherit=True)
52 
53     def update_config(self, config):
54         '''
55         Set up the resource library, public directory and
56         template directory for the view
57         '''
58         toolkit.add_public_directory(config, 'theme/public')
59         toolkit.add_template_directory(config, 'theme/templates')
60         toolkit.add_resource('theme/public', 'ckanext-reclineview')
61 
62     def can_view(self, data_dict):
63         resource = data_dict['resource']
64         return (resource.get('datastore_active') or
65                 '_datastore_only_resource' in resource.get('url', ''))
66 
67     def setup_template_variables(self, context, data_dict):
68         return {'resource_json': json.dumps(data_dict['resource']),
69                 'resource_view_json': json.dumps(data_dict['resource_view'])}
70 
71     def view_template(self, context, data_dict):
72         return 'recline_view.html'
73 
74 
75 class ReclineView(ReclineViewBase):
76     '''
77     This extension views resources using a Recline MultiView.
78     '''
79 
80     def info(self):
81         return {'name': 'recline_view',
82                 'title': 'Data Explorer',
83                 'filterable': True,
84                 'icon': 'table',
85                 'requires_datastore': False,
86                 'default_title': p.toolkit._('Data Explorer'),
87                 }
88 
89     def can_view(self, data_dict):
90         resource = data_dict['resource']
91 
92         if (resource.get('datastore_active') or
93                 '_datastore_only_resource' in resource.get('url', '')):
94             return True
95         resource_format = resource.get('format', None)
96         if resource_format:
97             return resource_format.lower() in ['csv', 'xls', 'xlsx', 'tsv']
98         else:
99             return False
100 
101 
102 class ReclineGridView(ReclineViewBase):
103     '''
104     This extension views resources using a Recline grid.
105     '''
106 
107     def info(self):
108         return {'name': 'recline_grid_view',
109                 'title': 'Grid',
110                 'filterable': True,
111                 'icon': 'table',
112                 'requires_datastore': True,
113                 'default_title': p.toolkit._('Table'),
114                 }
115 
116 
117 class ReclineGraphView(ReclineViewBase):
118     '''
119     This extension views resources using a Recline graph.
120     '''
121 
122     graph_types = [{'value': 'lines-and-points',
123                     'text': 'Lines and points'},
124                    {'value': 'lines', 'text': 'Lines'},
125                    {'value': 'points', 'text': 'Points'},
126                    {'value': 'bars', 'text': 'Bars'},
127                    {'value': 'columns', 'text': 'Columns'}]
128 
129     datastore_fields = []
130 
131     datastore_field_types = ['numeric', 'int4', 'timestamp']
132 
133     def list_graph_types(self):
134         return [t['value'] for t in self.graph_types]
135 
136     def list_datastore_fields(self):
137         return [t['value'] for t in self.datastore_fields]
138 
139     def info(self):
140         # in_list validator here is passed functions because this
141         # method does not know what the possible values of the
142         # datastore fields are (requires a datastore search)
143         schema = {
144             'offset': [ignore_empty, natural_number_validator],
145             'limit': [ignore_empty, natural_number_validator],
146             'graph_type': [ignore_empty, in_list(self.list_graph_types)],
147             'group': [ignore_empty, in_list(self.list_datastore_fields)],
148             'series': [ignore_empty, in_list(self.list_datastore_fields)]
149         }
150         return {'name': 'recline_graph_view',
151                 'title': 'Graph',
152                 'filterable': True,
153                 'icon': 'bar-chart',
154                 'requires_datastore': True,
155                 'schema': schema,
156                 'default_title': p.toolkit._('Graph'),
157                 }
158 
159     def setup_template_variables(self, context, data_dict):
160         self.datastore_fields = datastore_fields(data_dict['resource'],
161                                                  self.datastore_field_types)
162         vars = ReclineViewBase.setup_template_variables(self, context,
163                                                         data_dict)
164         vars.update({'graph_types': self.graph_types,
165                      'graph_fields': self.datastore_fields})
166         return vars
167 
168     def form_template(self, context, data_dict):
169         return 'recline_graph_form.html'
170 
171 
172 class ReclineMapView(ReclineViewBase):
173     '''
174     This extension views resources using a Recline map.
175     '''
176 
177     map_field_types = [{'value': 'lat_long',
178                         'text': 'Latitude / Longitude fields'},
179                        {'value': 'geojson', 'text': 'GeoJSON'}]
180 
181     datastore_fields = []
182 
183     datastore_field_latlon_types = ['numeric']
184 
185     datastore_field_geojson_types = ['text']
186 
187     def list_map_field_types(self):
188         return [t['value'] for t in self.map_field_types]
189 
190     def list_datastore_fields(self):
191         return [t['value'] for t in self.datastore_fields]
192 
193     def info(self):
194         # in_list validator here is passed functions because this
195         # method does not know what the possible values of the
196         # datastore fields are (requires a datastore search)
197         schema = {
198             'offset': [ignore_empty, natural_number_validator],
199             'limit': [ignore_empty, natural_number_validator],
200             'map_field_type': [ignore_empty,
201                                in_list(self.list_map_field_types)],
202             'latitude_field': [ignore_empty,
203                                in_list(self.list_datastore_fields)],
204             'longitude_field': [ignore_empty,
205                                 in_list(self.list_datastore_fields)],
206             'geojson_field': [ignore_empty,
207                               in_list(self.list_datastore_fields)],
208             'auto_zoom': [ignore_empty],
209             'cluster_markers': [ignore_empty]
210         }
211         return {'name': 'recline_map_view',
212                 'title': 'Map',
213                 'schema': schema,
214                 'filterable': True,
215                 'icon': 'map-marker',
216                 'default_title': p.toolkit._('Map'),
217                 }
218 
219     def setup_template_variables(self, context, data_dict):
220         map_latlon_fields = datastore_fields(
221             data_dict['resource'], self.datastore_field_latlon_types)
222         map_geojson_fields = datastore_fields(
223             data_dict['resource'], self.datastore_field_geojson_types)
224 
225         self.datastore_fields = map_latlon_fields + map_geojson_fields
226 
227         vars = ReclineViewBase.setup_template_variables(self, context,
228                                                         data_dict)
229         vars.update({'map_field_types': self.map_field_types,
230                      'map_latlon_fields': map_latlon_fields,
231                      'map_geojson_fields': map_geojson_fields
232                      })
233         return vars
234 
235     def form_template(self, context, data_dict):
236         return 'recline_map_form.html'
237
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/ckanext/reclineview/plugin.py b/ckanext/reclineview/plugin.py
--- a/ckanext/reclineview/plugin.py
+++ b/ckanext/reclineview/plugin.py
@@ -5,6 +5,7 @@
 from ckan.common import json
 import ckan.plugins as p
 import ckan.plugins.toolkit as toolkit
+from pylons import config
 
 log = getLogger(__name__)
 ignore_empty = p.toolkit.get_validator('ignore_empty')
@@ -12,6 +13,15 @@
 Invalid = p.toolkit.Invalid
 
 
+def get_mapview_config():
+    '''
+    Extracts and returns map view configuration of the reclineview extension.
+    '''
+    namespace = 'ckanext.spatial.common_map.'
+    return dict([(k.replace(namespace, ''), v) for k, v in config.iteritems()
+                 if k.startswith(namespace)])
+
+
 def in_list(list_possible_values):
     '''
     Validator that checks that the input value is one of the given
@@ -77,6 +87,8 @@
     This extension views resources using a Recline MultiView.
     '''
 
+    p.implements(p.ITemplateHelpers, inherit=True)
+
     def info(self):
         return {'name': 'recline_view',
                 'title': 'Data Explorer',
@@ -98,6 +110,11 @@
         else:
             return False
 
+    def get_helpers(self):
+        return {
+            'get_map_config': get_mapview_config
+        }
+
 
 class ReclineGridView(ReclineViewBase):
     '''
@@ -174,6 +191,8 @@
     This extension views resources using a Recline map.
     '''
 
+    p.implements(p.ITemplateHelpers, inherit=True)
+
     map_field_types = [{'value': 'lat_long',
                         'text': 'Latitude / Longitude fields'},
                        {'value': 'geojson', 'text': 'GeoJSON'}]
@@ -234,3 +253,8 @@
 
     def form_template(self, context, data_dict):
         return 'recline_map_form.html'
+
+    def get_helpers(self):
+        return {
+            'get_mapview_config': get_mapview_config
+        }

{"golden_diff": "diff --git a/ckanext/reclineview/plugin.py b/ckanext/reclineview/plugin.py\n--- a/ckanext/reclineview/plugin.py\n+++ b/ckanext/reclineview/plugin.py\n@@ -5,6 +5,7 @@\n from ckan.common import json\n import ckan.plugins as p\n import ckan.plugins.toolkit as toolkit\n+from pylons import config\n \n log = getLogger(__name__)\n ignore_empty = p.toolkit.get_validator('ignore_empty')\n@@ -12,6 +13,15 @@\n Invalid = p.toolkit.Invalid\n \n \n+def get_mapview_config():\n+    '''\n+    Extracts and returns map view configuration of the reclineview extension.\n+    '''\n+    namespace = 'ckanext.spatial.common_map.'\n+    return dict([(k.replace(namespace, ''), v) for k, v in config.iteritems()\n+                 if k.startswith(namespace)])\n+\n+\n def in_list(list_possible_values):\n     '''\n     Validator that checks that the input value is one of the given\n@@ -77,6 +87,8 @@\n     This extension views resources using a Recline MultiView.\n     '''\n \n+    p.implements(p.ITemplateHelpers, inherit=True)\n+\n     def info(self):\n         return {'name': 'recline_view',\n                 'title': 'Data Explorer',\n@@ -98,6 +110,11 @@\n         else:\n             return False\n \n+    def get_helpers(self):\n+        return {\n+            'get_map_config': get_mapview_config\n+        }\n+\n \n class ReclineGridView(ReclineViewBase):\n     '''\n@@ -174,6 +191,8 @@\n     This extension views resources using a Recline map.\n     '''\n \n+    p.implements(p.ITemplateHelpers, inherit=True)\n+\n     map_field_types = [{'value': 'lat_long',\n                         'text': 'Latitude / Longitude fields'},\n                        {'value': 'geojson', 'text': 'GeoJSON'}]\n@@ -234,3 +253,8 @@\n \n     def form_template(self, context, data_dict):\n         return 'recline_map_form.html'\n+\n+    def get_helpers(self):\n+        return {\n+            'get_mapview_config': get_mapview_config\n+        }\n", "issue": "DataStore Map and Explorer not displaying map tiles since 11 July 2016\nDirect tile access to MapQuest maps has been discontinued as of 11 July 2016 and the DataStore Map and Explorer previews no longer display map tiles. \n\nThe issue actually lies with recline.js and it has been logged https://github.com/okfn/recline/issues/500  and there is a referenced patch to replace MapQuest with Open Street Map frodrigo/recline@3df0c2a2bb8897124bdbbca715b2be1fd99cb08f\n\nThought it would be useful to have a record here and request the packaged recline.js should be updated.\n\n", "before_files": [{"content": "# encoding: utf-8\n\nfrom logging import getLogger\n\nfrom ckan.common import json\nimport ckan.plugins as p\nimport ckan.plugins.toolkit as toolkit\n\nlog = getLogger(__name__)\nignore_empty = p.toolkit.get_validator('ignore_empty')\nnatural_number_validator = p.toolkit.get_validator('natural_number_validator')\nInvalid = p.toolkit.Invalid\n\n\ndef in_list(list_possible_values):\n    '''\n    Validator that checks that the input value is one of the given\n    possible values.\n\n    :param list_possible_values: function that returns list of possible values\n        for validated field\n    :type possible_values: function\n    '''\n    def validate(key, data, errors, context):\n        if not data[key] in list_possible_values():\n            raise Invalid('\"{0}\" is not a valid parameter'.format(data[key]))\n    return validate\n\n\ndef datastore_fields(resource, valid_field_types):\n    '''\n    Return a list of all datastore fields for a given resource, as long as\n    the datastore field type is in valid_field_types.\n\n    :param resource: resource dict\n    :type resource: dict\n    :param valid_field_types: field types to include in returned list\n    :type valid_field_types: list of strings\n    '''\n    data = {'resource_id': resource['id'], 'limit': 0}\n    fields = toolkit.get_action('datastore_search')({}, data)['fields']\n    return [{'value': f['id'], 'text': f['id']} for f in fields\n            if f['type'] in valid_field_types]\n\n\nclass ReclineViewBase(p.SingletonPlugin):\n    '''\n    This base class for the Recline view extensions.\n    '''\n    p.implements(p.IConfigurer, inherit=True)\n    p.implements(p.IResourceView, inherit=True)\n\n    def update_config(self, config):\n        '''\n        Set up the resource library, public directory and\n        template directory for the view\n        '''\n        toolkit.add_public_directory(config, 'theme/public')\n        toolkit.add_template_directory(config, 'theme/templates')\n        toolkit.add_resource('theme/public', 'ckanext-reclineview')\n\n    def can_view(self, data_dict):\n        resource = data_dict['resource']\n        return (resource.get('datastore_active') or\n                '_datastore_only_resource' in resource.get('url', ''))\n\n    def setup_template_variables(self, context, data_dict):\n        return {'resource_json': json.dumps(data_dict['resource']),\n                'resource_view_json': json.dumps(data_dict['resource_view'])}\n\n    def view_template(self, context, data_dict):\n        return 'recline_view.html'\n\n\nclass ReclineView(ReclineViewBase):\n    '''\n    This extension views resources using a Recline MultiView.\n    '''\n\n    def info(self):\n        return {'name': 'recline_view',\n                'title': 'Data Explorer',\n                'filterable': True,\n                'icon': 'table',\n                'requires_datastore': False,\n                'default_title': p.toolkit._('Data Explorer'),\n                }\n\n    def can_view(self, data_dict):\n        resource = data_dict['resource']\n\n        if (resource.get('datastore_active') or\n                '_datastore_only_resource' in resource.get('url', '')):\n            return True\n        resource_format = resource.get('format', None)\n        if resource_format:\n            return resource_format.lower() in ['csv', 'xls', 'xlsx', 'tsv']\n        else:\n            return False\n\n\nclass ReclineGridView(ReclineViewBase):\n    '''\n    This extension views resources using a Recline grid.\n    '''\n\n    def info(self):\n        return {'name': 'recline_grid_view',\n                'title': 'Grid',\n                'filterable': True,\n                'icon': 'table',\n                'requires_datastore': True,\n                'default_title': p.toolkit._('Table'),\n                }\n\n\nclass ReclineGraphView(ReclineViewBase):\n    '''\n    This extension views resources using a Recline graph.\n    '''\n\n    graph_types = [{'value': 'lines-and-points',\n                    'text': 'Lines and points'},\n                   {'value': 'lines', 'text': 'Lines'},\n                   {'value': 'points', 'text': 'Points'},\n                   {'value': 'bars', 'text': 'Bars'},\n                   {'value': 'columns', 'text': 'Columns'}]\n\n    datastore_fields = []\n\n    datastore_field_types = ['numeric', 'int4', 'timestamp']\n\n    def list_graph_types(self):\n        return [t['value'] for t in self.graph_types]\n\n    def list_datastore_fields(self):\n        return [t['value'] for t in self.datastore_fields]\n\n    def info(self):\n        # in_list validator here is passed functions because this\n        # method does not know what the possible values of the\n        # datastore fields are (requires a datastore search)\n        schema = {\n            'offset': [ignore_empty, natural_number_validator],\n            'limit': [ignore_empty, natural_number_validator],\n            'graph_type': [ignore_empty, in_list(self.list_graph_types)],\n            'group': [ignore_empty, in_list(self.list_datastore_fields)],\n            'series': [ignore_empty, in_list(self.list_datastore_fields)]\n        }\n        return {'name': 'recline_graph_view',\n                'title': 'Graph',\n                'filterable': True,\n                'icon': 'bar-chart',\n                'requires_datastore': True,\n                'schema': schema,\n                'default_title': p.toolkit._('Graph'),\n                }\n\n    def setup_template_variables(self, context, data_dict):\n        self.datastore_fields = datastore_fields(data_dict['resource'],\n                                                 self.datastore_field_types)\n        vars = ReclineViewBase.setup_template_variables(self, context,\n                                                        data_dict)\n        vars.update({'graph_types': self.graph_types,\n                     'graph_fields': self.datastore_fields})\n        return vars\n\n    def form_template(self, context, data_dict):\n        return 'recline_graph_form.html'\n\n\nclass ReclineMapView(ReclineViewBase):\n    '''\n    This extension views resources using a Recline map.\n    '''\n\n    map_field_types = [{'value': 'lat_long',\n                        'text': 'Latitude / Longitude fields'},\n                       {'value': 'geojson', 'text': 'GeoJSON'}]\n\n    datastore_fields = []\n\n    datastore_field_latlon_types = ['numeric']\n\n    datastore_field_geojson_types = ['text']\n\n    def list_map_field_types(self):\n        return [t['value'] for t in self.map_field_types]\n\n    def list_datastore_fields(self):\n        return [t['value'] for t in self.datastore_fields]\n\n    def info(self):\n        # in_list validator here is passed functions because this\n        # method does not know what the possible values of the\n        # datastore fields are (requires a datastore search)\n        schema = {\n            'offset': [ignore_empty, natural_number_validator],\n            'limit': [ignore_empty, natural_number_validator],\n            'map_field_type': [ignore_empty,\n                               in_list(self.list_map_field_types)],\n            'latitude_field': [ignore_empty,\n                               in_list(self.list_datastore_fields)],\n            'longitude_field': [ignore_empty,\n                                in_list(self.list_datastore_fields)],\n            'geojson_field': [ignore_empty,\n                              in_list(self.list_datastore_fields)],\n            'auto_zoom': [ignore_empty],\n            'cluster_markers': [ignore_empty]\n        }\n        return {'name': 'recline_map_view',\n                'title': 'Map',\n                'schema': schema,\n                'filterable': True,\n                'icon': 'map-marker',\n                'default_title': p.toolkit._('Map'),\n                }\n\n    def setup_template_variables(self, context, data_dict):\n        map_latlon_fields = datastore_fields(\n            data_dict['resource'], self.datastore_field_latlon_types)\n        map_geojson_fields = datastore_fields(\n            data_dict['resource'], self.datastore_field_geojson_types)\n\n        self.datastore_fields = map_latlon_fields + map_geojson_fields\n\n        vars = ReclineViewBase.setup_template_variables(self, context,\n                                                        data_dict)\n        vars.update({'map_field_types': self.map_field_types,\n                     'map_latlon_fields': map_latlon_fields,\n                     'map_geojson_fields': map_geojson_fields\n                     })\n        return vars\n\n    def form_template(self, context, data_dict):\n        return 'recline_map_form.html'\n", "path": "ckanext/reclineview/plugin.py"}], "after_files": [{"content": "# encoding: utf-8\n\nfrom logging import getLogger\n\nfrom ckan.common import json\nimport ckan.plugins as p\nimport ckan.plugins.toolkit as toolkit\nfrom pylons import config\n\nlog = getLogger(__name__)\nignore_empty = p.toolkit.get_validator('ignore_empty')\nnatural_number_validator = p.toolkit.get_validator('natural_number_validator')\nInvalid = p.toolkit.Invalid\n\n\ndef get_mapview_config():\n    '''\n    Extracts and returns map view configuration of the reclineview extension.\n    '''\n    namespace = 'ckanext.spatial.common_map.'\n    return dict([(k.replace(namespace, ''), v) for k, v in config.iteritems()\n                 if k.startswith(namespace)])\n\n\ndef in_list(list_possible_values):\n    '''\n    Validator that checks that the input value is one of the given\n    possible values.\n\n    :param list_possible_values: function that returns list of possible values\n        for validated field\n    :type possible_values: function\n    '''\n    def validate(key, data, errors, context):\n        if not data[key] in list_possible_values():\n            raise Invalid('\"{0}\" is not a valid parameter'.format(data[key]))\n    return validate\n\n\ndef datastore_fields(resource, valid_field_types):\n    '''\n    Return a list of all datastore fields for a given resource, as long as\n    the datastore field type is in valid_field_types.\n\n    :param resource: resource dict\n    :type resource: dict\n    :param valid_field_types: field types to include in returned list\n    :type valid_field_types: list of strings\n    '''\n    data = {'resource_id': resource['id'], 'limit': 0}\n    fields = toolkit.get_action('datastore_search')({}, data)['fields']\n    return [{'value': f['id'], 'text': f['id']} for f in fields\n            if f['type'] in valid_field_types]\n\n\nclass ReclineViewBase(p.SingletonPlugin):\n    '''\n    This base class for the Recline view extensions.\n    '''\n    p.implements(p.IConfigurer, inherit=True)\n    p.implements(p.IResourceView, inherit=True)\n\n    def update_config(self, config):\n        '''\n        Set up the resource library, public directory and\n        template directory for the view\n        '''\n        toolkit.add_public_directory(config, 'theme/public')\n        toolkit.add_template_directory(config, 'theme/templates')\n        toolkit.add_resource('theme/public', 'ckanext-reclineview')\n\n    def can_view(self, data_dict):\n        resource = data_dict['resource']\n        return (resource.get('datastore_active') or\n                '_datastore_only_resource' in resource.get('url', ''))\n\n    def setup_template_variables(self, context, data_dict):\n        return {'resource_json': json.dumps(data_dict['resource']),\n                'resource_view_json': json.dumps(data_dict['resource_view'])}\n\n    def view_template(self, context, data_dict):\n        return 'recline_view.html'\n\n\nclass ReclineView(ReclineViewBase):\n    '''\n    This extension views resources using a Recline MultiView.\n    '''\n\n    p.implements(p.ITemplateHelpers, inherit=True)\n\n    def info(self):\n        return {'name': 'recline_view',\n                'title': 'Data Explorer',\n                'filterable': True,\n                'icon': 'table',\n                'requires_datastore': False,\n                'default_title': p.toolkit._('Data Explorer'),\n                }\n\n    def can_view(self, data_dict):\n        resource = data_dict['resource']\n\n        if (resource.get('datastore_active') or\n                '_datastore_only_resource' in resource.get('url', '')):\n            return True\n        resource_format = resource.get('format', None)\n        if resource_format:\n            return resource_format.lower() in ['csv', 'xls', 'xlsx', 'tsv']\n        else:\n            return False\n\n    def get_helpers(self):\n        return {\n            'get_map_config': get_mapview_config\n        }\n\n\nclass ReclineGridView(ReclineViewBase):\n    '''\n    This extension views resources using a Recline grid.\n    '''\n\n    def info(self):\n        return {'name': 'recline_grid_view',\n                'title': 'Grid',\n                'filterable': True,\n                'icon': 'table',\n                'requires_datastore': True,\n                'default_title': p.toolkit._('Table'),\n                }\n\n\nclass ReclineGraphView(ReclineViewBase):\n    '''\n    This extension views resources using a Recline graph.\n    '''\n\n    graph_types = [{'value': 'lines-and-points',\n                    'text': 'Lines and points'},\n                   {'value': 'lines', 'text': 'Lines'},\n                   {'value': 'points', 'text': 'Points'},\n                   {'value': 'bars', 'text': 'Bars'},\n                   {'value': 'columns', 'text': 'Columns'}]\n\n    datastore_fields = []\n\n    datastore_field_types = ['numeric', 'int4', 'timestamp']\n\n    def list_graph_types(self):\n        return [t['value'] for t in self.graph_types]\n\n    def list_datastore_fields(self):\n        return [t['value'] for t in self.datastore_fields]\n\n    def info(self):\n        # in_list validator here is passed functions because this\n        # method does not know what the possible values of the\n        # datastore fields are (requires a datastore search)\n        schema = {\n            'offset': [ignore_empty, natural_number_validator],\n            'limit': [ignore_empty, natural_number_validator],\n            'graph_type': [ignore_empty, in_list(self.list_graph_types)],\n            'group': [ignore_empty, in_list(self.list_datastore_fields)],\n            'series': [ignore_empty, in_list(self.list_datastore_fields)]\n        }\n        return {'name': 'recline_graph_view',\n                'title': 'Graph',\n                'filterable': True,\n                'icon': 'bar-chart',\n                'requires_datastore': True,\n                'schema': schema,\n                'default_title': p.toolkit._('Graph'),\n                }\n\n    def setup_template_variables(self, context, data_dict):\n        self.datastore_fields = datastore_fields(data_dict['resource'],\n                                                 self.datastore_field_types)\n        vars = ReclineViewBase.setup_template_variables(self, context,\n                                                        data_dict)\n        vars.update({'graph_types': self.graph_types,\n                     'graph_fields': self.datastore_fields})\n        return vars\n\n    def form_template(self, context, data_dict):\n        return 'recline_graph_form.html'\n\n\nclass ReclineMapView(ReclineViewBase):\n    '''\n    This extension views resources using a Recline map.\n    '''\n\n    p.implements(p.ITemplateHelpers, inherit=True)\n\n    map_field_types = [{'value': 'lat_long',\n                        'text': 'Latitude / Longitude fields'},\n                       {'value': 'geojson', 'text': 'GeoJSON'}]\n\n    datastore_fields = []\n\n    datastore_field_latlon_types = ['numeric']\n\n    datastore_field_geojson_types = ['text']\n\n    def list_map_field_types(self):\n        return [t['value'] for t in self.map_field_types]\n\n    def list_datastore_fields(self):\n        return [t['value'] for t in self.datastore_fields]\n\n    def info(self):\n        # in_list validator here is passed functions because this\n        # method does not know what the possible values of the\n        # datastore fields are (requires a datastore search)\n        schema = {\n            'offset': [ignore_empty, natural_number_validator],\n            'limit': [ignore_empty, natural_number_validator],\n            'map_field_type': [ignore_empty,\n                               in_list(self.list_map_field_types)],\n            'latitude_field': [ignore_empty,\n                               in_list(self.list_datastore_fields)],\n            'longitude_field': [ignore_empty,\n                                in_list(self.list_datastore_fields)],\n            'geojson_field': [ignore_empty,\n                              in_list(self.list_datastore_fields)],\n            'auto_zoom': [ignore_empty],\n            'cluster_markers': [ignore_empty]\n        }\n        return {'name': 'recline_map_view',\n                'title': 'Map',\n                'schema': schema,\n                'filterable': True,\n                'icon': 'map-marker',\n                'default_title': p.toolkit._('Map'),\n                }\n\n    def setup_template_variables(self, context, data_dict):\n        map_latlon_fields = datastore_fields(\n            data_dict['resource'], self.datastore_field_latlon_types)\n        map_geojson_fields = datastore_fields(\n            data_dict['resource'], self.datastore_field_geojson_types)\n\n        self.datastore_fields = map_latlon_fields + map_geojson_fields\n\n        vars = ReclineViewBase.setup_template_variables(self, context,\n                                                        data_dict)\n        vars.update({'map_field_types': self.map_field_types,\n                     'map_latlon_fields': map_latlon_fields,\n                     'map_geojson_fields': map_geojson_fields\n                     })\n        return vars\n\n    def form_template(self, context, data_dict):\n        return 'recline_map_form.html'\n\n    def get_helpers(self):\n        return {\n            'get_mapview_config': get_mapview_config\n        }\n", "path": "ckanext/reclineview/plugin.py"}]}