-
Notifications
You must be signed in to change notification settings - Fork 51
/
beemapi.pl
executable file
·126 lines (115 loc) · 4.3 KB
/
beemapi.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# Rough implementation of some Beeminder API calls needed for TagTime
# See http://beeminder.com/api
# Get your personal Beeminder auth token (after signing in) from
# https://www.beeminder.com/api/v1/auth_token.json
# And set a global variable like $beemauth = "abc123";
# (That's already done in TagTime settings but if you're using this elsewhere
# you'll need to set $beemauth.)
use LWP::UserAgent; # tip: run 'sudo cpan' and at the cpan prompt do 'upgrade'
use JSON; # then 'install LWP::UserAgent' and 'install JSON' etc
use HTTP::Request::Common; # pjf recomends cpanmin.us
use Data::Dumper; $Data::Dumper::Terse = 1;
#use LWP::Protocol::Net::Curl; # Philip Hellyer recommends this to nix SSL errors
$beembase = 'https://www.beeminder.com/api/v1/';
# Fetch the Beeminder deadline for the relevant TagTime goal
sub beemdeadline { my($u, $g) = @_;
my $ua = LWP::UserAgent->new;
$ua->ssl_opts(
SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE,
verify_hostname => 0
);
my $uri = $beembase .
"users/$u/goals/$g.json?auth_token=$beemauth";
my $resp = $ua->get($uri);
beemerr('GET', $uri, {}, $resp);
my $x = decode_json($resp->content);
return $x->{"deadline"};
}
# Delete datapoint with given id for beeminder.com/u/g
sub beemdelete { my($u, $g, $id) = @_;
my $ua = LWP::UserAgent->new;
$ua->ssl_opts(
SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE,
verify_hostname => 0
);
my $uri = $beembase .
"users/$u/goals/$g/datapoints/$id.json?auth_token=$beemauth";
my $resp = $ua->delete($uri);
beemerr('DELETE', $uri, {}, $resp);
}
# Fetch all the datapoints for beeminder.com/u/g
sub beemfetch { my($u, $g) = @_;
my $ua = LWP::UserAgent->new;
$ua->ssl_opts(
SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE,
verify_hostname => 0
);
#$ua->timeout(30); # give up if no response for this many seconds; default 180
my $uri = $beembase .
"users/$u/goals/$g/datapoints.json?auth_token=$beemauth";
my $resp = $ua->get($uri);
beemerr('GET', $uri, {}, $resp);
return decode_json($resp->content);
}
# Create a new datapoint {timestamp t, value v, comment c} for bmndr.com/u/g
# and return the id of the new datapoint.
sub beemcreate { my($u, $g, $t, $v, $c) = @_;
my $ua = LWP::UserAgent->new;
$ua->ssl_opts(
SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE,
verify_hostname => 0
);
my $uri = $beembase."users/$u/goals/$g/datapoints.json?auth_token=$beemauth";
my $data = { timestamp => $t,
value => $v,
comment => $c };
my $resp = $ua->post($uri, Content => $data);
beemerr('POST', $uri, $data, $resp);
my $x = decode_json($resp->content);
return $x->{"id"};
}
# Update a datapoint with the given id. Similar to beemcreate/beemdelete.
sub beemupdate { my($u, $g, $id, $t, $v, $c) = @_;
my $ua = LWP::UserAgent->new;
$ua->ssl_opts(
SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE,
verify_hostname => 0
);
my $uri = $beembase .
"users/$u/goals/$g/datapoints/$id.json?auth_token=$beemauth";
my $data = { timestamp => $t,
value => $v,
comment => $c };
# you'd think the following would work:
# my $resp = $ua->put($uri, Content => $data);
# but it doesn't so we use the following workaround, courtesy of
# http://stackoverflow.com/questions/11202123/how-can-i-make-a-http-put
my $req = POST($uri, Content => $data);
$req->method('PUT');
my $resp = $ua->request($req);
beemerr('PUT', $uri, $data, $resp);
}
# Takes request type (GET, POST, etc), uri string, hashref of data arguments,
# and response object; barfs verbosely if problems.
# Obviously this isn't the best way to do this.
sub beemerr { my($rt, $uri, $data, $resp) = @_;
if(!$resp->is_success) {
print "Error making the following $rt request to Beeminder:\n$uri\n";
print Dumper $data;
print $resp->status_line, "\n", $resp->content, "\n";
exit 1;
}
}
1; # when requiring a library in perl it has to return 1.
# How Paul Fenwick does it in Perl:
#my ($user, $auth_token, $datapoint, $comment);
#my $mech = WWW::Mechanize( autocheck => 1 )
#$mech->post(
#"http://beeminder.com/api/v1/users/$busr/goals/$slug/datapoints.json?
#auth_token=$auth_token",
#{
# timestamp => time(),
# value => $datapoint,
# comment => $comment
#}
#);