beeminder 0.2.10 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/beeminder.gemspec +6 -6
- data/bin/beemind +4 -4
- data/lib/beeminder.rb +1 -0
- data/lib/beeminder/goals.rb +31 -2
- data/lib/beeminder/user.rb +32 -11
- data/lib/beeminder/version.rb +1 -1
- metadata +19 -38
- checksums.yaml.gz.sig +0 -2
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d48e75546e891468169cba69c260a9b183a02856
|
4
|
+
data.tar.gz: a8bec82ae557bdd48009dd6b8ae96e4bc19f977a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4dfdd266db0b8ed2b2a0e7aa8583e497719792351c2d7cb7aeb5fbfbccae9e7beb37b20204dea9ff3a4748b83069bd2b015311c3b0d49e18abb67d4944d1206
|
7
|
+
data.tar.gz: 80a2fd645e8762ba2d8f241628db3dffc2b42ec72a102e2505a75eaaf6b012dc929dc33402f9524929a217caa2d7968fb9a906e50c8cba8c31fbf5b1b6f6770c
|
data/beeminder.gemspec
CHANGED
@@ -6,8 +6,8 @@ require 'beeminder/version'
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "beeminder"
|
8
8
|
gem.version = Beeminder::VERSION
|
9
|
-
gem.authors = ["muflax"]
|
10
|
-
gem.email = ["
|
9
|
+
gem.authors = ["muflax", "bsoule"]
|
10
|
+
gem.email = ["support@beeminder.com"]
|
11
11
|
gem.description = "Convenient access to Beeminder's API."
|
12
12
|
gem.summary = "access Beeminder API"
|
13
13
|
gem.homepage = "https://github.com/beeminder/beeminder-gem"
|
@@ -16,10 +16,10 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
17
|
gem.require_paths = ["lib"]
|
18
18
|
|
19
|
-
gem.add_dependency 'activesupport', ['>= 3.2', '<
|
19
|
+
gem.add_dependency 'activesupport', ['>= 3.2', '< 6']
|
20
20
|
gem.add_dependency 'chronic', '~> 0.7'
|
21
|
-
gem.add_dependency 'json'
|
21
|
+
gem.add_dependency 'json', '~> 1'
|
22
22
|
gem.add_dependency 'highline', '~> 1.6'
|
23
|
-
gem.add_dependency '
|
24
|
-
gem.add_dependency 'tzinfo'
|
23
|
+
gem.add_dependency 'optimist', '~> 3'
|
24
|
+
gem.add_dependency 'tzinfo', '~> 1.2'
|
25
25
|
end
|
data/bin/beemind
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'chronic'
|
5
5
|
require 'highline/import'
|
6
|
-
require '
|
6
|
+
require 'optimist'
|
7
7
|
require 'yaml'
|
8
8
|
|
9
9
|
# load library
|
@@ -18,7 +18,7 @@ else
|
|
18
18
|
end
|
19
19
|
|
20
20
|
usage = "usage: beemind goal value [comment]"
|
21
|
-
opts =
|
21
|
+
opts = Optimist::options do
|
22
22
|
banner usage
|
23
23
|
|
24
24
|
opt :config, "Path to config.", :type => :string, :default => "~/.beeminderrc"
|
@@ -27,7 +27,7 @@ opts = Trollop::options do
|
|
27
27
|
opt :date, "Set a manual date. Uses Chronic syntax.", :type => :string, :default => "now"
|
28
28
|
end
|
29
29
|
|
30
|
-
|
30
|
+
Optimist::die usage if not (2..3).include?(ARGV.size) and not opts[:list]
|
31
31
|
goal, value, comment = ARGV unless opts[:list]
|
32
32
|
|
33
33
|
opts[:config] = File.expand_path opts[:config]
|
@@ -66,7 +66,7 @@ if opts[:list]
|
|
66
66
|
end
|
67
67
|
else
|
68
68
|
date = Chronic.parse(opts[:date], :context => :past)
|
69
|
-
|
69
|
+
Optimist::die "invalid date" if date.nil?
|
70
70
|
|
71
71
|
g = bee.goal goal
|
72
72
|
dp = Beeminder::Datapoint.new :timestamp => date,
|
data/lib/beeminder.rb
CHANGED
data/lib/beeminder/goals.rb
CHANGED
@@ -59,6 +59,9 @@ module Beeminder
|
|
59
59
|
|
60
60
|
# @return [Beeminder::User] User that owns this goal.
|
61
61
|
attr_reader :user
|
62
|
+
|
63
|
+
# @return [Array<Integer, Float, Float>] All road settings over time
|
64
|
+
attr_accessor :roadall
|
62
65
|
|
63
66
|
def initialize user, name_or_info
|
64
67
|
@user = user
|
@@ -79,7 +82,7 @@ module Beeminder
|
|
79
82
|
# Reload data from Beeminder.
|
80
83
|
def reload
|
81
84
|
info = @user.get "users/me/goals/#{@slug}.json"
|
82
|
-
|
85
|
+
_parse_info info
|
83
86
|
end
|
84
87
|
|
85
88
|
# List of datapoints.
|
@@ -108,8 +111,9 @@ module Beeminder
|
|
108
111
|
"secret" => @secret || false,
|
109
112
|
"datapublic" => @datapublic || false,
|
110
113
|
}
|
114
|
+
data['roadall'] = @roadall if @roadall
|
111
115
|
|
112
|
-
@user.
|
116
|
+
@user.put_document "users/me/goals/#{@slug}.json", data
|
113
117
|
end
|
114
118
|
|
115
119
|
# Send new road setting to Beeminder.
|
@@ -126,6 +130,20 @@ module Beeminder
|
|
126
130
|
|
127
131
|
@user.post "users/me/goals/#{@slug}/dial_road.json", dials
|
128
132
|
end
|
133
|
+
|
134
|
+
# Schedule a break.
|
135
|
+
# Adds two new entries to `roadall` reflecting the break.
|
136
|
+
# Use #update to actually update the goal.
|
137
|
+
#
|
138
|
+
# @param start_time [Time] when to start the break -- must be after the akrasia horizon
|
139
|
+
# @param end_time [Time] when to end the break
|
140
|
+
# @param rate [Float] the slope of the road during the break
|
141
|
+
def schedule_break start_time, end_time, rate = 0.0
|
142
|
+
check_break start_time, end_time
|
143
|
+
|
144
|
+
roadall.insert(-2, [start_time.to_i, nil, roadall.last.last])
|
145
|
+
roadall.insert(-2, [end_time.to_i, nil, rate])
|
146
|
+
end
|
129
147
|
|
130
148
|
# Add one or more datapoints to the goal.
|
131
149
|
#
|
@@ -172,6 +190,14 @@ module Beeminder
|
|
172
190
|
|
173
191
|
private
|
174
192
|
|
193
|
+
def check_break start_time, end_time
|
194
|
+
akrasia_horizon = user.akrasia_horizon
|
195
|
+
fail ArgumentError, "break start can't be before the akrasia horizon (#{akrasia_horizon})" \
|
196
|
+
if start_time < akrasia_horizon
|
197
|
+
fail ArgumentError, 'break must start before it ends' \
|
198
|
+
unless end_time > start_time
|
199
|
+
end
|
200
|
+
|
175
201
|
def _parse_info info
|
176
202
|
# set variables
|
177
203
|
info.each do |k,v|
|
@@ -184,6 +210,9 @@ module Beeminder
|
|
184
210
|
@losedate = DateTime.strptime(@losedate.to_s, '%s').in_time_zone(@user.timezone) unless @losedate.nil?
|
185
211
|
@updated_at = DateTime.strptime(@updated_at.to_s, '%s').in_time_zone(@user.timezone)
|
186
212
|
@curdate = DateTime.strptime(@curdate.to_s, '%s').in_time_zone(@user.timezone) unless @curdate.nil?
|
213
|
+
|
214
|
+
# reported data is sometimes malformed like this
|
215
|
+
roadall.last[0] = nil if !roadall.nil? && roadall.last[0] == 0
|
187
216
|
end
|
188
217
|
end
|
189
218
|
|
data/lib/beeminder/user.rb
CHANGED
@@ -19,13 +19,13 @@ module Beeminder
|
|
19
19
|
|
20
20
|
# @return [true|false] Enforce user timezone for all passed times? Should be true unless you know what you're doing. (Default: `true`.)
|
21
21
|
attr_accessor :enforce_timezone
|
22
|
-
|
22
|
+
|
23
23
|
def initialize token, opts={}
|
24
24
|
opts = {
|
25
25
|
:auth_type => :personal,
|
26
26
|
:enforce_timezone => true,
|
27
27
|
}.merge(opts)
|
28
|
-
|
28
|
+
|
29
29
|
@token = token
|
30
30
|
@auth_type = opts[:auth_type]
|
31
31
|
@enforce_timezone = opts[:enforce_timezone]
|
@@ -39,7 +39,7 @@ module Beeminder
|
|
39
39
|
else
|
40
40
|
raise ArgumentError, "Auth type not supported, must be :personal or :oauth."
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
info = get "users/me.json"
|
44
44
|
|
45
45
|
@name = info["username"]
|
@@ -47,13 +47,13 @@ module Beeminder
|
|
47
47
|
@updated_at = DateTime.strptime(info["updated_at"].to_s, '%s').in_time_zone(@timezone)
|
48
48
|
end
|
49
49
|
|
50
|
-
# Enforce timezone for all passed times?
|
50
|
+
# Enforce timezone for all passed times?
|
51
51
|
#
|
52
52
|
# @return [true|false]
|
53
53
|
def enforce_timezone?
|
54
54
|
!!@enforce_timezone
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
# List of goals.
|
58
58
|
#
|
59
59
|
# @param filter [Symbol] filter goals, can be `:all` (default), `:frontburner` or `:backburner`
|
@@ -87,7 +87,7 @@ module Beeminder
|
|
87
87
|
dp = Beeminder::Datapoint.new :value => value, :comment => comment
|
88
88
|
goal.add dp
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
# Create new goal.
|
92
92
|
#
|
93
93
|
# @param opts [Hash] Goal options.
|
@@ -127,26 +127,43 @@ module Beeminder
|
|
127
127
|
_connection :put, cmd, data
|
128
128
|
end
|
129
129
|
|
130
|
+
# Send PUT request with a JSON document to API.
|
131
|
+
#
|
132
|
+
# @param cmd [String] the API command, like `users/#{user.name}.json`
|
133
|
+
# @param data [Hash] data to send
|
134
|
+
def put_document cmd, data = {}
|
135
|
+
_connection :put_json, cmd, data
|
136
|
+
end
|
137
|
+
|
130
138
|
# Converts time object to one with user's timezone.
|
131
139
|
#
|
132
140
|
# @param time [Date|DateTime|Time] Time to convert.
|
133
141
|
# @return [Time] Converted time.
|
134
142
|
def convert_to_timezone time
|
135
143
|
Time.use_zone(@timezone){
|
136
|
-
|
144
|
+
|
137
145
|
time = time.to_time unless time.is_a?(Time)
|
138
146
|
Time.local(time.year, time.month, time.day, time.hour, time.min, time.sec)
|
139
|
-
|
147
|
+
|
140
148
|
}
|
141
149
|
end
|
142
150
|
|
143
|
-
|
151
|
+
# Returns the current akrasia horizon.
|
152
|
+
#
|
153
|
+
# @return [Time] The first instant changes can be made for.
|
154
|
+
def akrasia_horizon
|
155
|
+
Time.use_zone(@timezone) do
|
156
|
+
-8.days.ago.beginning_of_day
|
157
|
+
end
|
158
|
+
end
|
144
159
|
|
160
|
+
private
|
161
|
+
|
145
162
|
# Establish HTTPS connection to API.
|
146
163
|
def _connection type, cmd, data
|
147
164
|
api = "https://www.beeminder.com/api/v1/#{cmd}"
|
148
165
|
data = {@token_type => @token}.merge(data)
|
149
|
-
|
166
|
+
|
150
167
|
url = URI.parse(api)
|
151
168
|
http = Net::HTTP.new(url.host, url.port)
|
152
169
|
http.read_timeout = 8640
|
@@ -159,7 +176,7 @@ module Beeminder
|
|
159
176
|
raise ArgumentError, "invalid timestamp: #{data["timestamp"]}"
|
160
177
|
end
|
161
178
|
end
|
162
|
-
|
179
|
+
|
163
180
|
json = ""
|
164
181
|
http.start do |http|
|
165
182
|
case type
|
@@ -173,6 +190,10 @@ module Beeminder
|
|
173
190
|
when :put
|
174
191
|
req = Net::HTTP::Put.new(url.path)
|
175
192
|
req.set_form_data(data)
|
193
|
+
when :put_json
|
194
|
+
req = Net::HTTP::Put.new(url.path)
|
195
|
+
req.body = data.to_json
|
196
|
+
req.content_type = 'application/json'
|
176
197
|
else
|
177
198
|
raise "invalid connection type"
|
178
199
|
end
|
data/lib/beeminder/version.rb
CHANGED
metadata
CHANGED
@@ -1,34 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beeminder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- muflax
|
8
|
+
- bsoule
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
|
-
cert_chain:
|
11
|
-
-
|
12
|
-
-----BEGIN CERTIFICATE-----
|
13
|
-
MIIDLDCCAhSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA8MQ0wCwYDVQQDDARtYWls
|
14
|
-
MRYwFAYKCZImiZPyLGQBGRYGbXVmbGF4MRMwEQYKCZImiZPyLGQBGRYDY29tMB4X
|
15
|
-
DTE0MDMxNzA1NTUwM1oXDTE1MDMxNzA1NTUwM1owPDENMAsGA1UEAwwEbWFpbDEW
|
16
|
-
MBQGCgmSJomT8ixkARkWBm11ZmxheDETMBEGCgmSJomT8ixkARkWA2NvbTCCASIw
|
17
|
-
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMBwn+ZDlWYfoEevtvoQBKK+NBFA
|
18
|
-
U9iKN5Aa4g51ZjiFUtoasYeTVUvqKmkRDM+tFTjlTNRCMtFKZy+Fbw+Q2+JALBnk
|
19
|
-
isyJmRCxoWLxUds/XT40I0m+mtwP5etKr7g01lE3gsIM8644iEBGw41pG7F8nm2w
|
20
|
-
dxcs78uGx/Y89vH4xlP5utdq4lChCo60+jQWUBNdnRlrFoBerUrdEUWlj7HhOQSl
|
21
|
-
coJqx3UHhPw1e97CxC4r4IEO4vfNwMr3Uxxcv/idcQwDi5thDwtzjG3u4xwzL3xS
|
22
|
-
HSvktDccLmeF9hsWUGlmee87oQGqZvZTmRmLmpcpzsNxFcVJxGK72VfbsjUCAwEA
|
23
|
-
AaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFEEiWHZRn5hp
|
24
|
-
8ho98JIewpJitn3DMA0GCSqGSIb3DQEBBQUAA4IBAQCFr4wcczJG+SkvzaP+LPaB
|
25
|
-
PyDf6lhOYB5BbxteVc3qoK1bxOhMKRlzl9k5pzKbd8FCAokhojoPvUFkZuB7E2RB
|
26
|
-
VC1cDAdYr7s8CCNnUjH1nk3esXRyXGWBBTOlAc96SmbukEV+qVdf2CWnRRHxDtyZ
|
27
|
-
Ov/8JRksnmBUhPzUgAxsEZaX3eSLv/cJGjnOeEgNKA52FmY6S1/MNkLN743AXFfR
|
28
|
-
njhyNen7eGs/8Og1krIw4crmFCVawKI0LXuWTff/3zb8d9SZXZePbzPv+q0IG3ek
|
29
|
-
lmwpPc3Bdi/+i0PzT69bN5W+96Yp2JUDPmQXTG2QGwWDqEQF/BnHtlVQ/1w649V+
|
30
|
-
-----END CERTIFICATE-----
|
31
|
-
date: 2014-04-21 00:00:00.000000000 Z
|
11
|
+
cert_chain: []
|
12
|
+
date: 2018-09-27 00:00:00.000000000 Z
|
32
13
|
dependencies:
|
33
14
|
- !ruby/object:Gem::Dependency
|
34
15
|
name: activesupport
|
@@ -39,7 +20,7 @@ dependencies:
|
|
39
20
|
version: '3.2'
|
40
21
|
- - "<"
|
41
22
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
23
|
+
version: '6'
|
43
24
|
type: :runtime
|
44
25
|
prerelease: false
|
45
26
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -49,7 +30,7 @@ dependencies:
|
|
49
30
|
version: '3.2'
|
50
31
|
- - "<"
|
51
32
|
- !ruby/object:Gem::Version
|
52
|
-
version: '
|
33
|
+
version: '6'
|
53
34
|
- !ruby/object:Gem::Dependency
|
54
35
|
name: chronic
|
55
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -68,16 +49,16 @@ dependencies:
|
|
68
49
|
name: json
|
69
50
|
requirement: !ruby/object:Gem::Requirement
|
70
51
|
requirements:
|
71
|
-
- - "
|
52
|
+
- - "~>"
|
72
53
|
- !ruby/object:Gem::Version
|
73
|
-
version: '
|
54
|
+
version: '1'
|
74
55
|
type: :runtime
|
75
56
|
prerelease: false
|
76
57
|
version_requirements: !ruby/object:Gem::Requirement
|
77
58
|
requirements:
|
78
|
-
- - "
|
59
|
+
- - "~>"
|
79
60
|
- !ruby/object:Gem::Version
|
80
|
-
version: '
|
61
|
+
version: '1'
|
81
62
|
- !ruby/object:Gem::Dependency
|
82
63
|
name: highline
|
83
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -93,36 +74,36 @@ dependencies:
|
|
93
74
|
- !ruby/object:Gem::Version
|
94
75
|
version: '1.6'
|
95
76
|
- !ruby/object:Gem::Dependency
|
96
|
-
name:
|
77
|
+
name: optimist
|
97
78
|
requirement: !ruby/object:Gem::Requirement
|
98
79
|
requirements:
|
99
80
|
- - "~>"
|
100
81
|
- !ruby/object:Gem::Version
|
101
|
-
version: '
|
82
|
+
version: '3'
|
102
83
|
type: :runtime
|
103
84
|
prerelease: false
|
104
85
|
version_requirements: !ruby/object:Gem::Requirement
|
105
86
|
requirements:
|
106
87
|
- - "~>"
|
107
88
|
- !ruby/object:Gem::Version
|
108
|
-
version: '
|
89
|
+
version: '3'
|
109
90
|
- !ruby/object:Gem::Dependency
|
110
91
|
name: tzinfo
|
111
92
|
requirement: !ruby/object:Gem::Requirement
|
112
93
|
requirements:
|
113
|
-
- - "
|
94
|
+
- - "~>"
|
114
95
|
- !ruby/object:Gem::Version
|
115
|
-
version: '
|
96
|
+
version: '1.2'
|
116
97
|
type: :runtime
|
117
98
|
prerelease: false
|
118
99
|
version_requirements: !ruby/object:Gem::Requirement
|
119
100
|
requirements:
|
120
|
-
- - "
|
101
|
+
- - "~>"
|
121
102
|
- !ruby/object:Gem::Version
|
122
|
-
version: '
|
103
|
+
version: '1.2'
|
123
104
|
description: Convenient access to Beeminder's API.
|
124
105
|
email:
|
125
|
-
-
|
106
|
+
- support@beeminder.com
|
126
107
|
executables:
|
127
108
|
- beemind
|
128
109
|
extensions: []
|
@@ -160,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
141
|
version: '0'
|
161
142
|
requirements: []
|
162
143
|
rubyforge_project:
|
163
|
-
rubygems_version: 2.
|
144
|
+
rubygems_version: 2.6.12
|
164
145
|
signing_key:
|
165
146
|
specification_version: 4
|
166
147
|
summary: access Beeminder API
|
checksums.yaml.gz.sig
DELETED
data.tar.gz.sig
DELETED
Binary file
|
metadata.gz.sig
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
��mj<���Q]0H�+_���V��<�N]n�+���S��
|