timestamp_api 0.1.0 → 0.2.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: 2e4fca3476b72032b4d7c6f60103a1786233dd37
4
- data.tar.gz: b5cd56f6c58af100d6603a12daa2553849fa0735
3
+ metadata.gz: 6a870a3e355cac05312491e1f1de0868959a58cb
4
+ data.tar.gz: 030bdb7e4306a523c303f66121b003661b7ea38a
5
5
  SHA512:
6
- metadata.gz: 45f343a6cf9ed1bdbd90bb88f486af98031687f4649f016128201388d6e9d9619bbe4e93e359872529b9cb84490fbe4e65bc9eb3e061d3429cbaccf16b35df98
7
- data.tar.gz: 835fcd3aa22f5b502be689036d2cb040f35a91b19c05cfaabc74931a6ffc85b24adac530b59565b61ab69770562b83a713b3848590c84d3aaf9d3ecb3fe09ab8
6
+ metadata.gz: b84b0632fd788418b36bc86a1398326973cc64f9676a875579285e35345aa2523f4789ddc75d427fe34b74e08866f2c762e355556e2f17b35ea831fe1a8c165f
7
+ data.tar.gz: d63292c7170080dc6b3b72b6a5183db06fe0bbb986610d22a9bf11769a1adfbf6cb4ec7043c53d97060685389114c0ab6ddee2a8ec9ef6d1396f77b25cb68286
data/.gitignore CHANGED
@@ -10,3 +10,4 @@
10
10
  /.ruby-version
11
11
  /.ruby-gemset
12
12
  /.rvmrc
13
+ *.gem
data/README.md CHANGED
@@ -1,10 +1,13 @@
1
1
  # Timestamp API
2
2
 
3
3
  [![Build Status](https://travis-ci.org/alpinelab/timestamp_api.svg?branch=master)](https://travis-ci.org/alpinelab/timestamp_api)
4
+ [![Code Climate](https://codeclimate.com/github/alpinelab/timestamp_api/badges/gpa.svg)](https://codeclimate.com/github/alpinelab/timestamp_api)
5
+ [![Test Coverage](https://codeclimate.com/github/alpinelab/timestamp_api/badges/coverage.svg)](https://codeclimate.com/github/alpinelab/timestamp_api/coverage)
6
+ [![Gem Version](https://badge.fury.io/rb/timestamp_api.svg)](https://badge.fury.io/rb/timestamp_api)
7
+ [![security](https://hakiri.io/github/alpinelab/timestamp_api/master.svg)](https://hakiri.io/github/alpinelab/timestamp_api/master)
8
+ [![Dependency Status](https://gemnasium.com/alpinelab/timestamp_api.svg)](https://gemnasium.com/alpinelab/timestamp_api)
4
9
 
5
- This gem is a set of Ruby bindings for the [Timestamp](https://www.timestamphq.com) API.
6
-
7
- :warning: The API is not documented nor even officially supported by Timestamp.
10
+ This gem is an unofficial set of Ruby bindings for the [Timestamp](https://www.timestamphq.com) API.
8
11
 
9
12
  ## Installation
10
13
 
@@ -24,7 +27,59 @@ Or install it yourself as:
24
27
 
25
28
  ## Usage
26
29
 
27
- TODO: Write usage instructions here
30
+ Configure your Timestamp API key by setting environment variable `TIMESTAMP_API_KEY` or manually:
31
+ ```ruby
32
+ TimestampAPi.api_key = "YOUR_TIMESTAMP_API_KEY"
33
+ ```
34
+
35
+ List all projects:
36
+ ```ruby
37
+ projects = TimestampAPI::Project.all
38
+ projects.map(&:name) # => ["A project", "Another project", "One more project"]
39
+ ```
40
+
41
+ Find a given project:
42
+ ```ruby
43
+ project = TimestampAPI::Project.find(123456)
44
+ project.client.name # => "My beloved customer"
45
+ ```
46
+
47
+ ### Low level API calls
48
+
49
+ The above methods are simple wrappers around the generic low-level-ish API request method `TimestampAPI.request` that take a HTTP `method` (verb) and a `path` (to be appended to preconfigured API endpoint URL):
50
+ ```ruby
51
+ TimestampAPI.request(:get, "/projects") # Same as TimestampAPI::Project.all
52
+ TimestampAPI.request(:get, "/projects/123456") # Same as TimestampAPI::Project.find(123456)
53
+ ```
54
+
55
+ Response is provided as a [RecursiveOpenStruct](https://github.com/aetherknight/recursive-open-struct) (or as an `Array` of `RecursiveOpenStruct`), thus can be accessed by:
56
+ ```ruby
57
+ project = TimestampAPI.request(:get, "/projects/123456")
58
+ project.id # => 123456
59
+ project.name # => "Awesome project"
60
+ project.client.name # => "My beloved customer"
61
+ ```
62
+
63
+ ## Reverse engineering
64
+
65
+ As the API is not documented nor even officially supported by Timestamp, we're trying to reverse-engineer it.
66
+
67
+ :warning: This means that Timestamp can introduce breaking changes within their API without prior notice at any time (and thus break this gem).
68
+
69
+ It also means that if you're willing to hack into it with us, you're very welcome :+1:
70
+
71
+ While logged in, the Timestamp API data can be explored from your favourite browser (with a JSON viewer addon, if needed) here: https://api.ontimestamp.com/api
72
+
73
+ There's also a `bin/console` executable provided with this gem, if you want a REPL to hack around.
74
+
75
+ ### What's implemented already ?
76
+
77
+ * [x] Project#all
78
+ * [x] Project#find
79
+
80
+ ### What's not implemented yet ?
81
+
82
+ * [ ] _everything else_ :scream:
28
83
 
29
84
  ## Development
30
85
 
data/bin/console CHANGED
@@ -11,4 +11,7 @@ require "timestamp_api"
11
11
  # Pry.start
12
12
 
13
13
  require "irb"
14
- IRB.start
14
+ require "awesome_print"
15
+ require "pry"
16
+
17
+ Pry.start
@@ -0,0 +1,13 @@
1
+ module TimestampAPI
2
+ class MissingAPIKey < StandardError
3
+ def message
4
+ "API key must be configured either via the `TIMESTAMP_API_KEY` environment variable or using `TimestampAPi.api_key = \"YOUR_TIMESTAMP_API_KEY\"`."
5
+ end
6
+ end
7
+
8
+ class InvalidServerResponse < StandardError
9
+ def message
10
+ "Server responded with invalid JSON. A possible cause is an invalid or revoked API key."
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ module TimestampAPI
2
+ class Project
3
+ def self.all
4
+ TimestampAPI.request(:get, "/projects")
5
+ end
6
+
7
+ def self.find(id)
8
+ TimestampAPI.request(:get, "/projects/#{id}")
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module TimestampAPI
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/timestamp_api.rb CHANGED
@@ -1,5 +1,41 @@
1
+ require "rest-client"
2
+ require "recursive-open-struct"
3
+
1
4
  require "timestamp_api/version"
5
+ require "timestamp_api/errors"
6
+ require "timestamp_api/project"
2
7
 
3
8
  module TimestampAPI
4
- # Your code goes here...
9
+ @api_endpoint = "https://api.ontimestamp.com/api"
10
+
11
+ class << self
12
+ attr_accessor :api_endpoint, :api_key
13
+ end
14
+
15
+ def self.request(method, url)
16
+ response = RestClient::Request.execute(request_options(method, url))
17
+ objectify(JSON.parse(response))
18
+ rescue JSON::ParserError
19
+ raise InvalidServerResponse
20
+ end
21
+
22
+ def self.request_options(method, url)
23
+ {
24
+ method: method,
25
+ url: api_endpoint + url,
26
+ headers: {
27
+ "X-API-Key" => api_key || ENV["TIMESTAMP_API_KEY"] || raise(MissingAPIKey),
28
+ :accept => :json,
29
+ :user_agent => "TimestampAPI Ruby gem https://github.com/alpinelab/timestamp_api"
30
+ }
31
+ }
32
+ end
33
+
34
+ def self.objectify(json)
35
+ case json
36
+ when Array then json.map { |item| RecursiveOpenStruct.new(item, recurse_over_arrays: true) }
37
+ when Hash then RecursiveOpenStruct.new(json, recurse_over_arrays: true)
38
+ else json
39
+ end
40
+ end
5
41
  end
@@ -19,7 +19,12 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
+ spec.add_runtime_dependency "rest-client"
23
+ spec.add_runtime_dependency "recursive-open-struct"
24
+
22
25
  spec.add_development_dependency "bundler", "~> 1.9"
23
26
  spec.add_development_dependency "rake", "~> 10.0"
24
27
  spec.add_development_dependency "rspec"
28
+ spec.add_development_dependency "pry"
29
+ spec.add_development_dependency "awesome_print"
25
30
  end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timestamp_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.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-23 00:00:00.000000000 Z
11
+ date: 2016-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rest-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: recursive-open-struct
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: bundler
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +80,34 @@ dependencies:
52
80
  - - ">="
53
81
  - !ruby/object:Gem::Version
54
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: awesome_print
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
55
111
  description: 'Timestamp is "real-time project tracking for you and your clients" according
56
112
  to their website: https://www.timestamphq.com'
57
113
  email:
@@ -73,6 +129,8 @@ files:
73
129
  - bin/console
74
130
  - bin/setup
75
131
  - lib/timestamp_api.rb
132
+ - lib/timestamp_api/errors.rb
133
+ - lib/timestamp_api/project.rb
76
134
  - lib/timestamp_api/version.rb
77
135
  - timestamp_api.gemspec
78
136
  homepage: https://github.com/alpinelab/timestamp_api