From 6a561d9d4c48c0b0839111004621a1fe423459bb Mon Sep 17 00:00:00 2001 From: Jeroen Date: Sun, 26 Nov 2023 08:14:34 +0100 Subject: [PATCH] Added Google location logic --- .gitignore | 1 + public/port-0.0.0-py3-none-any.whl | Bin 5363 -> 6326 bytes .../py/dist/port-0.0.0-py3-none-any.whl | Bin 5363 -> 6326 bytes src/framework/processing/py/port/script.py | 296 ++++++++++++------ .../processing/py/tests/script_test.py | 156 +++++++++ 5 files changed, 358 insertions(+), 95 deletions(-) create mode 100644 src/framework/processing/py/tests/script_test.py diff --git a/.gitignore b/.gitignore index 8b69396a..eabcd78f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +__pycache__/ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. release.zip diff --git a/public/port-0.0.0-py3-none-any.whl b/public/port-0.0.0-py3-none-any.whl index 4b6f4ac8baeb11dfa0fc4c207279c476f92455b7..2032c42111a1a45c0f5ea3849714e3739cd5052f 100644 GIT binary patch delta 3246 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 delta 2300 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 delta 2300 zcmV3{LbIU!$XOpRN6AS&3P&2rB@PhLo8^i_%8y{`v`8M4)BP zZKiZ#*a^FeF1LTeq9npZr#ykBQXBezCXMAQ%?oO-0vw4D~*mYA=wY!*m~rIJ@rzk3SX!2 zY1Vi`;vlO6G{vd4#|M$F0xVyo+;Z~ydN_<}E-`Cy9HoD-tSG1$?HcI*7~SC7M$-^M zZ|ue8t8?}Y-$4$EWp)kBrL>l4O#ks@Hw=wTFzF8^+p+B$QP`!fptb)XV^MKYT4xNI z+{N&(PD#N@cvz5J6Ew^=qUR#v7KwI*G@UUEpX?C|2pRR!Xy#imRc;Z@b5%R;FC1kN zU{RvC9q@lv|E!5mA5&x<*!f~%Z%bG#*vScda?Wpa#nTI`k@rvf!8s^E=nt+QizuT( zqN^5BvT-m~7YbFZaoPuA*OzNJ?MJR-_YKc07^0$c1K{t_Ga+$;NJo77Uw$cxYc!#X zl2!SPtrWA0B}y7(AFZEa%;OFncWoS%U25Q)VcdUm1K;RHpfB2+30*iEk^LI1zI8DU zD-Or^`Qc<2`XFlhIbE&I%jrI{cJkU)IZ9hv(0dYmPm&NskULo5n z7!}x`vV-jM`FWuBbgv*m9@#c@{8&d1r zpQe7%l(FPK&?~iQ2)<)+sMMWyD})5^J{r@|qz%TsPo-~bT;Di9r~A9Ja~ykxE_o|) zWmH=3_J=V|+`-8eC@RLgUNFo0%oN>GEc6yr#6hb3#J3^WIo4neJ=qatc`98cj!Bt&gI25f)W*Drrx z;O6@E%Rh|U4uzM>T2(Z(PnFyL*8B#L!-Hiq!s7QTU!krMgTdf&j>uyiKWj>P#;S4! z7?2f8c&4h7=#QHS*PPoq`^7PGMU)&_6MoJn7aK=woQw{>L3Sf1m*k~}WNi&bgZSPM z;6E5ZM}ae0RyOV=v6tdNg-3s#A|x*$a3ZJ-E%^cuWK{7G)ta~w4cHG0c|7`S+EXxA z&~|Ii{JAiEo0$J4N@rWErWPEYq^Wx%89Iu)$@Gw8U5Tgtt>5XdxBNaTT>`5xB0Go` zSb7|h>a`8@dgdn5hnkZ1p@k85^%z09=T6TMf=V!M3_c}LHXmi?ptXO}$Gg%|=(eN& zqOSWekq$esV^15mco$aK93EMhF!VkfbsC2S>P)Uxm6FXhxBFbp)#@OXzpE7sACX41 z(c2|xflC9$dy2@@MW!kFs41Pl#OG6bjD0u~l~;u{Cs$ETB>JXQr;0vNVRC55{a#Po zkPVuMy4X^{PjR(eI#*Vr4&M={6YW{YIFIXcGiq#;wXVg~&5~*L*R|^o%0VVlHrnX6 z$(eO5dc-bMqsCWG`}K@nwYFThHO4i;8^Av1qrrC4xKAeiiZb#Ib2wx2FHlPZ1e3}a z8nf^cjR6k&;FOK;eD?KS`-4f=z=qf zC^%HQhm`qO0mv`(izz66Mk$)@#Pq29W>SbKoi z>bKMsxP3sf>wTXWNU3bdPDdDdReu#vjHC=)wV%PR4`$r0L2m=i5ESL-BVIC0`v)bE zt^Ug5VLNFzc`OIIBj2K>E-l7Va=#xqNhU?9-6FP%1)z++Q$*?YYg^2F5x0Bt7CNb6 z8>#WDPW>^Bf*#r~zhEOZJEJD7u9U9Z44xa#+7i}1uNUrE7i4Yp9EHB)%rAdMH@tKS zZn6&)X*a3R)|rUHQkNOHpUj+FS=4BACYiib1YLg)t{iK*vIXJgAG1vsO92Xlaonb- z1^@sk6_cVDOacxMlkgWw0v-^P@D~@8QWzB+`rw)PrU3u|b^-tZ8vp 1: + print(extract_data_from_zip(sys.argv[1])) + else: + print("please provide a zip file as argument") diff --git a/src/framework/processing/py/tests/script_test.py b/src/framework/processing/py/tests/script_test.py new file mode 100644 index 00000000..650d846c --- /dev/null +++ b/src/framework/processing/py/tests/script_test.py @@ -0,0 +1,156 @@ +from datetime import datetime +import pytest +import zipfile + + +from port.script import parse_json_to_dataframe +from port.script import aggregate_distance_by_day_activity +from port.script import extract +from port.script import extract_data_from_zip + + +@pytest.fixture +def sample_data(): + return { + "timelineObjects": [ + { + "activitySegment": { + "duration": {"startTimestamp": "2023-04-01T19:13:27.023Z"}, + "activityType": "CYCLING", + "waypointPath": {"distanceMeters": 3600.33}, + } + } + ] + } + + +@pytest.fixture +def sample_data_multiple_activities(): + return { + "timelineObjects": [ + { + "activitySegment": { + "duration": {"startTimestamp": "2023-04-01T19:13:27.023Z"}, + "activityType": "CYCLING", + "waypointPath": {"distanceMeters": 3600.33}, + } + }, + { + "activitySegment": { + "duration": {"startTimestamp": "2023-04-01T20:13:27.023Z"}, + "activityType": "CYCLING", + "waypointPath": {"distanceMeters": 1400.0}, + } + }, + { + "activitySegment": { + "duration": {"startTimestamp": "2023-04-02T08:13:27.023Z"}, + "activityType": "WALKING", + "waypointPath": {"distanceMeters": 800.5}, + } + }, + { + "activitySegment": { + "duration": {"startTimestamp": "2023-04-01T19:13:27.023Z"}, + "activityType": "RUNNING", + "waypointPath": {"distanceMeters": 3600.33}, + } + }, + { + "activitySegment": { + "duration": {"startTimestamp": "2023-04-01T20:13:27.023Z"}, + "activityType": "RUNNING", + "waypointPath": {"distanceMeters": 1400.0}, + } + }, + ] + } + + +def test_parse_json_to_dataframe(sample_data): + df = parse_json_to_dataframe(sample_data) + assert len(df) == 1 + assert df.iloc[0]["activityType"] == "CYCLING" + assert df.iloc[0]["distanceMeters"] == 3600.33 + assert isinstance(df.iloc[0]["startTimestamp"], datetime) + + +def test_parse_json_to_dataframe_skips_non_walking_or_cycling(): + parsed_dict = { + "timelineObjects": [ + { + "activitySegment": { + "activityType": "WALKING", + "duration": {"startTimestamp": "2023-09-17T10:00:00Z"}, + "waypointPath": {"distanceMeters": 1000}, + } + }, + { + "activitySegment": { + "activityType": "CYCLING", + "duration": {"startTimestamp": "2023-09-17T11:00:00Z"}, + "waypointPath": {"distanceMeters": 5000}, + } + }, + { + "activitySegment": { + "activityType": "DRIVING", + "duration": {"startTimestamp": "2023-09-17T12:00:00Z"}, + "waypointPath": {"distanceMeters": 20000}, + } + }, + ] + } + + df = parse_json_to_dataframe(parsed_dict) + assert "DRIVING" not in df.activityType.values + + +def test_aggregate_distance_by_day_activity(sample_data): + df = parse_json_to_dataframe(sample_data) + aggregated_df = aggregate_distance_by_day_activity(df) + + assert len(aggregated_df) == 1 + assert aggregated_df.iloc[0]["startTimestamp"] == "2023-04-01" + assert aggregated_df.iloc[0]["activityType"] == "CYCLING" + assert aggregated_df.iloc[0]["distanceMeters"] == 3600.33 + + +def test_aggregation_over_multiple_activities(sample_data_multiple_activities): + df = parse_json_to_dataframe(sample_data_multiple_activities) + aggregated_df = aggregate_distance_by_day_activity(df) + + # Verify that there are 2 aggregated entries (one for each day) + assert len(aggregated_df) == 3 + + # For 2023-04-01, there were two cycling activities. We sum their distances. + cycling_data = aggregated_df[(aggregated_df["activityType"] == "CYCLING")] + assert len(cycling_data) == 1 + assert cycling_data.iloc[0]["distanceMeters"] == (3600.33 + 1400.0) + + # For 2023-04-02, there was one walking activity. + walking_data = aggregated_df[aggregated_df["activityType"] == "WALKING"] + assert len(walking_data) == 1 + assert walking_data.iloc[0]["distanceMeters"] == 800.5 + + # For 2023-05-02, there was one running activity. + walking_data = aggregated_df[aggregated_df["activityType"] == "RUNNING"] + assert len(walking_data) == 1 + assert walking_data.iloc[0]["distanceMeters"] == (3600.33 + 1400.0) + + +def test_extract_sample_data(sample_data): + results = extract(parse_json_to_dataframe(sample_data)) + # Verify the results + assert len(results) == 1 + assert results[0].id == "cycling" + assert results[0].title.translations["nl"] == "Gefietst" + for result in results: + assert "distanceMeters" not in result.data_frame.columns + assert "Afstand in km" in result.data_frame.columns + +def test_empty_zip(tmp_path): + path = tmp_path.joinpath("test.zip") + z = zipfile.ZipFile(path, "w") + z.close() + assert extract_data_from_zip(path) == "no-data" \ No newline at end of file