Skip to content

Instantly share code, notes, and snippets.

@fedragon
Last active August 26, 2021 22:31
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save fedragon/4e3ba48ed992495d337e50f71e82c39d to your computer and use it in GitHub Desktop.
Collect total running distance since last Monday from Strava API
from datetime import date, datetime, time, timedelta
import json
import os
import shutil
from urllib import parse, request
from urllib.error import HTTPError
import yaml
def get_new_access_token(ctx):
data = parse.urlencode(
{
"client_id": ctx["client_id"],
"client_secret": ctx["client_secret"],
"refresh_token": ctx["refresh_token"],
"grant_type": "refresh_token",
}
).encode()
req = request.Request("https://www.strava.com/api/v3/oauth/token", data=data)
try:
res = request.urlopen(req)
data = json.loads(res.read().decode("utf-8"))
except:
print("Got unexpected HTTP status code {}".format(res.getcode()))
exit(1)
shutil.move(".env", ".env.bck")
with open(".env", "w") as f:
f.write("set -x ACCESS_TOKEN {}\n".format(data["access_token"]))
f.write("set -x REFRESH_TOKEN {}\n".format(data["refresh_token"]))
f.write("set -x CLIENT_ID {}\n".format(ctx["client_id"]))
f.write("set -x CLIENT_SECRET {}\n".format(ctx["client_secret"]))
ctx["access_token"] = data["access_token"]
ctx["refresh_token"] = data["refresh_token"]
return ctx
def get_activities(ctx, start_datetime):
req = request.Request(
"https://www.strava.com/api/v3/athlete/activities?after={}".format(
start_datetime
)
)
req.add_header("Authorization", "Bearer {}".format(ctx["access_token"]))
try:
res = request.urlopen(req)
total_m = 0
for x in json.loads(res.read().decode("utf-8")):
if x["type"] == "Run":
total_m += x["distance"]
total_km_rounded = round(total_m / 1000, 1)
return total_km_rounded
except HTTPError as e:
if e.code == 401:
new_ctx = get_new_access_token(ctx)
return get_activities(new_ctx, start_datetime)
else:
print("Got unexpected HTTP status code {}".format(res.getcode()))
exit(1)
def write_mileage(mileage):
data = {"mileage": {"weekly": mileage}}
with open("data/running.yaml", "w") as f:
yaml.dump(data, f)
def main():
ctx = {
"access_token": os.environ.get("ACCESS_TOKEN"),
"refresh_token": os.environ.get("REFRESH_TOKEN"),
"client_id": os.environ.get("CLIENT_ID"),
"client_secret": os.environ.get("CLIENT_SECRET"),
}
if ctx["access_token"] is None:
print("ACCESS_TOKEN not set. Quitting.")
exit(1)
if ctx["refresh_token"] is None:
print("REFRESH_TOKEN not set. Quitting.")
exit(1)
if ctx["client_id"] is None:
print("CLIENT_ID not set. Quitting.")
exit(1)
if ctx["client_secret"] is None:
print("CLIENT_SECRET not set. Quitting.")
exit(1)
today = date.today()
if today.weekday() == 0:
last_monday_at_midnight = round(datetime.combine(today, time.min).timestamp())
else:
last_monday_at_midnight = round(
datetime.combine(
today - timedelta(days=today.weekday()), time.min
).timestamp()
)
mileage = get_activities(ctx=ctx, start_datetime=last_monday_at_midnight)
write_mileage(mileage)
if __name__ == "__main__":
main()
@fedragon
Copy link
Author

and then save it to data/running.yaml so that it can be referenced in Hugo data templates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment