David Larlet committed 1a955dc

Add an hashpath storage, thanks Axel Gembe

Comments (0)

Files changed (2)

     * 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).


+import os, hashlib, errno
+from django.conf import settings
+from 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 =
+        # 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('\\', '/'))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.