Skip to content

Commit 4cd12e0

Browse files
authored
[sftp] Format times to UTC (#1420)
1 parent ea25226 commit 4cd12e0

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

storages/backends/sftpstorage.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@
44
#
55
# Modeled on the FTP storage by Rafal Jonca <[email protected]>
66

7+
import datetime
78
import getpass
89
import io
910
import os
1011
import posixpath
1112
import stat
12-
from datetime import datetime
1313
from urllib.parse import urljoin
1414

1515
import paramiko
1616
from django.core.files.base import File
17-
from django.utils import timezone
1817
from django.utils.deconstruct import deconstructible
1918
from paramiko.util import ClosingContextManager
2019

@@ -192,17 +191,20 @@ def size(self, name):
192191
remote_path = self._remote_path(name)
193192
return self.sftp.stat(remote_path).st_size
194193

194+
# From Django
195+
def _datetime_from_timestamp(self, ts):
196+
tz = datetime.timezone.utc if setting("USE_TZ") else None
197+
return datetime.datetime.fromtimestamp(ts, tz=tz)
198+
195199
def get_accessed_time(self, name):
196200
remote_path = self._remote_path(name)
197201
utime = self.sftp.stat(remote_path).st_atime
198-
ts = datetime.fromtimestamp(utime)
199-
return timezone.make_aware(ts) if setting("USE_TZ") else ts
202+
return self._datetime_from_timestamp(utime)
200203

201204
def get_modified_time(self, name):
202205
remote_path = self._remote_path(name)
203206
utime = self.sftp.stat(remote_path).st_mtime
204-
ts = datetime.fromtimestamp(utime)
205-
return timezone.make_aware(ts) if setting("USE_TZ") else ts
207+
return self._datetime_from_timestamp(utime)
206208

207209
def url(self, name):
208210
if self._base_url is None:

tests/test_sftp.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,17 @@ def test_url(self):
167167
self.storage._base_url = None
168168
self.storage.url("foo")
169169

170+
@patch(
171+
"storages.backends.sftpstorage.SFTPStorage.sftp",
172+
**{
173+
"stat.return_value.st_mtime": 1720287559,
174+
"stat.return_value.st_atime": 1720287559,
175+
},
176+
)
177+
def test_times(self, mock_sftp):
178+
self.storage.get_modified_time("foo")
179+
self.storage.get_accessed_time("foo")
180+
170181
@patch("paramiko.transport.Transport", **{"is_active.side_effect": (True, False)})
171182
@patch("storages.backends.sftpstorage.SFTPStorage._connect")
172183
def test_sftp(self, connect, transport):

0 commit comments

Comments
 (0)