Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak sftp #568

Merged
merged 3 commits into from
Aug 26, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 16 additions & 24 deletions storages/backends/sftpstorage.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ def __init__(self, host=None, params=None, interactive=None, file_mode=None,
if root_path is None else root_path
self._base_url = setting('MEDIA_URL') if base_url is None else base_url

# for now it's all posix paths. Maybe someday we'll support figuring
# out if the remote host is windows.
self._pathmod = posixpath
self._sftp = None

def _connect(self):
Expand Down Expand Up @@ -90,12 +87,8 @@ def sftp(self):
self._connect()
return self._sftp

def _join(self, *args):
# Use the path module for the remote host type to join a path together
return self._pathmod.join(*args)

def _remote_path(self, name):
return self._join(self._root_path, name)
return posixpath.join(self._root_path, name)

def _open(self, name, mode='rb'):
return SFTPStorageFile(name, self, mode)
Expand All @@ -117,7 +110,7 @@ def _chown(self, path, uid=None, gid=None):
def _mkdir(self, path):
"""Create directory, recursing up to create parent dirs if
necessary."""
parent = self._pathmod.dirname(path)
parent = posixpath.dirname(path)
if not self.exists(parent):
self._mkdir(parent)
self.sftp.mkdir(path)
Expand All @@ -132,7 +125,7 @@ def _save(self, name, content):
"""Save file via SFTP."""
content.open()
path = self._remote_path(name)
dirname = self._pathmod.dirname(path)
dirname = posixpath.dirname(path)
if not self.exists(dirname):
self._mkdir(dirname)

Expand All @@ -148,15 +141,14 @@ def _save(self, name, content):
return name

def delete(self, name):
remote_path = self._remote_path(name)
self.sftp.remove(remote_path)
try:
self.sftp.remove(self._remote_path(name))
except IOError:
pass

def exists(self, name):
# Try to retrieve file info. Return true on success, false on failure.
remote_path = self._remote_path(name)

try:
self.sftp.stat(remote_path)
self.sftp.stat(self._remote_path(name))
return True
except IOError:
return False
Expand Down Expand Up @@ -200,34 +192,34 @@ def url(self, name):

class SFTPStorageFile(File):
def __init__(self, name, storage, mode):
self._name = name
self._storage = storage
self._mode = mode
self._is_dirty = False
self.name = name
self.mode = mode
self.file = BytesIO()
self._storage = storage
self._is_read = False
self._is_dirty = False

@property
def size(self):
if not hasattr(self, '_size'):
self._size = self._storage.size(self._name)
self._size = self._storage.size(self.name)
return self._size

def read(self, num_bytes=None):
if not self._is_read:
self.file = self._storage._read(self._name)
self.file = self._storage._read(self.name)
self._is_read = True

return self.file.read(num_bytes)

def write(self, content):
if 'w' not in self._mode:
if 'w' not in self.mode:
raise AttributeError("File was opened for read-only access.")
self.file = BytesIO(content)
self._is_dirty = True
self._is_read = True

def close(self):
if self._is_dirty:
self._storage._save(self._name, self)
self._storage._save(self.name, self)
self.file.close()