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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fe9446419e3fc9249d45e27dfdb7e93eaa2fd293
4
- data.tar.gz: 940d2b2b7a75f34c276aef94a89d76b2f2624adc
3
+ metadata.gz: d48e75546e891468169cba69c260a9b183a02856
4
+ data.tar.gz: a8bec82ae557bdd48009dd6b8ae96e4bc19f977a
5
5
  SHA512:
6
- metadata.gz: 375ad660e200645afa73bbf18df8b3717b7eb7dc945d7c9985a20bf695239d68b0819acab666bb0ff3bbac8e305dde35a47d714b292144ef6f0700283f4c3be9
7
- data.tar.gz: 620545b90de4a56f0fd4cf785763dfc6a6bd2b0baaf18b6ddaa788461b246d725d011001da4e8907b5653a51cba237331a09f169ead72ceeb12dba4e74562668
6
+ metadata.gz: f4dfdd266db0b8ed2b2a0e7aa8583e497719792351c2d7cb7aeb5fbfbccae9e7beb37b20204dea9ff3a4748b83069bd2b015311c3b0d49e18abb67d4944d1206
7
+ data.tar.gz: 80a2fd645e8762ba2d8f241628db3dffc2b42ec72a102e2505a75eaaf6b012dc929dc33402f9524929a217caa2d7968fb9a906e50c8cba8c31fbf5b1b6f6770c
@@ -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 = ["mail@muflax.com"]
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', '< 5']
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 'trollop', '~> 2'
24
- gem.add_dependency 'tzinfo'
23
+ gem.add_dependency 'optimist', '~> 3'
24
+ gem.add_dependency 'tzinfo', '~> 1.2'
25
25
  end
@@ -3,7 +3,7 @@
3
3
 
4
4
  require 'chronic'
5
5
  require 'highline/import'
6
- require 'trollop'
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 = Trollop::options do
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
- Trollop::die usage if not (2..3).include?(ARGV.size) and not opts[:list]
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
- Trollop::die "invalid date" if date.nil?
69
+ Optimist::die "invalid date" if date.nil?
70
70
 
71
71
  g = bee.goal goal
72
72
  dp = Beeminder::Datapoint.new :timestamp => date,
@@ -1,5 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
+ require 'active_support'
3
4
  require 'active_support/core_ext'
4
5
  require 'date'
5
6
  require 'json'
@@ -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
- parse_info info
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.put "users/me/goals/#{@slug}.json", data
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
 
@@ -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
- private
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
@@ -1,3 +1,3 @@
1
1
  module Beeminder
2
- VERSION = "0.2.10"
2
+ VERSION = "0.2.12"
3
3
  end
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.10
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: '5'
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: '5'
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: '0'
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: '0'
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: trollop
77
+ name: optimist
97
78
  requirement: !ruby/object:Gem::Requirement
98
79
  requirements:
99
80
  - - "~>"
100
81
  - !ruby/object:Gem::Version
101
- version: '2'
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: '2'
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: '0'
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: '0'
103
+ version: '1.2'
123
104
  description: Convenient access to Beeminder's API.
124
105
  email:
125
- - mail@muflax.com
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.2.2
144
+ rubygems_version: 2.6.12
164
145
  signing_key:
165
146
  specification_version: 4
166
147
  summary: access Beeminder API
@@ -1,2 +0,0 @@
1
- �do�K�湷M����$�V�qD/�
2
- �\oQ��4deu��νbJ'��+t�7M;"�`*��[5�
data.tar.gz.sig DELETED
Binary file
metadata.gz.sig DELETED
@@ -1 +0,0 @@
1
- ��mj<���Q]0H�+_��� V��<�N]n�+���S��