Last active
October 8, 2016 19:49
-
-
Save spott/8ae519e93840cb438608f86ab81374d4 to your computer and use it in GitHub Desktop.
Beeminder weekends off function
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
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Added comments