Created
June 9, 2024 10:49
-
-
Save dimisjim/173c78d01219bc767d1f373e48e6a28a to your computer and use it in GitHub Desktop.
jsonToCsvConverterGoogleTimeline
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import json | |
import csv | |
import sys | |
import datetime | |
import os | |
def make_reader(in_json): | |
# Open location history data | |
with open(in_json) as f: | |
json_data = json.load(f) | |
print("JSON data loaded.") | |
# Process the JSON data | |
if 'timelineObjects' in json_data: | |
timeline_objects = json_data['timelineObjects'] | |
else: | |
print("Expected 'timelineObjects' in JSON data.") | |
return | |
# Process placeVisit entries | |
for item in timeline_objects: | |
if 'placeVisit' in item: | |
visit = item['placeVisit'] | |
location = visit['location'] | |
duration = visit['duration'] | |
try: | |
dt_start = datetime.datetime.strptime(duration['startTimestamp'], '%Y-%m-%dT%H:%M:%SZ') | |
except ValueError: | |
dt_start = datetime.datetime.strptime(duration['startTimestamp'], '%Y-%m-%dT%H:%M:%S.%fZ') | |
try: | |
dt_end = datetime.datetime.strptime(duration['endTimestamp'], '%Y-%m-%dT%H:%M:%SZ') | |
except ValueError: | |
dt_end = datetime.datetime.strptime(duration['endTimestamp'], '%Y-%m-%dT%H:%M:%S.%fZ') | |
longitude = location['longitudeE7'] / 10000000.0 | |
latitude = location['latitudeE7'] / 10000000.0 | |
place_id = location['placeId'] | |
address = location.get('address', 'N/A') | |
location_confidence = location.get('locationConfidence', 'N/A') | |
yield [dt_start, dt_start.strftime('%Y-%m-%d'), dt_start.strftime('%H:%M:%S'), | |
dt_end, dt_end.strftime('%Y-%m-%d'), dt_end.strftime('%H:%M:%S'), | |
longitude, latitude, place_id, address, location_confidence, 'N/A', 'N/A'] | |
# Process activitySegment entries | |
for item in timeline_objects: | |
if 'activitySegment' in item: | |
segment = item['activitySegment'] | |
start_location = segment['startLocation'] | |
end_location = segment['endLocation'] | |
duration = segment['duration'] | |
activity_type = segment['activityType'] | |
distance = segment.get('distance', 0) | |
try: | |
dt_start = datetime.datetime.strptime(duration['startTimestamp'], '%Y-%m-%dT%H:%M:%SZ') | |
except ValueError: | |
dt_start = datetime.datetime.strptime(duration['startTimestamp'], '%Y-%m-%dT%H:%M:%S.%fZ') | |
try: | |
dt_end = datetime.datetime.strptime(duration['endTimestamp'], '%Y-%m-%dT%H:%M:%SZ') | |
except ValueError: | |
dt_end = datetime.datetime.strptime(duration['endTimestamp'], '%Y-%m-%dT%H:%M:%S.%fZ') | |
start_longitude = start_location['longitudeE7'] / 10000000.0 | |
start_latitude = start_location['latitudeE7'] / 10000000.0 | |
end_longitude = end_location['longitudeE7'] / 10000000.0 | |
end_latitude = end_location['latitudeE7'] / 10000000.0 | |
yield [dt_start, dt_start.strftime('%Y-%m-%d'), dt_start.strftime('%H:%M:%S'), | |
dt_end, dt_end.strftime('%Y-%m-%d'), dt_end.strftime('%H:%M:%S'), | |
start_longitude, start_latitude, 'N/A', 'N/A', 'N/A', 'N/A', | |
end_longitude, end_latitude, activity_type, distance] | |
def getFullPath(inPath): | |
if not os.path.isabs(inPath): | |
# we need to set up the absolute path | |
script_path = os.path.abspath(__file__) | |
path, file = os.path.split(script_path) | |
inPath = os.path.join(path, inPath) | |
return inPath | |
# Read the Parameters | |
if len(sys.argv) < 3: | |
print("Usage: script.py <input_json_file> <output_csv_file>") | |
sys.exit(1) | |
in_file = sys.argv[1] | |
out_file = sys.argv[2] | |
in_file = getFullPath(in_file) | |
out_file = getFullPath(out_file) | |
features = [] | |
# add the Headers | |
features.append(['Start Datetime', 'Start Date', 'Start Time', 'End Datetime', 'End Date', 'End Time', | |
'Longitude', 'Latitude', 'Place ID', 'Address', 'Location Confidence', | |
'Start Longitude', 'Start Latitude', 'End Longitude', 'End Latitude', 'Activity Type', 'Distance']) | |
print("Reading {0}".format(in_file)) | |
reader = make_reader(in_file) | |
record_count = 0 | |
for r in reader: | |
print(r) # Print each record to see what is being processed | |
features.append(r) | |
record_count += 1 | |
print(f'Read {record_count} Records') | |
# write this data | |
with open(out_file, 'w', newline='') as f: | |
writer = csv.writer(f) | |
writer.writerows(features) | |
print(f'CSV output written to {out_file}') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment