Skip to content

Ensure UTC datetimes (via #102). #130

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

Merged
merged 1 commit into from
Nov 16, 2016
Merged
Show file tree
Hide file tree
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
4 changes: 3 additions & 1 deletion intercom/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from . import errors
from datetime import datetime
from pytz import utc

import certifi
import json
Expand Down Expand Up @@ -93,7 +94,8 @@ def set_rate_limit_details(self, resp):
if remaining:
rate_limit_details['remaining'] = int(remaining)
if reset:
rate_limit_details['reset_at'] = datetime.fromtimestamp(int(reset))
reset_at = datetime.utcfromtimestamp(int(reset)).replace(tzinfo=utc)
rate_limit_details['reset_at'] = reset_at
self.rate_limit_details = rate_limit_details

def raise_errors_on_failure(self, resp):
Expand Down
6 changes: 4 additions & 2 deletions intercom/traits/api_resource.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# -*- coding: utf-8 -*-

import calendar
import datetime
import time

from intercom.lib.flat_store import FlatStore
from intercom.lib.typed_json_deserializer import JsonDeserializer
from pytz import utc


def type_field(attribute):
Expand All @@ -29,7 +31,7 @@ def datetime_value(value):

def to_datetime_value(value):
if value:
return datetime.datetime.fromtimestamp(int(value))
return datetime.datetime.utcfromtimestamp(int(value)).replace(tzinfo=utc)


class Resource(object):
Expand Down Expand Up @@ -105,7 +107,7 @@ def __setattr__(self, attribute, value):
elif self._flat_store_attribute(attribute):
value_to_set = FlatStore(value)
elif timestamp_field(attribute) and datetime_value(value):
value_to_set = time.mktime(value.timetuple())
value_to_set = calendar.timegm(value.utctimetuple())
else:
value_to_set = value
if attribute != 'changed_attributes':
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#
certifi
inflection==0.3.0
pytz==2016.7
requests==2.6.0
urllib3==1.10.2
six==1.9.0
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@
],
packages=find_packages(),
include_package_data=True,
install_requires=["requests", "inflection", "certifi", "six"],
install_requires=["requests", "inflection", "certifi", "six", "pytz"],
zip_safe=False
)
31 changes: 16 additions & 15 deletions tests/unit/test_user.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-

import calendar
import json
import mock
import time
Expand Down Expand Up @@ -35,13 +36,13 @@ def it_to_dict_itself(self):
as_dict = user.to_dict()
eq_(as_dict["email"], "jim@example.com")
eq_(as_dict["user_id"], "12345")
eq_(as_dict["created_at"], time.mktime(created_at.timetuple()))
eq_(as_dict["created_at"], calendar.timegm(created_at.utctimetuple()))
eq_(as_dict["name"], "Jim Bob")

@istest
def it_presents_created_at_and_last_impression_at_as_datetime(self):
now = datetime.utcnow()
now_ts = time.mktime(now.timetuple())
now_ts = calendar.timegm(now.utctimetuple())
user = User.from_api(
{'created_at': now_ts, 'last_impression_at': now_ts})
self.assertIsInstance(user.created_at, datetime)
Expand All @@ -63,9 +64,9 @@ def it_presents_a_complete_user_record_correctly(self):
eq_('Joe Schmoe', user.name)
eq_('the-app-id', user.app_id)
eq_(123, user.session_count)
eq_(1401970114, time.mktime(user.created_at.timetuple()))
eq_(1393613864, time.mktime(user.remote_created_at.timetuple()))
eq_(1401970114, time.mktime(user.updated_at.timetuple()))
eq_(1401970114, calendar.timegm(user.created_at.utctimetuple()))
eq_(1393613864, calendar.timegm(user.remote_created_at.utctimetuple()))
eq_(1401970114, calendar.timegm(user.updated_at.utctimetuple()))

Avatar = create_class_instance('Avatar') # noqa
Company = create_class_instance('Company') # noqa
Expand All @@ -82,14 +83,14 @@ def it_presents_a_complete_user_record_correctly(self):
eq_('bbbbbbbbbbbbbbbbbbbbbbbb', user.companies[0].id)
eq_('the-app-id', user.companies[0].app_id)
eq_('Company 1', user.companies[0].name)
eq_(1390936440, time.mktime(
user.companies[0].remote_created_at.timetuple()))
eq_(1401970114, time.mktime(
user.companies[0].created_at.timetuple()))
eq_(1401970114, time.mktime(
user.companies[0].updated_at.timetuple()))
eq_(1401970113, time.mktime(
user.companies[0].last_request_at.timetuple()))
eq_(1390936440, calendar.timegm(
user.companies[0].remote_created_at.utctimetuple()))
eq_(1401970114, calendar.timegm(
user.companies[0].created_at.utctimetuple()))
eq_(1401970114, calendar.timegm(
user.companies[0].updated_at.utctimetuple()))
eq_(1401970113, calendar.timegm(
user.companies[0].last_request_at.utctimetuple()))
eq_(0, user.companies[0].monthly_spend)
eq_(0, user.companies[0].session_count)
eq_(1, user.companies[0].user_count)
Expand Down Expand Up @@ -134,7 +135,7 @@ def it_allows_update_last_request_at(self):
@istest
def it_allows_easy_setting_of_custom_data(self):
now = datetime.utcnow()
now_ts = time.mktime(now.timetuple())
now_ts = calendar.timegm(now.utctimetuple())

user = User()
user.custom_attributes["mad"] = 123
Expand Down Expand Up @@ -324,7 +325,7 @@ def it_gets_sets_rw_keys(self):
'name': 'Bob Smith',
'last_seen_ip': '1.2.3.4',
'last_seen_user_agent': 'ie6',
'created_at': time.mktime(created_at.timetuple())
'created_at': calendar.timegm(created_at.utctimetuple())
}
user = User(**payload)
expected_keys = ['custom_attributes']
Expand Down
7 changes: 5 additions & 2 deletions tests/unit/traits/test_api_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from nose.tools import eq_
from nose.tools import ok_
from nose.tools import istest
from pytz import utc


class IntercomTraitsApiResource(unittest.TestCase):
Expand All @@ -34,7 +35,8 @@ def it_does_not_set_type_on_parsing_json(self):

@istest
def it_coerces_time_on_parsing_json(self):
eq_(datetime.fromtimestamp(1374056196), self.api_resource.created_at)
dt = datetime.utcfromtimestamp(1374056196).replace(tzinfo=utc)
eq_(dt, self.api_resource.created_at)

@istest
def it_dynamically_defines_accessors_for_non_existent_properties(self):
Expand All @@ -55,7 +57,8 @@ def it_accepts_unix_timestamps_into_dynamically_defined_date_setters(self):
@istest
def it_exposes_dates_correctly_for_dynamically_defined_getters(self):
self.api_resource.foo_at = 1401200468
eq_(datetime.fromtimestamp(1401200468), self.api_resource.foo_at)
dt = datetime.utcfromtimestamp(1401200468).replace(tzinfo=utc)
eq_(dt, self.api_resource.foo_at)

@istest
def it_throws_regular_error_when_non_existant_getter_is_called_that_is_backed_by_an_instance_variable(self): # noqa
Expand Down