Skip to content

Commit

Permalink
Enforcing black formatting, adding CI
Browse files Browse the repository at this point in the history
  • Loading branch information
mrhheffernan committed Apr 29, 2023
1 parent 31e4f2d commit 71a63f3
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 94 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/black.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: Lint

on: [push, pull_request]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: psf/black@stable
63 changes: 38 additions & 25 deletions fit_to_csv.py
Original file line number Diff line number Diff line change
@@ -1,63 +1,76 @@
import csv
import os
#to install fitparse, run
#sudo pip3 install -e git+https://github.com/dtcooper/python-fitparse#egg=python-fitparse

# to install fitparse, run
# sudo pip3 install -e git+https://github.com/dtcooper/python-fitparse#egg=python-fitparse
import fitparse
import pytz

allowed_fields = ['timestamp','position_lat','position_long', 'distance',
'enhanced_altitude', 'altitude','enhanced_speed',
'speed', 'heart_rate','cadence','fractional_cadence']
required_fields = ['timestamp', 'position_lat', 'position_long', 'altitude']
allowed_fields = [
"timestamp",
"position_lat",
"position_long",
"distance",
"enhanced_altitude",
"altitude",
"enhanced_speed",
"speed",
"heart_rate",
"cadence",
"fractional_cadence",
]
required_fields = ["timestamp", "position_lat", "position_long", "altitude"]

UTC = pytz.UTC
CST = pytz.timezone('US/Central')
CST = pytz.timezone("US/Central")


def main():
files = os.listdir()
fit_files = [file for file in files if file[-4:].lower()=='.fit']
fit_files = [file for file in files if file[-4:].lower() == ".fit"]
for file in fit_files:
new_filename = file[:-4] + '.csv'
new_filename = file[:-4] + ".csv"
if os.path.exists(new_filename):
#print('%s already exists. skipping.' % new_filename)
# print('%s already exists. skipping.' % new_filename)
continue
fitfile = fitparse.FitFile(file,
data_processor=fitparse.StandardUnitsDataProcessor())
fitfile = fitparse.FitFile(
file, data_processor=fitparse.StandardUnitsDataProcessor()
)

print('converting %s' % file)
print("converting %s" % file)
write_fitfile_to_csv(fitfile, new_filename)
print('finished conversions')
print("finished conversions")


def write_fitfile_to_csv(fitfile, output_file='test_output.csv'):
def write_fitfile_to_csv(fitfile, output_file="test_output.csv"):
messages = fitfile.messages
data = []
for m in messages:
skip=False
if not hasattr(m, 'fields'):
skip = False
if not hasattr(m, "fields"):
continue
fields = m.fields
#check for important data types
# check for important data types
mdata = {}
for field in fields:
if field.name in allowed_fields:
if field.name=='timestamp':
if field.name == "timestamp":
mdata[field.name] = UTC.localize(field.value).astimezone(CST)
else:
mdata[field.name] = field.value
for rf in required_fields:
if rf not in mdata:
skip=True
skip = True
if not skip:
data.append(mdata)
#write to csv
with open(output_file, 'w') as f:
# write to csv
with open(output_file, "w") as f:
writer = csv.writer(f)
writer.writerow(allowed_fields)
for entry in data:
writer.writerow([ str(entry.get(k, '')) for k in allowed_fields])
print('wrote %s' % output_file)
writer.writerow([str(entry.get(k, "")) for k in allowed_fields])
print("wrote %s" % output_file)


if __name__=='__main__':
if __name__ == "__main__":
main()
92 changes: 52 additions & 40 deletions personal_heatmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,34 @@
from geopy.geocoders import Nominatim

geolocator = Nominatim()
location = geolocator.geocode("Montreal Quebec") # Change this to change location centering
lat_check = float(location.raw['lat'])
lon_check = float(location.raw['lon'])
location = geolocator.geocode(
"Montreal Quebec"
) # Change this to change location centering
lat_check = float(location.raw["lat"])
lon_check = float(location.raw["lon"])

data = glob.glob('*.gpx')
fitdata = glob.glob('*.fit')
data = glob.glob("*.gpx")
fitdata = glob.glob("*.fit")

if not len(fitdata) == 0:
print('Converting Garmin FIT files')
os.system('python fit_to_csv.py')
os.system('mkdir fit_files')
os.system('mv *.fit ./fit_files')
print("Converting Garmin FIT files")
os.system("python fit_to_csv.py")
os.system("mkdir fit_files")
os.system("mv *.fit ./fit_files")

csvdata = glob.glob('*.csv')
csvdata = glob.glob("*.csv")

lat = []
lon = []

all_lat = []
all_long = []

print('Loading data')
print("Loading data")

for activity in data:
gpx_filename = activity
gpx_file = open(gpx_filename, 'r')
gpx_file = open(gpx_filename, "r")
gpx = gpxpy.parse(gpx_file)

for track in gpx.tracks:
Expand All @@ -43,10 +45,14 @@
lat.append(point.latitude)
lon.append(point.longitude)

check1 = np.any(np.isclose(lat,lat_check,atol=0.5)) # Change the tolerance 'atol' to include a larger or smaller area around the centering point
check2 = np.any(np.isclose(lon, lon_check,atol=0.5)) # Change the tolerance 'atol' to include a larger or smaller area around the centering point
check1 = np.any(
np.isclose(lat, lat_check, atol=0.5)
) # Change the tolerance 'atol' to include a larger or smaller area around the centering point
check2 = np.any(
np.isclose(lon, lon_check, atol=0.5)
) # Change the tolerance 'atol' to include a larger or smaller area around the centering point

if check1 and check2 :
if check1 and check2:
all_lat.append(lat)
all_long.append(lon)

Expand All @@ -58,13 +64,17 @@
csv_file = pd.read_csv(csv_filename)

for i in range(len(csv_file)):
lat.append(csv_file['position_lat'][i])
lon.append(csv_file['position_long'][i])
lat.append(csv_file["position_lat"][i])
lon.append(csv_file["position_long"][i])

check1 = np.any(np.isclose(lat,lat_check,atol=0.5)) # Change the tolerance 'atol' to include a larger or smaller area around the centering point
check2 = np.any(np.isclose(lon, lon_check,atol=0.5)) # Change the tolerance 'atol' to include a larger or smaller area around the centering point
check1 = np.any(
np.isclose(lat, lat_check, atol=0.5)
) # Change the tolerance 'atol' to include a larger or smaller area around the centering point
check2 = np.any(
np.isclose(lon, lon_check, atol=0.5)
) # Change the tolerance 'atol' to include a larger or smaller area around the centering point

if check1 and check2 :
if check1 and check2:
all_lat.append(lat)
all_long.append(lon)

Expand All @@ -74,17 +84,19 @@
all_lat = all_lat[0]
all_long = all_long[0]

central_long = sum(all_long)/float(len(all_long))
central_lat = sum(all_lat)/float(len(all_lat))
central_long = sum(all_long) / float(len(all_long))
central_lat = sum(all_lat) / float(len(all_lat))

print('Initializing map')
m = folium.Map(location=[central_lat,central_long],tiles="Stamen Toner",zoom_start=14.2) # Recommended map styles are "Stamen Terrain", "Stamen Toner"
print("Initializing map")
m = folium.Map(
location=[central_lat, central_long], tiles="Stamen Toner", zoom_start=14.2
) # Recommended map styles are "Stamen Terrain", "Stamen Toner"

print('Plotting gpx data')
print("Plotting gpx data")

for activity in data:
gpx_filename = activity
gpx_file = open(gpx_filename, 'r')
gpx_file = open(gpx_filename, "r")
gpx = gpxpy.parse(gpx_file)

for track in gpx.tracks:
Expand All @@ -93,30 +105,30 @@
lat.append(point.latitude)
lon.append(point.longitude)

points = zip(lat,lon)
points = [item for item in zip(lat,lon)]
points = zip(lat, lon)
points = [item for item in zip(lat, lon)]

folium.PolyLine(points, color="red", weight=2.5, opacity=0.5).add_to(m)
lat = []
lon = []

print('Plotting csv data')
print("Plotting csv data")
color = "red"
hr = []
for activity in csvdata:
csv_filename = activity
csv_file = pd.read_csv(csv_filename)
for i in range(len(csv_file)):
lat.append(csv_file['position_lat'][i])
lon.append(csv_file['position_long'][i])
hr.append(csv_file['heart_rate'][i])
points = zip(lat,lon)
points = [item for item in zip(lat,lon)]

#color = []
#print('heart_rate',csv_file['heart_rate'])
#hr = hr / max(hr)
#for value in hr:
lat.append(csv_file["position_lat"][i])
lon.append(csv_file["position_long"][i])
hr.append(csv_file["heart_rate"][i])
points = zip(lat, lon)
points = [item for item in zip(lat, lon)]

# color = []
# print('heart_rate',csv_file['heart_rate'])
# hr = hr / max(hr)
# for value in hr:
# if value < 0.2:
# color.append("darkred")
# elif value >= 0.2 and value < 0.4:
Expand All @@ -133,4 +145,4 @@
lon = []
hr = []

m.save('heatmap.html')
m.save("heatmap.html")
51 changes: 30 additions & 21 deletions selenium_downloader.py
Original file line number Diff line number Diff line change
@@ -1,64 +1,73 @@
from selenium import webdriver
import time
driver = webdriver.Chrome(executable_path='<replace>')

download_dir = '<replace>'
driver = webdriver.Chrome(executable_path="<replace>")

download_dir = "<replace>"

options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors')
options.add_argument("--ignore-certificate-errors")
options.add_argument("--test-type")
options.binary_location = "/usr/bin/chromium-browser"

options.add_experimental_option('prefs', {
"plugins.plugins_list": [{"enabled":False,"name":"Chrome PDF Viewer"}],
"download": {
"prompt_for_download": False,
"default_directory" : download_dir
}
})
options.add_experimental_option(
"prefs",
{
"plugins.plugins_list": [{"enabled": False, "name": "Chrome PDF Viewer"}],
"download": {"prompt_for_download": False, "default_directory": download_dir},
},
)
driver = webdriver.Chrome(chrome_options=options)

usern, passw, id = open('login_info.secret').read().strip().split(',')
usern, passw, id = open("login_info.secret").read().strip().split(",")

driver.get('http://strava.com/login')
driver.get("http://strava.com/login")

usern_box = driver.find_element_by_xpath("//input[@name='email' and @type='email']")
usern_box.send_keys(usern)

passw_box = driver.find_element_by_xpath("//input[@name='password' and @type='password']")
passw_box = driver.find_element_by_xpath(
"//input[@name='password' and @type='password']"
)
passw_box.send_keys(passw)

submit_button = driver.find_element_by_xpath('//button[@id="login-button"]')
submit_button.click()

time.sleep(2)

driver.get("https://www.strava.com/athletes/"+str(id))
driver.get("https://www.strava.com/athletes/" + str(id))

monthly_button = driver.find_element_by_xpath('//a[contains(@class,"button btn-xs") and contains(@href,"month")]')
monthly_button = driver.find_element_by_xpath(
'//a[contains(@class,"button btn-xs") and contains(@href,"month")]'
)
monthly_button.click()

time.sleep(2)

bar_list = driver.find_elements_by_xpath('//a[@class="bar" and contains(@href,"interval")]')
bar_list = driver.find_elements_by_xpath(
'//a[@class="bar" and contains(@href,"interval")]'
)

activity_list = []

for bar in bar_list:
bar.click()
time.sleep(3)

for a in driver.find_elements_by_xpath('.//a[contains(@href, "activities") and not(contains(@href, "twitter")) and not(contains(@href, "#")) and not(contains(@href, "photos")) and not(contains(@href, "segments"))]'):
activity_list.append(a.get_attribute('href'))
for a in driver.find_elements_by_xpath(
'.//a[contains(@href, "activities") and not(contains(@href, "twitter")) and not(contains(@href, "#")) and not(contains(@href, "photos")) and not(contains(@href, "segments"))]'
):
activity_list.append(a.get_attribute("href"))

activity_list = set(activity_list)

print('Number of activities found: ',len(activity_list))
print("Number of activities found: ", len(activity_list))

for address in activity_list:
driver.get(address+"/export_gpx")
driver.get(address + "/export_gpx")
time.sleep(1)

print('Data downloaded to '+download_dir+', quitting.')
print("Data downloaded to " + download_dir + ", quitting.")

driver.quit()
Loading

0 comments on commit 71a63f3

Please sign in to comment.