diff options
| author | Yuval Adam <yuval@segmanta.com> | 2014-03-20 17:49:16 +0200 |
|---|---|---|
| committer | Yuval Adam <yuval@segmanta.com> | 2014-03-20 17:49:16 +0200 |
| commit | 75f93a3f7854a7383febd047391e2bfd4caceee0 (patch) | |
| tree | d5e634ef292c6b84acacc3982dbcaa0d300a346e /storages/backends/hashpath.py | |
Diffstat (limited to 'storages/backends/hashpath.py')
| -rw-r--r-- | storages/backends/hashpath.py | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/storages/backends/hashpath.py b/storages/backends/hashpath.py new file mode 100644 index 0000000..7603604 --- /dev/null +++ b/storages/backends/hashpath.py @@ -0,0 +1,40 @@ +import os, hashlib, errno + +from django.core.files.storage import FileSystemStorage +from django.utils.encoding import force_unicode + +class HashPathStorage(FileSystemStorage): + """ + Creates a hash from the uploaded file to build the path. + """ + + def save(self, name, content): + # Get the content name if name is not given + if name is None: name = content.name + + # Get the SHA1 hash of the uploaded file + sha1 = hashlib.sha1() + for chunk in content.chunks(): + sha1.update(chunk) + sha1sum = sha1.hexdigest() + + # Build the new path and split it into directory and filename + name = os.path.join(os.path.split(name)[0], sha1sum[:1], sha1sum[1:2], sha1sum) + dir_name, file_name = os.path.split(name) + + # Return the name if the file is already there + if self.exists(name): + return name + + # Try to create the directory relative to location specified in __init__ + try: + os.makedirs(os.path.join(self.location, dir_name)) + except OSError as e: + if e.errno is not errno.EEXIST: + raise e + + # Save the file + name = self._save(name, content) + + # Store filenames with forward slashes, even on Windows + return force_unicode(name.replace('\\', '/')) |
