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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4a0f32becb73b472f08339084946177bd46c4e91
4
- data.tar.gz: 6231f1d36873b7467d6d5d70d4d2ea1db26e3e74
3
+ metadata.gz: 67c11519366433b792e43a3d44a6a2dae38e6b2a
4
+ data.tar.gz: 72c994d54a419b40ba8bc14bb7459edba86b18e8
5
5
  SHA512:
6
- metadata.gz: 84bc0fe028acd831ee41d3e1f81d7c11e78a807974fcae420ab2f382fb808ea9bb112d4b1e90b8dce21b7f71908ed1a1d4e167fb39f5904a5774c0ed4a7e73ad
7
- data.tar.gz: 71a13d05744b67fc07ec4f13ce5bc50135c9428a731b50157105ed7dfecbd67e27eac8383734f97124dd03c52e346d402b1e9dc73b24d3767946ef0a33899056
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` or manually:
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
- TimestampAPi.api_key = "YOUR_TIMESTAMP_API_KEY"
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 all projects:
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 # => "My awesome project"
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
- #### Clients
70
+ #### Users
50
71
 
51
- List all clients:
72
+ List users:
52
73
  ```ruby
53
- TimestampAPI::Client.all
74
+ TimestampAPI::User.all # => Returns all users
54
75
  ```
55
76
 
56
- Find a given client:
77
+ Find a given user:
57
78
  ```ruby
58
- client = TimestampAPI::Client.find(123)
79
+ user = TimestampAPI::User.find(123)
59
80
 
60
- client.name # => "My beloved customer"
81
+ user.full_name # => "Great developer"
61
82
  ```
62
83
 
63
- Find the client of a project
84
+ #### Tasks
85
+
86
+ List tasks:
64
87
  ```ruby
65
- project = TimestampAPI::Project.find(123)
88
+ TimestampAPI::Task.all # => Returns all tasks
89
+ TimestampAPI::Task.for_project_id(123) # => Returns tasks for project 123
90
+ ```
66
91
 
67
- project.client.name # => "My beloved customer"
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
- ## Models
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
- output(method, path, camelize_keys(query_params)) if verbose
30
- response = RestClient::Request.execute(request_options(method, path, camelize_keys(query_params)))
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(method, path, query_params)
64
+ def self.output(request_options)
61
65
  print "TimestampAPI ".colorize(:red)
62
- print "#{method.upcase} ".colorize(:yellow)
63
- full_path = path
64
- full_path += "?#{query_params.each_with_object([]) { |p, acc| acc << "#{p[0]}=#{p[1]}" }.join("&")}" unless query_params.empty?
65
- puts full_path.colorize(:yellow)
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
@@ -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.downcase
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.gsub(/(.)([A-Z])/, '\1_\2').downcase
25
+ camelize(klass.name.split("::").last)
24
26
  end
25
27
  end
26
28
  end
@@ -0,0 +1,11 @@
1
+ module TimestampAPI
2
+ class Event < Model
3
+ api_path "/events"
4
+
5
+ has_attributes :resource_object, :change_type, :data
6
+
7
+ def object
8
+ TimestampAPI::ModelRegistry.model_for(data).new(data)
9
+ end
10
+ end
11
+ 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
@@ -1,3 +1,3 @@
1
1
  module TimestampAPI
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  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.5.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-31 00:00:00.000000000 Z
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