~ubuntu-branches/debian/sid/python-django/sid

« back to all changes in this revision

Viewing changes to django/core/files/storage.py

  • Committer: Package Import Robot
  • Author(s): Raphaël Hertzog
  • Date: 2014-09-17 14:15:11 UTC
  • mfrom: (1.3.17) (6.2.18 experimental)
  • Revision ID: package-import@ubuntu.com-20140917141511-icneokthe9ww5sk4
Tags: 1.7-2
* Release to unstable.
* Add a migrate-south sample script to help users apply their South
  migrations. Thanks to Brian May.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
from django.utils.crypto import get_random_string
10
10
from django.utils.encoding import force_text, filepath_to_uri
11
11
from django.utils.functional import LazyObject
12
 
from django.utils.module_loading import import_by_path
 
12
from django.utils.module_loading import import_string
13
13
from django.utils.six.moves.urllib.parse import urljoin
14
14
from django.utils.text import get_valid_filename
15
15
from django.utils._os import safe_join, abspathu
 
16
from django.utils.deconstruct import deconstructible
16
17
 
17
18
 
18
19
__all__ = ('Storage', 'FileSystemStorage', 'DefaultStorage', 'default_storage')
19
20
 
 
21
 
20
22
class Storage(object):
21
23
    """
22
24
    A base storage class, providing some default behaviors that all other
91
93
        """
92
94
        Deletes the specified file from the storage system.
93
95
        """
94
 
        raise NotImplementedError()
 
96
        raise NotImplementedError('subclasses of Storage must provide a delete() method')
95
97
 
96
98
    def exists(self, name):
97
99
        """
98
 
        Returns True if a file referened by the given name already exists in the
 
100
        Returns True if a file referenced by the given name already exists in the
99
101
        storage system, or False if the name is available for a new file.
100
102
        """
101
 
        raise NotImplementedError()
 
103
        raise NotImplementedError('subclasses of Storage must provide an exists() method')
102
104
 
103
105
    def listdir(self, path):
104
106
        """
105
107
        Lists the contents of the specified path, returning a 2-tuple of lists;
106
108
        the first item being directories, the second item being files.
107
109
        """
108
 
        raise NotImplementedError()
 
110
        raise NotImplementedError('subclasses of Storage must provide a listdir() method')
109
111
 
110
112
    def size(self, name):
111
113
        """
112
114
        Returns the total size, in bytes, of the file specified by name.
113
115
        """
114
 
        raise NotImplementedError()
 
116
        raise NotImplementedError('subclasses of Storage must provide a size() method')
115
117
 
116
118
    def url(self, name):
117
119
        """
118
120
        Returns an absolute URL where the file's contents can be accessed
119
121
        directly by a Web browser.
120
122
        """
121
 
        raise NotImplementedError()
 
123
        raise NotImplementedError('subclasses of Storage must provide a url() method')
122
124
 
123
125
    def accessed_time(self, name):
124
126
        """
125
127
        Returns the last accessed time (as datetime object) of the file
126
128
        specified by name.
127
129
        """
128
 
        raise NotImplementedError()
 
130
        raise NotImplementedError('subclasses of Storage must provide an accessed_time() method')
129
131
 
130
132
    def created_time(self, name):
131
133
        """
132
134
        Returns the creation time (as datetime object) of the file
133
135
        specified by name.
134
136
        """
135
 
        raise NotImplementedError()
 
137
        raise NotImplementedError('subclasses of Storage must provide a created_time() method')
136
138
 
137
139
    def modified_time(self, name):
138
140
        """
139
141
        Returns the last modified time (as datetime object) of the file
140
142
        specified by name.
141
143
        """
142
 
        raise NotImplementedError()
143
 
 
 
144
        raise NotImplementedError('subclasses of Storage must provide a modified_time() method')
 
145
 
 
146
 
 
147
@deconstructible
144
148
class FileSystemStorage(Storage):
145
149
    """
146
150
    Standard filesystem storage
147
151
    """
148
152
 
149
 
    def __init__(self, location=None, base_url=None):
 
153
    def __init__(self, location=None, base_url=None, file_permissions_mode=None,
 
154
            directory_permissions_mode=None):
150
155
        if location is None:
151
156
            location = settings.MEDIA_ROOT
152
157
        self.base_location = location
154
159
        if base_url is None:
155
160
            base_url = settings.MEDIA_URL
156
161
        self.base_url = base_url
 
162
        self.file_permissions_mode = (
 
163
            file_permissions_mode if file_permissions_mode is not None
 
164
            else settings.FILE_UPLOAD_PERMISSIONS
 
165
        )
 
166
        self.directory_permissions_mode = (
 
167
            directory_permissions_mode if directory_permissions_mode is not None
 
168
            else settings.FILE_UPLOAD_DIRECTORY_PERMISSIONS
 
169
        )
157
170
 
158
171
    def _open(self, name, mode='rb'):
159
172
        return File(open(self.path(name), mode))
168
181
        directory = os.path.dirname(full_path)
169
182
        if not os.path.exists(directory):
170
183
            try:
171
 
                os.makedirs(directory)
 
184
                if self.directory_permissions_mode is not None:
 
185
                    # os.makedirs applies the global umask, so we reset it,
 
186
                    # for consistency with file_permissions_mode behavior.
 
187
                    old_umask = os.umask(0)
 
188
                    try:
 
189
                        os.makedirs(directory, self.directory_permissions_mode)
 
190
                    finally:
 
191
                        os.umask(old_umask)
 
192
                else:
 
193
                    os.makedirs(directory)
172
194
            except OSError as e:
173
195
                if e.errno != errno.EEXIST:
174
196
                    raise
186
208
                # This file has a file path that we can move.
187
209
                if hasattr(content, 'temporary_file_path'):
188
210
                    file_move_safe(content.temporary_file_path(), full_path)
189
 
                    content.close()
190
211
 
191
212
                # This is a normal uploadedfile that we can stream.
192
213
                else:
221
242
                # OK, the file save worked. Break out of the loop.
222
243
                break
223
244
 
224
 
        if settings.FILE_UPLOAD_PERMISSIONS is not None:
225
 
            os.chmod(full_path, settings.FILE_UPLOAD_PERMISSIONS)
 
245
        if self.file_permissions_mode is not None:
 
246
            os.chmod(full_path, self.file_permissions_mode)
226
247
 
227
248
        return name
228
249
 
277
298
    def modified_time(self, name):
278
299
        return datetime.fromtimestamp(os.path.getmtime(self.path(name)))
279
300
 
 
301
 
280
302
def get_storage_class(import_path=None):
281
 
    return import_by_path(import_path or settings.DEFAULT_FILE_STORAGE)
 
303
    return import_string(import_path or settings.DEFAULT_FILE_STORAGE)
 
304
 
282
305
 
283
306
class DefaultStorage(LazyObject):
284
307
    def _setup(self):