prowler 1.1.1 → 1.2.0

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.
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ * Support usage as a gem plugin
2
+
3
+ * Add option for custom url
4
+
5
+ * Optional parameters are deprecated in favor of an options hash
6
+
7
+ * Verify SSL certificates by default
8
+
9
+
1
10
  *1.1.1 (August 4th, 2009)
2
11
 
3
12
  * Add support for verifying server certificate
data/INSTALL CHANGED
@@ -1,14 +1,29 @@
1
1
  Prowler
2
2
  =======
3
3
 
4
- This is a plugin for integrating apps with the Prowl iPhone application.
4
+ This is a plugin/gem for integrating apps with the Prowl iPhone application.
5
5
 
6
6
  INSTALLATION
7
7
 
8
- From your project's RAILS_ROOT, run:
8
+ To install as a plugin from your application root, run:
9
9
 
10
+ Rails 2.x:
10
11
  script/plugin install git://github.com/pixeltrix/prowler.git
11
12
 
13
+ Rails 3.x:
14
+ script/rails plugin install git://github.com/pixeltrix/prowler.git
15
+
16
+ To install as a gem configure your config.gems or Gemfile:
17
+
18
+ Rails 2.x:
19
+ config.gems 'prowler', :version => '~> 1.2'
20
+
21
+ Rails 3.x:
22
+ gem 'prowler', '~> 1.2'
23
+
24
+ Prowler is not limited to Rails apps - it can be used in any situation
25
+ where you need to send push notifications to your iPhone.
26
+
12
27
  CONFIGURATION
13
28
 
14
29
  You should have something like this in config/initializers/prowler.rb.
@@ -19,24 +34,24 @@ You should have something like this in config/initializers/prowler.rb.
19
34
  end
20
35
 
21
36
  You can test that Prowler is working in your production environment by using
22
- this rake task (from RAILS_ROOT):
37
+ this rake task (from your application root):
23
38
 
24
39
  rake prowler:test
25
40
 
26
41
  If everything is configured properly the task will send a request to
27
- prowl.weks.net which will be appear on your iPhone after a short delay.
42
+ prowlapp.com which will be appear on your iPhone after a short delay.
28
43
 
29
44
  USAGE
30
45
 
31
46
  To use Prowler within your application just call the notify method, e.g.
32
47
 
33
- Prowler.notify "Event", "Description", Prowler::Priority::NORMAL
48
+ Prowler.notify "Event", "Description"
34
49
 
35
50
  If you need to send to multiple accounts from within a single application you
36
51
  can create an instance of the Prowler class to override the global settings, e.g.
37
52
 
38
53
  prowler = Prowler.new('apikey', 'application')
39
- prowler.notify "Event", "Description", Prowler::Priority::NORMAL
54
+ prowler.notify "Event", "Description"
40
55
 
41
56
  If performance is a concern then there is built in support for Delayed::Job.
42
57
  This can done either on a global basis, e.g.
@@ -47,7 +62,7 @@ This can done either on a global basis, e.g.
47
62
 
48
63
  or on a individual message basis, e.g.
49
64
 
50
- Prowler.notify "Event", "Description", Prowler::Priority::NORMAL, true
65
+ Prowler.notify "Event", "Description", :delayed => true
51
66
 
52
67
  ABOUT
53
68
 
@@ -56,4 +71,4 @@ a Growl notification forwarder from your Mac. However they provide an API
56
71
  which can be called by a generic script which allows you to use the
57
72
  application as a general push notification application for your iPhone.
58
73
 
59
- For more about the Prowl application see: http://prowl.weks.net/
74
+ For more about the Prowl application see: http://prowlapp.com/
data/README CHANGED
@@ -1,14 +1,28 @@
1
- Prowler
2
- =======
1
+ == Prowler
3
2
 
4
- This is a plugin for integrating apps with the Prowl iPhone application.
3
+ This is a plugin/gem for integrating apps with the Prowl iPhone application.
5
4
 
6
5
  INSTALLATION
7
6
 
8
- From your project's RAILS_ROOT, run:
7
+ To install as a plugin from your application root, run:
9
8
 
9
+ Rails 2.x:
10
10
  script/plugin install git://github.com/pixeltrix/prowler.git
11
11
 
12
+ Rails 3.x:
13
+ script/rails plugin install git://github.com/pixeltrix/prowler.git
14
+
15
+ To install as a gem configure your config.gems or Gemfile:
16
+
17
+ Rails 2.x:
18
+ config.gems 'prowler', :version => '~> 1.2'
19
+
20
+ Rails 3.x:
21
+ gem 'prowler', '~> 1.2'
22
+
23
+ Prowler is not limited to Rails apps - it can be used in any situation
24
+ where you need to send push notifications to your iPhone.
25
+
12
26
  CONFIGURATION
13
27
 
14
28
  You should have something like this in config/initializers/prowler.rb.
@@ -19,24 +33,24 @@ You should have something like this in config/initializers/prowler.rb.
19
33
  end
20
34
 
21
35
  You can test that Prowler is working in your production environment by using
22
- this rake task (from RAILS_ROOT):
36
+ this rake task (from your application root):
23
37
 
24
38
  rake prowler:test
25
39
 
26
40
  If everything is configured properly the task will send a request to
27
- prowl.weks.net which will be appear on your iPhone after a short delay.
41
+ prowlapp.com which will be appear on your iPhone after a short delay.
28
42
 
29
43
  USAGE
30
44
 
31
45
  To use Prowler within your application just call the notify method, e.g.
32
46
 
33
- Prowler.notify "Event", "Description", Prowler::Priority::NORMAL
47
+ Prowler.notify "Event", "Description"
34
48
 
35
49
  If you need to send to multiple accounts from within a single application you
36
50
  can create an instance of the Prowler class to override the global settings, e.g.
37
51
 
38
52
  prowler = Prowler.new('apikey', 'application')
39
- prowler.notify "Event", "Description", Prowler::Priority::NORMAL
53
+ prowler.notify "Event", "Description"
40
54
 
41
55
  If performance is a concern then there is built in support for Delayed::Job.
42
56
  This can done either on a global basis, e.g.
@@ -47,7 +61,7 @@ This can done either on a global basis, e.g.
47
61
 
48
62
  or on a individual message basis, e.g.
49
63
 
50
- Prowler.notify "Event", "Description", Prowler::Priority::NORMAL, true
64
+ Prowler.notify "Event", "Description", :delayed => true
51
65
 
52
66
  ABOUT
53
67
 
@@ -56,4 +70,4 @@ a Growl notification forwarder from your Mac. However they provide an API
56
70
  which can be called by a generic script which allows you to use the
57
71
  application as a general push notification application for your iPhone.
58
72
 
59
- For more about the Prowl application see: http://prowl.weks.net/
73
+ For more about the Prowl application see: http://prowlapp.com/
data/Rakefile CHANGED
@@ -25,10 +25,10 @@ begin
25
25
  require 'jeweler'
26
26
  Jeweler::Tasks.new do |gemspec|
27
27
  gemspec.name = "prowler"
28
- gemspec.summary = "Provides access to the Prowl API."
28
+ gemspec.summary = "Provides access to the Prowl API (http://prowlapp.com)."
29
29
  gemspec.email = "andyw@pixeltrix.co.uk"
30
30
  gemspec.homepage = "http://github.com/pixeltrix/prowler/"
31
- gemspec.description = "A simple wrapper class that provides basic access to the Prowl API."
31
+ gemspec.description = "A plugin/gem that provides access to the Prowl API (http://prowlapp.com). Works with Rails 2 or 3 as well as any other Ruby web frameworks or in your own scripts."
32
32
  gemspec.authors = ["Andrew White"]
33
33
  end
34
34
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.1
1
+ 1.2.0
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'prowler'
data/lib/prowler.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # === Installation
4
4
  #
5
- # From your project's RAILS_ROOT, run:
5
+ # From your application root, run:
6
6
  #
7
7
  # script/plugin install git://github.com/pixeltrix/prowler.git
8
8
  #
@@ -16,12 +16,12 @@
16
16
  # end
17
17
  #
18
18
  # You can test that Prowler is working in your production environment by using
19
- # this rake task (from RAILS_ROOT):
19
+ # this rake task (from your application root):
20
20
  #
21
21
  # rake prowler:test
22
22
  #
23
23
  # If everything is configured properly the task will send a request to
24
- # prowl.weks.net which will be appear on your iPhone after a short delay.
24
+ # prowlapp.com which will be appear on your iPhone after a short delay.
25
25
  #
26
26
  # === Usage
27
27
  #
@@ -53,244 +53,43 @@
53
53
  # which can be called by a generic script which allows you to use the
54
54
  # application as a general push notification application for your iPhone.
55
55
  #
56
- # For more about the Prowl application see: http://prowl.weks.net/
56
+ # For more about the Prowl application see: http://prowlapp.com/
57
57
 
58
58
  require 'logger'
59
59
  require 'net/https'
60
60
  require 'uri'
61
61
 
62
- class Prowler
63
-
64
- SERVICE_URL = "https://prowl.weks.net/publicapi"
65
- USER_AGENT = "Prowler/1.1.1"
66
- MULTIPLE_APIKEY_COMMANDS = %w(add)
67
-
68
- module Priority
69
- VERY_LOW = -2
70
- MODERATE = -1
71
- NORMAL = 0
72
- HIGH = 1
73
- EMERGENCY = 2
74
- end
75
-
76
- class ConfigurationError < StandardError; end
77
-
78
- class DelayedJob
79
- attr_accessor :api_key, :provider_key, :application
80
- attr_accessor :event, :message, :priority
81
-
82
- def initialize #:nodoc:
83
- yield self if block_given?
84
- end
85
-
86
- # Send notification
87
- def perform
88
- prowler = Prowler.new(api_key, application, provider_key)
89
- prowler.notify(event, message, priority, false)
90
- end
91
- end
62
+ require 'prowler/application'
63
+ require 'prowler/railtie' if defined?(Rails::Railtie)
92
64
 
65
+ module Prowler
93
66
  class << self
94
- attr_accessor :api_key, :provider_key
95
- attr_accessor :application, :send_notifications
96
- attr_accessor :read_timeout, :open_timeout #:nodoc:
97
- attr_accessor :delayed, :verify_certificate, :root_certificates
98
-
99
- # Call this method to configure your account details in an initializer.
100
- def configure
101
- yield self
102
- end
103
-
104
- def send_notifications #:nodoc:
105
- @send_notifications.nil? ? true : !!@send_notifications
106
- end
107
-
108
- def delayed #:nodoc:
109
- @delayed.nil? ? false : !!@delayed
110
- end
111
-
112
- # Reset configuration
113
- def reset_configuration
114
- @application = @api_key = @provider_key = nil
115
- @delayed = @verify_certificate = @root_certificates = nil
116
- end
117
-
118
- # Whether the library has been configured
119
- def configured?
120
- !@application.nil? && !@api_key.nil?
121
- end
122
-
123
- # Whether to verify the server's SSL certificate
124
- def verify_certificate?
125
- @verify_certificate ||= false
126
- end
127
-
128
- # Location of the root certificates file.
129
- # Default: RAILS_ROOT/config/cacert.pem
130
- def root_certificates
131
- @root_certificates ||= File.join(RAILS_ROOT, "config", "cacert.pem")
132
- end
133
-
134
- # Returns the default logger or a logger that prints to STDOUT.
135
- def logger
136
- ActiveRecord::Base.logger
137
- rescue
138
- @logger ||= Logger.new(STDERR)
139
- end
140
-
141
- def read_timeout #:nodoc:
142
- @read_timeout ||= 5
143
- end
144
-
145
- def open_timeout #:nodoc:
146
- @open_timeout ||= 2
147
- end
148
-
149
67
  # Send a notification to your iPhone:
150
68
  # * event: The title of notification you want to send.
151
69
  # * message: The text of the notification message you want to send.
152
- # * priority: The priority of the notification - see Prowler::Priority. (Optional)
153
- # * delayed: Whether to use Delayed::Job to send notifications. (Optional)
154
- def notify(event, message, priority = Priority::NORMAL, delayed = self.delayed)
155
- raise ConfigurationError, "You must provide an API key to send notifications" if api_key.nil?
156
- raise ConfigurationError, "You must provide an application name to send notifications" if application.nil?
157
- if delayed
158
- enqueue_delayed_job(self, event, message, priority)
159
- else
160
- perform(
161
- :add, api_key, provider_key,
162
- {
163
- :application => application,
164
- :event => event,
165
- :description => message,
166
- :priority => priority
167
- }
168
- )
169
- end
70
+ #
71
+ # The following options are supported:
72
+ # * +:delayed+: Whether to use Delayed::Job to send notifications. (Optional)
73
+ # * +:priority+: The priority of the notification - see Prowler::Priority. (Optional)
74
+ # * +:url+: A custom url for the Prowl application to open. (Optional)
75
+ def notify(event, message, *args)
76
+ app = new(api_key, application, provider_key)
77
+ app.notify(event, message, *args)
170
78
  end
171
79
 
172
80
  # Verify the configured API key is valid
173
81
  def verify
174
- raise ConfigurationError, "You must provide an API key to verify" if api_key.nil?
175
- perform(:verify, api_key, provider_key, {}, :get)
176
- end
177
-
178
- def perform(command, api_key, provider_key, data = {}, method = :post) #:nodoc:
179
- params = { :apikey => format_api_key(command, api_key), :provider_key => provider_key }.merge(data).delete_if { |k,v| v.nil? }
180
- case method
181
- when :post
182
- perform_post(command, params)
183
- else
184
- perform_get(command, params)
185
- end
82
+ app = new(api_key, application, provider_key)
83
+ app.verify
186
84
  end
187
85
 
188
- def enqueue_delayed_job(config, event, message, priority) #:nodoc:
189
- record = Delayed::Job.enqueue(DelayedJob.new do |job|
190
- job.api_key = config.api_key
191
- job.provider_key = config.provider_key
192
- job.application = config.application
193
- job.event = event
194
- job.message = message
195
- job.priority = priority
196
- end)
197
- !record.new_record?
86
+ # Create an instance for sending to different accounts within a single Rails application
87
+ # * api_key: Your API key.
88
+ # * application: The name of your application.
89
+ # * provider_key: Key to override the rate limit of 1000 requests per hour. (Optional)
90
+ def new(api_key, application, provider_key = nil)
91
+ Prowler::Application.new(api_key, application, provider_key)
198
92
  end
199
-
200
- private
201
- def headers(extra_headers = {}) #:nodoc:
202
- { 'User-Agent' => USER_AGENT }.merge(extra_headers)
203
- end
204
-
205
- def perform_get(command, params) #:nodoc:
206
- url = URI.parse("#{SERVICE_URL}/#{command}?#{params.map{ |k,v| %(#{URI.encode(k.to_s)}=#{URI.encode(v.to_s)}) }.join('&')}")
207
- request = Net::HTTP::Get.new("#{url.path}?#{url.query}", headers)
208
- perform_request(url, request)
209
- end
210
-
211
- def perform_post(command, params) #:nodoc:
212
- url = URI.parse("#{SERVICE_URL}/#{command}")
213
- request = Net::HTTP::Post.new(url.path, headers)
214
- request.form_data = params
215
- perform_request(url, request)
216
- end
217
-
218
- def perform_request(url, request) #:nodoc:
219
- http = Net::HTTP.new(url.host, url.port)
220
- http.use_ssl = true
221
- if verify_certificate?
222
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
223
- http.ca_file = root_certificates
224
- else
225
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
226
- end
227
- http.read_timeout = read_timeout
228
- http.open_timeout = open_timeout
229
- http.start do
230
- begin
231
- return true unless send_notifications
232
- response = http.request(request)
233
- case response
234
- when Net::HTTPSuccess then
235
- logger.info "Prowl Success: #{response.class}"
236
- true
237
- else
238
- logger.error "Prowl Failure: #{response.class}\n#{response.body if response.respond_to? :body}"
239
- false
240
- end
241
- rescue TimeoutError => e
242
- logger.error "Timeout while contacting the Prowl server."
243
- false
244
- end
245
- end
246
- end
247
-
248
- def format_api_key(command, api_key)
249
- if api_key.is_a?(Array)
250
- MULTIPLE_APIKEY_COMMANDS.include?(command.to_s) ? api_key.join(",") : api_key.first.to_s
251
- else
252
- api_key.to_s
253
- end
254
- end
255
- end
256
-
257
- attr_accessor :api_key, :provider_key #:nodoc:
258
- attr_accessor :application, :send_notifications #:nodoc:
259
-
260
- # Create an instance for sending to different accounts within a single Rails application
261
- # * api_key: Your API key.
262
- # * application: The name of your application.
263
- # * provider_key: Key to override the rate limit of 1000 requests per hour. (Optional)
264
- def initialize(api_key, application, provider_key = nil)
265
- @api_key, @application, @provider_key = api_key, application, provider_key
266
- end
267
-
268
- # Send a notification to your iPhone:
269
- # * event: The title of notification you want to send.
270
- # * message: The text of the notification message you want to send.
271
- # * priority: The priority of the notification - see Prowler::Priority. (Optional)
272
- # * delayed: Whether to use Delayed::Job to send notifications. (Optional)
273
- def notify(event, message, priority = Priority::NORMAL, delayed = self.class.delayed)
274
- raise ConfigurationError, "You must provide an API key to send notifications" if api_key.nil?
275
- raise ConfigurationError, "You must provide an application name to send notifications" if application.nil?
276
- if delayed
277
- self.class.enqueue_delayed_job(self, event, message, priority)
278
- else
279
- self.class.perform(
280
- :add, api_key, provider_key,
281
- {
282
- :application => application,
283
- :event => event,
284
- :description => message,
285
- :priority => priority
286
- }
287
- )
288
- end
289
- end
290
-
291
- # Verify the configured API key is valid
292
- def verify
293
- raise ConfigurationError, "You must provide an API key to verify" if api_key.nil?
294
- self.class.perform(:verify, api_key, provider_key, {}, :get)
295
93
  end
296
94
  end
95
+
@@ -0,0 +1,168 @@
1
+ require 'prowler/configuration'
2
+ require 'prowler/delayed_job'
3
+ require 'prowler/priority'
4
+ require 'prowler/version'
5
+
6
+ module Prowler
7
+
8
+ SERVICE_URL = "https://prowlapp.com/publicapi"
9
+ USER_AGENT = "Prowler/#{VERSION}"
10
+ MULTIPLE_APIKEY_COMMANDS = %w(add)
11
+
12
+ class ConfigurationError < StandardError; end
13
+
14
+ class Application
15
+ attr_accessor :api_key, :provider_key #:nodoc:
16
+ attr_accessor :application, :send_notifications #:nodoc:
17
+
18
+ # Create an instance for sending to different accounts within a single Rails application
19
+ # * api_key: Your API key.
20
+ # * application: The name of your application.
21
+ # * provider_key: Key to override the rate limit of 1000 requests per hour. (Optional)
22
+ def initialize(api_key, application, provider_key = nil)
23
+ @api_key, @application, @provider_key = api_key, application, provider_key
24
+ end
25
+
26
+ # Send a notification to your iPhone:
27
+ # * event: The title of notification you want to send.
28
+ # * message: The text of the notification message you want to send.
29
+ #
30
+ # The following options are supported:
31
+ # * +:delayed+: Whether to use Delayed::Job to send notifications. (Optional)
32
+ # * +:priority+: The priority of the notification - see Prowler::Priority. (Optional)
33
+ # * +:url+: A custom url for the Prowl application to open. (Optional)
34
+ def notify(event, message, *args)
35
+ raise ConfigurationError, "You must provide an API key to send notifications" if api_key.nil?
36
+ raise ConfigurationError, "You must provide an application name to send notifications" if application.nil?
37
+
38
+ if args.first.is_a?(Hash)
39
+ options = args.first
40
+ options[:priority] ||= Prowler::Priority::NORMAL
41
+ options[:delayed] ||= Prowler.delayed
42
+ else
43
+ options = {
44
+ :priority => args.shift || Prowler::Priority::NORMAL,
45
+ :delayed => args.shift || Prowler.delayed
46
+ }
47
+ end
48
+
49
+ if options.delete(:delayed)
50
+ enqueue_delayed_job(event, message, options)
51
+ else
52
+ perform(
53
+ :add, api_key, provider_key,
54
+ options.merge({
55
+ :application => application,
56
+ :event => event,
57
+ :description => message
58
+ })
59
+ )
60
+ end
61
+ end
62
+
63
+ # Verify the configured API key is valid
64
+ def verify
65
+ raise ConfigurationError, "You must provide an API key to verify" if api_key.nil?
66
+ perform(:verify, api_key, provider_key, {}, :get)
67
+ end
68
+
69
+ private
70
+ def perform(command, api_key, provider_key, data = {}, method = :post) #:nodoc:
71
+ params = { :apikey => format_api_key(command, api_key), :provider_key => provider_key }.merge(data).delete_if { |k,v| v.nil? }
72
+ case method
73
+ when :post
74
+ perform_post(command, params)
75
+ else
76
+ perform_get(command, params)
77
+ end
78
+ end
79
+
80
+ def enqueue_delayed_job(event, message, options) #:nodoc:
81
+ record = Delayed::Job.enqueue(Prowler::DelayedJob.new do |job|
82
+ job.api_key = api_key
83
+ job.provider_key = provider_key
84
+ job.application = application
85
+ job.event = event
86
+ job.message = message
87
+ job.priority = options[:priority] || Priority::NORMAL
88
+ job.url = options[:url]
89
+ end)
90
+ !record.new_record?
91
+ end
92
+
93
+ def headers(extra_headers = {}) #:nodoc:
94
+ { 'User-Agent' => USER_AGENT }.merge(extra_headers)
95
+ end
96
+
97
+ def logger #:nodoc:
98
+ Prowler.logger
99
+ end
100
+
101
+ def verify_certificate? #:nodoc:
102
+ Prowler.verify_certificate?
103
+ end
104
+
105
+ def root_certificates #:nodoc:
106
+ Prowler.root_certificates
107
+ end
108
+
109
+ def send_notifications #:nodoc:
110
+ @send_notifications.nil? ? true : !!@send_notifications
111
+ end
112
+
113
+ def send_notifications? #:nodoc:
114
+ send_notifications && Prowler.send_notifications
115
+ end
116
+
117
+ def perform_get(command, params) #:nodoc:
118
+ url = URI.parse("#{SERVICE_URL}/#{command}?#{params.map{ |k,v| %(#{URI.encode(k.to_s)}=#{URI.encode(v.to_s)}) }.join('&')}")
119
+ request = Net::HTTP::Get.new("#{url.path}?#{url.query}", headers)
120
+ perform_request(url, request)
121
+ end
122
+
123
+ def perform_post(command, params) #:nodoc:
124
+ url = URI.parse("#{SERVICE_URL}/#{command}")
125
+ request = Net::HTTP::Post.new(url.path, headers)
126
+ request.form_data = params
127
+ perform_request(url, request)
128
+ end
129
+
130
+ def perform_request(url, request) #:nodoc:
131
+ http = Net::HTTP.new(url.host, url.port)
132
+ http.use_ssl = true
133
+ if verify_certificate?
134
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
135
+ http.ca_file = root_certificates
136
+ else
137
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
138
+ end
139
+ http.read_timeout = Prowler.read_timeout
140
+ http.open_timeout = Prowler.open_timeout
141
+ http.start do
142
+ begin
143
+ return true unless send_notifications?
144
+ response = http.request(request)
145
+ case response
146
+ when Net::HTTPSuccess then
147
+ logger.info "Prowl Success: #{response.class}"
148
+ true
149
+ else
150
+ logger.error "Prowl Failure: #{response.class}\n#{response.body if response.respond_to? :body}"
151
+ false
152
+ end
153
+ rescue TimeoutError => e
154
+ logger.error "Timeout while contacting the Prowl server."
155
+ false
156
+ end
157
+ end
158
+ end
159
+
160
+ def format_api_key(command, api_key) #:nodoc:
161
+ if api_key.is_a?(Array)
162
+ MULTIPLE_APIKEY_COMMANDS.include?(command.to_s) ? api_key.join(",") : api_key.first.to_s
163
+ else
164
+ api_key.to_s
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,78 @@
1
+ module Prowler
2
+ class << self
3
+ attr_accessor :api_key, :provider_key
4
+ attr_accessor :application, :send_notifications
5
+ attr_accessor :read_timeout, :open_timeout #:nodoc:
6
+ attr_accessor :delayed, :verify_certificate, :root_certificates
7
+
8
+ # Call this method to configure your account details in an initializer.
9
+ def configure
10
+ yield self
11
+ end
12
+
13
+ def send_notifications #:nodoc:
14
+ @send_notifications.nil? ? true : !!@send_notifications
15
+ end
16
+
17
+ def delayed #:nodoc:
18
+ @delayed.nil? ? false : !!@delayed
19
+ end
20
+
21
+ # Reset configuration
22
+ def reset_configuration
23
+ @application = @api_key = @provider_key = nil
24
+ @delayed = @verify_certificate = @root_certificates = nil
25
+ @send_notifications = @read_timeout = @open_timeout = nil
26
+ end
27
+
28
+ # Whether the library has been configured
29
+ def configured?
30
+ !@application.nil? && !@api_key.nil?
31
+ end
32
+
33
+ # Whether to verify the server's SSL certificate
34
+ def verify_certificate?
35
+ @verify_certificate.nil? ? true : !!@verify_certificate
36
+ end
37
+
38
+ # Location of the root certificates file.
39
+ # Default: #{Rails.root}/config/cacert.pem
40
+ def root_certificates
41
+ if defined?(Rails.root)
42
+ @root_certificates ||= File.expand_path('config/cacert.pem', Rails.root)
43
+ elsif defined?(RAILS_ROOT)
44
+ @root_certificates ||= File.expand_path('config/cacert.pem', RAILS_ROOT)
45
+ else
46
+ @root_certificates ||= File.expand_path('../config/cacert.pem', __FILE__)
47
+ end
48
+ end
49
+
50
+ # Returns the default logger or a logger that prints to STDOUT.
51
+ def logger
52
+ @logger ||= rails_logger
53
+ end
54
+
55
+ # Override the default logger
56
+ def logger=(new_logger)
57
+ @logger = new_logger
58
+ end
59
+
60
+ def rails_logger #:nodoc:
61
+ if defined?(Rails.logger)
62
+ Rails.logger
63
+ elsif defined?(RAILS_DEFAULT_LOGGER)
64
+ RAILS_DEFAULT_LOGGER
65
+ else
66
+ Logger.new(STDERR)
67
+ end
68
+ end
69
+
70
+ def read_timeout #:nodoc:
71
+ @read_timeout ||= 5
72
+ end
73
+
74
+ def open_timeout #:nodoc:
75
+ @open_timeout ||= 2
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,20 @@
1
+ module Prowler
2
+ class DelayedJob
3
+ attr_accessor :api_key, :provider_key, :application
4
+ attr_accessor :event, :message, :priority, :url
5
+
6
+ def initialize #:nodoc:
7
+ yield self if block_given?
8
+ end
9
+
10
+ # Send notification
11
+ def perform
12
+ prowler = Prowler.new(api_key, application, provider_key)
13
+ prowler.notify(event, message, options)
14
+ end
15
+
16
+ def options #:nodoc:
17
+ { :priority => priority, :url => url, :delayed => false }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ module Prowler
2
+ module Priority
3
+ VERY_LOW = -2
4
+ MODERATE = -1
5
+ NORMAL = 0
6
+ HIGH = 1
7
+ EMERGENCY = 2
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ require 'prowler'
2
+ require 'rails'
3
+
4
+ module Prowler
5
+ class Railtie < Rails::Railtie #:nodoc:
6
+ rake_tasks do
7
+ require "prowler/tasks"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ namespace :prowler do
2
+ desc "Verify your Prowler installation by sending a test notification to the Prowl iPhone application"
3
+ task :test => :environment do
4
+ Prowler.notify "Test Message", "Testing, testing, testing ..."
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module Prowler
2
+ VERSION = "1.2.0"
3
+ end
data/prowler.gemspec CHANGED
@@ -1,50 +1,57 @@
1
1
  # Generated by jeweler
2
- # DO NOT EDIT THIS FILE
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{prowler}
8
- s.version = "1.1.1"
8
+ s.version = "1.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andrew White"]
12
- s.date = %q{2009-10-05}
13
- s.description = %q{A simple wrapper class that provides basic access to the Prowl API.}
12
+ s.date = %q{2011-01-27}
13
+ s.description = %q{A plugin/gem that provides access to the Prowl API (http://prowlapp.com). Works with Rails 2 or 3 as well as any other Ruby web frameworks or in your own scripts.}
14
14
  s.email = %q{andyw@pixeltrix.co.uk}
15
15
  s.extra_rdoc_files = [
16
16
  "README"
17
17
  ]
18
18
  s.files = [
19
19
  "CHANGELOG",
20
- "INSTALL",
21
- "MIT-LICENSE",
22
- "README",
23
- "Rakefile",
24
- "VERSION",
25
- "install.rb",
26
- "lib/prowler.rb",
27
- "prowler.gemspec",
28
- "tasks/prowler.rake",
29
- "test/config/cacert.pem",
30
- "test/prowler_test.rb"
20
+ "INSTALL",
21
+ "MIT-LICENSE",
22
+ "README",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "init.rb",
26
+ "install.rb",
27
+ "lib/prowler.rb",
28
+ "lib/prowler/application.rb",
29
+ "lib/prowler/configuration.rb",
30
+ "lib/prowler/delayed_job.rb",
31
+ "lib/prowler/priority.rb",
32
+ "lib/prowler/railtie.rb",
33
+ "lib/prowler/tasks.rb",
34
+ "lib/prowler/version.rb",
35
+ "prowler.gemspec",
36
+ "tasks/prowler.rake",
37
+ "test/config/cacert.pem",
38
+ "test/prowler_test.rb"
31
39
  ]
32
40
  s.homepage = %q{http://github.com/pixeltrix/prowler/}
33
- s.rdoc_options = ["--charset=UTF-8"]
34
41
  s.require_paths = ["lib"]
35
- s.rubygems_version = %q{1.3.5}
36
- s.summary = %q{Provides access to the Prowl API.}
42
+ s.rubygems_version = %q{1.4.2}
43
+ s.summary = %q{Provides access to the Prowl API (http://prowlapp.com).}
37
44
  s.test_files = [
38
45
  "test/prowler_test.rb"
39
46
  ]
40
47
 
41
48
  if s.respond_to? :specification_version then
42
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
43
49
  s.specification_version = 3
44
50
 
45
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
51
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
46
52
  else
47
53
  end
48
54
  else
49
55
  end
50
56
  end
57
+
data/tasks/prowler.rake CHANGED
@@ -1,6 +1 @@
1
- namespace :prowler do
2
- desc "Verify your plugin installation by sending a test notification to the Prowl iPhone application"
3
- task :test => :environment do
4
- Prowler.notify "Test Message", "Testing, testing, testing ..."
5
- end
6
- end
1
+ require File.expand_path('../../lib/prowler/tasks', __FILE__)
data/test/prowler_test.rb CHANGED
@@ -2,15 +2,24 @@ require 'test/unit'
2
2
  require 'rubygems'
3
3
  require 'mocha'
4
4
  require 'shoulda'
5
- require File.join(File.dirname(__FILE__), "..", "lib", "prowler")
5
+ require 'webmock/test_unit'
6
+ require File.expand_path('../../lib/prowler', __FILE__)
7
+
8
+ class FakeLogger
9
+ def info(*args); end
10
+ def debug(*args); end
11
+ def warn(*args); end
12
+ def error(*args); end
13
+ def fatal(*args); end
14
+ end
6
15
 
7
16
  RAILS_ROOT = File.dirname(__FILE__)
17
+ RAILS_DEFAULT_LOGGER = FakeLogger.new
8
18
 
9
19
  class ProwlerTest < Test::Unit::TestCase
10
20
  context "Prowler configuration" do
11
21
  setup do
12
22
  Prowler.reset_configuration
13
- Prowler.send_notifications = false
14
23
  end
15
24
 
16
25
  should "be done with a block" do
@@ -45,18 +54,17 @@ class ProwlerTest < Test::Unit::TestCase
45
54
  config.api_key = "apikey"
46
55
  config.application = "Application Name"
47
56
  end
48
- Prowler.send_notifications = false
49
57
  end
50
58
 
51
59
  should "raise an exception if API key not configured" do
52
60
  Prowler.reset_configuration
53
61
  assert_raises Prowler::ConfigurationError do
54
- Prowler.notify("Event", "Description", Prowler::Priority::NORMAL)
62
+ Prowler.notify("Event", "Description")
55
63
  end
56
64
 
57
65
  prowler = Prowler.new(nil, nil)
58
66
  assert_raises Prowler::ConfigurationError do
59
- prowler.notify("Event", "Description", Prowler::Priority::NORMAL)
67
+ prowler.notify("Event", "Description")
60
68
  end
61
69
  end
62
70
 
@@ -75,39 +83,71 @@ class ProwlerTest < Test::Unit::TestCase
75
83
  end
76
84
  end
77
85
 
78
- should "not verify SSL certificates by default" do
86
+ should "verify SSL certificates by default" do
79
87
  Net::HTTP.any_instance.expects(:use_ssl=).with(true)
80
- Net::HTTP.any_instance.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
81
- Prowler.notify("Event Name", "Message Text", Prowler::Priority::NORMAL)
88
+ Net::HTTP.any_instance.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
89
+ Net::HTTP.any_instance.expects(:ca_file=).with(File.expand_path('config/cacert.pem', RAILS_ROOT))
90
+
91
+ Prowler.send_notifications = false
92
+ Prowler.notify("Event Name", "Message Text")
82
93
  end
83
94
 
84
- should "verify SSL certificates if verification is turned on" do
85
- Prowler.configure do |config|
86
- config.verify_certificate = true
87
- end
95
+ should "not verify SSL certificates if verification is turned off" do
88
96
  Net::HTTP.any_instance.expects(:use_ssl=).with(true)
89
- Net::HTTP.any_instance.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
90
- Net::HTTP.any_instance.expects(:ca_file=).with(File.join(RAILS_ROOT, "config", "cacert.pem"))
91
- Prowler.notify("Event Name", "Message Text", Prowler::Priority::NORMAL)
97
+ Net::HTTP.any_instance.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
98
+
99
+ Prowler.send_notifications = false
100
+ Prowler.verify_certificate = false
101
+ Prowler.notify("Event Name", "Message Text")
92
102
  end
93
103
 
94
104
  should "not send notifications if send_notifications is false" do
95
- Net::HTTP.any_instance.expects(:request).never
96
- Prowler.notify("Event Name", "Message Text", Prowler::Priority::NORMAL)
105
+ Prowler.send_notifications = false
106
+ assert_not_notified Prowler, "Event Name", "Message Text"
97
107
  end
98
108
 
99
109
  should "send multiple API keys if configured" do
100
- Prowler.configure do |config|
101
- config.api_key = %w(apikey1 apikey2)
110
+ Prowler.api_key = %w(apikey1 apikey2)
111
+ assert_notified Prowler, "Event Name", "Message Text"
112
+ end
113
+
114
+ should "log a successful response" do
115
+ Prowler.logger.expects(:info).with("Prowl Success: Net::HTTPOK")
116
+ assert_notified Prowler, "Event Name", "Message Text"
117
+ end
118
+
119
+ should "log an error response" do
120
+ Prowler.logger.expects(:error).with("Prowl Failure: Net::HTTPInternalServerError\n")
121
+ assert_notified Prowler, "Event Name", "Message Text" do |request|
122
+ request.to_return(:status => 500, :body => "", :headers => {})
102
123
  end
103
- Net::HTTP::Post.any_instance.expects(:form_data=).with({
104
- :apikey => "apikey1,apikey2",
105
- :application => "Application Name",
106
- :event => "Event Name",
107
- :description => "Message Text",
108
- :priority => Prowler::Priority::NORMAL
109
- })
110
- Prowler.notify("Event Name", "Message Text", Prowler::Priority::NORMAL)
124
+ end
125
+
126
+ should "delay sending if configured globally" do
127
+ Prowler.delayed = true
128
+ assert_delayed Prowler, "Event Name", "Message Text"
129
+ end
130
+
131
+ should "delay sending using deprecated parameter" do
132
+ Prowler.delayed = false
133
+ assert_delayed Prowler, "Event Name", "Message Text", Prowler::Priority::NORMAL, true
134
+ end
135
+
136
+ should "delay sending using options" do
137
+ Prowler.delayed = false
138
+ assert_delayed Prowler, "Event Name", "Message Text", :delayed => true
139
+ end
140
+
141
+ should "send a custom url" do
142
+ assert_notified Prowler, "Event Name", "Message Text", :url => "http://www.pixeltrix.co.uk"
143
+ end
144
+
145
+ should "send with a high priority using deprecated parameter" do
146
+ assert_notified Prowler, "Event Name", "Message Text", Prowler::Priority::HIGH
147
+ end
148
+
149
+ should "send with a high priority using options" do
150
+ assert_notified Prowler, "Event Name", "Message Text", :priority => Prowler::Priority::HIGH
111
151
  end
112
152
  end
113
153
 
@@ -118,7 +158,6 @@ class ProwlerTest < Test::Unit::TestCase
118
158
  config.api_key = "apikey"
119
159
  config.application = "Application Name"
120
160
  end
121
- Prowler.send_notifications = false
122
161
  end
123
162
 
124
163
  should "raise an exception if API key not configured" do
@@ -129,37 +168,128 @@ class ProwlerTest < Test::Unit::TestCase
129
168
 
130
169
  prowler = Prowler.new(nil, nil)
131
170
  assert_raises Prowler::ConfigurationError do
132
- prowler.verify
171
+ Prowler.verify
133
172
  end
134
173
  end
135
174
 
136
175
  should "only verify the first API key" do
137
- Prowler.configure do |config|
138
- config.api_key = %w(apikey1 apikey2)
139
- end
140
- Net::HTTP::Get.expects(:new).with("/publicapi/verify?apikey=apikey1", { 'User-Agent' => Prowler::USER_AGENT }).once
141
- Prowler.verify
176
+ Prowler.api_key = %w(apikey1 apikey2)
177
+ assert_verified Prowler, "apikey1"
142
178
  end
143
179
 
144
- should "not verify SSL certificates by default" do
145
- Net::HTTP.any_instance.expects(:use_ssl=).with(true)
146
- Net::HTTP.any_instance.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
147
- Prowler.verify
180
+ should "not send notifications if send_notifications is false" do
181
+ Prowler.send_notifications = false
182
+ assert_not_verified Prowler
148
183
  end
149
184
 
150
- should "verify SSL certificates if verification is turned on" do
151
- Prowler.configure do |config|
152
- config.verify_certificate = true
153
- end
185
+ should "verify SSL certificates by default" do
154
186
  Net::HTTP.any_instance.expects(:use_ssl=).with(true)
155
187
  Net::HTTP.any_instance.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
156
- Net::HTTP.any_instance.expects(:ca_file=).with(File.join(RAILS_ROOT, "config", "cacert.pem"))
188
+ Net::HTTP.any_instance.expects(:ca_file=).with(File.expand_path('config/cacert.pem', RAILS_ROOT))
189
+
190
+ Prowler.send_notifications = false
157
191
  Prowler.verify
158
192
  end
159
193
 
160
- should "not send notifications if send_notifications is false" do
161
- Net::HTTP.any_instance.expects(:request).never
194
+ should "not verify SSL certificates if verification is turned off" do
195
+ Net::HTTP.any_instance.expects(:use_ssl=).with(true)
196
+ Net::HTTP.any_instance.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
197
+
198
+ Prowler.send_notifications = false
199
+ Prowler.verify_certificate = false
162
200
  Prowler.verify
163
201
  end
164
202
  end
203
+
204
+ private
205
+ def verify_url
206
+ "#{Prowler::SERVICE_URL}/verify"
207
+ end
208
+
209
+ def assert_verified(config, api_key = "apikey", &block)
210
+ request = stub_request(:get, "#{verify_url}?apikey=#{api_key}")
211
+ request.with(:headers => { "Accept" => "*/*" })
212
+ request.with(:headers => { "User-Agent" => Prowler::USER_AGENT })
213
+
214
+ if block_given?
215
+ yield request
216
+ else
217
+ request.to_return(:status => 200, :body => "", :headers => {})
218
+ end
219
+
220
+ config.verify
221
+ assert_requested :get, "#{verify_url}?apikey=#{api_key}"
222
+ end
223
+
224
+ def assert_not_verified(config, api_key = "apikey")
225
+ config.verify
226
+ assert_not_requested :get, "#{verify_url}?apikey=#{api_key}"
227
+ end
228
+
229
+ def notify_url
230
+ "#{Prowler::SERVICE_URL}/add"
231
+ end
232
+
233
+ def build_request(config, event, message, options)
234
+ body = {}
235
+ if options.is_a?(Hash)
236
+ body["priority"] = (options[:priority] || Prowler::Priority::NORMAL).to_s
237
+ body["url"] = options[:url] if options[:url]
238
+ else
239
+ body["priority"] = (options || Prowler::Priority::NORMAL).to_s
240
+ end
241
+ body["application"] = config.application
242
+ body["event"] = event
243
+ body["apikey"] = Array(config.api_key).join(",")
244
+ body["description"] = message
245
+ body["providerkey"] = config.provider_key if config.provider_key
246
+ body
247
+ end
248
+
249
+ def assert_notified(config, event, message, options = {}, &block)
250
+ body = build_request(config, event, message, options)
251
+
252
+ request = stub_request(:post, notify_url)
253
+ request.with(:headers => { "Accept" => "*/*" })
254
+ request.with(:headers => { "User-Agent" => Prowler::USER_AGENT })
255
+ request.with(:headers => { "Content-Type" => "application/x-www-form-urlencoded" })
256
+ request.with(:body => body)
257
+
258
+ if block_given?
259
+ yield request
260
+ else
261
+ request.to_return(:status => 200, :body => "", :headers => {})
262
+ end
263
+
264
+ config.notify event, message, options
265
+ assert_requested :post, notify_url, :body => body
266
+ end
267
+
268
+ def assert_not_notified(config, event, message, options = {})
269
+ config.notify event, message
270
+ assert_not_requested :post, notify_url, :body => build_request(config, event, message, options)
271
+ end
272
+
273
+ def assert_delayed(config, event, message, *args, &block)
274
+ if args.first.is_a?(Hash) || args.empty?
275
+ options = args.first || {}
276
+ delayed = options.delete(:delayed)
277
+ options[:priority] ||= Prowler::Priority::NORMAL
278
+
279
+ Prowler::Application.any_instance.expects(:enqueue_delayed_job).with("Event Name", "Message Text", options)
280
+ config.notify event, message, options.merge(:delayed => delayed)
281
+ else
282
+ priority = args.shift
283
+ delayed = args.shift
284
+ options = { :priority => priority }
285
+
286
+ Prowler::Application.any_instance.expects(:enqueue_delayed_job).with("Event Name", "Message Text", options)
287
+ config.notify event, message, priority, delayed
288
+ end
289
+
290
+ if delayed
291
+ assert_not_requested :post, notify_url, :body => build_request(config, event, message, options)
292
+ end
293
+ end
294
+
165
295
  end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prowler
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ hash: 31
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 2
9
+ - 0
10
+ version: 1.2.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Andrew White
@@ -9,11 +15,11 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2009-10-05 00:00:00 +01:00
18
+ date: 2011-01-27 00:00:00 +00:00
13
19
  default_executable:
14
20
  dependencies: []
15
21
 
16
- description: A simple wrapper class that provides basic access to the Prowl API.
22
+ description: A plugin/gem that provides access to the Prowl API (http://prowlapp.com). Works with Rails 2 or 3 as well as any other Ruby web frameworks or in your own scripts.
17
23
  email: andyw@pixeltrix.co.uk
18
24
  executables: []
19
25
 
@@ -28,8 +34,16 @@ files:
28
34
  - README
29
35
  - Rakefile
30
36
  - VERSION
37
+ - init.rb
31
38
  - install.rb
32
39
  - lib/prowler.rb
40
+ - lib/prowler/application.rb
41
+ - lib/prowler/configuration.rb
42
+ - lib/prowler/delayed_job.rb
43
+ - lib/prowler/priority.rb
44
+ - lib/prowler/railtie.rb
45
+ - lib/prowler/tasks.rb
46
+ - lib/prowler/version.rb
33
47
  - prowler.gemspec
34
48
  - tasks/prowler.rake
35
49
  - test/config/cacert.pem
@@ -39,28 +53,34 @@ homepage: http://github.com/pixeltrix/prowler/
39
53
  licenses: []
40
54
 
41
55
  post_install_message:
42
- rdoc_options:
43
- - --charset=UTF-8
56
+ rdoc_options: []
57
+
44
58
  require_paths:
45
59
  - lib
46
60
  required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
47
62
  requirements:
48
63
  - - ">="
49
64
  - !ruby/object:Gem::Version
65
+ hash: 3
66
+ segments:
67
+ - 0
50
68
  version: "0"
51
- version:
52
69
  required_rubygems_version: !ruby/object:Gem::Requirement
70
+ none: false
53
71
  requirements:
54
72
  - - ">="
55
73
  - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 0
56
77
  version: "0"
57
- version:
58
78
  requirements: []
59
79
 
60
80
  rubyforge_project:
61
- rubygems_version: 1.3.5
81
+ rubygems_version: 1.4.2
62
82
  signing_key:
63
83
  specification_version: 3
64
- summary: Provides access to the Prowl API.
84
+ summary: Provides access to the Prowl API (http://prowlapp.com).
65
85
  test_files:
66
86
  - test/prowler_test.rb