1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 | from django.core.files.storage import FileSystemStorage
from django.core.files.storage import Storage
from django.conf import settings
from django.core.files import locks, File
import hashlib
import os
import errno
# A handy base-conversion thingie
from base_n_utils import base_n_encode
class OverwritingStorage(FileSystemStorage):
"""
FileSystemStorage that allows overwriting files
"""
def get_available_name(self, name):
return name
def _save(self, name, content):
"""
lifted from django/core/files/storage.py
"""
full_path = self.path(name)
directory = os.path.dirname(full_path)
if not os.path.exists(directory):
os.makedirs(directory)
elif not os.path.isdir(directory):
raise IOError("%s exists and is not a directory." % directory)
# This file has a file path that we can move.
if hasattr(content, 'temporary_file_path'):
file_move_safe(content.temporary_file_path(), full_path)
content.close()
# This is a normal uploadedfile that we can stream.
else:
# This fun binary flag incantation makes os.open throw an
# OSError if the file already exists before we open it.
try:
fd = os.open(full_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0))
locks.lock(fd, locks.LOCK_EX)
for chunk in content.chunks():
os.write(fd, chunk)
locks.unlock(fd)
os.close(fd)
except OSError, e:
if e.errno != errno.EEXIST:
raise
else:
# TODO: Should check if files are identical and shout if they are not
pass
if settings.FILE_UPLOAD_PERMISSIONS is not None:
os.chmod(full_path, settings.FILE_UPLOAD_PERMISSIONS)
return name
def delete(self, name):
"""
Never deletes anything
TODO: Could conceivably check if any ImageFields in the application are pointing to it
"""
pass
@classmethod
def hashed_path(cls, image):
m = hashlib.md5()
m.update(image.read())
num = int(m.hexdigest(), 16)
md5_36 = base_n_encode(num, '0123456789abcdefghijklmnopqrstuvwxyz')
pathname = settings.MEDIA_ROOT + '/images/' + md5_36[:2] + '/' + md5_36[2:4] + '/' + md5_36[4:6] + '/' + md5_36 + '.jpg'
return pathname
|
Comments
Warning: this doesn't actually to work… If the file already exists, an
OSErrorEEXISTwill be raised, which is explicitly ignored.Also, if a
savefails, the old file will be overwritten.I have fixed these two issues in my version: http://djangosnippets.org/snippets/2173/.
#