Skip to content

Instantly share code, notes, and snippets.

@spott
Last active October 8, 2016 19:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spott/8ae519e93840cb438608f86ab81374d4 to your computer and use it in GitHub Desktop.
Save spott/8ae519e93840cb438608f86ab81374d4 to your computer and use it in GitHub Desktop.
Beeminder weekends off function
def beeminder_weekends_off(username, goal, auth_token):
# requests (http://docs.python-requests.org/en/stable/) is used for the requests
import requests
# I use too many time libraries...
import time as tt
from datetime import date, time, datetime, timedelta
#base API url
url = "https://www.beeminder.com/api/v1/users/"+username+"/goals/"+goal+".json"
with requests.Session() as s:
r = s.get(url, params=auth_token)
data = r.json()
#get the road:
road = data['roadall']
#what the weekday is today
current_weekday = date.fromtimestamp(tt.time()).weekday()
#find the distance to the next friday we can actually change (beyond the akrasia horizon)
editable_next_fri = timedelta(7 - current_weekday + 4) if current_weekday > 4 else timedelta(4-current_weekday)
# the friday we can edit. Using date so we get days rather than datetime.
date_wanted = date.fromtimestamp(tt.time()) + editable_next_fri + timedelta(7)
#the slope over the weekend
wanted_slope = 0
#read the whole road, figure out what the slope should be on the date we want, and what it should be after what we want.
for i, (t, val, slope) in reversed(list(enumerate(road))):
# compare dates for the monday after (not times) to see if the slope over the weekend is
# already set. Note, if the "weekend" doesn't start on a friday we don't actually check that.
if date.fromtimestamp(t) == date_wanted + timedelta(3) and slope == 0:
return # we are already on a break, and don't need to change anything.
if date.fromtimestamp(t) < date_wanted:
break # the last point we saw contains the slope we want.
else:
#if we aren't before the end date of the weekend, we record the slope. This is the slope after the weekend.
wanted_slope = slope
if i == 0:
#we didn't find the date... something went wrong.
raise
#we now have the wanted slope, and the point to insert it at (i), so we can insert things correctly:
road = data["roadall"][0:i+1] + \
[[int(datetime.combine(date_wanted, time(0)).timestamp()),None,wanted_slope]] + \
[[int(datetime.combine(date_wanted + timedelta(3),time(0)).timestamp()),None,0]] + data["roadall"][i+1:]
#create the payload for the requests library.
payload = {"roadall": road }
#add the authorization token
payload.update(auth_token)
print(payload)
#send it along. The payload must be sent using the json field rather than the data field
# otherwise things don't work.
r = s.put(url, json=payload)
print(r.request.body)
r.raise_for_status()
return r
@spott
Copy link
Author

spott commented Oct 8, 2016

Added comments

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