Skip to content
This repository was archived by the owner on Jul 13, 2020. It is now read-only.

Commit 1fcb7bc

Browse files
committed
Added subject class (snowplow#39)
1 parent 09c9e05 commit 1fcb7bc

4 files changed

Lines changed: 41 additions & 118 deletions

File tree

CHANGES.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
Version 0.4.0 (2014-05-xx)
22
--------------------------
3-
Added callbacks for flushing (#78)
4-
Added Python-logging (#76)
5-
Added Redis and gevent based async approach (#75) (TODO)
6-
Added thread-based AsyncBufferedConsumer (#74) (TODO)
7-
Improved test coverage up to 50% (73) (TODO)
3+
Added callbacks for flushing
4+
Added Python-logging
5+
Added Redis and gevent based async approach (#75)
6+
Added thread-based AsyncBufferedConsumer (#74)
7+
Improved test coverage up to 50% (73)
88
Added ability to specify port for collector (#72) (TODO)
99
Added POST support to tracker (#70)
10-
Added Redis-based queue (#45) (TODO)
11-
Added Buffered Consumer (#44) (TODO)
12-
Changed user_id to be set on a per-event basis (#39) (TODO)
10+
Added Redis-based queue (#45)
11+
Added Buffered Consumer (#44)
12+
Changed user_id to be set on a per-event basis (#39)
1313

1414
Version 0.3.0 (2014-04-25)
1515
--------------------------

snowplow_tracker/test/integration/test_integration.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@
2222
import unittest
2323
import time
2424
import re
25-
from snowplow_tracker import tracker, _version, consumer
25+
from snowplow_tracker import tracker, _version, consumer, subject
2626
from httmock import all_requests, HTTMock
2727

2828
querystrings = [""]
2929

3030
default_consumer = consumer.Consumer("localhost")
3131

32+
default_subject = subject.Subject()
33+
3234
def from_querystring(field, url):
3335
pattern = re.compile("^[^#]*[?&]" + field + "=([^&#]*)")
3436
match = pattern.match(url)
@@ -54,21 +56,21 @@ def fail_response_content(url, request):
5456
class IntegrationTest(unittest.TestCase):
5557

5658
def test_integration_page_view(self):
57-
t = tracker.Tracker(default_consumer)
59+
t = tracker.Tracker(default_consumer, default_subject)
5860
with HTTMock(pass_response_content):
5961
t.track_page_view("http://savethearctic.org", "Save The Arctic", None)
6062
self.assertEquals(from_querystring("page", querystrings[-1]),"Save+The+Arctic")
6163

6264
def test_integration_ecommerce_transaction_item(self):
63-
t = tracker.Tracker(default_consumer)
65+
t = tracker.Tracker(default_consumer, default_subject)
6466
with HTTMock(pass_response_content):
6567
t.track_ecommerce_transaction_item("12345", "pbz0025", 7.99, 2, "black-tarot", "tarot", currency="GBP")
6668
expected_fields = {"ti_ca": "tarot", "ti_id": "12345", "ti_qu": "2", "ti_sk": "pbz0025", "e": "ti", "ti_nm": "black-tarot", "ti_pr": "7.99", "ti_cu": "GBP"}
6769
for key in expected_fields:
6870
self.assertEquals(from_querystring(key, querystrings[-1]), expected_fields[key])
6971

7072
def test_integration_ecommerce_transaction(self):
71-
t = tracker.Tracker(default_consumer)
73+
t = tracker.Tracker(default_consumer, default_subject)
7274
with HTTMock(pass_response_content):
7375
t.track_ecommerce_transaction("6a8078be", 35, city="London", currency="GBP", items=
7476
[{
@@ -98,39 +100,39 @@ def test_integration_ecommerce_transaction(self):
98100
self.assertEquals(from_querystring(key, querystrings[-3]), from_querystring(key, querystrings[-2]))
99101

100102
def test_integration_screen_view(self):
101-
t = tracker.Tracker(default_consumer)
103+
t = tracker.Tracker(default_consumer, default_subject)
102104
with HTTMock(pass_response_content):
103105
t.track_screen_view("Game HUD 2", "Hello!")
104106
expected_fields = {"e": "ue", "ue_na": "screen_view", "evn": "com.snowplowanalytics"}
105107
for key in expected_fields:
106108
self.assertEquals(from_querystring(key, querystrings[-1]), expected_fields[key])
107109

108110
def test_integration_struct_event(self):
109-
t = tracker.Tracker(default_consumer)
111+
t = tracker.Tracker(default_consumer, default_subject)
110112
with HTTMock(pass_response_content):
111113
t.track_struct_event("Ecomm", "add-to-basket", "dog-skateboarding-video", "hd", 13.99)
112114
expected_fields = {"se_ca": "Ecomm", "se_pr": "hd", "se_la": "dog-skateboarding-video", "se_va": "13.99", "se_ac": "add-to-basket", "e": "se"}
113115
for key in expected_fields:
114116
self.assertEquals(from_querystring(key, querystrings[-1]), expected_fields[key])
115117

116118
def test_integration_unstruct_event_non_base64(self):
117-
t = tracker.Tracker(default_consumer, encode_base64=False)
119+
t = tracker.Tracker(default_consumer, default_subject, encode_base64=False)
118120
with HTTMock(pass_response_content):
119121
t.track_unstruct_event("com.example_company", "viewed_product", {"product_id": "ASO01043", "price$flt": 49.95, "walrus$tms": int(time.time() * 1000)})
120122
expected_fields = {"e": "ue", "evn": "com.example_company", "ue_na": "viewed_product"}
121123
for key in expected_fields:
122124
self.assertEquals(from_querystring(key, querystrings[-1]), expected_fields[key])
123125

124126
def test_integration_unstruct_event_base64(self):
125-
t = tracker.Tracker(default_consumer)
127+
t = tracker.Tracker(default_consumer, default_subject)
126128
with HTTMock(pass_response_content):
127129
t.track_unstruct_event("com.example_company", "viewed_product", {"product_id": "ASO01043", "price$flt": 49.95, "walrus$tms": int(time.time() * 1000)})
128130
expected_fields = {"e": "ue", "ue_na": "viewed_product"}
129131
for key in expected_fields:
130132
self.assertEquals(from_querystring(key, querystrings[-1]), expected_fields[key])
131133

132134
def test_integration_unstruct_event_non_base64_error(self):
133-
t = tracker.Tracker(default_consumer, encode_base64=False)
135+
t = tracker.Tracker(default_consumer, default_subject, encode_base64=False)
134136
try:
135137
t.track_unstruct_event("com.example_company", "viewed_product",
136138
{
@@ -143,7 +145,7 @@ def test_integration_unstruct_event_non_base64_error(self):
143145

144146

145147
def test_integration_unstruct_event_base64_error(self):
146-
t = tracker.Tracker(default_consumer)
148+
t = tracker.Tracker(default_consumer, default_subject)
147149
try:
148150
t.track_unstruct_event("com.example_company", "viewed_product",
149151
{
@@ -155,13 +157,13 @@ def test_integration_unstruct_event_base64_error(self):
155157
self.assertEquals("walrus$tms in dict is not a tms", str(e))
156158

157159
def test_integration_standard_nv_pairs(self):
158-
t = tracker.Tracker(default_consumer, "cf", app_id="angry-birds-android", context_vendor="com.example")
159-
t.set_platform("mob")
160-
t.set_user_id("user12345")
161-
t.set_screen_resolution(100, 200)
162-
t.set_color_depth(24)
163-
t.set_timezone("Europe London")
164-
t.set_lang("en")
160+
t = tracker.Tracker(default_consumer, default_subject, "cf", app_id="angry-birds-android", context_vendor="com.example")
161+
default_subject.set_platform("mob")
162+
default_subject.set_user_id("user12345")
163+
default_subject.set_screen_resolution(100, 200)
164+
default_subject.set_color_depth(24)
165+
default_subject.set_timezone("Europe London")
166+
default_subject.set_lang("en")
165167
with HTTMock(pass_response_content):
166168
t.track_page_view("localhost", "local host", None, {'user': {'user_type': 'tester'}})
167169
expected_fields = {"tna": "cf", "evn": "com.snowplowanalytics", "res": "100x200",
@@ -171,6 +173,6 @@ def test_integration_standard_nv_pairs(self):
171173
self.assertEquals(from_querystring(key, querystrings[-1]), expected_fields[key])
172174

173175
def test_integration_request_failure(self):
174-
t = tracker.Tracker(consumer.Consumer("drnv83ldfo4ed.cloudfront.net"))
176+
t = tracker.Tracker(consumer.Consumer("drnv83ldfo4ed.cloudfront.net"), default_subject)
175177
with HTTMock(fail_response_content):
176178
tracking_return_value = t.track_page_view("Title page")

snowplow_tracker/test/unit/test_tracker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def setUp(self):
3131
pass
3232

3333
def test_initialisation(self):
34-
t = Tracker("d3rkrsqld9gmqf.cloudfront.net", "cloudfront", encode_base64= False, app_id="AF003", context_vendor="com.example")
34+
t = Tracker(None, namespace="cloudfront", encode_base64= False, app_id="AF003", context_vendor="com.example")
3535
self.assertEquals(t.standard_nv_pairs["tna"], "cloudfront")
3636
self.assertEquals(t.standard_nv_pairs["aid"], "AF003")
3737
self.assertEquals(t.encode_base64, False)

snowplow_tracker/tracker.py

Lines changed: 12 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@
3636

3737
VERSION = "py-%s" % _version.__version__
3838
DEFAULT_ENCODE_BASE64 = True
39-
DEFAULT_PLATFORM = "pc"
40-
SUPPORTED_PLATFORMS = set(["pc", "tv", "mob", "cnsl", "iot"])
4139
DEFAULT_VENDOR = "com.snowplowanalytics"
4240

4341

@@ -55,7 +53,7 @@ class Tracker:
5553

5654
new_contract("tracker", lambda s: isinstance(s, Tracker))
5755

58-
def __init__(self, out_queue,
56+
def __init__(self, out_queue, subject=None,
5957
namespace=None, app_id=None, context_vendor=None, encode_base64=DEFAULT_ENCODE_BASE64,
6058
contracts=True, log=True):
6159
"""
@@ -68,11 +66,11 @@ def __init__(self, out_queue,
6866
logger.setLevel(logging.CRITICAL)
6967

7068
self.out_queue = out_queue
69+
self.subject=subject
7170
self.encode_base64 = encode_base64
7271
self.context_vendor = context_vendor
7372

7473
self.standard_nv_pairs = {
75-
"p": DEFAULT_PLATFORM,
7674
"tv": VERSION,
7775
"tna": namespace,
7876
"aid": app_id
@@ -104,91 +102,6 @@ def get_timestamp(tstamp=None):
104102
elif isinstance(tstamp, (int, float)):
105103
return int(tstamp)
106104

107-
"""
108-
Setter methods
109-
"""
110-
111-
@contract
112-
def set_platform(self, value):
113-
"""
114-
:param value: One of ["pc", "tv", "mob", "cnsl", "iot"]
115-
:type value: str
116-
:rtype: tracker
117-
"""
118-
if value in SUPPORTED_PLATFORMS:
119-
self.standard_nv_pairs["p"] = value
120-
else:
121-
raise RuntimeError(value + " is not a supported platform")
122-
return self
123-
124-
@contract
125-
def set_user_id(self, user_id):
126-
"""
127-
:param user_id: User ID
128-
:type user_id: non_empty_string
129-
:rtype: tracker
130-
"""
131-
self.standard_nv_pairs["uid"] = user_id
132-
return self
133-
134-
@contract
135-
def set_screen_resolution(self, width, height):
136-
"""
137-
:param width: Width of the screen
138-
:param height: Height of the screen
139-
:type width: int,>0
140-
:type height: int,>0
141-
:rtype: tracker
142-
"""
143-
self.standard_nv_pairs["res"] = "".join([str(width), "x", str(height)])
144-
return self
145-
146-
@contract
147-
def set_viewport(self, width, height):
148-
"""
149-
:param width: Width of the viewport
150-
:param height: Height of the viewport
151-
:type width: int,>0
152-
:type height: int,>0
153-
:rtype: tracker
154-
"""
155-
self.standard_nv_pairs["vp"] = "".join([str(width), "x", str(height)])
156-
return self
157-
158-
@contract
159-
def set_color_depth(self, depth):
160-
"""
161-
:param depth: Depth of the color on the screen
162-
:type depth: int
163-
:rtype: tracker
164-
"""
165-
self.standard_nv_pairs["cd"] = depth
166-
return self
167-
168-
@contract
169-
def set_timezone(self, timezone):
170-
"""
171-
Set timezone for the Tracker object.
172-
173-
:param timezone: Timezone as a string
174-
:type timezone: non_empty_string
175-
:rtype: tracker
176-
"""
177-
self.standard_nv_pairs["tz"] = timezone
178-
return self
179-
180-
@contract
181-
def set_lang(self, lang):
182-
"""
183-
Set language.
184-
185-
:param lang: Language the application is set to
186-
:type lang: non_empty_string
187-
:rtype: tracker
188-
"""
189-
self.standard_nv_pairs["lang"] = lang
190-
return self
191-
192105

193106
"""
194107
Tracking methods
@@ -201,7 +114,7 @@ def track(self, pb):
201114
202115
:param pb: Payload builder
203116
:type pb: payload
204-
#:rtype: tuple(bool, int | str)
117+
:rtype: tracker | int
205118
"""
206119
result = self.out_queue.input(pb.nv_pairs)
207120
if result is not None:
@@ -217,12 +130,14 @@ def complete_payload(self, pb):
217130
218131
:param pb: Payload builder
219132
:type pb: payload
220-
#:rtype: tuple(bool, int | str)
133+
:rtype: tracker | int
221134
"""
222135
pb.add_dict(self.standard_nv_pairs)
223136
if "co" in pb.nv_pairs or "cx" in pb.nv_pairs:
224137
pb.add("cv", self.context_vendor)
225138

139+
pb.add_dict(self.subject.standard_nv_pairs)
140+
226141
return self.track(pb)
227142

228143
@contract
@@ -458,3 +373,9 @@ def flush(self, async=True):
458373
return self.out_queue.flush()
459374
else:
460375
return self.out_queue.sync_flush()
376+
377+
def set_subject(self, subject):
378+
"""
379+
Set the subject of the events fired by the tracker
380+
"""
381+
self.subject = subject

0 commit comments

Comments
 (0)