Skip to content
Closed
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
11 changes: 11 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ Use the following settings to authenticate with AliCloud OSS.
# AliCloud access key secret
OSS_ACCESS_KEY_SECRET = <Your Access Key Secret>

Storage settings
=======================

For public or public-read buckets, storage urls will be bucket_name.endpoint/key format

For private buckets, storage urls will be signed url. The expires time can be set by OSS_EXPIRE_TIME as environment variable or as Django settings. The default value for OSS_EXPIRE_TIME is 30 days.

.. code-block:: bash

OSS_EXPIRE_TIME = <Expire Time in Seconds>

File storage settings
=====================

Expand Down
23 changes: 16 additions & 7 deletions django_oss_storage/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@

import oss2.utils
import oss2.exceptions
from oss2 import Auth, Service, Bucket, ObjectIterator
from oss2 import Auth, Service, Bucket, ObjectIterator, BUCKET_ACL_PRIVATE

from .defaults import logger


def _get_config(name):
config = os.environ.get(name, getattr(settings, name, None))
def _get_config(name, default=None):
config = os.environ.get(name, getattr(settings, name, default))
if config is not None:
if isinstance(config, six.string_types):
return config.strip()
Expand Down Expand Up @@ -56,19 +56,20 @@ class OssStorage(Storage):
Aliyun OSS Storage
"""

def __init__(self, access_key_id=None, access_key_secret=None, end_point=None, bucket_name=None):
def __init__(self, access_key_id=None, access_key_secret=None, end_point=None, bucket_name=None, expire_time=None):
self.access_key_id = access_key_id if access_key_id else _get_config('OSS_ACCESS_KEY_ID')
self.access_key_secret = access_key_secret if access_key_secret else _get_config('OSS_ACCESS_KEY_SECRET')
self.end_point = _normalize_endpoint(end_point if end_point else _get_config('OSS_ENDPOINT'))
self.bucket_name = bucket_name if bucket_name else _get_config('OSS_BUCKET_NAME')
self.expire_time = expire_time if expire_time else int(_get_config('OSS_EXPIRE_TIME', default=60*60*24*30))

self.auth = Auth(self.access_key_id, self.access_key_secret)
self.service = Service(self.auth, self.end_point)
self.bucket = Bucket(self.auth, self.end_point, self.bucket_name)

# try to get bucket acl to check bucket exist or not
try:
self.bucket.get_bucket_acl().acl
self.bucket_acl = self.bucket.get_bucket_acl().acl
except oss2.exceptions.NoSuchBucket:
raise SuspiciousOperation("Bucket '%s' does not exist." % self.bucket_name)

Expand All @@ -79,6 +80,9 @@ def _get_key_name(self, name):
input : test.txt
output : media/test.txt
"""
# urljoin won't work if name is absolute path
name = name.lstrip('/')

base_path = force_text(self.location)
final_path = urljoin(base_path + "/", name)
name = os.path.normpath(final_path.lstrip('/'))
Expand Down Expand Up @@ -197,9 +201,14 @@ def listdir(self, name):
logger().debug("files: %s", files)
return dirs, files

def url(self, name, expire):
def url(self, name):
key = self._get_key_name(name)
return self.bucket.sign_url('GET', key, expire)

if self.bucket_acl == BUCKET_ACL_PRIVATE:
return self.bucket.sign_url('GET', key, expires=self.expire_time)

scheme, endpoint = self.end_point.split('//')
return urljoin(scheme + '//' + self.bucket_name + '.' + endpoint, key)

def delete(self, name):
name = self._get_key_name(name)
Expand Down
12 changes: 6 additions & 6 deletions tests/django-oss-storage-test/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,17 @@ def test_save_small_file(self):
with self.save_file():
logging.info("content type: %s", default_storage.content_type("test.txt"))
self.assertEqual(default_storage.open("test.txt").read(), b"test")
self.assertEqual(requests.get(default_storage.url("test.txt", 60)).content, b"test")
self.assertEqual(requests.get(default_storage.url("test.txt")).content, b"test")

def test_save_big_file(self):
with self.save_file(content=b"test" * 1000):
logging.info("content type: %s", default_storage.content_type("test.txt"))
self.assertEqual(default_storage.open("test.txt").read(), b"test" * 1000)
self.assertEqual(requests.get(default_storage.url("test.txt", 60)).content, b"test" * 1000)
self.assertEqual(requests.get(default_storage.url("test.txt")).content, b"test" * 1000)

def test_url(self):
with self.save_file():
url = default_storage.url("test.txt", 100)
url = default_storage.url("test.txt")
logging.info("url: %s", url)
response = requests.get(url)

Expand All @@ -110,7 +110,7 @@ def test_url_cn(self):
logging.info("objname: %s", objname)
with self.save_file(objname, content=u'我的座右铭') as name:
self.assertEqual(name, objname)
url = default_storage.url(objname, 300)
url = default_storage.url(objname)
logging.info("url: %s", url)
response = requests.get(url)
self.assertEqual(response.status_code, 200)
Expand Down Expand Up @@ -229,7 +229,7 @@ def test_overwrite_cn(self):

def test_static_url(self):
with self.save_file(storage=staticfiles_storage):
url = staticfiles_storage.url("test.txt", 60)
url = staticfiles_storage.url("test.txt")
logging.info("url: %s", url)
response = requests.get(url)

Expand All @@ -239,7 +239,7 @@ def test_static_url(self):

def test_configured_url(self):
with self.settings(MEDIA_URL= "/media/"), self.save_file():
url = default_storage.url("test.txt", 60)
url = default_storage.url("test.txt")
logging.info("url: %s", url)
response = requests.get(url)

Expand Down