diff --git a/ckan/config/routing.py b/ckan/config/routing.py index 84010d238a3..3890032817f 100644 --- a/ckan/config/routing.py +++ b/ckan/config/routing.py @@ -141,7 +141,12 @@ def make_map(): action='read', url='', conditions=GET) m.connect('datastore_write', '/api/data/{id}{url:(/.*)?}', action='write', url='', conditions=PUT_POST_DELETE) - + m.connect('datastore_read_shortcut', + '/dataset/{dataset}/resource/{id}/api{url:(/.*)?}', + action='read', url='', conditions=GET) + m.connect('datastore_write_shortcut', + '/dataset/{dataset}/resource/{id}/api{url:(/.*)?}', + action='write', url='', conditions=PUT_POST_DELETE) map.redirect('/packages', '/dataset') map.redirect('/packages/{url:.*}', '/dataset/{url}') @@ -188,8 +193,14 @@ def make_map(): ) m.connect('/dataset/{id}.{format}', action='read') m.connect('/dataset/{id}', action='read') - m.connect('/dataset/{id}/resource/{resource_id}', action='resource_read') - m.connect('/dataset/{id}/resource/{resource_id}/embed', action='resource_embedded_dataviewer') + m.connect('/dataset/{id}/resource/{resource_id}', + action='resource_read') + m.connect('/dataset/{id}/resource/{resource_id}/download', + action='resource_download') + m.connect('/dataset/{id}/resource/{resource_id}/embed', + action='resource_embedded_dataviewer') + m.connect('/dataset/{id}/resource/{resource_id}/viewer', + action='resource_embedded_dataviewer', width="960", height="800") # group map.redirect('/groups', '/group') diff --git a/ckan/controllers/package.py b/ckan/controllers/package.py index 6e84d5edf2d..59a5e9b4942 100644 --- a/ckan/controllers/package.py +++ b/ckan/controllers/package.py @@ -767,6 +767,26 @@ def resource_read(self, id, resource_id): self._setup_follow_button(context) return render('package/resource_read.html') + def resource_download(self, id, resource_id): + """ + Provides a direct download by redirecting the user to the url stored + against this resource. + """ + context = {'model': model, 'session': model.Session, + 'user': c.user or c.author} + + try: + rsc = get_action('resource_show')(context, {'id': resource_id}) + pkg = get_action('package_show')(context, {'id': id}) + except NotFound: + abort(404, _('Resource not found')) + except NotAuthorized: + abort(401, _('Unauthorized to read resource %s') % id) + + if not 'url' in rsc: + abort(404, _('No download is available')) + redirect( rsc['url'] ) + def followers(self, id=None): context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'for_view': True} @@ -787,9 +807,12 @@ def followers(self, id=None): return render('package/followers.html') - def resource_embedded_dataviewer(self, id, resource_id): + def resource_embedded_dataviewer(self, id, resource_id, + width=500, height=500): """ - Embeded page for a read-only resource dataview. + Embeded page for a read-only resource dataview. Allows + for width and height to be specified as part of the + querystring (as well as accepting them via routes). """ context = {'model': model, 'session': model.Session, 'user': c.user or c.author} @@ -816,8 +839,8 @@ def resource_embedded_dataviewer(self, id, resource_id): c.recline_state = json.dumps(recline_state) - c.width = max(int(request.params.get('width', 500)), 100) - c.height = max(int(request.params.get('height', 500)), 100) + c.width = max(int(request.params.get('width', width)), 100) + c.height = max(int(request.params.get('height', height)), 100) c.embedded = True return render('package/resource_embedded_dataviewer.html')