Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added code and license and content to the readme

  • Loading branch information...
commit 839908d045d366b46d7aba45b4e5ba042d9aa297 1 parent b2d52a4
@seanbrant seanbrant authored
View
28 LICENSE.txt
@@ -0,0 +1,28 @@
+Copyright (c) 2010, Sean Brant
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of the author nor the names of other
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
View
0  queued_storage/__init__.py
No changes.
View
68 queued_storage/backend.py
@@ -0,0 +1,68 @@
+import urllib
+
+from django.core.cache import cache
+from django.core.files.storage import get_storage_class, Storage
+
+from bishop.storages.tasks import SaveToRemoteTask
+
+QUEUED_REMOTE_STORAGE_CACHE_KEY_PREFIX = 'queued_remote_storage_'
+
+class QueuedRemoteStorage(Storage):
+ def __init__(self, local, remote, cache_prefix=QUEDED_REMOTE_STORAGE_CACHE_KEY_PREFIX):
+ self.local_class = local
+ self.local = get_storage_class(self.local_class)()
+ self.remote_class = remote
+ self.remote = get_storage_class(self.remote_class)()
+ self.cache_prefix = cache_prefix
+
+ def get_storage(self, name):
+ cache_result = cache.get(self.get_cache_key(name))
+ if cache_result:
+ return self.remote
+ elif cache_result is None:
+ if self.remote.exists(name):
+ cache.set(self.get_cache_key(name), True)
+ return self.remote
+ return self.local
+
+ def get_cache_key(self, name):
+ return '%s%s' % (self.cache_prefix, urllib.quote(name))
+
+ def using_local(self, name):
+ return self.get_storage(name) is self.local
+
+ def using_remote(self, name):
+ return self.get_storage(name) is self.remote
+
+ def open(self, name, **kwargs):
+ return self.local.open(name, **kwargs)
+
+ def save(self, name, content):
+ cache.set(self.get_cache_key(name), False)
+ name = self.local.save(name, content)
+ SaveToRemoteTask.delay(name, self.local_class, self.remote_class, self.get_cache_key(name))
+ return name
+
+ def get_valid_name(self, name):
+ return self.get_storage(name).get_valid_name(name)
+
+ def get_available_name(self, name):
+ return self.get_storage(name).get_available_name(name)
+
+ def path(self, name):
+ return self.get_storage(name).path(name)
+
+ def delete(self, name):
+ return self.get_storage(name).delete(name)
+
+ def exists(self, name):
+ return self.get_storage(name).exists(name)
+
+ def listdir(self, name):
+ return self.get_storage(name).listdir(name)
+
+ def size(self, name):
+ return self.get_storage(name).size(name)
+
+ def url(self, name):
+ return self.get_storage(name).url(name)
View
3  queued_storage/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
View
15 queued_storage/tasks.py
@@ -0,0 +1,15 @@
+from django.core.cache import cache
+from django.core.files.storage import get_storage_class
+
+from celery.registry import tasks
+from celery.task import Task
+
+class SaveToRemoteTask(Task):
+ def run(self, name, local, remote, cache_key):
+ local_storage = get_storage_class(local)()
+ remote_storage = get_storage_class(remote)()
+ remote_storage.save(name, local_storage.open(name))
+ cache.set(cache_key, True)
+ return True
+
+tasks.register(SaveToRemoteTask)
View
23 queued_storage/tests.py
@@ -0,0 +1,23 @@
+"""
+This file demonstrates two different styles of tests (one doctest and one
+unittest). These will both pass when you run "manage.py test".
+
+Replace these with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+class SimpleTest(TestCase):
+ def test_basic_addition(self):
+ """
+ Tests that 1 + 1 always equals 2.
+ """
+ self.failUnlessEqual(1 + 1, 2)
+
+__test__ = {"doctest": """
+Another way to test that 1 + 1 is equal to 2.
+
+>>> 1 + 1 == 2
+True
+"""}
+
View
1  queued_storage/views.py
@@ -0,0 +1 @@
+# Create your views here.
Please sign in to comment.
Something went wrong with that request. Please try again.