2021-03-12 11:08:40 +11:00

52 lines
1.6 KiB
Python

from django.core.files.storage import Storage
class MultiStorage(Storage):
''' Django storage class that proxies multiple storage classes.
Uses a name prefix to determine store e.g. 'images:foo/bar.jpg'
'''
def __init__(self, config=None):
self.config = config or getattr(settings, 'BRING_YOUR_OWN_STORAGE', {})
self._cache = {}
def get_storage(self, name):
if name not in self._cache:
config = self.config[name]
self._cache[name] = get_storage_class(config['storage'])(**config['settings'])
return self._cache[name]
def split(self, name):
return name.split(":", 1)
def _open(self, name, mode='rb'):
storage, p = self.split(name)
return self.get_storage(storage)._open(p, mode)
def _proxy(self, method, name, *args, **kwargs):
storage, p = self.split(name)
sname = getattr(self.get_storage(storage), method)(name, *args, **kwargs)
if sname is not None:
return f"{storage}:{sname}"
def _save(self, name, content, max_length=None):
return self._proxy('save', name, content, max_length)
class BYOStorage(MultiStorage):
''' Database driven Bring-Your-Own-Storage
Multiple storages can
'''
def get_storage(self, name):
if name not in self._cache:
# use storage from config by default
if name in self.config:
return super(BYOStorage, self).get_storage(name)
from .models import UserStorage
obj = UserStorage.objects.get(name=name)
self._cache[name] = obj.instance()
return self._cache[name]