From 5096c2e7550571ca2572d3d11c12484041e7a1b6 Mon Sep 17 00:00:00 2001 From: HemangChothani Date: Tue, 4 Feb 2020 16:35:09 +0530 Subject: [PATCH] fix(storage): fix incorrect mtime by UTC offset --- google/cloud/storage/_helpers.py | 15 +++++++++++++++ google/cloud/storage/blob.py | 8 ++++++-- tests/unit/test_blob.py | 7 +++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/google/cloud/storage/_helpers.py b/google/cloud/storage/_helpers.py index 5bfa13e31..b1f9741f9 100644 --- a/google/cloud/storage/_helpers.py +++ b/google/cloud/storage/_helpers.py @@ -19,6 +19,7 @@ import base64 from hashlib import md5 +from datetime import datetime import os STORAGE_EMULATOR_ENV_VAR = "STORAGE_EMULATOR_HOST" @@ -273,3 +274,17 @@ def _base64_md5hash(buffer_object): _write_buffer_to_hash(buffer_object, hash_obj) digest_bytes = hash_obj.digest() return base64.b64encode(digest_bytes) + + +def _convert_to_timestamp(value): + """Convert non-none datetime to timestamp. + + :type value: :class:`datetime.datetime` + :param value: The datetime to convert. + + :rtype: int + :returns: The timestamp. + """ + utc_naive = value.replace(tzinfo=None) - value.utcoffset() + mtime = (utc_naive - datetime(1970, 1, 1)).total_seconds() + return mtime diff --git a/google/cloud/storage/blob.py b/google/cloud/storage/blob.py index f134c3e45..5a6ae5f87 100644 --- a/google/cloud/storage/blob.py +++ b/google/cloud/storage/blob.py @@ -31,8 +31,8 @@ from io import BytesIO import mimetypes import os -import time import warnings +import six from six.moves.urllib.parse import parse_qsl from six.moves.urllib.parse import quote @@ -57,6 +57,7 @@ from google.cloud.storage._helpers import _get_storage_host from google.cloud.storage._helpers import _PropertyMixin from google.cloud.storage._helpers import _scalar_property +from google.cloud.storage._helpers import _convert_to_timestamp from google.cloud.storage._signing import generate_signed_url_v2 from google.cloud.storage._signing import generate_signed_url_v4 from google.cloud.storage.acl import ACL @@ -773,7 +774,10 @@ def download_to_filename( updated = self.updated if updated is not None: - mtime = time.mktime(updated.timetuple()) + if six.PY2: + mtime = _convert_to_timestamp(updated) + else: + mtime = updated.timestamp() os.utime(file_obj.name, (mtime, mtime)) def download_as_string(self, client=None, start=None, end=None, raw_download=False): diff --git a/tests/unit/test_blob.py b/tests/unit/test_blob.py index 746e659c5..cab2c2036 100644 --- a/tests/unit/test_blob.py +++ b/tests/unit/test_blob.py @@ -1014,7 +1014,7 @@ def test_download_to_file_w_chunks_w_raw(self): def _download_to_filename_helper(self, updated, raw_download): import os - import time + from google.cloud.storage._helpers import _convert_to_timestamp from google.cloud._testing import _NamedTemporaryFile blob_name = "blob-name" @@ -1034,7 +1034,10 @@ def _download_to_filename_helper(self, updated, raw_download): self.assertIsNone(blob.updated) else: mtime = os.path.getmtime(temp.name) - updated_time = time.mktime(blob.updated.timetuple()) + if six.PY2: + updated_time = _convert_to_timestamp(blob.updated) + else: + updated_time = blob.updated.timestamp() self.assertEqual(mtime, updated_time) headers = {"accept-encoding": "gzip"}