Commit 9a59de52 authored by chris's avatar chris
Browse files

Modified the default behavior to automatically export files from the

database if they don't exist on the filesystem.
parent 740b182a
......@@ -9,6 +9,8 @@ from django.core.urlresolvers import reverse
from database_files import models
from database_files import utils
AUTO_EXPORT_DB_TO_FS = getattr(settings, 'DB_FILES_AUTO_EXPORT_DB_TO_FS', True)
class DatabaseStorage(FileSystemStorage):
def _generate_name(self, name, pk):
......@@ -29,6 +31,15 @@ class DatabaseStorage(FileSystemStorage):
f = models.File.objects.get_from_name(name)
content = f.content
size = f.size
if AUTO_EXPORT_DB_TO_FS \
and not utils.is_fresh(f.name, f.content_hash):
# Automatically write the file to the filesystem
# if it's missing and exists in the database.
# This happens if we're using multiple web servers connected
# to a common databaes behind a load balancer.
# One user might upload a file from one web server, and then
# another might access if from another server.
utils.write_file(f.name, f.content)
except models.File.DoesNotExist:
# If not yet in the database, check the local file system
# and load it into the database if present.
......
......@@ -21,10 +21,11 @@ class DatabaseFilesTestCase(TestCase):
media_dir = os.path.join(DIR,'media/i/special')
if not os.path.isdir(media_dir):
os.makedirs(media_dir)
fqfn = os.path.join(media_dir,'test.txt')
open(fqfn,'w').write('hello there')
o = Thing()
o.upload = 'i/special/test.txt'
test_fqfn = os.path.join(media_dir,'test.txt')
open(test_fqfn,'w').write('hello there')
o1 = o = Thing()
test_fn = 'i/special/test.txt'
o.upload = test_fn
o.save()
id = o.id
......@@ -32,7 +33,7 @@ class DatabaseFilesTestCase(TestCase):
Thing.objects.update()
q = Thing.objects.all()
self.assertEqual(q.count(), 1)
self.assertEqual(q[0].upload.name, 'i/special/test.txt')
self.assertEqual(q[0].upload.name, test_fn)
# Confirm the file only exists on the file system
# and hasn't been loaded into the database.
......@@ -68,6 +69,14 @@ class DatabaseFilesTestCase(TestCase):
t.upload.delete()
self.assertEqual(File.objects.count(), 1)
# Delete file from local filesystem and re-export it from the database.
self.assertEqual(os.path.isfile(test_fqfn), True)
os.remove(test_fqfn)
self.assertEqual(os.path.isfile(test_fqfn), False)
o1.upload.read() # This forces the re-export to the filesystem.
self.assertEqual(os.path.isfile(test_fqfn), True)
# This dumps all files to the filesystem.
File.dump_files()
# Confirm when delete a file from the database, we also delete it from
......@@ -75,7 +84,7 @@ class DatabaseFilesTestCase(TestCase):
self.assertEqual(default_storage.exists('i/special/test.txt'), True)
default_storage.delete('i/special/test.txt')
self.assertEqual(default_storage.exists('i/special/test.txt'), False)
self.assertEqual(os.path.isfile(fqfn), False)
self.assertEqual(os.path.isfile(test_fqfn), False)
def test_hash(self):
verbose = 0
......
......@@ -18,6 +18,12 @@ def is_fresh(name, content_hash):
if not content_hash:
return False
# Check that the actual file exists.
fqfn = os.path.join(settings.MEDIA_ROOT, name)
fqfn = os.path.normpath(fqfn)
if not os.path.isfile(fqfn):
return False
# Check for cached hash file.
hash_fn = get_hash_fn(name)
if os.path.isfile(hash_fn):
......
......@@ -23,7 +23,7 @@ class TestCommand(Command):
pass
def run(self):
os.system('django-admin.py test --pythonpath=. --settings=database_files.tests.settings tests')
#os.system('django-admin.py test --pythonpath=. --settings=database_files.tests.settings tests.DatabaseFilesTestCase.test_hash')
#os.system('django-admin.py test --pythonpath=. --settings=database_files.tests.settings tests.DatabaseFilesTestCase.test_adding_file')
setup(
name='django-database-files',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment