storage.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. from django.conf import settings
  2. from django.core.files.storage import FileSystemStorage as DjangoStorage
  3. from s3sync.utils import (get_pending_key, get_pending_delete_key,
  4. get_s3sync_cache)
  5. deleting_key = get_pending_delete_key()
  6. pending_key = get_pending_key()
  7. cache = get_s3sync_cache()
  8. is_production = getattr(settings, 'PRODUCTION', False)
  9. class S3PendingStorage(DjangoStorage):
  10. """Subclass Django's file system storage to queue new files as pending
  11. to a cache key, for later S3 upload using an s3sync cron."""
  12. def delete(self, name):
  13. """Remove files that were pending, or mark non-pending for deletion."""
  14. super(S3PendingStorage, self).delete(name)
  15. if not is_production:
  16. return
  17. deleting = cache.get(deleting_key, [])
  18. pending = cache.get(pending_key, [])
  19. # File was pending? Ok, remove it from upload queue.
  20. if name in pending:
  21. cache.delete(name)
  22. del pending[pending.index(name)]
  23. else: # otherwise, mark it for deletion
  24. deleting.append(name)
  25. cache.set(deleting_key, deleting)
  26. cache.set(pending_key, pending)
  27. def save(self, name, content):
  28. new_name = super(S3PendingStorage, self).save(name, content)
  29. if not is_production:
  30. return new_name
  31. cache.set(new_name, True)
  32. pending = cache.get(pending_key, [])
  33. if not new_name in pending:
  34. pending.append(new_name)
  35. cache.set(pending_key, pending)
  36. return new_name
  37. def url(self, name):
  38. url = super(S3PendingStorage, self).url(name)
  39. # Is this file pending? Return local URL.
  40. if cache.get(name) or not is_production:
  41. return url
  42. return settings.BUCKET_UPLOADS_URL + name