snitcher 0.3.2 → 0.4.0.pre1

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: 27871ec34b5ab2bb24c584562a646931855745d4
4
- data.tar.gz: 82156be355ece58115b1880651c98aa14ec47d60
3
+ metadata.gz: 31fd69148d1e700f8fb0530699877e3efc5fad4b
4
+ data.tar.gz: cd47d65eb4574061cab9352d6de6818cdbc591dc
5
5
  SHA512:
6
- metadata.gz: 3bf4288bea7ae411853643790614e4fa7850f0ba57f9586e8e57170852198e8e67d64900832e1b16f8e0c4cf0c1dea495872c792aa690c4d73f40ced3fe86c65
7
- data.tar.gz: 9b1dbe9bde047d543996ad4bb14025a4058559cf8ecad36f46aaf183a83cbc052007ce8a93b97cb907ec15737ca8b0657cd4f01e7b6b1b8f404fa1991c2eced4
6
+ metadata.gz: 934c98e32c1880697ecd3e13d50c4296b843de6fd85c7625ed150117c07cbbb2391fc7efc3c221efad17abe20a31caabd5bc1c14a7abe40941697ab585da6bfd
7
+ data.tar.gz: d6c37d3f7ff629ba62c2a6cf79254998a6a528ce85d63ab8104c3abcd129d509eaeae7a21f5d6182d9edb91746de7dba9ba26c01758d6d050b3e4eb8fdb53975
@@ -5,9 +5,18 @@ language: ruby
5
5
  matrix:
6
6
  allow_failures:
7
7
  - rvm: ruby-head
8
+
9
+ before_install:
10
+ - gem install bundler
11
+
12
+ # Disable support for sudo to get faster builds with Docker
13
+ sudo: false
14
+
8
15
  rvm:
9
16
  - 1.9.3
10
17
  - 2.0.0
11
18
  - 2.1
12
19
  - 2.2
20
+ - 2.3.0
21
+ - jruby
13
22
  - ruby-head
@@ -1,4 +1,10 @@
1
- ## 0.3.1 / TBD
1
+ ## 0.4.0 / TBD
2
+ * [FEATURE] Add Snitcher::API for integrating with the DMS API ([[@danabrit](https://github.com/danabrit))
3
+
4
+ ## 0.3.2 / 2015-08-13
5
+ * [BUG] Fixed passing messaging during a check-in ([@ryoung](https://github.com/ryoung))
6
+
7
+ ## 0.3.1 / 2015-06-23
2
8
  * [ENHANCEMENT] Add a custom User-Agent
3
9
 
4
10
  ## 0.3.0 / 2014-10-14
data/Gemfile CHANGED
@@ -2,8 +2,12 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
+ group :development do
6
+ gem "pry"
7
+ end
8
+
5
9
  group :test do
6
- gem "coveralls", "~> 0.7", require: false
7
- gem "rspec", "~> 2.14"
8
- gem "webmock", "~> 1.17"
10
+ gem "coveralls", require: false
11
+ gem "rspec"
12
+ gem "webmock"
9
13
  end
data/README.md CHANGED
@@ -23,27 +23,163 @@ You also may provide a message with the check in:
23
23
  Snitcher.snitch("c2354d53d2", message: "Finished in 23.8 seconds.")
24
24
  ```
25
25
 
26
- The default timeout of 2 seconds can be overridden:
26
+ The default timeout of 5 seconds can be overridden:
27
27
 
28
28
  ```ruby
29
29
  Snitcher.snitch("c2354d53d2", timeout: 10)
30
30
  ```
31
31
 
32
- ## Command Line Tool
32
+ ## API Access
33
33
 
34
- You can also check in from the command line:
34
+ ### Retrieving Your API Key At Command Line
35
35
 
36
- ```bash
37
- $ snitch c2354d53d2
36
+ ```ruby
37
+ require "snitcher/api"
38
+
39
+ key = Snitcher::API.get_key("jane@example.com", "password")
38
40
  ```
39
41
 
40
- If you want to include a message, use the `-m` or `--message` flag.
42
+ Returns an authentication key to access the api.
43
+
44
+ ### Setup
45
+
46
+ Initialize the API client directly with your api key:
47
+
48
+ ```ruby
49
+ require "snitcher/api"
41
50
 
42
- ```bash
43
- $ snitch c2354d53d2 -m "Finished in 23.8 seconds."
44
- $ snitch c2354d53d2 --message "Finished in 23.8 seconds."
51
+ client = Snitcher::API::Client.new("my_awesome_key")
45
52
  ```
46
53
 
54
+ #### Heroku
55
+
56
+ Dead Man's Snitch exposes the `DEADMANSSNITCH_API_KEY` environment variable for
57
+ accessing the API.
58
+
59
+ ```ruby
60
+ require "snitcher/api"
61
+
62
+ client = Snitcher::API::Client.new(ENV["DEADMANSSNITCH_API_KEY"])
63
+ ```
64
+
65
+ ### Listing Snitches
66
+
67
+ ```ruby
68
+ client.snitches
69
+ ```
70
+
71
+ Returns an array of snitches.
72
+
73
+ ### Retrieve a Single Snitch
74
+
75
+ ```ruby
76
+ token = "c2354d53d2"
77
+ client.snitch(token)
78
+ ```
79
+
80
+ Returns a snitch.
81
+
82
+ ### Retrieve Snitches That Match a Set of Tags
83
+
84
+ ```ruby
85
+ tags = ["critical", "sales"]
86
+ client.tagged_snitches(tags)
87
+ ```
88
+
89
+ Returns an array of snitches.
90
+
91
+ ### Create a Snitch
92
+
93
+ Required attributes are name and interval. Optional attributes are notes and tags.
94
+
95
+ ```ruby
96
+ attributes = { "name": "Nightly User Data Backups",
97
+ "interval": "daily",
98
+ "notes": "User login and usage data",
99
+ "tags": ["users", "critical"]
100
+ }
101
+ client.create_snitch(attributes)
102
+ ```
103
+
104
+ Returns the newly-created snitch.
105
+
106
+ ### Edit a Snitch
107
+
108
+ You only need to pass the edit_snitch function the attributes you want to change. The rest of a snitch's attributes will remain the same.
109
+
110
+ ```ruby
111
+ token = "c2354d53d2"
112
+ new_attributes = { "name": "Important Nightly User Data Backups" }
113
+ client.edit_snitch(token, new_attributes)
114
+ ```
115
+
116
+ Returns the edited snitch.
117
+
118
+ ### Adding Tags to a Snitch
119
+
120
+ This function adds tags to a snitch, retaining whatever tags it already has.
121
+
122
+ ```ruby
123
+ token = "c2354d53d2"
124
+ tags = ["spring_campaign", "support"]
125
+ client.add_tags(token, tags)
126
+ ```
127
+
128
+ Returns an array of all of the snitch's tags.
129
+
130
+ ### Deleting a Tag From a Snitch
131
+
132
+ This function is for deleting a single tag from a snitch.
133
+
134
+ ```ruby
135
+ token = "c2354d53d2"
136
+ tag = "support"
137
+ client.remove_tag(token, tag)
138
+ ```
139
+
140
+ Returns an array of all of the snitch's remaining tags.
141
+
142
+ ### Replace Tags on a Snitch
143
+
144
+ Replaces all of a snitch's tags with an array of new tags.
145
+
146
+ ```ruby
147
+ token = "c2354d53d2"
148
+ tags = ["csv", "server_a"]
149
+ client.replace_tags(token, tags)
150
+ ```
151
+
152
+ Returns the updated snitch.
153
+
154
+ ### Remove Tags From a Snitch
155
+
156
+ Removes all of a snitch's tags.
157
+
158
+ ```ruby
159
+ token = "c2354d53d2"
160
+ client.clear_tags(token)
161
+ ```
162
+
163
+ Returns the updated snitch.
164
+
165
+ ### Pause a Snitch
166
+
167
+ ```ruby
168
+ token = "c2354d53d2"
169
+ client.pause_snitch(token)
170
+ ```
171
+
172
+ Returns a hash with a `message` key, whose value is "Response complete".
173
+
174
+ ### Delete a Snitch
175
+
176
+ ```ruby
177
+ token = "c2354d53d2"
178
+ client.delete_snitch(token)
179
+ ```
180
+
181
+ Returns a hash with a `message` key, whose value is "Response complete".
182
+
47
183
  ## Contributing
48
184
 
49
185
  Snitcher is open source and contributions from the community are encouraged! No
data/bin/snitch CHANGED
@@ -24,7 +24,7 @@ if token
24
24
  print "Snitching #{token} ... "
25
25
 
26
26
  opts = {
27
- :message => params[:message]
27
+ message: params[:message]
28
28
  }
29
29
 
30
30
  if Snitcher.snitch(token, opts)
@@ -1,16 +1,18 @@
1
1
  require "uri"
2
2
  require "timeout"
3
3
  require "net/http"
4
+ require "snitcher/version"
4
5
 
5
6
  module Snitcher
6
7
  extend self
7
8
 
8
9
  # Public: Check-in to Deadman's Snitch
9
10
  #
10
- # token - The Snitch token given by Deadman's Snitch (see the install page).
11
- # opts - The hash of optional parameters that can be given during check-in:
12
- # :message - Text message limited to ~250 characters.
13
- # :timeout - Number of seconds to set as connect and read timeout.
11
+ # token: The Snitch token given by Deadman's Snitch (see the install page).
12
+ # opts: The hash of optional parameters that can be given during check-in:
13
+ # :message - Text message limited to ~250 characters.
14
+ # :timeout - Number of seconds to set as connect and read timeout.
15
+ # :uri - URL to use for snitch checkins.
14
16
  #
15
17
  # Examples
16
18
  #
@@ -19,16 +21,10 @@ module Snitcher
19
21
  #
20
22
  # Returns true if the check-in succeeded or false if it failed
21
23
  def snitch(token, opts = {})
22
- uri = URI.parse("https://nosnch.in/#{token}")
23
- uri.query = URI.encode_www_form(:m => opts[:message]) if opts[:message]
24
- timeout = opts.fetch(:timeout, 2)
25
-
26
- opts = {
27
- :open_timeout => timeout,
28
- :read_timeout => timeout,
29
- :ssl_timeout => timeout,
30
- :use_ssl => uri.port == 443
31
- }
24
+ uri = URI.parse(checkin_url(opts, token))
25
+ uri.query = URI.encode_www_form(m: opts[:message]) if opts[:message]
26
+
27
+ opts = initialize_opts(opts, uri)
32
28
 
33
29
  Net::HTTP.start(uri.host, uri.port, opts) do |http|
34
30
  request = Net::HTTP::Get.new(uri.request_uri)
@@ -43,11 +39,34 @@ module Snitcher
43
39
 
44
40
  private
45
41
 
42
+ def initialize_opts(options, uri)
43
+ timeout = options.fetch(:timeout, 5)
44
+
45
+ {
46
+ open_timeout: timeout,
47
+ read_timeout: timeout,
48
+ ssl_timeout: timeout,
49
+ use_ssl: use_ssl?(uri)
50
+ }
51
+ end
52
+
53
+ def checkin_url(opts, token)
54
+ if opts[:uri].nil?
55
+ "https://nosnch.in/#{token}"
56
+ else
57
+ "#{opts[:uri]}/#{token}"
58
+ end
59
+ end
60
+
61
+ def use_ssl?(uri)
62
+ uri.scheme == "https"
63
+ end
64
+
46
65
  def user_agent
47
66
  # RUBY_ENGINE was not added until 1.9.3
48
67
  engine = defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : "Ruby"
49
68
 
50
- "Snitcher; #{engine}/#{RUBY_VERSION}; #{RUBY_PLATFORM}; v#{VERSION}"
69
+ "Snitcher; #{engine}/#{RUBY_VERSION}; #{RUBY_PLATFORM}; v#{::Snitcher::VERSION}"
51
70
  end
52
71
  end
53
72
 
@@ -0,0 +1,72 @@
1
+ require "snitcher"
2
+ require "net/https"
3
+ require "json"
4
+
5
+ require "timeout"
6
+ require "snitcher/version"
7
+
8
+ module Snitcher
9
+ module API
10
+ extend self
11
+
12
+ # Snitcher::API::Error and subclasses
13
+ require "snitcher/api/error"
14
+
15
+ # Public: Retrieve API Key
16
+ #
17
+ # username: The username associated with a Deadman's Snitch account
18
+ # password: The password associated with a Deadman's Snitch account
19
+ #
20
+ # options:
21
+ # uri - String URL of the DMS API to connect to.
22
+ # timeout - Number of seconds to wait for open, read, and ssl handshake.
23
+ #
24
+ # Example
25
+ #
26
+ # Snitcher::API.get_key("alice@example.com", "password")
27
+ # # => "_caeEiZXnEyEzXXYVh2NhQ"
28
+ #
29
+ # Returns the string api_key
30
+ # Raises Snitcher::API::Error based on the type from the server.
31
+ # Raises Timeout::Error if the request timed out.
32
+ def get_key(username, password, options={})
33
+ api = options.fetch(:uri, "https://deadmanssnitch.com")
34
+ uri = URI.parse("#{api}/v1/api_key")
35
+
36
+ timeout = options.fetch(:timeout, 5)
37
+ http_options = {
38
+ open_timeout: timeout,
39
+ read_timeout: timeout,
40
+ ssl_timeout: timeout,
41
+ use_ssl: uri.scheme == "https",
42
+ }
43
+
44
+ Net::HTTP.start(uri.host, uri.port, http_options) do |http|
45
+ request = Net::HTTP::Get.new(uri.path)
46
+ request["User-Agent"] = user_agent
47
+ request.basic_auth(username, password)
48
+
49
+ response = http.request(request)
50
+
51
+ if response.is_a?(Net::HTTPSuccess)
52
+ JSON.parse(response.body)["api_key"]
53
+ else
54
+ error = JSON.parse(response.body)
55
+
56
+ raise ::Snitcher::API::Error.new(error)
57
+ end
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def user_agent
64
+ # RUBY_ENGINE was not added until 1.9.3
65
+ engine = defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : "Ruby"
66
+
67
+ "Snitcher; #{engine}/#{RUBY_VERSION}; #{RUBY_PLATFORM}; v#{::Snitcher::VERSION}"
68
+ end
69
+ end
70
+ end
71
+
72
+ require "snitcher/api/client"
@@ -0,0 +1,396 @@
1
+ require "net/https"
2
+ require "timeout"
3
+ require "json"
4
+
5
+ require "snitcher/api"
6
+ require "snitcher/version"
7
+ require "snitcher/api/snitch"
8
+ require "snitcher/api/error"
9
+
10
+ class Snitcher::API::Client
11
+ DEFAULT_ENDPOINT = "https://api.deadmanssnitch.com"
12
+
13
+ # Public: Create a new Client
14
+ #
15
+ # key - Access key available at https://deadmanssnitch.com/account/keys.
16
+ #
17
+ # options
18
+ # endpoint - String URL of the DMS API connecting to.
19
+ # timeout - Number of seconds to wait at most when making a request.
20
+ #
21
+ # Example
22
+ #
23
+ # Initialize API client for user with api key "abc123"
24
+ # @client = Snitcher::API::Client.new("abc123")
25
+ #
26
+ def initialize(key, options = {})
27
+ endpoint = options[:endpoint] || DEFAULT_ENDPOINT
28
+
29
+ @key = key
30
+ @endpoint = URI.parse(endpoint).freeze
31
+ @timeout = options.fetch(:timeout, 5.0)
32
+ end
33
+
34
+ # Public: List snitches on the account
35
+ #
36
+ # Example
37
+ #
38
+ # Get a list of all snitches
39
+ # @client.snitches
40
+ # => [#<Snitcher::API::Snitch:0x007fdcf51ec380 @token="c2354d53d3",
41
+ # @name="Daily Backups", @tags=["production", "critical"],
42
+ # @status="healthy", @checked_in_at="2014-01-01T12:00:00.000Z",
43
+ # @interval="daily", @check_in_url="https://nosnch.in/c2354d53d3",
44
+ # @created_at="2014-01-01T08:00:00.000Z", @notes=nil>,
45
+ # #<Snitcher::API::Snitch:0x007fdcf51ec358 @token="c2354d53d4",
46
+ # @name="Hourly Emails", @tags=[], @status="healthy",
47
+ # @checked_in_at="2014-01-01T12:00:00.000Z", @interval="hourly",
48
+ # @check_in_url="https://nosnch.in/c2354d53d4",
49
+ # @created_at="2014-01-01T07:50:00.000Z", @notes=nil>]
50
+ #
51
+ # Raise Timeout::Error if the API request times out
52
+ def snitches
53
+ snitch_array(get("/v1/snitches"))
54
+ end
55
+
56
+ # Public: Get a single snitch by unique token
57
+ #
58
+ # token: The unique token of the snitch to get. Should be a string.
59
+ #
60
+ # Example
61
+ #
62
+ # Get the snitch with token "c2354d53d2"
63
+ #
64
+ # @client.snitch("c2354d53d2")
65
+ # => #<Snitcher::API::Snitch:0x007fdcf50ad2d0 @token="c2354d53d3",
66
+ # @name="Daily Backups", @tags=["production", "critical"],
67
+ # @status="pending", @checked_in_at=nil, @interval="daily",
68
+ # @check_in_url="https://nosnch.in/c2354d53d3",
69
+ # @created_at="2015-08-15T12:15:00.234Z",
70
+ # @notes="Important user data.">
71
+ #
72
+ # Raise Timeout::Error if the API request times out
73
+ def snitch(token)
74
+ payload = get("/v1/snitches/#{token}")
75
+ Snitcher::API::Snitch.new(payload)
76
+ end
77
+
78
+ # Public: Retrieve snitches that match all of the tags in a list
79
+ #
80
+ # tags: An array of strings. Each string is a tag.
81
+ #
82
+ # Example
83
+ #
84
+ # Get the snitches that match a list of tags
85
+ # @client.tagged_snitches(["production","critical"])
86
+ # => [#<Snitcher::API::Snitch:0x007fdcf51ec380 @token="c2354d53d3",
87
+ # @name="Daily Backups", @tags=["production", "critical"],
88
+ # @status="pending", @checked_in_at=nil, @interval="daily",
89
+ # @check_in_url="https://nosnch.in/c2354d53d3",
90
+ # @created_at="2014-01-01T08:00:00.000Z", @notes=nil>,
91
+ # #<Snitcher::API::Snitch:0x007fdcf51ec358 @token="c2354d53d4",
92
+ # @name="Hourly Emails", @tags=["production", "critical"],
93
+ # @status="healthy", @checked_in_at="2014-01-01T12:00:00.000Z",
94
+ # @interval="hourly", @check_in_url="https://nosnch.in/c2354d53d4",
95
+ # @created_at="2014-01-01T07:50:00.000Z", @notes=nil>]
96
+ #
97
+ # Raise Timeout::Error if the API request times out
98
+ def tagged_snitches(*tags)
99
+ (tags ||= []).flatten!
100
+
101
+ query = URI.encode_www_form({
102
+ # Strip extra spaces, dedupe, and clean up the list of tags to be filtered
103
+ # by.
104
+ tags: tags.map(&:strip).compact.uniq.join(","),
105
+ })
106
+
107
+ snitch_array(get("/v1/snitches?#{query}"))
108
+ end
109
+
110
+ # Public: Create a snitch using passed-in values. Returns the new snitch.
111
+ #
112
+ # attributes: A hash of the snitch properties. It should include these keys:
113
+ # "name": String value is the name of the snitch
114
+ # "interval": String value representing how often the snitch is
115
+ # expected to fire. Options are "hourly", "daily",
116
+ # "weekly", "monthly"
117
+ # "notes": Optional string value for recording additional
118
+ # information about the snitch
119
+ # "tags": Optional array of string tags
120
+ #
121
+ # Example
122
+ #
123
+ # Create a new snitch
124
+ # attributes = {
125
+ # "name": "Daily Backups",
126
+ # "interval": "daily",
127
+ # "notes": "Customer and supplier tables",
128
+ # "tags": ["backups", "maintenance"]
129
+ # }
130
+ # @client.create_snitch(attributes)
131
+ # => #<Snitcher::API::Snitch:0x007fdcf50ad2d0 @token="c2354d53d3",
132
+ # @name="Daily Backups", @tags=["backups", "maintenance"],
133
+ # @status="pending", @checked_in_at=nil, @interval="daily",
134
+ # @check_in_url="https://nosnch.in/c2354d53d3",
135
+ # @created_at="2015-08-15T12:15:00.234Z",
136
+ # @notes="Customer and supplier tables">
137
+ #
138
+ # Raise Timeout::Error if the API request times out
139
+ def create_snitch(attributes={})
140
+ payload = post("/v1/snitches", attributes)
141
+ Snitcher::API::Snitch.new(payload)
142
+ end
143
+
144
+ # Public: Edit an existing snitch, identified by token, using passed-in
145
+ # values. Only changes those values included in the attributes
146
+ # hash; other attributes are not changed. Returns the updated snitch.
147
+ #
148
+ # token: The unique token of the snitch to get. Should be a string.
149
+ # attributes: A hash of the snitch properties. It should only include those
150
+ # values you want to change. Options include these keys:
151
+ # "name": String value is the name of the snitch
152
+ # "interval": String value representing how often the snitch
153
+ # is expected to fire. Options are "hourly",
154
+ # "daily", "weekly", and "monthly".
155
+ # "notes": Optional string value for recording additional
156
+ # information about the snitch
157
+ # "tags": Optional array of string tags
158
+ #
159
+ # Example
160
+ #
161
+ # Edit an existing snitch using values passed in a hash.
162
+ # token = "c2354d53d2"
163
+ # attributes = {
164
+ # "name": "Monthly Backups",
165
+ # "interval": "monthly"
166
+ # }
167
+ # @client.edit_snitch(token, attributes)
168
+ # => #<Snitcher::API::Snitch:0x007fdcf50ad2d0 @token="c2354d53d3",
169
+ # @name="Monthly Backups", @tags=["backups", "maintenance"],
170
+ # @status="pending", @checked_in_at=nil, @interval="monthly",
171
+ # @check_in_url="https://nosnch.in/c2354d53d3",
172
+ # @created_at="2015-08-15T12:15:00.234Z",
173
+ # @notes="Customer and supplier tables">
174
+ #
175
+ # Raise Timeout::Error if the API request times out
176
+ def edit_snitch(token, attributes={})
177
+ payload = patch("/v1/snitches/#{token}", attributes)
178
+ Snitcher::API::Snitch.new(payload)
179
+ end
180
+
181
+ # Public: Add one or more tags to an existing snitch, identified by token.
182
+ # Returns an array of the snitch's tags.
183
+ #
184
+ # token: The unique token of the snitch to edit. Should be a string.
185
+ # tags: Array of string tags. Will append these tags to any existing tags.
186
+ #
187
+ # Example
188
+ #
189
+ # Add tags to an existing snitch.
190
+ # token = "c2354d53d2"
191
+ # tags = [ "red", "green" ]
192
+ # @client.add_tags(token, tags)
193
+ # => [
194
+ # "red",
195
+ # "green"
196
+ # ]
197
+ #
198
+ # Raise Timeout::Error if the API request times out
199
+ def add_tags(token, tags=[])
200
+ post("/v1/snitches/#{token}/tags", tags)
201
+ end
202
+
203
+ # Public: Remove a tag from an existing snitch, identified by token.
204
+ # Returns an array of the snitch's tags.
205
+ #
206
+ # token: The unique token of the snitch to edit. Should be a string.
207
+ # tag: Tag to be removed from a snitch's tags. Should be a string.
208
+ #
209
+ # Example
210
+ #
211
+ # Assume a snitch that already has the tags "critical" and "production"
212
+ # token = "c2354d53d2"
213
+ # tag = "production"
214
+ # @client.remove_tag(token, tag)
215
+ # => [
216
+ # "critical"
217
+ # ]
218
+ #
219
+ # Raise Timeout::Error if the API request times out
220
+ def remove_tag(token, tag)
221
+ delete("/v1/snitches/#{token}/tags/#{tag}")
222
+ end
223
+
224
+ # Public: Replace all of a snitch's tags with those supplied.
225
+ # Returns the updated snitch.
226
+ #
227
+ # token: The unique token of the snitch to edit. Should be a string.
228
+ # tags: Array of string tags. Will replace the snitch's current tags with
229
+ # these.
230
+ #
231
+ # Example
232
+ #
233
+ # Assume a snitch with the tag "critical". Replace with tags provided.
234
+ # token = "c2354d53d3"
235
+ # tags = ["production", "urgent"]
236
+ # @client.replace_tags(token, tags)
237
+ # => #<Snitcher::API::Snitch:0x007fdcf50ad2d0 @token="c2354d53d3",
238
+ # @name="Daily Backups", @tags=["production", "urgent"],
239
+ # @status="pending", @checked_in_at=nil, @interval="daily",
240
+ # @check_in_url="https://nosnch.in/c2354d53d3",
241
+ # @created_at="2015-08-15T12:15:00.234Z",
242
+ # @notes="Customer and supplier tables">
243
+ #
244
+ # Raise Timeout::Error if the API request times out
245
+ def replace_tags(token, tags=[])
246
+ attributes = {"tags" => tags}
247
+
248
+ edit_snitch(token, attributes)
249
+ end
250
+
251
+ # Public: Remove all of a snitch's tags.
252
+ # Returns the updated snitch.
253
+ #
254
+ # token: The unique token of the snitch to edit. Should be a string.
255
+ #
256
+ # Example
257
+ #
258
+ # Remove all tags.
259
+ # token = "c2354d53d3"
260
+ # @client.clear_tags(token)
261
+ # => #<Snitcher::API::Snitch:0x007fdcf50ad2d0 @token="c2354d53d3",
262
+ # @name="Daily Backups", @tags=[], @status="pending",
263
+ # @checked_in_at=nil, @interval="daily",
264
+ # @check_in_url="https://nosnch.in/c2354d53d3",
265
+ # @created_at="2015-08-15T12:15:00.234Z",
266
+ # @notes="Customer and supplier tables">
267
+ #
268
+ # Raise Timeout::Error if the API request times out
269
+ def clear_tags(token)
270
+ edit_snitch(token, :tags => [])
271
+ end
272
+
273
+ # Public: Pauses a snitch. The return is a hash with the message "Response
274
+ # complete".
275
+ #
276
+ # token: The unique token of the snitch to pause. Should be a string.
277
+ #
278
+ # Example
279
+ #
280
+ # Pause a snitch.
281
+ # token = "c2354d53d3"
282
+ # @client.pause_snitch(token)
283
+ # => { :message => "Response complete" }
284
+ #
285
+ # Raise Timeout::Error if the API request times out
286
+ def pause_snitch(token)
287
+ post("/v1/snitches/#{token}/pause")
288
+ end
289
+
290
+ # Public: Deletes a snitch. The return is a hash with the message "Response
291
+ # complete".
292
+ #
293
+ # token: The unique token of the snitch to delete. Should be a string.
294
+ #
295
+ # Example
296
+ #
297
+ # Delete a snitch.
298
+ # token = "c2354d53d3"
299
+ # @client.delete_snitch(token)
300
+ # => { :message => "Response complete" }
301
+ #
302
+ # Raise Timeout::Error if the API request times out
303
+ def delete_snitch(token)
304
+ delete("/v1/snitches/#{token}")
305
+ end
306
+
307
+ protected
308
+
309
+ def user_agent
310
+ # RUBY_ENGINE was not added until 1.9.3
311
+ engine = defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : "Ruby"
312
+
313
+ "Snitcher; #{engine}/#{RUBY_VERSION}; #{RUBY_PLATFORM}; v#{::Snitcher::VERSION}"
314
+ end
315
+
316
+ def execute_request(request, options={})
317
+ http_options = {
318
+ open_timeout: @timeout,
319
+ read_timeout: @timeout,
320
+ ssl_timeout: @timeout,
321
+ use_ssl: @endpoint.scheme == "https",
322
+ }
323
+
324
+ Net::HTTP.start(@endpoint.host, @endpoint.port, http_options) do |http|
325
+ request.basic_auth(@key, "")
326
+ request["User-Agent"] = user_agent
327
+
328
+ # All requests (with bodies) are made using JSON.
329
+ if request.body
330
+ request["Content-Type"] = "application/json"
331
+
332
+ # Some trickiery to allow pushing the JSON rendering down as far as
333
+ # possible.
334
+ if !request.body.is_a?(String)
335
+ request.body = JSON.generate(request.body)
336
+ end
337
+ end
338
+
339
+ response = http.request(request)
340
+ evaluate_response(response)
341
+ end
342
+ end
343
+
344
+ def evaluate_response(response)
345
+ case response
346
+ when Net::HTTPNoContent
347
+ nil
348
+ when Net::HTTPSuccess
349
+ JSON.parse(response.body)
350
+ when Net::HTTPInternalServerError
351
+ # InternalServerError does not have a parseable body as the error may not
352
+ # be generated by the application itself.
353
+ raise ::Snitcher::API::InternalServerError.new(
354
+ "http_#{response.code}", response.body
355
+ )
356
+ else
357
+ error = JSON.parse(response.body)
358
+
359
+ raise ::Snitcher::API::Error.new(error)
360
+ end
361
+ end
362
+
363
+ def get(path, options={})
364
+ request = Net::HTTP::Get.new(path)
365
+ execute_request(request, options)
366
+ end
367
+
368
+ def post(path, data=nil, options={})
369
+ request = Net::HTTP::Post.new(path)
370
+ request.body = data
371
+
372
+ execute_request(request, options)
373
+ end
374
+
375
+ def patch(path, data, options={})
376
+ request = Net::HTTP::Patch.new(path)
377
+ request.body = data
378
+
379
+ execute_request(request, options)
380
+ end
381
+
382
+ def delete(path, options={})
383
+ request = Net::HTTP::Delete.new(path)
384
+ execute_request(request, options)
385
+ end
386
+
387
+ private
388
+
389
+ def snitch_array(json_payload)
390
+ arr = []
391
+ json_payload.each do |payload|
392
+ arr << Snitcher::API::Snitch.new(payload)
393
+ end
394
+ arr
395
+ end
396
+ end