timestamp_api 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +98 -15
- data/lib/timestamp_api.rb +15 -10
- data/lib/timestamp_api/model.rb +1 -1
- data/lib/timestamp_api/model_registry.rb +3 -1
- data/lib/timestamp_api/models/event.rb +11 -0
- data/lib/timestamp_api/models/project.rb +10 -0
- data/lib/timestamp_api/models/time_entry.rb +16 -0
- data/lib/timestamp_api/models/user.rb +4 -0
- data/lib/timestamp_api/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67c11519366433b792e43a3d44a6a2dae38e6b2a
|
4
|
+
data.tar.gz: 72c994d54a419b40ba8bc14bb7459edba86b18e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e743c9cbeb2fac5c20a97895f9fec04f6c0636a73fe3ddedd070ec794fc126146bbcd775764d79ea2008378e0256234c7214dcbaaf3fa3bb5306c2999719604
|
7
|
+
data.tar.gz: b4dede14115223f3445e1d86e987cad5fa018b772b91332bd1afe2f819bece132b722abc0e8789bad132d174a2292b20fee9c94045da57f00c53e182f24dc061
|
data/README.md
CHANGED
@@ -27,47 +27,112 @@ Or install it yourself as:
|
|
27
27
|
|
28
28
|
## Usage
|
29
29
|
|
30
|
-
Configure your Timestamp API key by setting environment variable `TIMESTAMP_API_KEY
|
30
|
+
Configure your Timestamp API key by setting environment variable `TIMESTAMP_API_KEY`:
|
31
|
+
```shell
|
32
|
+
$ TIMESTAMP_API_KEY="YOUR_API_KEY" bin/console
|
33
|
+
```
|
34
|
+
|
35
|
+
Or set it manually from the console:
|
36
|
+
```ruby
|
37
|
+
TimestampAPi.api_key = "YOUR_API_KEY"
|
38
|
+
```
|
39
|
+
|
40
|
+
#### Clients
|
41
|
+
|
42
|
+
List clients:
|
31
43
|
```ruby
|
32
|
-
|
44
|
+
TimestampAPI::Client.all # => Returns all clients
|
45
|
+
```
|
46
|
+
|
47
|
+
Find a given client:
|
48
|
+
```ruby
|
49
|
+
client = TimestampAPI::Client.find(123)
|
50
|
+
|
51
|
+
client.name # => "My beloved customer"
|
33
52
|
```
|
34
53
|
|
35
54
|
#### Projects
|
36
55
|
|
37
|
-
List
|
56
|
+
List projects:
|
38
57
|
```ruby
|
39
|
-
TimestampAPI::Project.all
|
58
|
+
TimestampAPI::Project.all # => Returns all projects
|
40
59
|
```
|
41
60
|
|
42
61
|
Find a given project:
|
43
62
|
```ruby
|
44
63
|
project = TimestampAPI::Project.find(123)
|
45
64
|
|
46
|
-
project.name
|
65
|
+
project.name # => "My awesome project"
|
66
|
+
project.client.name # => "My beloved customer"
|
67
|
+
project.enter_time(123, Date.today, 60) # => Creates a 60 minutes time entry for today on task 123 and returns the created TimeEntry
|
47
68
|
```
|
48
69
|
|
49
|
-
####
|
70
|
+
#### Users
|
50
71
|
|
51
|
-
List
|
72
|
+
List users:
|
52
73
|
```ruby
|
53
|
-
TimestampAPI::
|
74
|
+
TimestampAPI::User.all # => Returns all users
|
54
75
|
```
|
55
76
|
|
56
|
-
Find a given
|
77
|
+
Find a given user:
|
57
78
|
```ruby
|
58
|
-
|
79
|
+
user = TimestampAPI::User.find(123)
|
59
80
|
|
60
|
-
|
81
|
+
user.full_name # => "Great developer"
|
61
82
|
```
|
62
83
|
|
63
|
-
|
84
|
+
#### Tasks
|
85
|
+
|
86
|
+
List tasks:
|
64
87
|
```ruby
|
65
|
-
|
88
|
+
TimestampAPI::Task.all # => Returns all tasks
|
89
|
+
TimestampAPI::Task.for_project_id(123) # => Returns tasks for project 123
|
90
|
+
```
|
66
91
|
|
67
|
-
|
92
|
+
Find a given task:
|
93
|
+
```ruby
|
94
|
+
task = TimestampAPI::Task.find(123)
|
95
|
+
|
96
|
+
task.name # => "My fantastic task"
|
97
|
+
task.project.name # => "My awesome project"
|
68
98
|
```
|
69
99
|
|
70
|
-
|
100
|
+
#### TimeEntry
|
101
|
+
|
102
|
+
List time entries:
|
103
|
+
```ruby
|
104
|
+
TimestampAPI::TimeEntry.all # => Returns all time entries
|
105
|
+
TimestampAPI::TimeEntry.for_task_id(123) # => Returns time entries for task 123
|
106
|
+
```
|
107
|
+
|
108
|
+
Find a given time entry:
|
109
|
+
```ruby
|
110
|
+
time_entry = TimestampAPI::TimeEntry.find(123)
|
111
|
+
|
112
|
+
time_entry.comment # => "Stuff got done"
|
113
|
+
time_entry.client.name # => "My beloved customer"
|
114
|
+
time_entry.project.name # => "My awesome project"
|
115
|
+
time_entry.task.name # => "My fantastic task"
|
116
|
+
time_entry.user.full_name # => "Great developer"
|
117
|
+
```
|
118
|
+
|
119
|
+
#### Event
|
120
|
+
|
121
|
+
List events:
|
122
|
+
```ruby
|
123
|
+
TimestampAPI::Event.all # => Returns all events
|
124
|
+
```
|
125
|
+
|
126
|
+
Find a given event:
|
127
|
+
```ruby
|
128
|
+
event = TimestampAPI::Event.find(123)
|
129
|
+
|
130
|
+
event.object # => Returns the object on which event occured
|
131
|
+
```
|
132
|
+
|
133
|
+
## Objects representation
|
134
|
+
|
135
|
+
#### Models
|
71
136
|
|
72
137
|
The objects are represented by model classes (that inherits from `TimestampAPI::Model`):
|
73
138
|
```ruby
|
@@ -77,6 +142,8 @@ project.class # => TimestampAPI::Project
|
|
77
142
|
project.is_a? TimestampAPI::Model # => true
|
78
143
|
```
|
79
144
|
|
145
|
+
#### Collections
|
146
|
+
|
80
147
|
Collections of objects are represented by `TimestampAPI::Collection` that inherits from `Array` (and implement the chainable `.where(conditions)` filter method described above). It means any `Array` method works on `TimestampAPI::Collection`:
|
81
148
|
```ruby
|
82
149
|
projects = TimestampAPI::Project.all
|
@@ -85,6 +152,19 @@ projects.class # => TimestampAPI::Collection
|
|
85
152
|
projects.map(&:name) # => ["A project", "Another project", "One more project"]
|
86
153
|
```
|
87
154
|
|
155
|
+
#### Relationships
|
156
|
+
|
157
|
+
Models can can bound together and are accessible using a simple getter:
|
158
|
+
|
159
|
+
Exemple: find the client bound to a project:
|
160
|
+
```ruby
|
161
|
+
project = TimestampAPI::Project.find(123)
|
162
|
+
|
163
|
+
project.client.name # => "My beloved customer"
|
164
|
+
```
|
165
|
+
|
166
|
+
:information_source: First call to such a relation getter will trigger an API request and memoize the response for network optimization.
|
167
|
+
|
88
168
|
## Filtering
|
89
169
|
|
90
170
|
You can filter any object collection using the handy `.where()` syntax:
|
@@ -129,6 +209,8 @@ There's also a `bin/console` executable provided with this gem, if you want a RE
|
|
129
209
|
* [x] `Client` model
|
130
210
|
* [x] `Task` model
|
131
211
|
* [x] `User` model (their `roles` could be enhanced, though)
|
212
|
+
* [x] `TimeEntry` model
|
213
|
+
* [x] `Event` model
|
132
214
|
* [x] `belongs_to` relationships
|
133
215
|
|
134
216
|
### What's not implemented yet ?
|
@@ -136,6 +218,7 @@ There's also a `bin/console` executable provided with this gem, if you want a RE
|
|
136
218
|
* [ ] _all other models_ :scream:
|
137
219
|
* [ ] `has_many` relationships
|
138
220
|
* [ ] document and integrate [Inch-CI](https://inch-ci.org)
|
221
|
+
* [ ] timers
|
139
222
|
|
140
223
|
## Development
|
141
224
|
|
data/lib/timestamp_api.rb
CHANGED
@@ -11,10 +11,12 @@ require "timestamp_api/model_relations"
|
|
11
11
|
require "timestamp_api/model_default_api_methods"
|
12
12
|
require "timestamp_api/model"
|
13
13
|
require "timestamp_api/collection"
|
14
|
+
require "timestamp_api/models/event"
|
14
15
|
require "timestamp_api/models/project"
|
15
16
|
require "timestamp_api/models/client"
|
16
17
|
require "timestamp_api/models/task"
|
17
18
|
require "timestamp_api/models/user"
|
19
|
+
require "timestamp_api/models/time_entry"
|
18
20
|
|
19
21
|
module TimestampAPI
|
20
22
|
extend Utils
|
@@ -25,9 +27,10 @@ module TimestampAPI
|
|
25
27
|
attr_accessor :api_endpoint, :api_key, :verbose
|
26
28
|
end
|
27
29
|
|
28
|
-
def self.request(method, path, query_params = {})
|
29
|
-
|
30
|
-
|
30
|
+
def self.request(method, path, query_params = {}, payload = {})
|
31
|
+
request_options = request_options(method, path, query_params, payload)
|
32
|
+
output(request_options) if verbose
|
33
|
+
response = RestClient::Request.execute(request_options)
|
31
34
|
modelify(JSON.parse(response))
|
32
35
|
rescue RestClient::Forbidden
|
33
36
|
raise InvalidAPIKey
|
@@ -37,15 +40,16 @@ module TimestampAPI
|
|
37
40
|
|
38
41
|
private
|
39
42
|
|
40
|
-
def self.request_options(method, path, query_params)
|
43
|
+
def self.request_options(method, path, query_params, payload)
|
41
44
|
{
|
42
45
|
method: method,
|
43
46
|
url: api_endpoint + path,
|
47
|
+
payload: camelize_keys(payload).to_json,
|
44
48
|
headers: {
|
45
49
|
"X-API-Key" => api_key || ENV["TIMESTAMP_API_KEY"] || raise(MissingAPIKey),
|
46
50
|
:accept => :json,
|
47
51
|
:user_agent => "TimestampAPI Ruby gem (https://github.com/alpinelab/timestamp_api)",
|
48
|
-
:params => query_params
|
52
|
+
:params => camelize_keys(query_params)
|
49
53
|
}
|
50
54
|
}
|
51
55
|
end
|
@@ -57,11 +61,12 @@ private
|
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
60
|
-
def self.output(
|
64
|
+
def self.output(request_options)
|
61
65
|
print "TimestampAPI ".colorize(:red)
|
62
|
-
print "#{method.upcase} ".colorize(:yellow)
|
63
|
-
full_path =
|
64
|
-
full_path += "?#{
|
65
|
-
|
66
|
+
print "#{request_options[:method].upcase} ".colorize(:yellow)
|
67
|
+
full_path = request_options[:url]
|
68
|
+
full_path += "?#{request_options[:headers][:params].each_with_object([]) { |p, acc| acc << "#{p[0]}=#{p[1]}" }.join("&")}" unless request_options[:headers][:params].empty?
|
69
|
+
print full_path.colorize(:yellow)
|
70
|
+
puts " #{request_options[:payload] unless request_options[:payload].empty?}".colorize(:green)
|
66
71
|
end
|
67
72
|
end
|
data/lib/timestamp_api/model.rb
CHANGED
@@ -25,7 +25,7 @@ module TimestampAPI
|
|
25
25
|
|
26
26
|
def validate_init_data!
|
27
27
|
class_basename = self.class.name.split("::").last
|
28
|
-
raise InvalidModelData.new(class_basename, json_data) unless json_data.is_a?(Hash) && json_data["object"] == class_basename
|
28
|
+
raise InvalidModelData.new(class_basename, json_data) unless json_data.is_a?(Hash) && json_data["object"] == camelize(class_basename)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module TimestampAPI
|
2
2
|
class ModelRegistry
|
3
|
+
extend Utils
|
4
|
+
|
3
5
|
class << self
|
4
6
|
|
5
7
|
@@registry = {}
|
@@ -20,7 +22,7 @@ module TimestampAPI
|
|
20
22
|
private
|
21
23
|
|
22
24
|
def registry_key(klass)
|
23
|
-
klass.name.split("::").last
|
25
|
+
camelize(klass.name.split("::").last)
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
@@ -6,5 +6,15 @@ module TimestampAPI
|
|
6
6
|
:target_completion_date, :is_archived, :is_billable, :is_public, :is_approvable
|
7
7
|
|
8
8
|
belongs_to :client
|
9
|
+
|
10
|
+
def enter_time(task_id, day, duration_in_minutes, comment = "")
|
11
|
+
TimestampAPI.request(:post, "#{@@api_path}/#{id}/enterTime", {}, {
|
12
|
+
task_id: task_id,
|
13
|
+
day: day.strftime("%FT%T%:z"),
|
14
|
+
time_value: duration_in_minutes,
|
15
|
+
time_unit: "Minutes",
|
16
|
+
comment: comment
|
17
|
+
}).object
|
18
|
+
end
|
9
19
|
end
|
10
20
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module TimestampAPI
|
2
|
+
class TimeEntry < Model
|
3
|
+
api_path "/timeEntries"
|
4
|
+
|
5
|
+
has_attributes :id, :created_at, :comment, :day, :minutes, :is_archived, :is_approved, :is_invoiced, :is_externally_owned, :is_locked
|
6
|
+
|
7
|
+
belongs_to :client
|
8
|
+
belongs_to :project
|
9
|
+
belongs_to :task
|
10
|
+
belongs_to :user
|
11
|
+
|
12
|
+
def self.for_task_id(task_id)
|
13
|
+
all("$filter" => "TaskId%20eq%20#{task_id}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -4,5 +4,9 @@ module TimestampAPI
|
|
4
4
|
|
5
5
|
has_attributes :id, :created_at, :user_type, :first_name, :last_name, :email_address, :time_zone, :culture, :is_active,
|
6
6
|
:avatar_url, :last_accessed, :invited_at, :roles, :employment_type, :time_entry_mode, :importStatus, :invited
|
7
|
+
|
8
|
+
def full_name
|
9
|
+
"#{first_name} #{last_name}"
|
10
|
+
end
|
7
11
|
end
|
8
12
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timestamp_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Baudino
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01
|
11
|
+
date: 2016-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -165,8 +165,10 @@ files:
|
|
165
165
|
- lib/timestamp_api/model_registry.rb
|
166
166
|
- lib/timestamp_api/model_relations.rb
|
167
167
|
- lib/timestamp_api/models/client.rb
|
168
|
+
- lib/timestamp_api/models/event.rb
|
168
169
|
- lib/timestamp_api/models/project.rb
|
169
170
|
- lib/timestamp_api/models/task.rb
|
171
|
+
- lib/timestamp_api/models/time_entry.rb
|
170
172
|
- lib/timestamp_api/models/user.rb
|
171
173
|
- lib/timestamp_api/utils.rb
|
172
174
|
- lib/timestamp_api/version.rb
|