snitcher 0.4.0.rc1 → 0.4.2

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
- SHA1:
3
- metadata.gz: 85ae5078348c51d73c8830f198ff49a276a5ef36
4
- data.tar.gz: 18bf74b6a9b887f3ca6c213cbf2cd38bb7814be0
2
+ SHA256:
3
+ metadata.gz: 2613d8b9e2918478b19e16717aa65726a8a0b6aae250846bd0b966b5b34bffa5
4
+ data.tar.gz: ab08596c2a1fe6e7fba7db7e4c7ecb9b092eb6dd1ac16dae8b75fd68e2f7efd1
5
5
  SHA512:
6
- metadata.gz: fabe574bb26a7766144e532bcf6e12562e2a9ad0d8029dd5e04984ba5ba97ac5de44b7da7dba229618bfc388d43639182f38d5cfb3ba6f5b5b53688329b89d55
7
- data.tar.gz: b67166b247c7648b4d6a18a22c0894373176afb7bd5b62ecb5595770e9b25ced02462360c408ee69db4ff95c6ed1fa845d7f01c95ccc2becb87e61790c7cc70e
6
+ metadata.gz: 8ca6c380e026b3c086683eba26b836429ac32a6b61dad10f48a0a906012d2d0783c6e15097100b5ffeb4b6a4edfb47736d33e026533afd85e9c86e168fe1f6ba
7
+ data.tar.gz: a04bdb064748796ba5297a28268fed83c0c4c2867f10cecd22be56a595e8914feb7fb5fe5b56ea43d1842cbb775800ed519e1fa47859755df69972b5e1b86b1c
data/.travis.yml CHANGED
@@ -1,22 +1,20 @@
1
- branches:
2
- only:
3
- - master
1
+ dist: bionic
2
+
4
3
  language: ruby
5
4
  matrix:
6
5
  allow_failures:
7
6
  - rvm: ruby-head
8
7
 
9
- before_install:
10
- - gem install bundler
11
-
12
- # Disable support for sudo to get faster builds with Docker
13
- sudo: false
14
-
15
8
  rvm:
16
- - 1.9.3
17
- - 2.0.0
18
- - 2.1
19
- - 2.2
20
- - 2.3.0
9
+ - 2.5
10
+ - 2.6
11
+ - 2.7
12
+ - 3.0
21
13
  - jruby
22
14
  - ruby-head
15
+
16
+ notifications:
17
+ webhooks:
18
+ urls:
19
+ - http://buildlight.collectiveidea.com/
20
+ on_start: always
data/CHANGELOG.md CHANGED
@@ -1,8 +1,16 @@
1
- ## 0.4.0 / TBD
2
- * [FEATURE] Add Snitcher::API for integrating with the DMS API ([[@danabrit](https://github.com/danabrit))
1
+ ## 0.4.2 / 2021-06-07
2
+ * [BUG] Fixed Ruby 3.0 support ([@gaffneyc](https://github.com/gaffneyc))
3
+
4
+ ## 0.4.1 / 2018-07-09
5
+ * [FEATURE] Added :status option to Snitcher.snitch! ([@gaffneyc](https://github.com/gaffneyc))
6
+ *
7
+
8
+ ## 0.4.0 / 2016-06-20
9
+ * [FEATURE] Added Snitcher::API for integrating with the DMS API ([@danabrit](https://github.com/danabrit))
10
+ * [FEATURE] Added Snitcher.snitch! which raises exceptions on errors ([@gaffneyc](https://github.com/gaffneyc))
3
11
 
4
12
  ## 0.3.2 / 2015-08-13
5
- * [BUG] Fixed passing messaging during a check-in ([@ryoung](https://github.com/ryoung))
13
+ * [BUG] Fixed passing messages during a check-in ([@ryoung](https://github.com/ryoung))
6
14
 
7
15
  ## 0.3.1 / 2015-06-23
8
16
  * [ENHANCEMENT] Add a custom User-Agent
data/Gemfile CHANGED
@@ -4,7 +4,6 @@ gemspec
4
4
 
5
5
  group :development do
6
6
  gem "pry"
7
- gem "yard-ghpages"
8
7
  end
9
8
 
10
9
  group :test do
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Simple API client for [Dead Man's Snitch](https://deadmanssnitch.com)
4
4
 
5
5
  [![Gem Version](https://badge.fury.io/rb/snitcher.png)](http://badge.fury.io/rb/snitcher)
6
- [![Build Status](https://travis-ci.org/deadmanssnitch/snitcher.png?branch=master)](https://travis-ci.org/deadmanssnitch/snitcher)
6
+ [![Build Status](https://travis-ci.com/deadmanssnitch/snitcher.png?branch=master)](https://travis-ci.com/deadmanssnitch/snitcher)
7
7
  [![Code Climate](https://codeclimate.com/github/deadmanssnitch/snitcher.png)](https://codeclimate.com/github/deadmanssnitch/snitcher)
8
8
  [![Coverage Status](https://coveralls.io/repos/deadmanssnitch/snitcher/badge.png)](https://coveralls.io/r/deadmanssnitch/snitcher)
9
9
 
@@ -23,23 +23,21 @@ 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 5 seconds can be overridden:
26
+ Errors can be reported by providing the `status` option. A status of `nil`,
27
+ `0`, or `""` are all considered a success. Any other status is treated as a
28
+ failure.
27
29
 
28
30
  ```ruby
29
- Snitcher.snitch("c2354d53d2", timeout: 10)
31
+ Snitcher.snitch("c2354d53d2", status: 1)
30
32
  ```
31
33
 
32
- ## API Access
33
-
34
- ### Retrieving Your API Key At Command Line
34
+ The default timeout of 5 seconds can be overridden:
35
35
 
36
36
  ```ruby
37
- require "snitcher/api"
38
-
39
- key = Snitcher::API.get_key("jane@example.com", "password")
37
+ Snitcher.snitch("c2354d53d2", timeout: 10)
40
38
  ```
41
39
 
42
- Returns an authentication key to access the api.
40
+ ## API Access
43
41
 
44
42
  ### Setup
45
43
 
@@ -82,22 +80,22 @@ Returns a Snitch.
82
80
  ### Retrieve Snitches That Match a Set of Tags
83
81
 
84
82
  ```ruby
85
- tags = ["critical", "sales"]
86
- client.tagged_snitches(tags)
83
+ client.snitches(tags: ["critical", "sales"])
87
84
  ```
88
85
 
89
86
  Returns an array of Snitches.
90
87
 
91
88
  ### Create a Snitch
92
89
 
93
- Required attributes are name and interval. Optional attributes are notes and
94
- tags.
90
+ Both `:name` and `:interval` are required. Optional attributes include `:notes`,
91
+ and `:tags`. For a full list see [the API documentation](https://deadmanssnitch.com/docs/api/v1#creating-a-snitch).
95
92
 
96
93
  ```ruby
97
- attributes = { "name": "Nightly User Data Backups",
98
- "interval": "daily",
99
- "notes": "User login and usage data",
100
- "tags": ["users", "critical"]
94
+ attributes = {
95
+ name: "Nightly User Data Backups",
96
+ interval: "daily",
97
+ notes: "User login and usage data",
98
+ tags: ["users", "critical"],
101
99
  }
102
100
  client.create_snitch(attributes)
103
101
  ```
@@ -111,8 +109,8 @@ change. The rest of a Snitch's attributes will remain the same.
111
109
 
112
110
  ```ruby
113
111
  token = "c2354d53d2"
114
- new_attributes = { "name": "Important Nightly User Data Backups" }
115
- client.update_snitch(token, new_attributes)
112
+ attrs = { "name": "Important Nightly User Data Backups" }
113
+ client.update_snitch(token, attrs)
116
114
  ```
117
115
 
118
116
  Returns the edited Snitch.
@@ -123,7 +121,7 @@ This function adds tags to a Snitch, retaining whatever tags it already has.
123
121
 
124
122
  ```ruby
125
123
  token = "c2354d53d2"
126
- tags = ["spring_campaign", "support"]
124
+ tags = ["spring_campaign", "support"]
127
125
  client.add_tags(token, tags)
128
126
  ```
129
127
 
@@ -141,29 +139,20 @@ client.remove_tag(token, tag)
141
139
 
142
140
  Returns an array of all of the Snitch's remaining tags.
143
141
 
144
- ### Replace Tags on a Snitch
145
-
146
- Replaces all of a Snitch's tags with an array of new tags.
142
+ ### Setting the Tags on a Snitch
147
143
 
148
144
  ```ruby
149
145
  token = "c2354d53d2"
150
- tags = ["csv", "server_a"]
151
- client.replace_tags(token, tags)
146
+ client.update_snitch(token, tags: [ "production", "critical" ])
152
147
  ```
153
148
 
154
- Returns the updated Snitch.
155
-
156
- ### Remove Tags From a Snitch
157
-
158
- Removes all of a Snitch's tags.
149
+ ### Removing all Tags from a Snitch
159
150
 
160
151
  ```ruby
161
152
  token = "c2354d53d2"
162
- client.clear_tags(token)
153
+ client.update_snitch(token, tags: [])
163
154
  ```
164
155
 
165
- Returns the updated Snitch.
166
-
167
156
  ### Pause a Snitch
168
157
 
169
158
  ```ruby
@@ -171,7 +160,7 @@ token = "c2354d53d2"
171
160
  client.pause_snitch(token)
172
161
  ```
173
162
 
174
- Returns a hash with a `message` key, whose value is "Response complete".
163
+ Returns a nil object.
175
164
 
176
165
  ### Delete a Snitch
177
166
 
@@ -180,7 +169,7 @@ token = "c2354d53d2"
180
169
  client.delete_snitch(token)
181
170
  ```
182
171
 
183
- Returns a hash with a `message` key, whose value is "Response complete".
172
+ Returns a nil object.
184
173
 
185
174
  ## Contributing
186
175
 
data/Rakefile CHANGED
@@ -4,7 +4,4 @@ Bundler::GemHelper.install_tasks
4
4
  require "rspec/core/rake_task"
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
7
- require "yard-ghpages"
8
- Yard::GHPages::Tasks.install_tasks
9
-
10
7
  task default: :spec
data/examples/api.rb ADDED
@@ -0,0 +1,51 @@
1
+ $:.unshift File.expand_path("../../lib", __FILE__)
2
+
3
+ # Need to require the API separately as it is not required by Snitcher itself.
4
+ require "snitcher/api"
5
+
6
+ if !ENV["DMS_API_KEY"]
7
+ puts "Set DMS_API_KEY environment variable to your deadmanssnitch.com API key"
8
+ puts "before running this example."
9
+ puts
10
+ puts "example: DMS_API_KEY=c23452notarealkeyhello! ruby examples/api.rb"
11
+
12
+ exit 1
13
+ end
14
+
15
+ # Get an API key for a given user with password
16
+ key = ENV["DMS_API_KEY"]
17
+
18
+ # Create a new API client
19
+ client = Snitcher::API::Client.new(key)
20
+
21
+ # Create an hourly Snitch called "Monitor All The Things"
22
+ snitch = client.create_snitch({
23
+ name: "Monitor All The Things",
24
+ tags: ["things"],
25
+ interval: "hourly",
26
+ })
27
+ puts "Created: #{snitch.inspect}"
28
+
29
+ # Change the name and notes of an existing Snitch
30
+ snitch = client.update_snitch(snitch.token, {
31
+ name: "Monitor Fewer Things",
32
+ notes: "Only monitoring a couple things",
33
+ })
34
+
35
+ # Add new tags to a Snitch
36
+ snitch.tags = client.add_tags(snitch.token, ["production", "critical issues"])
37
+
38
+ # Remove the "critical issues" tag from the Snitch
39
+ snitch.tags = client.remove_tag(snitch.token, "critical issues")
40
+
41
+ # Get a list of Snitches tagged with "production"
42
+ production = client.snitches(tags: ["production"])
43
+ puts "Production Snitches:"
44
+ production.each { |s| puts " - #{s.inspect}"}
45
+
46
+ # Pause a Snitch if it's currently missing or errored
47
+ client.pause_snitch(snitch.token)
48
+
49
+ # Delete a Snitch
50
+ client.delete_snitch(snitch.token)
51
+ puts "Deleted: #{snitch.token}"
data/lib/snitcher.rb CHANGED
@@ -6,7 +6,7 @@ require "snitcher/version"
6
6
  module Snitcher
7
7
  extend self
8
8
 
9
- # Check-in to Dead Man's Snitch.
9
+ # Check-in to Dead Man's Snitch, exceptions are raised on failures.
10
10
  #
11
11
  # @param token [String] The unique Snitch token to check-in with. This can be
12
12
  # found on the Setup page as the last part of the HTTP check-in url. For
@@ -17,20 +17,30 @@ module Snitcher
17
17
  # @option opts [String] :message Text message to include with the check-in.
18
18
  # The message is limited to 256 characters.
19
19
  #
20
+ # @option opts [String, Fixnum, nil] :status Exit code for the check-in. A
21
+ # status of "", nil, or 0 are all treated as the job finishing successfully.
22
+ #
20
23
  # @option opts [Float, Fixnum] :timeout Number of seconds to wait for a
21
24
  # response from the server. Default is 5 seconds.
22
- # no
23
25
  #
24
26
  # @example
25
27
  # Snitch.snitch("c2354d53d2")
26
28
  # # => true
27
29
  #
28
- # @raise [Timeout::Error] if the request took too long and timed out.
29
- #
30
30
  # @return [Boolean] if the check-in succeeded.
31
- def snitch(token, opts = {})
32
- uri = URI.parse(checkin_url(opts, token))
33
- uri.query = URI.encode_www_form(m: opts[:message]) if opts[:message]
31
+ def snitch!(token, opts = {})
32
+ params = {}
33
+ params[:m] = opts[:message] if opts[:message]
34
+
35
+ # It's unnecessary to send an empty status
36
+ if opts[:status] && opts[:status] != ""
37
+ params[:s] = opts[:status]
38
+ end
39
+
40
+ uri = URI.parse(checkin_url(opts, token))
41
+ if params.any?
42
+ uri.query = URI.encode_www_form(params)
43
+ end
34
44
 
35
45
  opts = initialize_opts(opts, uri)
36
46
 
@@ -41,7 +51,33 @@ module Snitcher
41
51
  response = http.request(request)
42
52
  response.is_a?(Net::HTTPSuccess)
43
53
  end
44
- rescue ::Timeout::Error
54
+ end
55
+
56
+ # Check-in to Dead Man's Snitch.
57
+ #
58
+ # @param token [String] The unique Snitch token to check-in with. This can be
59
+ # found on the Setup page as the last part of the HTTP check-in url. For
60
+ # example, c2354d53d2 is the token in http://nosnch.in/c2354d53d2.
61
+ #
62
+ # @param [Hash] opts
63
+ #
64
+ # @option opts [String] :message Text message to include with the check-in.
65
+ # The message is limited to 256 characters.
66
+ #
67
+ # @option opts [String, Fixnum, nil] :status Exit code for the check-in. A
68
+ # status of "", nil, or 0 are all treated as the job finishing successfully.
69
+ #
70
+ # @option opts [Float, Fixnum] :timeout Number of seconds to wait for a
71
+ # response from the server. Default is 5 seconds.
72
+ #
73
+ # @example
74
+ # Snitch.snitch("c2354d53d2")
75
+ # # => true
76
+ #
77
+ # @return [Boolean] if the check-in succeeded.
78
+ def snitch(*args)
79
+ snitch!(*args)
80
+ rescue StandardError
45
81
  false
46
82
  end
47
83
 
@@ -54,7 +90,7 @@ module Snitcher
54
90
  open_timeout: timeout,
55
91
  read_timeout: timeout,
56
92
  ssl_timeout: timeout,
57
- use_ssl: use_ssl?(uri)
93
+ use_ssl: use_ssl?(uri),
58
94
  }
59
95
  end
60
96
 
data/lib/snitcher/api.rb CHANGED
@@ -7,67 +7,8 @@ require "snitcher/version"
7
7
 
8
8
  module Snitcher
9
9
  module API
10
- extend self
11
-
12
10
  # Snitcher::API::Error and subclasses
13
11
  require "snitcher/api/error"
14
-
15
- # Retrieve an API Key for your account.
16
- #
17
- # @param username [String] username for your Dead Man's Snitch account.
18
- # @param password [String] password for your Dead Man's Snitch account.
19
- #
20
- # @param [Hash] options
21
- # @option options [String] uri location of alternative Dead Man's Snitch API
22
- # @option timeout [Float, Fixnum] timeout number of seconds to wait for
23
- # server response before timing out.
24
- #
25
- # @example
26
- # Snitcher::API.get_key("alice@example.com", "password")
27
- # # => "_caeEiZXnEyEzXXYVh2NhQ"
28
- #
29
- # @raise [Timeout::Error] if the API request took too long to execute.
30
- # @raise [Snitcher::API::AuthenticationError] credentials are invalid.
31
- # @raise [Snitcher::API::Error] if any other API errors occur.
32
- #
33
- # @return [String] the API key to use for further API requests.
34
- def get_key(username, password, options={})
35
- api = options.fetch(:uri, "https://api.deadmanssnitch.com")
36
- uri = URI.parse("#{api}/v1/api_key")
37
-
38
- timeout = options.fetch(:timeout, 5)
39
- http_options = {
40
- open_timeout: timeout,
41
- read_timeout: timeout,
42
- ssl_timeout: timeout,
43
- use_ssl: uri.scheme == "https",
44
- }
45
-
46
- Net::HTTP.start(uri.host, uri.port, http_options) do |http|
47
- request = Net::HTTP::Get.new(uri.path)
48
- request["User-Agent"] = user_agent
49
- request.basic_auth(username, password)
50
-
51
- response = http.request(request)
52
-
53
- if response.is_a?(Net::HTTPSuccess)
54
- JSON.parse(response.body)["api_key"]
55
- else
56
- error = JSON.parse(response.body)
57
-
58
- raise ::Snitcher::API::Error.new(error)
59
- end
60
- end
61
- end
62
-
63
- private
64
-
65
- def user_agent
66
- # RUBY_ENGINE was not added until 1.9.3
67
- engine = defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : "Ruby"
68
-
69
- "Snitcher; #{engine}/#{RUBY_VERSION}; #{RUBY_PLATFORM}; v#{::Snitcher::VERSION}"
70
- end
71
12
  end
72
13
  end
73
14
 
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "net/https"
2
4
  require "timeout"
3
5
  require "json"
6
+ require "cgi"
4
7
 
5
8
  require "snitcher/api"
6
9
  require "snitcher/version"
@@ -35,16 +38,46 @@ class Snitcher::API::Client
35
38
 
36
39
  # Get the list snitches on the account
37
40
  #
41
+ # @param [Hash] filters
42
+ # @option filters [String, Array<String>] tags only return Snitches that are
43
+ # tagged with _all_ of the given tags. For example, if a Snitch is tagged
44
+ # with "production" and "critical" it will be returned when filtering by
45
+ # "production", "critical", or ["production", "critical"] but not
46
+ # ["production", "backups"].
47
+ #
38
48
  # @example List the Snitches on an account
39
- # client.snitches
40
- # # => [ #<Snitcher::API::Snitch:...>, #<Snitcher::API::Snitch:...> ]
49
+ # client.snitches
50
+ # # => [ #<Snitcher::API::Snitch:...>, #<Snitcher::API::Snitch:...> ]
51
+ #
52
+ # @example List Snitches with a specific tag
53
+ # client.snitches(tags: "production")
54
+ # # => [ #<Snitcher::API::Snitch:...>, #<Snitcher::API::Snitch:...> ]
55
+ #
56
+ # @example List Snitches with multiple tags
57
+ # client.snitches(tags: ["production", "critical"])
58
+ # # => [ #<Snitcher::API::Snitch:...>, #<Snitcher::API::Snitch:...> ]
41
59
  #
42
60
  # @raise [Timeout::Error] if the API request took too long to execute.
43
61
  # @raise [Snitcher::API::Error] if any API errors occur.
44
62
  #
45
63
  # @return [Array<Snitcher::API::Snitch>] the snitches on the account.
46
- def snitches
47
- snitch_array(get("/v1/snitches"))
64
+ def snitches(filters = {})
65
+ query = {}
66
+
67
+ # Tags allow for labeling Snitches for better categorization. This allows
68
+ # filtering by a set of tags.
69
+ if tags = filters[:tags]
70
+ tags = Array(tags).flatten
71
+ query[:tags] = tags.map(&:strip).compact.uniq.join(",")
72
+ end
73
+
74
+ # JSON array of Snitch attributes
75
+ response = get("/v1/snitches", query)
76
+
77
+ # Convert the attributes hashes into Objects
78
+ response.map! do |snitch|
79
+ Snitcher::API::Snitch.new(snitch)
80
+ end
48
81
  end
49
82
 
50
83
  # Get a single Snitch by it's unique token.
@@ -63,40 +96,12 @@ class Snitcher::API::Client
63
96
  #
64
97
  # @return [Snitcher::API::Snitch] the Snitch
65
98
  def snitch(token)
99
+ token = CGI.escape(token)
100
+
66
101
  payload = get("/v1/snitches/#{token}")
67
102
  Snitcher::API::Snitch.new(payload)
68
103
  end
69
104
 
70
- # Retrieve Snitches filtered by a list of tags. Only Snitches that are tagged
71
- # with all of the given tags will be returned.
72
- #
73
- # @param tags [String, Array<String>] the tag(s) to filter by.
74
- #
75
- # @example Get the snitches that match a list of tags
76
- # client.tagged_snitches(["production","critical"])
77
- #
78
- # # => [
79
- # #<Snitcher::API::Snitch tags=["production", "critical"]>,
80
- # #<Snitcher::API::Snitch tags=["production", "critical"]>,
81
- # ]
82
- #
83
- # @raise [Timeout::Error] if the API request took too long to execute.
84
- # with that token
85
- # @raise [Snitcher::API::Error] if any API errors occur.
86
- #
87
- # @return [Array<Snitcher::API::Snitch>] list of Snitches matching all tags.
88
- def tagged_snitches(*tags)
89
- (tags ||= []).flatten!
90
-
91
- query = URI.encode_www_form({
92
- # Strip extra spaces, dedupe, and clean up the list of tags to be filtered
93
- # by.
94
- tags: tags.map(&:strip).compact.uniq.join(","),
95
- })
96
-
97
- snitch_array(get("/v1/snitches?#{query}"))
98
- end
99
-
100
105
  # Create a new Snitch.
101
106
  #
102
107
  # @param [Hash] attributes The properties for the new Snitch
@@ -113,7 +118,7 @@ class Snitcher::API::Client
113
118
  # @example Create a new Snitch
114
119
  # client.create_snitch({
115
120
  # name: "Daily Backups",
116
- # type: { interval: "hourly" },
121
+ # interval: "hourly",
117
122
  # notes: "On error check the print tray for paper jams",
118
123
  # tags: [ "backups", "maintenance" ],
119
124
  # })
@@ -126,10 +131,10 @@ class Snitcher::API::Client
126
131
  # @raise [Snitcher::API::Error] if any other API errors occur.
127
132
  #
128
133
  # @return [Snitcher::API::Snitch] the new Snitch.
129
- def create_snitch(attributes={})
130
- if attributes.has_key?(:interval)
134
+ def create_snitch(attributes = {})
135
+ if interval = attributes.delete(:interval)
131
136
  type = attributes[:type] ||= {}
132
- type[:interval] ||= attributes.delete(:interval)
137
+ type[:interval] ||= interval
133
138
  end
134
139
 
135
140
  response = post("/v1/snitches", attributes)
@@ -174,17 +179,20 @@ class Snitcher::API::Client
174
179
  # @raise [Snitcher::API::Error] if any other API errors occur.
175
180
  #
176
181
  # Raise Timeout::Error if the API request times out
177
- def update_snitch(token, attributes={})
178
- if attributes.has_key?(:tags)
182
+ def update_snitch(token, attributes = {})
183
+ if attributes.key?(:tags)
179
184
  attributes[:tags] = [attributes[:tags]].flatten.compact
180
185
  end
181
186
 
182
- if attributes.has_key?(:interval)
187
+ # Expand the interval key to the full structure required by the API
188
+ if interval = attributes.delete(:interval)
183
189
  type = attributes[:type] ||= {}
184
- type[:interval] ||= attributes.delete(:interval)
190
+ type[:interval] ||= interval
185
191
  end
186
192
 
193
+ token = CGI.escape(token)
187
194
  payload = patch("/v1/snitches/#{token}", attributes)
195
+
188
196
  Snitcher::API::Snitch.new(payload)
189
197
  end
190
198
 
@@ -207,9 +215,10 @@ class Snitcher::API::Client
207
215
  # @raise [Snitcher::API::Error] if an API errors occur.
208
216
  #
209
217
  # @return [Array<String>] full list of tags on the Snitch.
210
- def add_tags(token, tags=[])
211
- tags = [tags].flatten
212
- post("/v1/snitches/#{token}/tags", tags)
218
+ def add_tags(token, tags = [])
219
+ token = CGI.escape(token)
220
+
221
+ post("/v1/snitches/#{token}/tags", Array(tags).flatten)
213
222
  end
214
223
 
215
224
  # Remove a tag from a Snitch.
@@ -227,6 +236,9 @@ class Snitcher::API::Client
227
236
  #
228
237
  # @return [Array<String>] list of the remaining tags on the Snitch.
229
238
  def remove_tag(token, tag)
239
+ token = CGI.escape(token)
240
+ tag = CGI.escape(tag)
241
+
230
242
  delete("/v1/snitches/#{token}/tags/#{tag}")
231
243
  end
232
244
 
@@ -245,6 +257,8 @@ class Snitcher::API::Client
245
257
  #
246
258
  # @return [nil]
247
259
  def pause_snitch(token)
260
+ token = CGI.escape(token)
261
+
248
262
  post("/v1/snitches/#{token}/pause")
249
263
 
250
264
  nil
@@ -264,6 +278,8 @@ class Snitcher::API::Client
264
278
  #
265
279
  # @return [nil]
266
280
  def delete_snitch(token)
281
+ token = CGI.escape(token)
282
+
267
283
  delete("/v1/snitches/#{token}")
268
284
 
269
285
  nil
@@ -278,12 +294,12 @@ class Snitcher::API::Client
278
294
  "Snitcher; #{engine}/#{RUBY_VERSION}; #{RUBY_PLATFORM}; v#{::Snitcher::VERSION}"
279
295
  end
280
296
 
281
- def execute_request(request, options={})
297
+ def execute_request(request)
282
298
  http_options = {
283
299
  open_timeout: @timeout,
284
300
  read_timeout: @timeout,
285
- ssl_timeout: @timeout,
286
- use_ssl: @endpoint.scheme == "https",
301
+ ssl_timeout: @timeout,
302
+ use_ssl: @endpoint.scheme == "https",
287
303
  }
288
304
 
289
305
  Net::HTTP.start(@endpoint.host, @endpoint.port, http_options) do |http|
@@ -294,7 +310,7 @@ class Snitcher::API::Client
294
310
  if request.body
295
311
  request["Content-Type"] = "application/json"
296
312
 
297
- # Some trickiery to allow pushing the JSON rendering down as far as
313
+ # Some trickery to allow pushing the JSON rendering down as far as
298
314
  # possible.
299
315
  if !request.body.is_a?(String)
300
316
  request.body = JSON.generate(request.body)
@@ -315,9 +331,10 @@ class Snitcher::API::Client
315
331
  when Net::HTTPInternalServerError
316
332
  # InternalServerError does not have a parseable body as the error may not
317
333
  # be generated by the application itself.
318
- raise ::Snitcher::API::InternalServerError.new(
319
- "http_#{response.code}", response.body
320
- )
334
+ raise ::Snitcher::API::InternalServerError.new({
335
+ "type" => "internal_server_error",
336
+ "error" => response.body,
337
+ })
321
338
  else
322
339
  error = JSON.parse(response.body)
323
340
 
@@ -325,37 +342,32 @@ class Snitcher::API::Client
325
342
  end
326
343
  end
327
344
 
328
- def get(path, options={})
345
+ def get(path, query = {})
346
+ # Only add the query param if any valid filters were given.
347
+ if query.any?
348
+ path = "#{path}?#{URI.encode_www_form(query)}"
349
+ end
350
+
329
351
  request = Net::HTTP::Get.new(path)
330
- execute_request(request, options)
352
+ execute_request(request)
331
353
  end
332
354
 
333
- def post(path, data=nil, options={})
355
+ def post(path, data = nil)
334
356
  request = Net::HTTP::Post.new(path)
335
357
  request.body = data
336
358
 
337
- execute_request(request, options)
359
+ execute_request(request)
338
360
  end
339
361
 
340
- def patch(path, data, options={})
362
+ def patch(path, data)
341
363
  request = Net::HTTP::Patch.new(path)
342
364
  request.body = data
343
365
 
344
- execute_request(request, options)
366
+ execute_request(request)
345
367
  end
346
368
 
347
- def delete(path, options={})
369
+ def delete(path)
348
370
  request = Net::HTTP::Delete.new(path)
349
- execute_request(request, options)
350
- end
351
-
352
- private
353
-
354
- def snitch_array(json_payload)
355
- arr = []
356
- json_payload.each do |payload|
357
- arr << Snitcher::API::Snitch.new(payload)
358
- end
359
- arr
371
+ execute_request(request)
360
372
  end
361
373
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Snitcher::API
2
4
  # Error is the base class for all API specific errors. For a full list of
3
5
  # errors and how they can happen please refer to the API documentation.
@@ -13,14 +15,15 @@ module Snitcher::API
13
15
  klass =
14
16
  case type.to_s
15
17
  # sign_in_incorrect is only returned when using username + password.
16
- when "sign_in_incorrect"; AuthenticationError
18
+ when "sign_in_incorrect"; AuthenticationError
17
19
  # api_key_invalid is only returned when using the API key.
18
- when "api_key_invalid"; AuthenticationError
19
- when "plan_limit_reached"; PlanLimitReachedError
20
- when "account_on_hold"; AccountOnHoldError
21
- when "resource_not_found"; ResourceNotFoundError
22
- when "resource_invalid"; ResourceInvalidError
23
- else Error
20
+ when "api_key_invalid"; AuthenticationError
21
+ when "plan_limit_reached"; PlanLimitReachedError
22
+ when "account_on_hold"; AccountOnHoldError
23
+ when "resource_not_found"; ResourceNotFoundError
24
+ when "resource_invalid"; ResourceInvalidError
25
+ when "internal_server_error"; InternalServerError
26
+ else Error
24
27
  end
25
28
 
26
29
  error = klass.allocate
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Snitcher::API::Snitch
2
4
  # @return [String] unique token used to identify a Snitch.
3
5
  attr_accessor :token
@@ -12,6 +14,14 @@ class Snitcher::API::Snitch
12
14
  # "pending", "healthy", "paused", "failed", or "errored".
13
15
  attr_accessor :status
14
16
 
17
+ # alert_email is a list of email addresses that will be notified when this
18
+ # Snitch goes missing, errors, or becomes healthy again. When this is set,
19
+ # only the email addresses in the list will be notified. When the list is
20
+ # empty then all team members will be alerted by default.
21
+ #
22
+ # @return [Array<String>] override list of email addresses
23
+ attr_accessor :alert_email
24
+
15
25
  # @return [String] when the Snitch last checked_in
16
26
  attr_accessor :checked_in_at
17
27
 
@@ -37,6 +47,7 @@ class Snitcher::API::Snitch
37
47
  # "token" => "c2354d53d3",
38
48
  # "href" => "/v1/snitches/c2354d53d3",
39
49
  # "name" => "Daily Backups",
50
+ # "alert_email" => [],
40
51
  # "tags" => [
41
52
  # "production",
42
53
  # "critical"
@@ -64,6 +75,7 @@ class Snitcher::API::Snitch
64
75
  @notes = payload["notes"]
65
76
 
66
77
  @created_at = payload["created_at"]
78
+ @alert_email = payload["alert_email"] || []
67
79
  @check_in_url = payload["check_in_url"]
68
80
  @checked_in_at = payload["checked_in_at"]
69
81
  end
@@ -1,3 +1,3 @@
1
1
  module Snitcher
2
- VERSION = "0.4.0.rc1"
2
+ VERSION = "0.4.2".freeze
3
3
  end
data/snitcher.gemspec CHANGED
@@ -19,6 +19,6 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.required_ruby_version = ">= 1.9.3"
21
21
 
22
- spec.add_development_dependency "bundler", "~> 1.5"
23
- spec.add_development_dependency "rake", "~> 10.1"
22
+ spec.add_development_dependency "bundler"
23
+ spec.add_development_dependency "rake"
24
24
  end
@@ -3,7 +3,7 @@ require "snitcher/api/client"
3
3
  require "base64"
4
4
  require "securerandom"
5
5
 
6
- describe Snitcher::API::Client do
6
+ RSpec.describe Snitcher::API::Client do
7
7
  subject(:client) do
8
8
  Snitcher::API::Client.new("key", endpoint: "http://api.dms.dev")
9
9
  end
@@ -60,6 +60,34 @@ describe Snitcher::API::Client do
60
60
  expect(client.snitches).to be_a(Array)
61
61
  expect(client.snitches.first).to be_a(Snitcher::API::Snitch)
62
62
  end
63
+
64
+ it "allows filtering by a tag" do
65
+ request = stub_request(:get, "#{snitch_url}?tags=production")
66
+ .to_return(body: body, status: 200)
67
+
68
+ client.snitches(tags: "production")
69
+ expect(request).to have_been_made.once
70
+ end
71
+
72
+ it "allows filtering by multiple tags" do
73
+ request = stub_request(:get, "#{snitch_url}?tags=phoenix%20foundary,murggle")
74
+ .to_return(body: body, status: 200)
75
+
76
+ client.snitches(tags: ["phoenix foundary", "murggle"])
77
+ expect(request).to have_been_made.once
78
+ end
79
+
80
+ context "when Net::HTTPInternalServerError" do
81
+ it "raise ::Snitcher::API::InternalServerError" do
82
+ stub_request(:any, "#{snitch_url}?tags=phoenix")
83
+ .to_return(body: "Server Error", status: 500)
84
+
85
+ expect { client.snitches(tags: ["phoenix"]) }.to raise_error do |error|
86
+ expect(error).to be_a(::Snitcher::API::InternalServerError)
87
+ expect(error.message).to eq("Server Error")
88
+ end
89
+ end
90
+ end
63
91
  end
64
92
 
65
93
  describe "#snitch" do
@@ -99,77 +127,6 @@ describe Snitcher::API::Client do
99
127
  end
100
128
  end
101
129
 
102
- describe "#tagged_snitches" do
103
- let(:tags) { ["sneetch", "belly"] }
104
- let(:url) { "#{snitch_url}?tags=sneetch,belly" }
105
- let(:body) { '[
106
- {
107
- "token": "c2354d53d2",
108
- "href": "/v1/snitches/c2354d53d2",
109
- "name": "Best Kind of Sneetch on the Beach",
110
- "tags": [
111
- "sneetch",
112
- "belly",
113
- "star-belly"
114
- ],
115
- "status": "pending",
116
- "checked_in_at": "",
117
- "type": {
118
- "interval": "hourly"
119
- }
120
- },
121
- {
122
- "token": "c2354d53d3",
123
- "href": "/v1/snitches/c2354d53d3",
124
- "name": "Have None Upon Thars",
125
- "tags": [
126
- "sneetch",
127
- "belly",
128
- "plain-belly"
129
- ],
130
- "status": "pending",
131
- "checked_in_at": "",
132
- "type": {
133
- "interval": "hourly"
134
- }
135
- }
136
- ]'
137
- }
138
-
139
- before do
140
- stub_request(:get, stub_url).to_return(:body => body, :status => 200)
141
- end
142
-
143
- it "pings API with the api_key" do
144
- client.tagged_snitches(tags)
145
-
146
- expect(a_request(:get, url)).to have_been_made.once
147
- end
148
-
149
- it "returns the snitches" do
150
- expect(client.tagged_snitches(tags)).to be_a(Array)
151
- expect(client.tagged_snitches(tags).first).to be_a(Snitcher::API::Snitch)
152
- end
153
-
154
- it "supports spaces in tags" do
155
- request = stub_request(:get, "#{snitch_url}?tags=phoenix%20foundary,murggle").
156
- to_return(body: body, status: 200)
157
-
158
- client.tagged_snitches("phoenix foundary", "murggle")
159
-
160
- expect(request).to have_been_made.once
161
- end
162
-
163
- it "allows an array to be passed for tags" do
164
- request = stub_request(:get, "#{snitch_url}?tags=murggle,gurgggle").
165
- to_return(body: body, status: 200)
166
-
167
- client.tagged_snitches(["murggle", "gurgggle"])
168
-
169
- expect(request).to have_been_made.once
170
- end
171
- end
172
-
173
130
  describe "#create_snitch" do
174
131
  let(:data) {
175
132
  {
@@ -443,6 +400,14 @@ describe Snitcher::API::Client do
443
400
  expect(a_request(:delete, url)).to have_been_made.once
444
401
  end
445
402
 
403
+ it "properly escapes tags with spaces" do
404
+ request = stub_request(:delete, "#{snitch_url}/c2354d53d2/tags/tag+with+spaces").
405
+ to_return(:body => body, :status => 200)
406
+
407
+ client.remove_tag(token, "tag with spaces")
408
+ expect(request).to have_been_made.once
409
+ end
410
+
446
411
  context "when successful" do
447
412
  it "returns an array of the snitch's remaining tags" do
448
413
  expect(client.remove_tag(token, tag)).to eq(JSON.parse(body))
@@ -1,4 +1,7 @@
1
- describe Snitcher::API::Error do
1
+ require "spec_helper"
2
+ require "snitcher/api"
3
+
4
+ RSpec.describe Snitcher::API::Error do
2
5
  it "returns a AuthenticationError for 'sign_in_incorrect'" do
3
6
  error = Snitcher::API::Error.new({
4
7
  "type" => "sign_in_incorrect",
@@ -58,5 +61,4 @@ describe Snitcher::API::Error do
58
61
  expect(error).to be_a(Snitcher::API::ResourceNotFoundError)
59
62
  expect(error.message).to eq("I can't find that!!")
60
63
  end
61
-
62
64
  end
@@ -2,30 +2,32 @@ require "spec_helper"
2
2
  require "snitcher/api"
3
3
  require "snitcher/api/snitch"
4
4
 
5
- describe Snitcher::API::Snitch do
5
+ RSpec.describe Snitcher::API::Snitch do
6
6
  describe "#new" do
7
- before do
7
+ let(:snitch) do
8
8
  payload = {
9
- "token" => "c2354d53d3",
10
- "name" => "Daily Backups",
11
- "type" => {
12
- "interval" => "daily"
9
+ "token" => "c2354d53d3",
10
+ "name" => "Daily Backups",
11
+ "alert_email" => ["user@example.com"],
12
+ "notes" => "Important user data.",
13
+ "type" => {
14
+ "interval" => "daily",
13
15
  },
14
- "notes" => "Important user data."
15
16
  }
16
17
 
17
- @snitch = Snitcher::API::Snitch.new(payload)
18
+ Snitcher::API::Snitch.new(payload)
18
19
  end
19
20
 
20
21
  it "returns a Snitch object" do
21
- expect(@snitch).to be_a(Snitcher::API::Snitch)
22
+ expect(snitch).to be_a(Snitcher::API::Snitch)
22
23
  end
23
24
 
24
25
  it "sets appropriate values" do
25
- expect(@snitch.name).to eq("Daily Backups")
26
- expect(@snitch.token).to eq("c2354d53d3")
27
- expect(@snitch.notes).to eq("Important user data.")
28
- expect(@snitch.interval).to eq("daily")
26
+ expect(snitch.name).to eq("Daily Backups")
27
+ expect(snitch.token).to eq("c2354d53d3")
28
+ expect(snitch.notes).to eq("Important user data.")
29
+ expect(snitch.interval).to eq("daily")
30
+ expect(snitch.alert_email).to eq(["user@example.com"])
29
31
  end
30
32
  end
31
33
  end
data/spec/api_spec.rb CHANGED
@@ -1,78 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- require "base64"
4
- require "securerandom"
5
-
6
3
  require "snitcher/api"
7
4
 
8
5
  describe Snitcher::API do
9
- describe "#get_key" do
10
- it "returns the api_key" do
11
- user = "alice@example.com"
12
- pass = "password"
13
-
14
- request = stub_request(:get, "https://api.deadmanssnitch.com/v1/api_key").
15
- with(basic_auth: [user, pass]).
16
- to_return({
17
- :body => '{"api_key": "_caeEiZXnEyEzXXYVh2NhQ"}',
18
- :status => 200
19
- })
20
-
21
- actual = Snitcher::API.get_key(user, pass)
22
-
23
- expect(actual).to eq("_caeEiZXnEyEzXXYVh2NhQ")
24
- expect(request).to have_been_made.once
25
- end
26
-
27
- it "raises an error if authentication failed" do
28
- user = "lol@notreally.horse"
29
- pass = "nope"
30
-
31
- request = stub_request(:get, "https://api.deadmanssnitch.com/v1/api_key").
32
- with(basic_auth: [user, pass]).
33
- to_return({
34
- :body => JSON.generate({
35
- :type => "sign_in_incorrect",
36
- :error => "Invalid email or password."
37
- }),
38
- :status => 401
39
- })
40
-
41
- expect {
42
- # Some shenanigans to verify type
43
- begin
44
- Snitcher::API.get_key(user, pass)
45
- rescue Snitcher::API::Error => e
46
- expect(e.type).to eq("sign_in_incorrect")
47
- expect(e.message).to eq("Invalid email or password.")
48
-
49
- raise e
50
- end
51
- }.to raise_error(Snitcher::API::AuthenticationError)
52
-
53
- expect(request).to have_been_made.once
54
- end
55
-
56
- it "raises Timeout::Error on a timeout" do
57
- stub_request(:any, "https://api.deadmanssnitch.com/v1/api_key").to_timeout
58
-
59
- expect {
60
- Snitcher::API.get_key("", "")
61
- }.to raise_error(Timeout::Error)
62
- end
63
-
64
- it "allows the API URI to be provided" do
65
- request = stub_request(:any, "dms.dev:4000/v1/api_key").
66
- with(basic_auth: ["user", "pass"]).
67
- to_return({
68
- :body => '{"api_key": "this_is_an_api_key"}',
69
- :status => 200
70
- })
71
-
72
- actual = Snitcher::API.get_key("user", "pass", uri: "http://dms.dev:4000")
73
-
74
- expect(actual).to eq("this_is_an_api_key")
75
- expect(request).to have_been_made.once
76
- end
77
- end
78
6
  end
@@ -9,15 +9,15 @@ describe Snitcher do
9
9
  stub_request(:get, /nosnch\.in/)
10
10
  end
11
11
 
12
- describe ".snitch" do
12
+ describe ".snitch!" do
13
13
  it "pings DMS with the given token" do
14
- Snitcher.snitch(token)
14
+ Snitcher.snitch!(token)
15
15
 
16
16
  expect(a_request(:get, "https://nosnch.in/#{token}")).to have_been_made.once
17
17
  end
18
18
 
19
19
  it "includes a custom user-agent" do
20
- Snitcher.snitch(token)
20
+ Snitcher.snitch!(token)
21
21
 
22
22
  expect(
23
23
  a_request(:get, "https://nosnch.in/#{token}").with(
@@ -26,42 +26,61 @@ describe Snitcher do
26
26
  ).to have_been_made
27
27
  end
28
28
 
29
- context "when successful" do
30
- before do
31
- stub_request(:get, "https://nosnch.in/#{token}").to_return(status: 200)
32
- end
29
+ it "returns true when successful" do
30
+ request = stub_request(:get, "https://nosnch.in/#{token}").to_return(status: 202)
33
31
 
34
- it "returns true" do
35
- expect(Snitcher.snitch(token)).to eq(true)
36
- end
32
+ expect(Snitcher.snitch!(token)).to eq(true)
33
+ expect(request).to have_been_made.once
37
34
  end
38
35
 
39
- context "when unsuccessful" do
40
- before do
41
- stub_request(:get, "https://nosnch.in/#{token}").to_return(status: 404)
42
- end
36
+ it "returns false when unsuccessful" do
37
+ request = stub_request(:get, "https://nosnch.in/#{token}").to_return(status: 404)
43
38
 
44
- it "returns false" do
45
- expect(Snitcher.snitch(token)).to eq(false)
46
- end
39
+ expect(Snitcher.snitch!(token)).to eq(false)
40
+ expect(request).to have_been_made.once
47
41
  end
48
42
 
49
43
  describe "with message" do
50
44
  it "includes the message as a query param" do
51
- Snitcher.snitch(token, message: "A thing just happened")
45
+ Snitcher.snitch!(token, message: "A thing just happened")
52
46
 
53
47
  expect(a_request(:get, "https://nosnch.in/#{token}?m=A%20thing%20just%20happened")).to have_been_made
54
48
  end
55
49
  end
56
50
 
57
- describe "timeout" do
58
- before do
59
- stub_request(:get, "https://nosnch.in/#{token}").to_raise(::Timeout::Error)
60
- end
51
+ specify "with status" do
52
+ Snitcher.snitch!(token, status: "0")
53
+ expect(a_request(:get, "https://nosnch.in/#{token}?s=0")).to have_been_made
61
54
 
62
- it "returns false when timed out" do
63
- expect(Snitcher.snitch(token)).to eq(false)
64
- end
55
+ Snitcher.snitch!(token, status: 1237)
56
+ expect(a_request(:get, "https://nosnch.in/#{token}?s=1237")).to have_been_made
57
+
58
+ # Both nil and "" avoid adding the `s` query param.
59
+ Snitcher.snitch!(token, status: nil)
60
+ Snitcher.snitch!(token, status: "")
61
+ expect(a_request(:get, "https://nosnch.in/#{token}")).to have_been_made.twice
62
+ end
63
+
64
+ it "raises a Timeout::Error if the request timesout" do
65
+ stub_request(:get, "https://nosnch.in/#{token}").to_timeout
66
+
67
+ expect { Snitcher.snitch!(token) }.to raise_error(Timeout::Error)
68
+ end
69
+ end
70
+
71
+ describe ".snitch" do
72
+ it "returns true on a successfuly check-in" do
73
+ stub_request(:get, "https://nosnch.in/#{token}").to_return(status: 202)
74
+
75
+ result = Snitcher.snitch(token)
76
+ expect(result).to be(true)
77
+ end
78
+
79
+ it "returns false on a timeout" do
80
+ stub_request(:get, "https://nosnch.in/#{token}").to_timeout
81
+
82
+ result = Snitcher.snitch(token)
83
+ expect(result).to be(false)
65
84
  end
66
85
  end
67
86
 
metadata CHANGED
@@ -1,44 +1,44 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snitcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0.rc1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Collective Idea
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-13 00:00:00.000000000 Z
11
+ date: 2021-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.5'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.5'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.1'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.1'
41
- description:
40
+ version: '0'
41
+ description:
42
42
  email: hi@deadmanssnitch.com
43
43
  executables:
44
44
  - snitch
@@ -54,6 +54,7 @@ files:
54
54
  - Rakefile
55
55
  - bin/snitch
56
56
  - doc/get_them_stitches.jpg
57
+ - examples/api.rb
57
58
  - lib/snitcher.rb
58
59
  - lib/snitcher/api.rb
59
60
  - lib/snitcher/api/client.rb
@@ -73,7 +74,7 @@ homepage: https://github.com/deadmanssnitch/snitcher
73
74
  licenses:
74
75
  - MIT
75
76
  metadata: {}
76
- post_install_message:
77
+ post_install_message:
77
78
  rdoc_options: []
78
79
  require_paths:
79
80
  - lib
@@ -84,13 +85,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
84
85
  version: 1.9.3
85
86
  required_rubygems_version: !ruby/object:Gem::Requirement
86
87
  requirements:
87
- - - ">"
88
+ - - ">="
88
89
  - !ruby/object:Gem::Version
89
- version: 1.3.1
90
+ version: '0'
90
91
  requirements: []
91
- rubyforge_project:
92
- rubygems_version: 2.5.1
93
- signing_key:
92
+ rubygems_version: 3.2.15
93
+ signing_key:
94
94
  specification_version: 4
95
95
  summary: Simple API client for deadmanssnitch.com
96
96
  test_files:
@@ -102,4 +102,3 @@ test_files:
102
102
  - spec/spec_helper.rb
103
103
  - spec/support/random.rb
104
104
  - spec/support/webmock.rb
105
- has_rdoc: