Skip to content

Instantly share code, notes, and snippets.

@dimisjim
Created June 9, 2024 10:49
Show Gist options
  • Save dimisjim/173c78d01219bc767d1f373e48e6a28a to your computer and use it in GitHub Desktop.
Save dimisjim/173c78d01219bc767d1f373e48e6a28a to your computer and use it in GitHub Desktop.
jsonToCsvConverterGoogleTimeline
#!/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