Skip to content

Commit 9354f64

Browse files
authored
Merge pull request #3 from RealGeeks/sc-23158-utmz-deprecation
Add support for new generic cookie parsing
2 parents ccc2116 + 36fff93 commit 9354f64

File tree

8 files changed

+168
-16
lines changed

8 files changed

+168
-16
lines changed

.circleci/config.yml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
version: 2
2+
jobs:
3+
build:
4+
working_directory: /opt/app
5+
docker:
6+
- image: docker:20.10.18-git
7+
steps:
8+
- checkout
9+
- setup_remote_docker:
10+
docker_layer_caching: true
11+
- run:
12+
name: Install dependencies
13+
command: |
14+
apk add --update --no-cache \
15+
docker-compose \
16+
make
17+
- run:
18+
name: Build image
19+
command: |
20+
docker-compose build
21+
- run:
22+
name: Run tests
23+
command: |
24+
make test-circle

Makefile

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
APP=docker-compose run --rm app
2+
TOX=tox
3+
4+
update:
5+
docker-compose build
6+
docker-compose stop
7+
docker-compose rm -f
8+
docker-compose build
9+
10+
test:
11+
$(APP) $(TOX)
12+
13+
test-circle: # run automated tests like circle-ci would
14+
docker-compose run --rm test-circle $(TOX)

README.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ pip install macadamia
2121
{'domain_hash': '208940939', 'campaign_number': '1', 'campaign_data': {'source': '(direct)', 'campaign_name': '(direct)', 'medium': '(none)'}, 'timestamp': datetime.datetime(2013, 4, 5, 8, 33, 4), 'session_counter': '1'}
2222
```
2323

24+
```python
25+
>>> from macadamia import parse_cookie
26+
>>> cookie_to_parse = "208940939.1365186784.1.1.fiztmcsr=(direct)|fiztmccn=(direct)|fiztmcmd=(none)"
27+
>>> parsed_cookie = parse_cookie(cookie_to_parse, prefix="fiztm")
28+
>>> {'domain_hash': '208940939', 'campaign_number': '1', 'campaign_data': {'source': '(direct)', 'campaign_name': '(direct)', 'medium': '(none)'}, 'timestamp': datetime.datetime(2013, 4, 5, 8, 33, 4), 'session_counter': '1'}
29+
```
2430

2531
###__utma Visitor Cookie (lasts 2 years)
2632
Used to distinguish users and sessions. The cookie is created when the javascript library executes and no existing __utma cookies exists. The cookie is updated every time data is sent to Google Analytics.
@@ -97,13 +103,12 @@ Sources:
97103

98104
## Running tests via tox and docker
99105
```bash
100-
docker build -t macadamia . && docker run -ti -v `pwd`:/opt/macadamia macadamia bash
101-
# then within the docker container run tox
102-
tox
106+
make test
103107
```
104108

105109
## Changelog
106110

111+
* 0.1.0: Support cookies shaped like `_utmz` but with a different name
107112
* 0.0.7: Actually add Python 3 compatibility and upgrade Dockerfile base image to test against Python 3.7
108113
* 0.0.6: Python 3 compatibility and add Dockerfile for development
109114
* 0.0.5: Fix typo parsing `utmgclid` cookie value

docker-compose.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
version: "3.9"
2+
3+
services:
4+
app: &app-base
5+
build: .
6+
volumes:
7+
- .:/opt/macadamia
8+
test-circle:
9+
<<: *app-base
10+
volumes: []

macadamia/__init__.py

+21-10
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,40 @@
11
import datetime
2+
23
try:
34
from urllib2 import unquote
45
except ImportError:
56
from urllib.parse import unquote
67

7-
def parse_campaign_data(data):
8+
9+
def parse_campaign_data(data, prefix="utm"):
810
human_names = {
9-
"utmcsr": "source",
10-
"utmcmd": "medium",
11-
"utmccn": "campaign_name",
12-
"utmctr": "campaign_keyword",
13-
"utmcct": "campaign_content",
14-
"utmgclid": "google_click_id",
11+
"%scsr" % prefix: "source",
12+
"%scmd" % prefix: "medium",
13+
"%sccn" % prefix: "campaign_name",
14+
"%sctr" % prefix: "campaign_keyword",
15+
"%scct" % prefix: "campaign_content",
16+
"%sgclid" % prefix: "google_click_id",
1517
}
18+
1619
fields = [d.split("=") for d in data.split("|")]
1720
info = dict((human_names[d[0]], unquote(d[1])) for d in fields)
1821

1922
return info
2023

21-
def parse_utmz(cookie):
22-
fields = cookie.split('.')
24+
25+
def parse_cookie(cookie, prefix="utm"):
26+
fields = cookie.split(".")
27+
28+
campaign_data = parse_campaign_data(".".join(fields[4:]), prefix=prefix)
29+
2330
return {
2431
"domain_hash": fields[0],
2532
"timestamp": datetime.datetime.fromtimestamp(int(fields[1])),
2633
"session_counter": fields[2],
2734
"campaign_number": fields[3],
28-
"campaign_data": parse_campaign_data(".".join(fields[4:])),
35+
"campaign_data": campaign_data,
2936
}
37+
38+
39+
def parse_utmz(cookie):
40+
return parse_cookie(cookie, prefix="utm")

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def run_tests(self):
1919
sys.exit(errno)
2020

2121
setup(name='macadamia',
22-
version='0.0.7',
22+
version='0.1.0',
2323
description="A parser for Google Analytics Cookies",
2424
author='Kevin McCarthy',
2525
author_email='[email protected]',

tests/test_fiztmz.py

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import datetime
2+
import pytest
3+
from macadamia import parse_cookie
4+
5+
6+
@pytest.mark.parametrize(
7+
("cookie", "expected"),
8+
[
9+
(
10+
"44858868.462535200.44.2.fiztmcsr=localhost:9000|fiztmccn=(referral)|fiztmcmd=referral|fiztmcct=/",
11+
{
12+
"domain_hash": "44858868",
13+
"timestamp": datetime.datetime(year=1984, month=8, day=28, hour=10),
14+
"session_counter": "44",
15+
"campaign_number": "2",
16+
"campaign_data": {
17+
"campaign_content": "/",
18+
"campaign_name": "(referral)",
19+
"medium": "referral",
20+
"source": "localhost:9000",
21+
},
22+
},
23+
),
24+
(
25+
"208940939.1365186784.1.1.fiztmcsr=(direct)|fiztmccn=(direct)|fiztmcmd=(none)",
26+
{
27+
"campaign_number": "1",
28+
"domain_hash": "208940939",
29+
"session_counter": "1",
30+
"timestamp": datetime.datetime(2013, 4, 5, 18, 33, 4),
31+
"campaign_data": {
32+
"campaign_name": "(direct)",
33+
"medium": "(none)",
34+
"source": "(direct)",
35+
},
36+
},
37+
),
38+
(
39+
"48016369.462535200.1.1.fiztmcsr=realgeeks.com|fiztmccn=(referral)|fiztmcmd=referral|fiztmcct=/clients/lee-cunningham/",
40+
{
41+
"campaign_number": "1",
42+
"domain_hash": "48016369",
43+
"session_counter": "1",
44+
"timestamp": datetime.datetime(year=1984, month=8, day=28, hour=10),
45+
"campaign_data": {
46+
"campaign_content": "/clients/lee-cunningham/",
47+
"campaign_name": "(referral)",
48+
"medium": "referral",
49+
"source": "realgeeks.com",
50+
},
51+
},
52+
),
53+
(
54+
"44858868.462535200.71.3.fiztmcsr=google|fiztmccn=(organic)|fiztmcmd=organic|fiztmctr=hawaii%20real%20estate",
55+
{
56+
"campaign_number": "3",
57+
"domain_hash": "44858868",
58+
"session_counter": "71",
59+
"timestamp": datetime.datetime(year=1984, month=8, day=28, hour=10),
60+
"campaign_data": {
61+
"campaign_keyword": "hawaii real estate",
62+
"campaign_name": "(organic)",
63+
"medium": "organic",
64+
"source": "google",
65+
},
66+
},
67+
),
68+
(
69+
"112962326.462535200.1.1.fiztmgclid=CMbMrdi_ybgCFWho7AodDyAAvQ|fiztmccn=(not set)|fiztmcmd=(not set)|fiztmctr=real estate for sale in wilmington nc",
70+
{
71+
"campaign_number": "1",
72+
"domain_hash": "112962326",
73+
"session_counter": "1",
74+
"timestamp": datetime.datetime(year=1984, month=8, day=28, hour=10),
75+
"campaign_data": {
76+
"campaign_keyword": "real estate for sale in wilmington nc",
77+
"campaign_name": "(not set)",
78+
"google_click_id": "CMbMrdi_ybgCFWho7AodDyAAvQ",
79+
"medium": "(not set)",
80+
},
81+
},
82+
),
83+
],
84+
)
85+
def test_cookie_split_and_parse(cookie, expected):
86+
info = parse_cookie(cookie, prefix="fiztm")
87+
assert info == expected

tox.ini

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ envlist = py27, py37
33
toxworkdir={toxinidir}/../.tox
44

55
[testenv]
6-
deps =
6+
deps =
77
pytest
88
commands =
9-
pytest tests/test_utmz.py
9+
pytest tests/test_utmz.py
10+
pytest tests/test_fiztmz.py

0 commit comments

Comments
 (0)