diff options
author | Mike Crute <mike@crute.us> | 2017-10-30 02:35:56 +0000 |
---|---|---|
committer | Mike Crute <mike@crute.us> | 2017-10-30 02:38:23 +0000 |
commit | 474e3068d62ba60e2656c54a01e42787dc618a03 (patch) | |
tree | ac7e82a1a8882bfabbae7ea286c6fbe985d96cbe | |
parent | d93429bf62f076a76876014ac35bbc9355fd5b30 (diff) | |
download | pydora-474e3068d62ba60e2656c54a01e42787dc618a03.tar.bz2 pydora-474e3068d62ba60e2656c54a01e42787dc618a03.tar.xz pydora-474e3068d62ba60e2656c54a01e42787dc618a03.zip |
Extract date formatter logic to SyntheticField
-rw-r--r-- | pandora/models/__init__.py | 18 | ||||
-rw-r--r-- | pandora/models/pandora.py | 8 | ||||
-rw-r--r-- | tests/test_pandora/test_models.py | 24 |
3 files changed, 35 insertions, 15 deletions
diff --git a/pandora/models/__init__.py b/pandora/models/__init__.py index 7a60889..bafb6ce 100644 --- a/pandora/models/__init__.py +++ b/pandora/models/__init__.py | |||
@@ -57,6 +57,20 @@ class SyntheticField(namedtuple("SyntheticField", ["field"])): | |||
57 | raise NotImplementedError | 57 | raise NotImplementedError |
58 | 58 | ||
59 | 59 | ||
60 | class DateField(SyntheticField): | ||
61 | """Date Field | ||
62 | |||
63 | Handles a JSON map that contains a time field which is the timestamp with | ||
64 | nanosecond precision. | ||
65 | """ | ||
66 | |||
67 | def formatter(self, api_client, data, value): | ||
68 | if not value: | ||
69 | return None | ||
70 | |||
71 | return datetime.utcfromtimestamp(value["time"] / 1000) | ||
72 | |||
73 | |||
60 | class ModelMetaClass(type): | 74 | class ModelMetaClass(type): |
61 | 75 | ||
62 | def __new__(cls, name, parents, dct): | 76 | def __new__(cls, name, parents, dct): |
@@ -84,10 +98,6 @@ class PandoraModel(with_metaclass(ModelMetaClass, object)): | |||
84 | consumers of these instances can ignore all of the details of this class. | 98 | consumers of these instances can ignore all of the details of this class. |
85 | """ | 99 | """ |
86 | 100 | ||
87 | @staticmethod | ||
88 | def json_to_date(api_client, data): | ||
89 | return datetime.utcfromtimestamp(data["time"] / 1000) | ||
90 | |||
91 | @classmethod | 101 | @classmethod |
92 | def from_json_list(cls, api_client, data): | 102 | def from_json_list(cls, api_client, data): |
93 | """Convert a list of JSON values to a list of models | 103 | """Convert a list of JSON values to a list of models |
diff --git a/pandora/models/pandora.py b/pandora/models/pandora.py index cd1e588..e6a37ff 100644 --- a/pandora/models/pandora.py +++ b/pandora/models/pandora.py | |||
@@ -1,7 +1,7 @@ | |||
1 | from ..client import BaseAPIClient | 1 | from ..client import BaseAPIClient |
2 | from ..errors import ParameterMissing | 2 | from ..errors import ParameterMissing |
3 | from . import SyntheticField | 3 | from . import Field, DateField, SyntheticField |
4 | from . import Field, PandoraModel, PandoraListModel, PandoraDictListModel | 4 | from . import PandoraModel, PandoraListModel, PandoraDictListModel |
5 | 5 | ||
6 | 6 | ||
7 | class Station(PandoraModel): | 7 | class Station(PandoraModel): |
@@ -13,7 +13,7 @@ class Station(PandoraModel): | |||
13 | is_quickmix = Field("isQuickMix") | 13 | is_quickmix = Field("isQuickMix") |
14 | 14 | ||
15 | art_url = Field("artUrl") | 15 | art_url = Field("artUrl") |
16 | date_created = Field("dateCreated", formatter=PandoraModel.json_to_date) | 16 | date_created = DateField("dateCreated") |
17 | detail_url = Field("stationDetailUrl") | 17 | detail_url = Field("stationDetailUrl") |
18 | id = Field("stationId") | 18 | id = Field("stationId") |
19 | name = Field("stationName") | 19 | name = Field("stationName") |
@@ -231,7 +231,7 @@ class Bookmark(PandoraModel): | |||
231 | artist_name = Field("artistName") | 231 | artist_name = Field("artistName") |
232 | art_url = Field("artUrl") | 232 | art_url = Field("artUrl") |
233 | bookmark_token = Field("bookmarkToken") | 233 | bookmark_token = Field("bookmarkToken") |
234 | date_created = Field("dateCreated", formatter=PandoraModel.json_to_date) | 234 | date_created = DateField("dateCreated") |
235 | 235 | ||
236 | # song only | 236 | # song only |
237 | sample_url = Field("sampleUrl") | 237 | sample_url = Field("sampleUrl") |
diff --git a/tests/test_pandora/test_models.py b/tests/test_pandora/test_models.py index 1310d71..808efa4 100644 --- a/tests/test_pandora/test_models.py +++ b/tests/test_pandora/test_models.py | |||
@@ -35,6 +35,23 @@ class TestModelMetaClass(TestCase): | |||
35 | self.assertFalse("__field__" in self.TestModel._fields) | 35 | self.assertFalse("__field__" in self.TestModel._fields) |
36 | 36 | ||
37 | 37 | ||
38 | class TestDateField(TestCase): | ||
39 | |||
40 | class SampleModel(m.PandoraModel): | ||
41 | |||
42 | date_field = m.DateField("foo") | ||
43 | |||
44 | def test_json_to_date(self): | ||
45 | expected = datetime(2015, 7, 18, 3, 8, 17) | ||
46 | data = {"foo": {"time": 1437188897616}} | ||
47 | |||
48 | model = self.SampleModel.from_json(None, data) | ||
49 | |||
50 | # Python2.7 doesn't restore microseconds and we don't care about | ||
51 | # it anyhow so just remove it for this test | ||
52 | self.assertEqual(expected, model.date_field.replace(microsecond=0)) | ||
53 | |||
54 | |||
38 | class TestPandoraModel(TestCase): | 55 | class TestPandoraModel(TestCase): |
39 | 56 | ||
40 | JSON_DATA = { | 57 | JSON_DATA = { |
@@ -66,13 +83,6 @@ class TestPandoraModel(TestCase): | |||
66 | def __repr__(self): | 83 | def __repr__(self): |
67 | return self._base_repr("Foo") | 84 | return self._base_repr("Foo") |
68 | 85 | ||
69 | def test_json_to_date(self): | ||
70 | expected = datetime(2015, 7, 18, 3, 8, 17) | ||
71 | result = m.PandoraModel.json_to_date(None, {"time": 1437188897616}) | ||
72 | # Python2.7 doesn't restore microseconds and we don't care about | ||
73 | # it anyhow so just remove it for this test | ||
74 | self.assertEqual(expected, result.replace(microsecond=0)) | ||
75 | |||
76 | def test_init_sets_defaults(self): | 86 | def test_init_sets_defaults(self): |
77 | model = self.TestModel(None) | 87 | model = self.TestModel(None) |
78 | self.assertEqual(model.field1, "a string") | 88 | self.assertEqual(model.field1, "a string") |