/
files.py
168 lines (116 loc) · 4.28 KB
/
files.py
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
"""File wrappers for use as exchange data between views and responses."""
from django.core.files import File
class StorageFile(File):
"""A file in a Django storage.
This class looks like :py:class:`django.db.models.fields.files.FieldFile`,
but unrelated to model instance.
"""
def __init__(self, storage, name, file=None):
"""Constructor.
storage:
Some :py:class:`django.core.files.storage.Storage` instance.
name:
File identifier in storage, usually a filename as a string.
"""
self.storage = storage
self.name = name
self.file = file
def _get_file(self):
"""Getter for :py:attr:``file`` property."""
if not hasattr(self, '_file') or self._file is None:
self._file = self.storage.open(self.name, 'rb')
return self._file
def _set_file(self, file):
"""Setter for :py:attr:``file`` property."""
self._file = file
def _del_file(self):
"""Deleter for :py:attr:``file`` property."""
del self._file
#: Required by django.core.files.utils.FileProxy.
file = property(_get_file, _set_file, _del_file)
def open(self, mode='rb'):
"""Retrieves the specified file from storage and return open() result.
Proxy to self.storage.open(self.name, mode).
"""
return self.storage.open(self.name, mode)
def save(self, content):
"""Saves new content to the file.
Proxy to self.storage.save(self.name).
The content should be a proper File object, ready to be read from the
beginning.
"""
return self.storage.save(self.name, content)
@property
def path(self):
"""Return a local filesystem path which is suitable for open().
Proxy to self.storage.path(self.name).
May raise NotImplementedError if storage doesn't support file access
with Python's built-in open() function
"""
return self.storage.path(self.name)
def delete(self):
"""Delete the specified file from the storage system.
Proxy to self.storage.delete(self.name).
"""
return self.storage.delete(self.name)
def exists(self):
"""Return True if file already exists in the storage system.
If False, then the name is available for a new file.
"""
return self.storage.exists(self.name)
@property
def size(self):
"""Return the total size, in bytes, of the file.
Proxy to self.storage.size(self.name).
"""
return self.storage.size(self.name)
@property
def url(self):
"""Return an absolute URL where the file's contents can be accessed.
Proxy to self.storage.url(self.name).
"""
return self.storage.url(self.name)
@property
def accessed_time(self):
"""Return the last accessed time (as datetime object) of the file.
Proxy to self.storage.accessed_time(self.name).
"""
return self.storage.accessed(self.name)
@property
def created_time(self):
"""Return the creation time (as datetime object) of the file.
Proxy to self.storage.created_time(self.name).
"""
return self.storage.created_time(self.name)
@property
def modified_time(self):
"""Return the last modification time (as datetime object) of the file.
Proxy to self.storage.modified_time(self.name).
"""
return self.storage.modified_time(self.name)
class VirtualFile(File):
def __init__(self, file=None, name=u'', url='', size=None):
"""Constructor.
file:
File object. Typically a StringIO.
name:
File basename.
url:
File URL.
"""
super(VirtualFile, self).__init__(file, name)
self.url = url
if size is not None:
self._size = size
def _get_size(self):
try:
return self._size
except AttributeError:
try:
self._size = self.file.size
except AttributeError:
self._size = len(self.file.getvalue())
return self._size
def _set_size(self, value):
return super(VirtualFile, self)._set_size(value)
size = property(_get_size, _set_size)