Skip to content
Browse files

Add an hashpath storage, thanks Axel Gembe

  • Loading branch information...
1 parent 4aa4acc commit 668a20945ce95fd2cc10fc2612499b4f7a84ca70 @davidbgk davidbgk committed Apr 28, 2010
Showing with 43 additions and 1 deletion.
  1. +2 −1 AUTHORS
  2. +41 −0 storages/backends/hashpath.py
View
3 AUTHORS
@@ -15,8 +15,9 @@ By order of apparition, thanks:
* Jason Christa (patches)
* Adam Nelson (patches)
* Erik CW (S3 encryption)
+ * Axel Gembe (Hash path)
-Extra thanks to Marty for adding this in Django,
+Extra thanks to Marty for adding this in Django,
you can buy his very interesting book (Pro Django).
View
41 storages/backends/hashpath.py
@@ -0,0 +1,41 @@
+import os, hashlib, errno
+
+from django.conf import settings
+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 os.path.exists(name):
+ return name
+
+ # Try to create the directory relative to the media root
+ try:
+ os.makedirs(os.path.join(settings.MEDIA_ROOT, 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('\\', '/'))

0 comments on commit 668a209

Please sign in to comment.
Something went wrong with that request. Please try again.