use sha1 names for image storage
authorTero Marttila <terom@fixme.fi>
Thu, 15 Aug 2013 01:29:43 +0300
changeset 41 4d38296d58a3
parent 40 5eefe5a294dc
child 42 e4f6ea904257
use sha1 names for image storage
qrurls/models.py
--- a/qrurls/models.py	Thu Aug 15 01:16:10 2013 +0300
+++ b/qrurls/models.py	Thu Aug 15 01:29:43 2013 +0300
@@ -1,12 +1,45 @@
 import datetime
+import hashlib
+import os.path
 
 from django.db import models
+import django.core.files.storage
 from django.core.urlresolvers import reverse
 import django.utils.http
 from django.contrib.sites.models import get_current_site
 from django.utils import timezone
 
 QRCODE_API = 'https://chart.googleapis.com/chart?cht=qr&chs={width}x{height}&chl={url}&chld=H'
+IMAGES_MEDIA = 'qrurls-images'
+
+class SecretFileSystemStorage (django.core.files.storage.FileSystemStorage) :
+    """
+        Store files named by a sha1 hash of their contents.
+    """
+
+    HASH = hashlib.sha1
+    
+    def _hash (self, content) :
+        """Compute hash for given UploadedFile (as a hex string)."""
+        hash = self.HASH()
+
+        for chunk in content.chunks() :
+            hash.update(chunk)
+
+        return hash.hexdigest()
+    
+    def save (self, name, content) :
+        # Get the proper name for the file, as it will actually be saved.
+        if name is None:
+            name = content.name
+        
+        dirname, filename = os.path.split(name)
+        basename, fileext = os.path.splitext(filename)
+        
+        # hash
+        name = "%s/%s%s" % (dirname, self._hash(content), fileext)
+
+        return super(SecretFileSystemStorage, self).save(name, content)
 
 class URL(models.Model):
     shorturl = models.SlugField(unique=True)
@@ -64,7 +97,7 @@
         return self.shorturl
 
 class URLImage(models.Model):
-    image = models.ImageField(upload_to='qrurls-images')
+    image = models.ImageField(upload_to=IMAGES_MEDIA, storage=SecretFileSystemStorage())
     title = models.CharField(max_length=1024)
     uploaded = models.DateTimeField(auto_now_add=True)