snitcher 0.3.2 → 0.4.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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