Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions ckanext/cloudstorage/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
from pylons import c
from pylons.i18n import _

from ckan.common import request, response
from ckan import logic, model
from ckan.lib import base, uploader
import ckan.lib.helpers as h

import ckanext.cloudstorage.storage as _storage
storage = _storage.CloudStorage
is_proxy_download=storage.proxy_download.fget(storage)

class StorageController(base.BaseController):
def resource_download(self, id, resource_id, filename=None):
Expand Down Expand Up @@ -48,12 +52,28 @@ def resource_download(self, id, resource_id, filename=None):
# if the client requests with a Content-Type header (e.g. Text preview)
# we have to add the header to the signature
try:
content_type = getattr(c.pylons.request, "content_type", None)
content_type = getattr(request, "content_type", None)
except AttributeError:
content_type = None
uploaded_url = upload.get_url_from_filename(resource['id'], filename,
content_type=content_type)

# If the repository is private you may want to use ckan accout to proxy
# protected contents
# ckanext.cloudstorage.proxy_download = [False|True]
# Default: False
if is_proxy_download:
# remote object
obj = upload.get_object(resource['id'],filename)
# metaadta
extra = obj.extra
if extra:
# let's leverage on external mimetype if present
response.headers['Content-Type'] = extra.get('content_type',content_type)
# return stream back
return upload.get_object_as_stream(obj)

uploaded_url = upload.get_url_from_filename(resource['id'], filename,
content_type=content_type)

# The uploaded file is missing for some reason, such as the
# provider being down.
if uploaded_url is None:
Expand Down
22 changes: 20 additions & 2 deletions ckanext/cloudstorage/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,16 @@ def guess_mimetype(self):
return p.toolkit.asbool(
config.get('ckanext.cloudstorage.guess_mimetype', False)
)


@property
def proxy_download(self):
"""
If the ckan may stream the object (will use service account to download
from private storages)
"""
return p.toolkit.asbool(
config.get('ckanext.cloudstorage.proxy_download', False)
)

class ResourceCloudStorage(CloudStorage):
def __init__(self, resource):
Expand Down Expand Up @@ -244,7 +253,7 @@ def upload(self, id, max_size=10):
content_settings=content_settings
)
else:

# TODO: This might not be needed once libcloud is upgraded
if isinstance(self.file_upload, SpooledTemporaryFile):
self.file_upload.next = self.file_upload.next()
Expand Down Expand Up @@ -354,6 +363,15 @@ def get_url_from_filename(self, rid, filename, content_type=None):
return obj.extra['url']
raise

def get_object(self, rid, filename):
# Find the key the file *should* be stored at.
path = self.path_from_filename(rid, filename)
# Find the object for the given key.
return self.container.get_object(path)

def get_object_as_stream(self, obj):
return self.driver.download_object_as_stream(obj)

@property
def package(self):
return model.Package.get(self.resource['package_id'])