rescuetime 0.2.0 → 0.3.0
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/.travis.yml +0 -1
- data/CONTRIBUTING.md +9 -8
- data/README.md +105 -21
- data/Rakefile +1 -1
- data/lib/rescuetime.rb +1 -0
- data/lib/rescuetime/client.rb +16 -97
- data/lib/rescuetime/collection.rb +51 -0
- data/lib/rescuetime/errors.rb +80 -4
- data/lib/rescuetime/query_buildable.rb +114 -0
- data/lib/rescuetime/requester.rb +40 -0
- data/lib/rescuetime/version.rb +1 -1
- data/rescuetime.gemspec +6 -4
- metadata +49 -32
- data/lib/rescuetime/activities.rb +0 -182
- data/lib/rescuetime/api.rb +0 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9e7a807f2b3aaf12d096fc4547b5990436cc661c
|
|
4
|
+
data.tar.gz: ef7cc81293795d19b560d028f51b752c85038261
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 55a8baa378221aef8445cac82fa16240fdfaf10dc296acb4f63316e13a9d4c02cfad3489627dcdc452e4e4553d79afe9b1fb7c44eecb75f8dc083a6227c5dbf3
|
|
7
|
+
data.tar.gz: 75df0025d9269632ae9659eb7f4dabac97b6047a248ba86cc11cf079ad09ad222bfc5c22b3904ea2f9c58adf394a6a633fe878e35665765157f715e3f2f867db
|
data/.travis.yml
CHANGED
data/CONTRIBUTING.md
CHANGED
|
@@ -29,13 +29,7 @@ You should be able to run the test specs now:
|
|
|
29
29
|
bundle exec rake
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
- fixing [bugs](https://github.com/leesharma/rescuetime/issues?q=is%3Aopen+is%3Aissue+-label%3A%22in+progress%22+label%3Abug)
|
|
34
|
-
- adding [features listed in our current milestone](https://github.com/leesharma/rescuetime/issues?q=is%3Aopen+is%3Aissue+-label%3A%22in+progress%22) (filter by milestone)
|
|
35
|
-
- adding/improving documentation, comments, etc.
|
|
36
|
-
- refactoring existing code
|
|
37
|
-
|
|
38
|
-
Check our [issue tracker](https://github.com/leesharma/rescuetime/issues) for more ideas.
|
|
32
|
+
This is a very small project, so if you are interested in contributing, it will be easiest if you contact me first.
|
|
39
33
|
|
|
40
34
|
## Standards
|
|
41
35
|
|
|
@@ -43,6 +37,13 @@ rescuetime uses RSpec for testing along with VCR and WebMock for mocking HTTP re
|
|
|
43
37
|
|
|
44
38
|
Be careful not to commit sensitive information (API keys, OAuth credentials, etc.) to public repositories!
|
|
45
39
|
|
|
40
|
+
### Comment Tags
|
|
41
|
+
|
|
42
|
+
* TODO
|
|
43
|
+
* FIXME
|
|
44
|
+
* OPTIMIZE
|
|
45
|
+
* REVIEW
|
|
46
|
+
|
|
46
47
|
## Questions
|
|
47
48
|
|
|
48
|
-
Have any questions?
|
|
49
|
+
Have any questions? Post on the github repo at leesharma/rescuetime.
|
data/README.md
CHANGED
|
@@ -20,7 +20,8 @@ For more information about RescueTime, visit [the RescueTime homepage](https://w
|
|
|
20
20
|
* [Installation](#installation)
|
|
21
21
|
* [Usage](#usage)
|
|
22
22
|
* [Prerequisites](#prerequisites)
|
|
23
|
-
* [
|
|
23
|
+
* [In a Nutshell](#in-a-nutshell) (skip to here if you want to see the syntax)
|
|
24
|
+
* [Finding Answers (Documentation)](#finding-answers-documentation)
|
|
24
25
|
* [Defaults](#defaults)
|
|
25
26
|
* [Rescuetime Exceptions](#rescuetime-exceptions)
|
|
26
27
|
* [Development](https://github.com/leesharma/rescuetime/wiki/Development) ([section](#development))
|
|
@@ -54,9 +55,7 @@ Ensure that you are using a [supported ruby version](https://github.com/leesharm
|
|
|
54
55
|
|
|
55
56
|
In order to use access your RescueTime data, you will need an API key. If you do not already have a key, visit the [API key management page](https://www.rescuetime.com/anapi/manage).
|
|
56
57
|
|
|
57
|
-
###
|
|
58
|
-
|
|
59
|
-
Using the rescuetime gem is simple. Here is some example code using the rescuetime gem (a full feature list can be found [here](https://github.com/leesharma/rescuetime/wiki#full-specs):
|
|
58
|
+
### In a Nutshell
|
|
60
59
|
|
|
61
60
|
```ruby
|
|
62
61
|
require 'rescuetime'
|
|
@@ -65,19 +64,88 @@ require 'rescuetime'
|
|
|
65
64
|
@client.api_key? #=> true
|
|
66
65
|
@client.valid_credentials? #=> true
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
@client.
|
|
73
|
-
@client.
|
|
74
|
-
|
|
75
|
-
@client.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
67
|
+
# Rescuetime uses lazy evaluation, so until you either manipulate the collection
|
|
68
|
+
# or explicitly call for it (with #all), it will remain in the Rescuetime::Collection
|
|
69
|
+
# format.
|
|
70
|
+
@client.overview.class #=> Rescuetime::Collection
|
|
71
|
+
@client.overview.all.class #=> Array
|
|
72
|
+
@client.overview.map {...} #=> Array
|
|
73
|
+
|
|
74
|
+
@client.overview # Returns an overview report, defaulting to "rank" order
|
|
75
|
+
@client.categories # Returns a catigorical report, defaulting to "rank" order
|
|
76
|
+
@client.activities # Returns a list of activities, defaulting to "rank" order
|
|
77
|
+
@client.productivity # Returns a productivity report, defaulting to "rank" order
|
|
78
|
+
@client.efficiency # Returns an efficiency report, defaulting to "time order"
|
|
79
|
+
|
|
80
|
+
##
|
|
81
|
+
# Date Range (:date, :frome, :to)
|
|
82
|
+
# -------------------------------
|
|
83
|
+
# Defaults:
|
|
84
|
+
# If nothing is provided, defaults to current day (since 00:00)
|
|
85
|
+
# If :from is provided, defaults :to to current day
|
|
86
|
+
#
|
|
87
|
+
# Valid date formats:
|
|
88
|
+
# - "YYYY-MM-DD" - "MM-DD-YYYY" - "DD/MM"
|
|
89
|
+
# - Object#strftime
|
|
90
|
+
@client.overview # Fetches results from today
|
|
91
|
+
@client.overview.date('2014-12-31') # Fetches results from Dec 31, 2014.
|
|
92
|
+
@client.overview.from('2015-01-01').to('2015-02-01')
|
|
93
|
+
@client.overview.from('2015-04-01')
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
##
|
|
97
|
+
# Report Order (:order_by)
|
|
98
|
+
# ------------------------
|
|
99
|
+
# Defaults:
|
|
100
|
+
# Efficiency defaults to chronological order; everything else defaults to "rank" order
|
|
101
|
+
#
|
|
102
|
+
# You can order_by:
|
|
103
|
+
# :rank, :time, or :member (note: efficiency can't be sorted by :rank)
|
|
104
|
+
#
|
|
105
|
+
# When ordering by time, default interval is 1 hour.
|
|
106
|
+
# Options include:
|
|
107
|
+
# :minute (5-minute chunks), :hour, :day, :week, :month
|
|
108
|
+
@client.efficiency # Defaults to :time
|
|
109
|
+
@client.productivity # Defaults to :rank
|
|
110
|
+
|
|
111
|
+
@client.productivity.order_by(:rank)
|
|
112
|
+
@client.productivity.order_by(:time)
|
|
113
|
+
@client.productivity.order_by(:member)
|
|
114
|
+
|
|
115
|
+
@client.productivity.order_by(:time) # Defaults to :hour
|
|
116
|
+
@client.productivity.order_by(:time, interval: :minute)
|
|
117
|
+
@client.productivity.order_by(:time, interval: :hour)
|
|
118
|
+
@client.productivity.order_by(:time, interval: :day)
|
|
119
|
+
@client.productivity.order_by(:time, interval: :week)
|
|
120
|
+
@client.productivity.order_by(:time, interval: :month)
|
|
121
|
+
|
|
122
|
+
##
|
|
123
|
+
# Name Restrictions (:where)
|
|
124
|
+
# --------------------------
|
|
125
|
+
# Fetches results where name is an exact match
|
|
126
|
+
# The following reports can be limited by name:
|
|
127
|
+
# :activities, :categories, :overview
|
|
128
|
+
#
|
|
129
|
+
# For activities, you can also limit by specific document title
|
|
130
|
+
# (ex. document 'rails/rails' for activity 'github.com')
|
|
131
|
+
# Try the query sans document for a list of valid options
|
|
132
|
+
#
|
|
133
|
+
# Names must be exact matches.
|
|
134
|
+
@client.activities.where(name: 'github.com')
|
|
135
|
+
@client.categories.where(name: 'Intelligence')
|
|
136
|
+
@client.overview.where(name: 'Utilities')
|
|
137
|
+
@client.activities.where(name: 'github.com', document: 'vcr/vcr')
|
|
138
|
+
|
|
139
|
+
##
|
|
140
|
+
# Formatting options (:csv, :array)
|
|
141
|
+
# ---------------------------------
|
|
142
|
+
@client.efficiency # Default return type is Array<Hash>
|
|
143
|
+
@client.efficiency.format(:cvs) # Returns a CSV
|
|
144
|
+
@client.efficiency.format(:array) # Returns Array<Hash>
|
|
79
145
|
```
|
|
80
146
|
|
|
147
|
+
### Finding Answers (Documentation)
|
|
148
|
+
|
|
81
149
|
For more details, please see [official gem documentation](http://www.rubydoc.info/gems/rescuetime/0.1.0) or [read the wiki](https://github.com/leesharma/rescuetime/wiki).
|
|
82
150
|
|
|
83
151
|
### Defaults
|
|
@@ -86,10 +154,9 @@ The `Rescuetime::Client#activities` action has the following defaults:
|
|
|
86
154
|
|
|
87
155
|
```ruby
|
|
88
156
|
|
|
89
|
-
{
|
|
90
|
-
|
|
91
|
-
date: <TODAY>
|
|
92
|
-
detail: 'activity' }
|
|
157
|
+
{ order_by: 'rank'
|
|
158
|
+
interval: 'hour'
|
|
159
|
+
date: <TODAY> }
|
|
93
160
|
|
|
94
161
|
```
|
|
95
162
|
|
|
@@ -97,8 +164,25 @@ The `Rescuetime::Client#activities` action has the following defaults:
|
|
|
97
164
|
|
|
98
165
|
There are a number of exceptions that extend from the custom Rescuetime::Error class:
|
|
99
166
|
|
|
100
|
-
* **Rescuetime::
|
|
101
|
-
* **Rescuetime::
|
|
167
|
+
* * **Rescuetime::MissingCredentialsError** is raised when a request is attempted by a client with no credentials. Try setting credentials with `@client.api_key = <YOUR_API_KEY>`.
|
|
168
|
+
* **Rescuetime::InvalidCredentialsError** is raised when a request is attempted by a client with invalid credentials. Double-check your API key and fix your client with `@client.api_key = <VALID_API_KEY>`.
|
|
169
|
+
* **Rescuetime::InvalidQueryError** is raised if you enter an invalid value for any of the RescueTime query methods (or if the server returns a bad query error)
|
|
170
|
+
* **Rescuetime::InvalidFormatError** is raised if you pass a disallowed format to the client
|
|
171
|
+
* HTTP Response Errors:
|
|
172
|
+
* **4xx => Rescuetime:: ClientError**
|
|
173
|
+
* 400 => Rescuetime::BadRequest
|
|
174
|
+
* 401 => Rescuetime::Unauthorized
|
|
175
|
+
* 403 => Rescuetime::Forbidden
|
|
176
|
+
* 404 => Rescuetime::NotFound
|
|
177
|
+
* 406 => Rescuetime::NotAcceptable
|
|
178
|
+
* 422 => Rescuetime::UnprocessableEntity
|
|
179
|
+
* 429 => Rescuetime::TooManyRequests
|
|
180
|
+
* **5xx => Rescuetime:: ServerError**
|
|
181
|
+
* 500 => Rescuetime::InternalServerError
|
|
182
|
+
* 501 => Rescuetime::NotImplemented
|
|
183
|
+
* 502 => Rescuetime::BadGateway
|
|
184
|
+
* 503 => Rescuetime::ServiceUnavailable
|
|
185
|
+
* 504 => Rescuetime::GatewayTimeout
|
|
102
186
|
|
|
103
187
|
## Development
|
|
104
188
|
|
data/Rakefile
CHANGED
data/lib/rescuetime.rb
CHANGED
data/lib/rescuetime/client.rb
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
require 'faraday'
|
|
2
2
|
require 'csv'
|
|
3
3
|
|
|
4
|
-
require 'rescuetime/
|
|
4
|
+
require 'rescuetime/query_buildable'
|
|
5
|
+
|
|
6
|
+
require 'rescuetime/requester'
|
|
7
|
+
require 'rescuetime/collection'
|
|
5
8
|
|
|
6
9
|
module Rescuetime
|
|
7
10
|
# Rescuetime::Client makes HTTP requests to the RescueTime API and returns
|
|
@@ -9,117 +12,33 @@ module Rescuetime
|
|
|
9
12
|
#
|
|
10
13
|
# @since v0.1.0
|
|
11
14
|
class Client
|
|
12
|
-
include
|
|
13
|
-
|
|
14
|
-
# Default options passed in any request
|
|
15
|
-
# @since v0.2.0
|
|
16
|
-
DEFAULT_OPTIONS = {format: 'csv', version: 0, operation: 'select' }
|
|
15
|
+
include QueryBuildable
|
|
17
16
|
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
# @!attribute [w] api_key
|
|
17
|
+
# @!attribute [rw] api_key
|
|
21
18
|
# @since v0.1.0
|
|
22
|
-
|
|
19
|
+
attr_accessor :api_key
|
|
23
20
|
|
|
24
|
-
# Initializes a new Client object
|
|
25
|
-
#
|
|
26
|
-
# @example
|
|
27
|
-
# @client = Rescuetime::Client.new # options must be set before requests can be made
|
|
28
|
-
# @example
|
|
29
|
-
# @client = Rescuetime::Client.new(api_key: '1234567890abcdefg')
|
|
30
|
-
#
|
|
31
|
-
# @param [Hash] options hash of RescueTime client options
|
|
32
|
-
# @option options [String] :api_key RescueTime API key
|
|
33
|
-
# @return [Rescuetime::Client]
|
|
34
21
|
# @since v0.1.0
|
|
35
|
-
def initialize(
|
|
36
|
-
@api_key
|
|
22
|
+
def initialize(key = nil, **opts)
|
|
23
|
+
@api_key = key || opts[:api_key]
|
|
37
24
|
end
|
|
38
25
|
|
|
39
|
-
# Checks whether an api key is set
|
|
40
|
-
#
|
|
41
|
-
# @return [Boolean]
|
|
42
26
|
# @since v0.1.0
|
|
43
27
|
def api_key?
|
|
44
|
-
!!@api_key
|
|
28
|
+
!!@api_key && !@api_key.empty?
|
|
45
29
|
end
|
|
46
30
|
|
|
47
|
-
# Checks whether client credentials are valid. If credentials are present, this
|
|
48
|
-
# action involves an HTTP request.
|
|
49
|
-
#
|
|
50
|
-
# @example Three cases of checking credentials (missing, invalid, and valid)
|
|
51
|
-
# @client = Rescuetime::Client.new
|
|
52
|
-
# @client.valid_credentials? # => false
|
|
53
|
-
#
|
|
54
|
-
# # Note: The following scenarios involve an HTTP request.
|
|
55
|
-
# @client.api_key = 'Invalid Key'
|
|
56
|
-
# @client.valid_credentials? # => false
|
|
57
|
-
#
|
|
58
|
-
# @client.api_key = VALID_API_KEY
|
|
59
|
-
# @client.valid_credentials? # => true
|
|
60
|
-
#
|
|
61
|
-
# @return [Boolean]
|
|
62
31
|
# @since v0.2.0
|
|
63
32
|
def valid_credentials?
|
|
64
33
|
return false unless api_key?
|
|
65
|
-
!!
|
|
34
|
+
!!activities.all rescue false
|
|
66
35
|
end
|
|
67
36
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
# Performs an HTTP get request
|
|
71
|
-
#
|
|
72
|
-
# @param [String] url request url
|
|
73
|
-
# @param [Hash] options query params for request
|
|
74
|
-
#
|
|
75
|
-
# @raise [Rescuetime::MissingCredentials] if the Rescuetime::Client has no set api key
|
|
76
|
-
# @raise [Rescuetime::InvalidCredentials] if the provided api key is rejected by RescueTime
|
|
77
|
-
# @since v0.2.0
|
|
78
|
-
def get(url, options={})
|
|
79
|
-
raise Rescuetime::MissingCredentials unless api_key?
|
|
80
|
-
response = Faraday.get url, query_params(options).
|
|
81
|
-
merge(DEFAULT_OPTIONS).
|
|
82
|
-
merge({key: @api_key})
|
|
83
|
-
|
|
84
|
-
invalid_credentials_body = '{"error":"# key not found","messages":"key not found"}'
|
|
85
|
-
raise Rescuetime::InvalidCredentials if response.body == invalid_credentials_body
|
|
86
|
-
|
|
87
|
-
response
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# Takes client request options hash and returns correct key/value pairs for HTTP request
|
|
91
|
-
#
|
|
92
|
-
# @param [Hash] options options hash of client request
|
|
93
|
-
# @return [Hash]
|
|
94
|
-
# @since v0.2.0
|
|
95
|
-
def query_params(options)
|
|
96
|
-
params = {}
|
|
97
|
-
params_mapping = { detail: :restrict_kind, by: :perspective, interval: :resolution_time }
|
|
98
|
-
|
|
99
|
-
params_mapping.each do |local, server|
|
|
100
|
-
params[server] = options[local] if options[local]
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# Special Cases
|
|
104
|
-
params[:perspective] = 'interval' if params[:perspective] == 'time'
|
|
105
|
-
if options[:date]
|
|
106
|
-
params[:restrict_begin] = date_string options[:date]
|
|
107
|
-
params[:restrict_end] = params[:restrict_begin]
|
|
108
|
-
end
|
|
109
|
-
if options[:from]
|
|
110
|
-
params[:restrict_begin] = date_string options[:from]
|
|
111
|
-
params[:restrict_end] = date_string(options[:to] || Time.now)
|
|
112
|
-
end
|
|
113
|
-
params
|
|
114
|
-
end
|
|
37
|
+
private
|
|
115
38
|
|
|
116
|
-
#
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
# @return [String]
|
|
120
|
-
def date_string(date)
|
|
121
|
-
return date if date.is_a? String
|
|
122
|
-
date.strftime('%Y-%m-%d')
|
|
39
|
+
# @since v0.3.0
|
|
40
|
+
def state
|
|
41
|
+
{ key: @api_key }
|
|
123
42
|
end
|
|
124
43
|
end
|
|
125
|
-
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'rescuetime/query_buildable'
|
|
2
|
+
|
|
3
|
+
module Rescuetime
|
|
4
|
+
class Collection
|
|
5
|
+
include QueryBuildable
|
|
6
|
+
include Enumerable
|
|
7
|
+
|
|
8
|
+
HOST = 'https://www.rescuetime.com/anapi/data'
|
|
9
|
+
|
|
10
|
+
def initialize(*terms)
|
|
11
|
+
@params = terms.reduce({}, :merge)
|
|
12
|
+
@format = :array
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def <<(terms)
|
|
16
|
+
@params.merge! terms
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def all
|
|
20
|
+
parse_response Requester.get(HOST, @params).body
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def each(&block)
|
|
24
|
+
all.each &block
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# TODO: Chainable to client
|
|
28
|
+
def format(format)
|
|
29
|
+
fail InvalidFormatError unless %w(array csv).include? format.to_s
|
|
30
|
+
@format = format.to_sym
|
|
31
|
+
self
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# @since v0.1.0
|
|
37
|
+
def parse_response(body)
|
|
38
|
+
report = CSV.new(body,
|
|
39
|
+
headers: true,
|
|
40
|
+
header_converters: :symbol,
|
|
41
|
+
converters: :all)
|
|
42
|
+
|
|
43
|
+
case @format
|
|
44
|
+
when :array then report.to_a.map(&:to_hash)
|
|
45
|
+
when :csv then report
|
|
46
|
+
else
|
|
47
|
+
fail InvalidFormatError
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/rescuetime/errors.rb
CHANGED
|
@@ -2,9 +2,85 @@ module Rescuetime
|
|
|
2
2
|
# Error class for rescuing all RescueTime errors
|
|
3
3
|
class Error < StandardError; end
|
|
4
4
|
|
|
5
|
+
##
|
|
6
|
+
# HTTP Errors
|
|
7
|
+
# ===========
|
|
8
|
+
# 4xx HTTP status code
|
|
9
|
+
class ClientError < Error; end
|
|
10
|
+
# HTTP status code 400
|
|
11
|
+
class BadRequest < ClientError; end
|
|
12
|
+
# HTTP status code 401
|
|
13
|
+
class Unauthorized < ClientError; end
|
|
14
|
+
# HTTP status code 403
|
|
15
|
+
class Forbidden < ClientError; end
|
|
16
|
+
# HTTP status code 404
|
|
17
|
+
class NotFound < ClientError; end
|
|
18
|
+
# HTTP status code 406
|
|
19
|
+
class NotAcceptable < ClientError; end
|
|
20
|
+
# HTTP status code 422
|
|
21
|
+
class UnprocessableEntity < ClientError; end
|
|
22
|
+
# HTTP status code 429
|
|
23
|
+
class TooManyRequests < ClientError; end
|
|
24
|
+
|
|
25
|
+
# 5xx HTTP status code
|
|
26
|
+
class ServerError < Error; end
|
|
27
|
+
# HTTP status code 500
|
|
28
|
+
class InternalServerError < ServerError; end
|
|
29
|
+
# HTTP status code 501
|
|
30
|
+
class NotImplemented < ServerError; end
|
|
31
|
+
# HTTP status code 502
|
|
32
|
+
class BadGateway < ServerError; end
|
|
33
|
+
# HTTP status code 503
|
|
34
|
+
class ServiceUnavailable < ServerError; end
|
|
35
|
+
# HTTP status code 504
|
|
36
|
+
class GatewayTimeout < ServerError; end
|
|
37
|
+
|
|
38
|
+
##
|
|
39
|
+
# Custom Errors
|
|
40
|
+
# =============
|
|
41
|
+
# class CredentialsError < Error; end
|
|
5
42
|
# Raised when a method requires credentials but none are provided
|
|
6
|
-
class
|
|
43
|
+
class MissingCredentialsError < Unauthorized
|
|
44
|
+
def initialize(msg = 'No API key provided. Please provide a valid key.')
|
|
45
|
+
super
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Raised when a method requires credentials but credentials are invalid
|
|
50
|
+
class InvalidCredentialsError < Unauthorized
|
|
51
|
+
def initialize(msg = 'API key is invalid. Please provide a valid key.')
|
|
52
|
+
super
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Raised when a user-submitted query value is invalid
|
|
57
|
+
class InvalidQueryError < BadRequest
|
|
58
|
+
def initialize(msg = 'Likely a badly formatted or missing parameter')
|
|
59
|
+
super
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Raised when a user-submitted query value is invalid
|
|
64
|
+
class InvalidFormatError < Error
|
|
65
|
+
def initialize(msg = 'Invalid format. Please see docs for allowed formats.')
|
|
66
|
+
super
|
|
67
|
+
end
|
|
68
|
+
end
|
|
7
69
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
70
|
+
class Error
|
|
71
|
+
CODES = {
|
|
72
|
+
400 => Rescuetime::BadRequest,
|
|
73
|
+
401 => Rescuetime::Unauthorized,
|
|
74
|
+
403 => Rescuetime::Forbidden,
|
|
75
|
+
404 => Rescuetime::NotFound,
|
|
76
|
+
406 => Rescuetime::NotAcceptable,
|
|
77
|
+
422 => Rescuetime::UnprocessableEntity,
|
|
78
|
+
429 => Rescuetime::TooManyRequests,
|
|
79
|
+
500 => Rescuetime::InternalServerError,
|
|
80
|
+
501 => Rescuetime::NotImplemented,
|
|
81
|
+
502 => Rescuetime::BadGateway,
|
|
82
|
+
503 => Rescuetime::ServiceUnavailable,
|
|
83
|
+
504 => Rescuetime::GatewayTimeout
|
|
84
|
+
}
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
module Rescuetime
|
|
2
|
+
# The Rescuetime::Reportable module contains client methods relating to
|
|
3
|
+
# generating requests to fetch reports on the /data endpoint of the
|
|
4
|
+
# Data Analytics API.
|
|
5
|
+
#
|
|
6
|
+
# @since v0.1.0
|
|
7
|
+
module QueryBuildable
|
|
8
|
+
BASE_PARAMS = { format: 'csv',
|
|
9
|
+
operation: 'select',
|
|
10
|
+
version: 0 }
|
|
11
|
+
|
|
12
|
+
# @return [Rescuetime::Collection]
|
|
13
|
+
# @since v0.3.0
|
|
14
|
+
def overview
|
|
15
|
+
add_to_query restrict_kind: 'overview'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @return [Rescuetime::Collection]
|
|
19
|
+
# @since v0.3.0
|
|
20
|
+
def categories
|
|
21
|
+
add_to_query restrict_kind: 'category'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @return [Rescuetime::Collection]
|
|
25
|
+
# @since v0.1.0
|
|
26
|
+
def activities
|
|
27
|
+
add_to_query restrict_kind: 'activity'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @return [Rescuetime::Collection]
|
|
31
|
+
# @since v0.2.0
|
|
32
|
+
def productivity
|
|
33
|
+
add_to_query restrict_kind: 'productivity'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @return [Rescuetime::Collection]
|
|
37
|
+
# @since v0.2.0
|
|
38
|
+
def efficiency
|
|
39
|
+
add_to_query restrict_kind: 'efficiency', perspective: 'interval'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @return [Rescuetime::Collection]
|
|
43
|
+
# @since v0.3.0
|
|
44
|
+
def order_by(order, opts = {})
|
|
45
|
+
fail(InvalidQueryError, "#{order} is not a valid order") unless
|
|
46
|
+
VALID[:order_by].include? order
|
|
47
|
+
fail(InvalidQueryError, "#{opts[:interval]} is not a valid interval") if
|
|
48
|
+
opts[:interval] && !VALID[:interval].include?(opts[:interval])
|
|
49
|
+
|
|
50
|
+
add_to_query perspective: (order.to_s == 'time' ? 'interval' : order),
|
|
51
|
+
resolution_time: opts[:interval] || opts['interval']
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @return [Rescuetime::Collection]
|
|
55
|
+
# @since v0.3.0
|
|
56
|
+
def date(date)
|
|
57
|
+
add_to_query restrict_end: to_formatted_s(date),
|
|
58
|
+
restrict_begin: to_formatted_s(date)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @return [Rescuetime::Collection]
|
|
62
|
+
# @since v0.3.0
|
|
63
|
+
def from(date)
|
|
64
|
+
add_to_query restrict_begin: to_formatted_s(date)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @return [Rescuetime::Collection]
|
|
68
|
+
# @since v0.3.0
|
|
69
|
+
def to(date)
|
|
70
|
+
add_to_query restrict_end: to_formatted_s(date)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @return [Rescuetime::Collection]
|
|
74
|
+
# @since v0.3.0
|
|
75
|
+
def where(options)
|
|
76
|
+
add_to_query restrict_thing: options[:name],
|
|
77
|
+
restrict_thingy: options[:document]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
VALID = {
|
|
83
|
+
order_by: [:time, :rank, :member],
|
|
84
|
+
interval: [:minute, :hour, :day, :week, :month]
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
def add_to_query(**terms)
|
|
88
|
+
if self.is_a? Rescuetime::Collection
|
|
89
|
+
self << terms
|
|
90
|
+
self
|
|
91
|
+
else
|
|
92
|
+
Rescuetime::Collection.new(BASE_PARAMS, state, terms)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# @since v0.3.0
|
|
97
|
+
def to_formatted_s(date)
|
|
98
|
+
case
|
|
99
|
+
when date.respond_to?(:strftime) then date.strftime('%Y-%m-%d')
|
|
100
|
+
when date =~ /\d{4}-\d{2}-\d{2}/ then date
|
|
101
|
+
when date =~ %r{\d{4}\/\d{2}\/\d{2}} then date.gsub '/', '-'
|
|
102
|
+
when date =~ %r{\d{2}[-\/]\d{2}[-\/]\d{4}/}
|
|
103
|
+
date_chunks = date.scan(/\d+/)
|
|
104
|
+
"#{ date_chunks[2] }-#{ date_chunks[0] }-#{ date_chunks[1] }"
|
|
105
|
+
when date =~ %r{\d{2}[-\/]\d{2}}
|
|
106
|
+
date_chunks = date.scan(/\d+/)
|
|
107
|
+
"#{ Time.now.year }-#{ date_chunks[0] }-#{ date_chunks[1] }"
|
|
108
|
+
else
|
|
109
|
+
fail InvalidQueryError,
|
|
110
|
+
'Invalid date entered. Please see docs for allowed formats.'
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Rescuetime
|
|
2
|
+
# The Rescuetime::Requestable module contains client methods relating to
|
|
3
|
+
# sending HTTP requests
|
|
4
|
+
#
|
|
5
|
+
# @since v0.2.0
|
|
6
|
+
class Requester
|
|
7
|
+
class << self
|
|
8
|
+
# @since v0.2.0
|
|
9
|
+
def get(host, params)
|
|
10
|
+
fail(Rescuetime::MissingCredentialsError) unless
|
|
11
|
+
params[:key] && !params[:key].to_s.empty?
|
|
12
|
+
|
|
13
|
+
response = Faraday.get(host,
|
|
14
|
+
params.delete_if { |_, v| !v || v.to_s.empty? })
|
|
15
|
+
|
|
16
|
+
fail_or_return response
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
INVALID = {
|
|
22
|
+
key_not_found: '"error":"# key not found","messages":"key not found"',
|
|
23
|
+
query: '"error": "# query error",'\
|
|
24
|
+
'"messages": "Error: Likely a badly formatted or missing parameter"'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
def fail_or_return(response)
|
|
28
|
+
fail Rescuetime::InvalidCredentialsError if
|
|
29
|
+
response.body =~ /#{INVALID[:key_not_found]}/
|
|
30
|
+
fail Rescuetime::InvalidQueryError if
|
|
31
|
+
response.body =~ /#{INVALID[:query]}/
|
|
32
|
+
|
|
33
|
+
error = Rescuetime::Error::CODES[response.status.to_i]
|
|
34
|
+
fail(error) if error
|
|
35
|
+
|
|
36
|
+
response
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/lib/rescuetime/version.rb
CHANGED
data/rescuetime.gemspec
CHANGED
|
@@ -9,17 +9,18 @@ Gem::Specification.new do |spec|
|
|
|
9
9
|
spec.authors = ['Lee Sharma']
|
|
10
10
|
spec.email = ['lee@leesharma.com']
|
|
11
11
|
|
|
12
|
-
spec.summary = %
|
|
13
|
-
spec.description = %
|
|
12
|
+
spec.summary = %w(Ruby interface for RescueTime)
|
|
13
|
+
spec.description = %w(Ruby interface for the RescueTime Data Analytics API.)
|
|
14
14
|
spec.homepage = 'https://github.com/leesharma/rescuetime'
|
|
15
15
|
spec.license = 'MIT'
|
|
16
16
|
|
|
17
|
-
spec.files = `git ls-files -z`.split("\x0")
|
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
|
18
|
+
.reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
18
19
|
spec.bindir = 'exe'
|
|
19
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
20
21
|
spec.require_paths = ['lib']
|
|
21
22
|
|
|
22
|
-
spec.required_ruby_version = '>=
|
|
23
|
+
spec.required_ruby_version = '>= 2.0.0'
|
|
23
24
|
|
|
24
25
|
spec.add_dependency 'faraday', '~> 0.9.1'
|
|
25
26
|
|
|
@@ -27,6 +28,7 @@ Gem::Specification.new do |spec|
|
|
|
27
28
|
spec.add_development_dependency 'rake', '~> 10.4', '>= 10.4.2'
|
|
28
29
|
|
|
29
30
|
spec.add_development_dependency 'rspec', '~> 3.2', '>= 3.2.0'
|
|
31
|
+
spec.add_development_dependency 'rspec-its'
|
|
30
32
|
spec.add_development_dependency 'vcr', '~> 2.9', '>= 2.9.3'
|
|
31
33
|
spec.add_development_dependency 'webmock', '~> 1.21', '>= 1.21.0'
|
|
32
34
|
end
|
metadata
CHANGED
|
@@ -1,133 +1,148 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rescuetime
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lee Sharma
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-04
|
|
11
|
+
date: 2015-05-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - ~>
|
|
17
|
+
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: 0.9.1
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- - ~>
|
|
24
|
+
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: 0.9.1
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: bundler
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- -
|
|
31
|
+
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: '0'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- -
|
|
38
|
+
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '0'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rake
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
|
-
- - ~>
|
|
45
|
+
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
47
|
version: '10.4'
|
|
48
|
-
- -
|
|
48
|
+
- - ">="
|
|
49
49
|
- !ruby/object:Gem::Version
|
|
50
50
|
version: 10.4.2
|
|
51
51
|
type: :development
|
|
52
52
|
prerelease: false
|
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
|
54
54
|
requirements:
|
|
55
|
-
- - ~>
|
|
55
|
+
- - "~>"
|
|
56
56
|
- !ruby/object:Gem::Version
|
|
57
57
|
version: '10.4'
|
|
58
|
-
- -
|
|
58
|
+
- - ">="
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
60
|
version: 10.4.2
|
|
61
61
|
- !ruby/object:Gem::Dependency
|
|
62
62
|
name: rspec
|
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
|
-
- - ~>
|
|
65
|
+
- - "~>"
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
67
|
version: '3.2'
|
|
68
|
-
- -
|
|
68
|
+
- - ">="
|
|
69
69
|
- !ruby/object:Gem::Version
|
|
70
70
|
version: 3.2.0
|
|
71
71
|
type: :development
|
|
72
72
|
prerelease: false
|
|
73
73
|
version_requirements: !ruby/object:Gem::Requirement
|
|
74
74
|
requirements:
|
|
75
|
-
- - ~>
|
|
75
|
+
- - "~>"
|
|
76
76
|
- !ruby/object:Gem::Version
|
|
77
77
|
version: '3.2'
|
|
78
|
-
- -
|
|
78
|
+
- - ">="
|
|
79
79
|
- !ruby/object:Gem::Version
|
|
80
80
|
version: 3.2.0
|
|
81
|
+
- !ruby/object:Gem::Dependency
|
|
82
|
+
name: rspec-its
|
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
|
84
|
+
requirements:
|
|
85
|
+
- - ">="
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '0'
|
|
88
|
+
type: :development
|
|
89
|
+
prerelease: false
|
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - ">="
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '0'
|
|
81
95
|
- !ruby/object:Gem::Dependency
|
|
82
96
|
name: vcr
|
|
83
97
|
requirement: !ruby/object:Gem::Requirement
|
|
84
98
|
requirements:
|
|
85
|
-
- - ~>
|
|
99
|
+
- - "~>"
|
|
86
100
|
- !ruby/object:Gem::Version
|
|
87
101
|
version: '2.9'
|
|
88
|
-
- -
|
|
102
|
+
- - ">="
|
|
89
103
|
- !ruby/object:Gem::Version
|
|
90
104
|
version: 2.9.3
|
|
91
105
|
type: :development
|
|
92
106
|
prerelease: false
|
|
93
107
|
version_requirements: !ruby/object:Gem::Requirement
|
|
94
108
|
requirements:
|
|
95
|
-
- - ~>
|
|
109
|
+
- - "~>"
|
|
96
110
|
- !ruby/object:Gem::Version
|
|
97
111
|
version: '2.9'
|
|
98
|
-
- -
|
|
112
|
+
- - ">="
|
|
99
113
|
- !ruby/object:Gem::Version
|
|
100
114
|
version: 2.9.3
|
|
101
115
|
- !ruby/object:Gem::Dependency
|
|
102
116
|
name: webmock
|
|
103
117
|
requirement: !ruby/object:Gem::Requirement
|
|
104
118
|
requirements:
|
|
105
|
-
- - ~>
|
|
119
|
+
- - "~>"
|
|
106
120
|
- !ruby/object:Gem::Version
|
|
107
121
|
version: '1.21'
|
|
108
|
-
- -
|
|
122
|
+
- - ">="
|
|
109
123
|
- !ruby/object:Gem::Version
|
|
110
124
|
version: 1.21.0
|
|
111
125
|
type: :development
|
|
112
126
|
prerelease: false
|
|
113
127
|
version_requirements: !ruby/object:Gem::Requirement
|
|
114
128
|
requirements:
|
|
115
|
-
- - ~>
|
|
129
|
+
- - "~>"
|
|
116
130
|
- !ruby/object:Gem::Version
|
|
117
131
|
version: '1.21'
|
|
118
|
-
- -
|
|
132
|
+
- - ">="
|
|
119
133
|
- !ruby/object:Gem::Version
|
|
120
134
|
version: 1.21.0
|
|
121
|
-
description: Ruby interface for the RescueTime Data Analytics
|
|
135
|
+
description: '["Ruby", "interface", "for", "the", "RescueTime", "Data", "Analytics",
|
|
136
|
+
"API."]'
|
|
122
137
|
email:
|
|
123
138
|
- lee@leesharma.com
|
|
124
139
|
executables: []
|
|
125
140
|
extensions: []
|
|
126
141
|
extra_rdoc_files: []
|
|
127
142
|
files:
|
|
128
|
-
- .gitignore
|
|
129
|
-
- .rspec
|
|
130
|
-
- .travis.yml
|
|
143
|
+
- ".gitignore"
|
|
144
|
+
- ".rspec"
|
|
145
|
+
- ".travis.yml"
|
|
131
146
|
- CHANGELOG.md
|
|
132
147
|
- CODE_OF_CONDUCT.md
|
|
133
148
|
- CONTRIBUTING.md
|
|
@@ -138,10 +153,11 @@ files:
|
|
|
138
153
|
- bin/console
|
|
139
154
|
- bin/setup
|
|
140
155
|
- lib/rescuetime.rb
|
|
141
|
-
- lib/rescuetime/activities.rb
|
|
142
|
-
- lib/rescuetime/api.rb
|
|
143
156
|
- lib/rescuetime/client.rb
|
|
157
|
+
- lib/rescuetime/collection.rb
|
|
144
158
|
- lib/rescuetime/errors.rb
|
|
159
|
+
- lib/rescuetime/query_buildable.rb
|
|
160
|
+
- lib/rescuetime/requester.rb
|
|
145
161
|
- lib/rescuetime/version.rb
|
|
146
162
|
- rescuetime.gemspec
|
|
147
163
|
homepage: https://github.com/leesharma/rescuetime
|
|
@@ -154,12 +170,12 @@ require_paths:
|
|
|
154
170
|
- lib
|
|
155
171
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
156
172
|
requirements:
|
|
157
|
-
- -
|
|
173
|
+
- - ">="
|
|
158
174
|
- !ruby/object:Gem::Version
|
|
159
|
-
version:
|
|
175
|
+
version: 2.0.0
|
|
160
176
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
161
177
|
requirements:
|
|
162
|
-
- -
|
|
178
|
+
- - ">="
|
|
163
179
|
- !ruby/object:Gem::Version
|
|
164
180
|
version: '0'
|
|
165
181
|
requirements: []
|
|
@@ -167,5 +183,6 @@ rubyforge_project:
|
|
|
167
183
|
rubygems_version: 2.4.5
|
|
168
184
|
signing_key:
|
|
169
185
|
specification_version: 4
|
|
170
|
-
summary: Ruby interface for RescueTime
|
|
186
|
+
summary: '["Ruby", "interface", "for", "RescueTime"]'
|
|
171
187
|
test_files: []
|
|
188
|
+
has_rdoc:
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
module Rescuetime
|
|
2
|
-
# The Rescuetime::Activities module contains client methods relating to user
|
|
3
|
-
# activities on the /data endpoint of the Data Analytics API.
|
|
4
|
-
#
|
|
5
|
-
# @since v0.1.0
|
|
6
|
-
module Activities
|
|
7
|
-
# Base URL for RescueTime Data Analytics API endpoint
|
|
8
|
-
# @since v0.1.0
|
|
9
|
-
BASE_URL = 'https://www.rescuetime.com/anapi/data'
|
|
10
|
-
# Map of numeric productivity levels to meaning
|
|
11
|
-
# @since v0.2.0
|
|
12
|
-
PRODUCTIVITY_LEVELS = { -2 => 'Very Unproductive',
|
|
13
|
-
-1 => 'Unproductive',
|
|
14
|
-
0 => 'Neutral',
|
|
15
|
-
1 => 'Productive',
|
|
16
|
-
2 => 'Very Productive' }
|
|
17
|
-
|
|
18
|
-
# Returns array of all activities.
|
|
19
|
-
#
|
|
20
|
-
# @example Basic behavior
|
|
21
|
-
# @activities = @client.activities
|
|
22
|
-
# @activities.class # => Array
|
|
23
|
-
# @acitvities[0].class # => Hash
|
|
24
|
-
#
|
|
25
|
-
# @activities[0]
|
|
26
|
-
# # => {
|
|
27
|
-
# # :rank=>1,
|
|
28
|
-
# # :time_spent_seconds=>5307,
|
|
29
|
-
# # :number_of_people=>1,
|
|
30
|
-
# # :activity=>"github.com",
|
|
31
|
-
# # :category=>"General Software Development",
|
|
32
|
-
# # :productivity=>2
|
|
33
|
-
# # }
|
|
34
|
-
#
|
|
35
|
-
# @example Set level of detail
|
|
36
|
-
# @client.activities(detail: 'overview')[0]
|
|
37
|
-
# # => { :rank=>1, :time_spent_seconds=>13140, :number_of_people=>1, :category=>'Software Development' }
|
|
38
|
-
#
|
|
39
|
-
# @client.activities(detail: 'category')[0]
|
|
40
|
-
# # => { :rank=>1, :time_spent_seconds=>5835, :number_of_people=>1, :category=>'Editing and IDEs' }
|
|
41
|
-
#
|
|
42
|
-
# @client.activities(detail: 'activity')[0]
|
|
43
|
-
# # => { :rank=>1,
|
|
44
|
-
# # :time_spent_seconds=>5835,
|
|
45
|
-
# # :number_of_people=>1,
|
|
46
|
-
# # :category=>'Editing and IDEs',
|
|
47
|
-
# # :activity=>'RubyMine',
|
|
48
|
-
# # :productivity=>2 }
|
|
49
|
-
#
|
|
50
|
-
# @client.activities(detail: 'productivity') # Equivalent to @client.productivity
|
|
51
|
-
# @client.activities(detail: 'efficiency', by: 'time') # Equivalent to @client.efficiency
|
|
52
|
-
#
|
|
53
|
-
# @example Set perspective
|
|
54
|
-
# @client.activities(by: 'rank') # Returns activities by rank (time spent per activity)
|
|
55
|
-
# @client.activities(by: 'interval') # Returns activities chronologically
|
|
56
|
-
# @client.activities(by: 'member') # Returns activities grouped by member
|
|
57
|
-
#
|
|
58
|
-
# @example Set date range (note: no time constraints are allowed)
|
|
59
|
-
# @client.activities(date: '2014-05-06') # Returns report for May 6, 2014
|
|
60
|
-
# @client.activities(from: '2014-05-06', to: '2014-06-06') # Returns report for May 6 to June 6, 2014
|
|
61
|
-
# @client.activities(from: '2015-04-10') # Returns report for April 10, 2015 to today
|
|
62
|
-
#
|
|
63
|
-
# @example Set time interval
|
|
64
|
-
# @client.efficiency( from: '2015-01-01', # Returns an efficiency report by
|
|
65
|
-
# to: Time.now, # week from the Jan 1, 2015 through
|
|
66
|
-
# interval: 'week') # today.
|
|
67
|
-
#
|
|
68
|
-
# @example Format
|
|
69
|
-
# @client.activities # Returns array of hashes
|
|
70
|
-
# @client.activities format: 'csv' # Returns Mime::CSV
|
|
71
|
-
#
|
|
72
|
-
# @param [Hash] options Query parameters to be passed to RescueTime
|
|
73
|
-
# @option options [String] :detail
|
|
74
|
-
# Restricts the level of detail of report returned
|
|
75
|
-
# 1. 'overview': sums statistics for all activities into their top level category
|
|
76
|
-
# 2. 'category': sums statistics for all activities into their sub category
|
|
77
|
-
# 3. 'activity' (default): sums statistics for individual applications / web sites / activities
|
|
78
|
-
# 4. 'productivity': productivity calculation (@see #productivity)
|
|
79
|
-
# 5. 'efficiency': efficiency calculation (not applicable in "rank" perspective, @see #efficiency)
|
|
80
|
-
# @option options [String] :by
|
|
81
|
-
# Lets you set the perspective of your report
|
|
82
|
-
# 1. 'rank' (default): returns a ranked report of activities by total time spent
|
|
83
|
-
# 2. 'time': returns a chronological report of activities
|
|
84
|
-
# 3. 'member': returns an activity report grouped by member
|
|
85
|
-
# @option options [String] :date
|
|
86
|
-
# Lets you set a single date for your report in a 'YYYY-MM-DD' format. Not
|
|
87
|
-
# valid with :to or :from. Cannot be a future date.
|
|
88
|
-
# @option options [String] :from
|
|
89
|
-
# Lets you set a start date for your report in a 'YYYY-MM-DD' format. Valid
|
|
90
|
-
# with the :to option or alone (:to defaults to current date). Cannot be a
|
|
91
|
-
# future date or after the :to date (if supplied).
|
|
92
|
-
# @option options [String] :to
|
|
93
|
-
# Lets you set an end date for your report in a 'YYYY-MM-DD' format. If a
|
|
94
|
-
# :to is supplied, :from must be supplied as well. Cannot be a future date or
|
|
95
|
-
# before the :from date.
|
|
96
|
-
# @option options [String] :interval
|
|
97
|
-
# Lets you set the time interval for your report (ie. client.efficiency(interval:'day')
|
|
98
|
-
# returns the efficiency report by day.) Possible values include:
|
|
99
|
-
# 1. 'minute': returns data in 5-minute increments
|
|
100
|
-
# 2. 'hour' (default): returns data in 1-hour increments
|
|
101
|
-
# 3. 'day': returns data in 1-day increments
|
|
102
|
-
# 4. 'week': returns data in 1-week increments
|
|
103
|
-
# 5. 'month': returns data in 1-month increments
|
|
104
|
-
# @option options [String] :format
|
|
105
|
-
# Lets you specify a return type for your report
|
|
106
|
-
# 1. default: returns an array of hashes with symbolized keys
|
|
107
|
-
# 2. 'csv': returns a Mime::CSV object
|
|
108
|
-
#
|
|
109
|
-
# @return [Array<Hash>]
|
|
110
|
-
#
|
|
111
|
-
# @raise [Rescuetime::MissingCredentials] if the Rescuetime::Client has no set api key
|
|
112
|
-
# @raise [Rescuetime::InvalidCredentials] if the provided api key is rejected by RescueTime
|
|
113
|
-
# @since v0.1.0
|
|
114
|
-
def activities(options={})
|
|
115
|
-
response = self.get BASE_URL, options
|
|
116
|
-
|
|
117
|
-
case options[:format]
|
|
118
|
-
when 'csv' then CSV.new(response.body, headers: true)
|
|
119
|
-
else array_of_hashes_from_csv(response.body)
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
# Returns efficiency report. Equivalent to #activities(by: time, detail: efficiency)
|
|
124
|
-
# @see #activities valid options
|
|
125
|
-
#
|
|
126
|
-
# @param [Hash] options options hash (same as #activities)
|
|
127
|
-
# @return [Array<Hash>]
|
|
128
|
-
def efficiency(options={})
|
|
129
|
-
self.activities({by: 'time'}.merge(options.merge(detail: 'efficiency')))
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
# Returns productivity report. Equivalent to #activities(detail: productivity)
|
|
133
|
-
# @see #activities valid options
|
|
134
|
-
#
|
|
135
|
-
# @example
|
|
136
|
-
# @client.productivity # Equivalent to @client.activities(detail: 'productivity')
|
|
137
|
-
# # => [
|
|
138
|
-
# # { :rank=>1, :time_spent_seconds=>6956, :number_of_people=>1, :productivity=>2 },
|
|
139
|
-
# # { :rank=>2, :time_spent_seconds=>2635, :number_of_people=>1, :productivity=>-2 },
|
|
140
|
-
# # { :rank=>3, :time_spent_seconds=>2415, :number_of_people=>1, :productivity=>1 },
|
|
141
|
-
# # { :rank=>4, :time_spent_seconds=>1210, :number_of_people=>1, :productivity=>0 },
|
|
142
|
-
# # { :rank=>5, :time_spent_seconds=>93, :number_of_people=>1, :productivity=>-1 }
|
|
143
|
-
# # ]
|
|
144
|
-
#
|
|
145
|
-
# @param [Hash] options options hash (same as #activities)
|
|
146
|
-
# @return [Array<Hash>]
|
|
147
|
-
def productivity(options={})
|
|
148
|
-
self.activities(options.merge(detail: 'productivity'))
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
# Returns map of numeric productivity levels to meaning
|
|
152
|
-
#
|
|
153
|
-
# @example
|
|
154
|
-
# @activity = @client.activities(restrict_kind: 'productivity')[0]
|
|
155
|
-
# @primary_productivity = @client.productivity_levels[@activity[:productivity]]
|
|
156
|
-
#
|
|
157
|
-
# puts "I have spent most of my time being #{@primary_productivity}."
|
|
158
|
-
# # => I have spent most of my time being Very Productive.
|
|
159
|
-
#
|
|
160
|
-
# @return [Hash] productivity levels, with integers from -2 to 2 as keys
|
|
161
|
-
# @since v0.2.0
|
|
162
|
-
def productivity_levels
|
|
163
|
-
PRODUCTIVITY_LEVELS
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
private
|
|
167
|
-
|
|
168
|
-
# Takes a CSV with headers and returns an array of hashes
|
|
169
|
-
#
|
|
170
|
-
# @param body[CSV] the original CSV file
|
|
171
|
-
# @return [Array] an array of hashes, containing keys of the CSV headers
|
|
172
|
-
# @since v0.1.0
|
|
173
|
-
def array_of_hashes_from_csv(body)
|
|
174
|
-
activities = CSV.new(body,
|
|
175
|
-
headers: true,
|
|
176
|
-
header_converters: :symbol,
|
|
177
|
-
converters: :all)
|
|
178
|
-
|
|
179
|
-
activities.to_a.map(&:to_hash)
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
end
|
data/lib/rescuetime/api.rb
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
require 'rescuetime/activities'
|
|
2
|
-
|
|
3
|
-
module Rescuetime
|
|
4
|
-
# The Rescuetime::API module includes all modules corresponding to RescueTime
|
|
5
|
-
# API endpoints.
|
|
6
|
-
#
|
|
7
|
-
# For more information on the RescueTime Client, see #Rescuetime::Client.
|
|
8
|
-
# For more information on included methods, see method summary below.
|
|
9
|
-
# @since v0.1.0
|
|
10
|
-
module Api
|
|
11
|
-
include Rescuetime::Activities
|
|
12
|
-
end
|
|
13
|
-
end
|