rescuetime 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|