1 import os |
1 import os |
2 import errno |
2 import errno |
3 import urlparse |
3 import urlparse |
|
4 import itertools |
4 |
5 |
5 from django.conf import settings |
6 from django.conf import settings |
6 from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation |
7 from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation |
7 from django.core.files import locks, File |
8 from django.core.files import locks, File |
8 from django.core.files.move import file_move_safe |
9 from django.core.files.move import file_move_safe |
9 from django.utils.encoding import force_unicode, smart_str |
10 from django.utils.encoding import force_unicode |
10 from django.utils.functional import LazyObject |
11 from django.utils.functional import LazyObject |
11 from django.utils.importlib import import_module |
12 from django.utils.importlib import import_module |
12 from django.utils.text import get_valid_filename |
13 from django.utils.text import get_valid_filename |
13 from django.utils._os import safe_join |
14 from django.utils._os import safe_join |
14 |
15 |
63 Returns a filename that's free on the target storage system, and |
64 Returns a filename that's free on the target storage system, and |
64 available for new content to be written to. |
65 available for new content to be written to. |
65 """ |
66 """ |
66 dir_name, file_name = os.path.split(name) |
67 dir_name, file_name = os.path.split(name) |
67 file_root, file_ext = os.path.splitext(file_name) |
68 file_root, file_ext = os.path.splitext(file_name) |
68 # If the filename already exists, keep adding an underscore (before the |
69 # If the filename already exists, add an underscore and a number (before |
69 # file extension, if one exists) to the filename until the generated |
70 # the file extension, if one exists) to the filename until the generated |
70 # filename doesn't exist. |
71 # filename doesn't exist. |
|
72 count = itertools.count(1) |
71 while self.exists(name): |
73 while self.exists(name): |
72 file_root += '_' |
|
73 # file_ext includes the dot. |
74 # file_ext includes the dot. |
74 name = os.path.join(dir_name, file_root + file_ext) |
75 name = os.path.join(dir_name, "%s_%s%s" % (file_root, count.next(), file_ext)) |
|
76 |
75 return name |
77 return name |
76 |
78 |
77 def path(self, name): |
79 def path(self, name): |
78 """ |
80 """ |
79 Returns a local filesystem path where the file can be retrieved using |
81 Returns a local filesystem path where the file can be retrieved using |
115 """ |
117 """ |
116 Returns an absolute URL where the file's contents can be accessed |
118 Returns an absolute URL where the file's contents can be accessed |
117 directly by a web browser. |
119 directly by a web browser. |
118 """ |
120 """ |
119 raise NotImplementedError() |
121 raise NotImplementedError() |
120 |
|
121 # Needed by django.utils.functional.LazyObject (via DefaultStorage). |
|
122 def get_all_members(self): |
|
123 return self.__members__ |
|
124 |
122 |
125 class FileSystemStorage(Storage): |
123 class FileSystemStorage(Storage): |
126 """ |
124 """ |
127 Standard filesystem storage |
125 Standard filesystem storage |
128 """ |
126 """ |
210 def path(self, name): |
208 def path(self, name): |
211 try: |
209 try: |
212 path = safe_join(self.location, name) |
210 path = safe_join(self.location, name) |
213 except ValueError: |
211 except ValueError: |
214 raise SuspiciousOperation("Attempted access to '%s' denied." % name) |
212 raise SuspiciousOperation("Attempted access to '%s' denied." % name) |
215 return smart_str(os.path.normpath(path)) |
213 return os.path.normpath(path) |
216 |
214 |
217 def size(self, name): |
215 def size(self, name): |
218 return os.path.getsize(self.path(name)) |
216 return os.path.getsize(self.path(name)) |
219 |
217 |
220 def url(self, name): |
218 def url(self, name): |