forked from sehmaschine/django-filebrowser
-
Notifications
You must be signed in to change notification settings - Fork 95
/
Copy pathstorage.py
176 lines (131 loc) · 5.35 KB
/
storage.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
169
170
171
172
173
174
175
176
# coding: utf-8
import os
import shutil
from django.core.files.move import file_move_safe
from django.utils.encoding import smart_str
from filebrowser.base import FileObject
from filebrowser.settings import DEFAULT_PERMISSIONS
class StorageMixin(object):
"""
Adds some useful methods to the Storage class.
"""
def isdir(self, name):
"""
Returns true if name exists and is a directory.
"""
raise NotImplementedError()
def isfile(self, name):
"""
Returns true if name exists and is a regular file.
"""
raise NotImplementedError()
def move(self, old_file_name, new_file_name, allow_overwrite=False):
"""
Moves safely a file from one location to another.
If allow_ovewrite==False and new_file_name exists, raises an exception.
"""
raise NotImplementedError()
def makedirs(self, name):
"""
Creates all missing directories specified by name. Analogue to os.mkdirs().
"""
raise NotImplementedError()
def rmtree(self, name):
"""
Deletes a directory and everything it contains. Analogue to shutil.rmtree().
"""
raise NotImplementedError()
def setpermission(self, name):
"""
Sets file permission
"""
raise NotImplementedError()
class FileSystemStorageMixin(StorageMixin):
def isdir(self, name):
return os.path.isdir(self.path(name))
def isfile(self, name):
return os.path.isfile(self.path(name))
def move(self, old_file_name, new_file_name, allow_overwrite=False):
file_move_safe(self.path(old_file_name), self.path(new_file_name), allow_overwrite=True)
def makedirs(self, name):
os.makedirs(self.path(name))
def rmtree(self, name):
shutil.rmtree(self.path(name))
def setpermission(self, name):
full_path = FileObject(smart_str(name), site=self).path_full
os.chmod(full_path, DEFAULT_PERMISSIONS)
class S3BotoStorageMixin(StorageMixin):
def isfile(self, name):
return self.exists(name)
def isdir(self, name):
# That's some inefficient implementation...
# If there are some files having 'name' as their prefix, then
# the name is considered to be a directory
if not name: # Empty name is a directory
return True
if self.isfile(name):
return False
name = self._normalize_name(self._clean_name(name))
dirlist = self.bucket.list(self._encode_name(name))
# Check whether the iterator is empty
for item in dirlist:
return True
return False
def move(self, old_file_name, new_file_name, allow_overwrite=False):
if self.exists(new_file_name):
if allow_overwrite:
self.delete(new_file_name)
else:
raise "The destination file '%s' exists and allow_overwrite is False" % new_file_name
old_key_name = self._encode_name(self._normalize_name(self._clean_name(old_file_name)))
new_key_name = self._encode_name(self._normalize_name(self._clean_name(new_file_name)))
k = self.bucket.copy_key(new_key_name, self.bucket.name, old_key_name)
if not k:
raise "Couldn't copy '%s' to '%s'" % (old_file_name, new_file_name)
self.delete(old_file_name)
def makedirs(self, name):
pass
def rmtree(self, name):
name = self._normalize_name(self._clean_name(name))
dirlist = self.bucket.list(self._encode_name(name))
for item in dirlist:
item.delete()
def setpermission(self, name):
# Permissions for S3 uploads with django-storages
# is set in settings.py with AWS_DEFAULT_ACL.
# More info: http://django-common-configs.readthedocs.org/en/latest/configs/storage.html
pass
class DropBoxStorageMixin(StorageMixin):
def isdir(self, name):
# NOTE: We are importing inside the function to not to require
# the dropbox library if DropBoxStorageMixin is not used
# This could changed if storage module is broken down
# into one module for each storage Mixin?
from dropbox.exceptions import ApiError
from dropbox.files import FileMetadata, FolderMetadata
try:
metadata = self.client.files_get_metadata(self._full_path(name))
return isinstance(metadata, FolderMetadata)
except ApiError:
return False
def isfile(self, name):
from dropbox.exceptions import ApiError
from dropbox.files import FileMetadata, FolderMetadata
try:
metadata = self.client.files_get_metadata(self._full_path(name))
return isinstance(metadata, FileMetadata)
except ApiError:
return False
def move(self, old_file_name, new_file_name, allow_overwrite=False):
if self.exists(new_file_name):
if allow_overwrite:
self.delete(new_file_name)
else:
raise "The destination file '%s' exists and allow_overwrite is False" % new_file_name
self.client.files_move(old_file_name, new_file_name)
def makedirs(self, name):
self.client.files_create_folder(self._full_path(name))
def rmtree(self, name):
self.client.files_delete(self._full_path(name))
def setpermission(self, name):
pass