prowler 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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