PushIt 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/bin/pushit +263 -0
  3. metadata +67 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5c06139aef409eda367d86c2a189fa6f23ac5b07
4
+ data.tar.gz: d2a4af4180dc92341895e5905d575ff1d45a27e5
5
+ SHA512:
6
+ metadata.gz: 7449c1186f71d74f0146db36d67b732210504fb11ced9d8ba3902e15eb0174220a7c4f76ffc2301d92fb57057decca89ef07b31b974dde7ac02fb897fdd9ae68
7
+ data.tar.gz: f8e5b29ee8968c3321f0c4295ac2f096504715331f5bad39079d7b1c0c401b30fe5a8f1530724a070df387c1ea9f0f396250a0b1fb03f9fdc2e44f8e051baffb
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'colored'
5
+ require 'commander/import'
6
+ require 'houston'
7
+ require 'yaml'
8
+ # require File.expand_path('../devices.rb', __FILE__)
9
+
10
+ # Possible future feature: Enable storing of device information within the gem, importing and exporting the .yaml file.
11
+
12
+ HighLine.track_eof = false # Fix for built-in Ruby
13
+
14
+ program :name, 'PushIt'
15
+ program :version, '1.0'
16
+ program :description, 'Sends push notifications to development iOS apps. Ensure that your certificate path is relative to your current directory.'
17
+
18
+ program :help, 'Author', 'Oletha Lai'
19
+ program :help_formatter, :compact
20
+
21
+ default_command :help
22
+
23
+ @devices = YAML::load_file "devices.yaml"
24
+
25
+ # Convenience method for debug logging.
26
+ # Takes a String as the log parameter.
27
+ # Prints the log in blue.
28
+ def debug_log (log)
29
+ puts log.blue if $DEBUG_MODE
30
+ end
31
+
32
+ command :devices do |c|
33
+
34
+ c.syntax = 'pushit devices [options]'
35
+ c.description = 'Prints out the list of available devices to push to.'
36
+
37
+ c.example 'Print the list.', 'pushit devices -f "mini"'
38
+
39
+ c.option '-f', '--filter STRING', 'Filters printed results by device type.'
40
+ c.option '-d', '--debug', 'Enables debug mode.'
41
+
42
+ c.action do |options|
43
+ $DEBUG_MODE = options.debug.nil? ? false : true
44
+
45
+ # Check that there is at least 1 device available
46
+ say_error "There are no available devices.".red and abort if @devices.empty?
47
+
48
+ # Filter the list if filtering has been requested.
49
+ if options.filter
50
+ filter = options.filter.downcase
51
+ debug_log "filter: #{@filter}"
52
+ @filtered_devices = Hash.new
53
+ debug_log "Created filtered devices hash."
54
+ @devices.each do |device, info|
55
+ debug_log "Checking for '#{@filter}' on #{device}."
56
+ if info[:model].downcase.match(/#{filter}/)
57
+ debug_log "Matched. Adding #{device} to filtered devices hash."
58
+ @filtered_devices[device] = info
59
+ end
60
+ end
61
+ debug_log "Filtering finished."
62
+
63
+ # Check that there was at least 1 result from the filtering
64
+ say_error "No devices matched your filter.".red and abort if @filtered_devices.empty?
65
+ end
66
+
67
+ # Sends the filtered list to be printed if it exists.
68
+ device_info = @filtered_devices ? @filtered_devices : @devices
69
+ debug_log @filtered_devices ? "Sending filtered devices list to be printed." : "Filtered devices undefined. Sending full device list to be printed."
70
+
71
+ # Print the list
72
+ debug_log "Commencing list printing..."
73
+ device_info.each do |device, info|
74
+ print "#{device}".bold
75
+
76
+ # To ensure that the items are in line with each other, the space of 5 tabs (4 spaces each) will be given for the name field and the space of 3 tabs will be given for the device type
77
+ chars = device.to_s.length
78
+ space_to_next_tab = (4 - (chars % 4))
79
+ if space_to_next_tab != 4
80
+ print "\t"
81
+ chars += space_to_next_tab
82
+ end
83
+ while chars % 20 != 0
84
+ print "\t"
85
+ chars += 4
86
+ end
87
+
88
+ print "#{info[:model]}".green
89
+
90
+ chars = info[:model].length
91
+ space_to_next_tab = (4 - (chars % 4))
92
+ if space_to_next_tab != 4
93
+ print "\t"
94
+ chars += space_to_next_tab
95
+ end
96
+ while chars % 12 != 0
97
+ print "\t"
98
+ chars += 4
99
+ end
100
+
101
+ print "#{info[:token]}".blue
102
+ print "\n"
103
+ end
104
+ debug_log "List printing complete."
105
+ end
106
+ end
107
+
108
+ command :push do |c|
109
+
110
+ c.syntax = 'pushit push DEVICE [options]'
111
+ c.description = 'Push a notification to the given device. Try running --help for options.'
112
+
113
+ c.example 'Send the reference name for your device and any additional options.', 'pushit push laipad --web-link -i'
114
+
115
+ # The command should send different payloads based on the options specified.
116
+
117
+ c.option '-a', '--app STRING', 'Specify the app you want the notification to be sent to. Ensure you have the certificate for the app named <app>.pem in this directory.'
118
+
119
+ c.option '-m', '--message STRING', 'The message to appear on the notification.'
120
+ c.option '-b', '--badge NUMBER', 'Sets the app badge when the notification is received.'
121
+ c.option '-s', '--sound STRING', 'Specifies a sound to be played when the notification is received.'
122
+ c.option '-n', '--newsstand', 'Adds content-available to the payload. Newsstand apps only.'
123
+ c.option '-d', '--download NUMBER', 'Sets the issue ID of the issue to be downloaded in the background.'
124
+
125
+ c.option '-l', '--link STRING', 'Sends a link of the given type. Choose from: web, itunes, appstore, email, page, location, telephone.'
126
+ c.option '-t', '--button STRING', 'Sets the action button on the notification. If no --button option is chosen, View will appear by default. Choose from: install, read, watch, browse, listen, visit.'
127
+
128
+ c.option '-e', '--environment ENV', [:production, :development], 'Environment to send push notification (production or development (default))'
129
+ c.option '-d', '--debug', 'Enables debug mode.'
130
+
131
+ c.action do |chosenDevices, options|
132
+ $DEBUG_MODE = options.debug.nil? ? false : true
133
+
134
+ # Log devices specified.
135
+ if $DEBUG_MODE
136
+ print "Debug logs will appear in ".bold + "blue".bold.blue + ".\n".bold
137
+ debug_log chosenDevices.empty? ? "No devices specified." : "Devices specified:"
138
+ chosenDevices.each do |chosenDevice|
139
+ debug_log "#{chosenDevice}"
140
+ end
141
+ print "\n"
142
+ end
143
+
144
+ # Ensures that a recipient device was specified.
145
+ say_error "Push aborted. One or more device references required.".red and abort if chosenDevices.empty?
146
+
147
+ # Ensures that data is available for the specified device.
148
+ chosenDevices.each do |chosenDevice|
149
+ if @devices[chosenDevice.to_sym].nil?
150
+ say_error "Push aborted. No data was found for #{chosenDevice}.".red and abort
151
+ end
152
+ end
153
+
154
+ debug_log "Setting environment..."
155
+ if options.environment
156
+ @environment = options.environment.downcase.to_sym
157
+ say_error "Invalid environment,'#{@environment}' (should be either :development or :production)" and abort unless [:development, :production].include?(@environment)
158
+ else
159
+ @environment = :development
160
+ end
161
+ debug_log "environment: #{@environment}"
162
+
163
+ @app = options.app if @app # This will be converted to the certificate filename later on.
164
+
165
+ @message = options.message
166
+ @badge = options.badge.nil? ? nil : options.badge.to_i
167
+ @sound = options.sound
168
+ @newsstand = options.newsstand ? true : false
169
+ @issue_id = options.download.nil? ? nil : options.download.to_i
170
+
171
+ debug_log "app: #{@app}"
172
+ debug_log "message: #{@message}"
173
+ debug_log "badge: #{@badge}"
174
+ debug_log "sound: #{@sound}"
175
+ debug_log "newsstand: #{@newsstand}"
176
+ debug_log "issue_id: #{@issue_id}"
177
+
178
+ unless @message or @badge or @sound or @newsstand
179
+ debug_log "message, badge, sound and newsstand values not specified."
180
+ @message = ask_editor "Please enter a message."
181
+ say_error "Push aborted. You must include use least one of the message, badge, sound or newsstand options.".red and abort if @message.nil?
182
+ end
183
+
184
+ if options.link
185
+ debug_log "Setting link..."
186
+ case options.link.downcase
187
+ when 'web'
188
+ @link = 'http://www.google.com/'
189
+ when 'itunes'
190
+ @link = 'itms://itunes.apple.com/gb/album/insomnia-best-faithless/id305775034'
191
+ when 'appstore'
192
+ @link = 'https://itunes.apple.com/us/app/wwdc/id640199958'
193
+ when 'email'
194
+ @link = 'mailto:testuser@pushit.com?subject=Email%20from%20a%20push%20notification%20link!'
195
+ when 'page'
196
+ @link = 'pm-page://local/54637/72/3/0.4746,0.7323,0.1845,0.5763'
197
+ when 'location'
198
+ @link = 'http://maps.apple.com/?q=cupertino'
199
+ when 'telephone'
200
+ @link = 'tel:150' # Free from a T-Mobile phone.
201
+ else
202
+ say_error "Push aborted. Invalid link type.".red and abort
203
+ end
204
+ debug_log "link: #{@link}"
205
+ end
206
+
207
+ if options.button
208
+ debug_log "Setting button..."
209
+ button_title = options.button.capitalize
210
+ unless button_title == ('Install' or 'Read' or 'Watch' or 'Browse' or 'Listen' or 'Visit')
211
+ say_error "Push aborted. Invalid button title.".red and abort
212
+ end
213
+ @button = "APNSActionButton" + button_title
214
+ debug_log "button: #{@button}"
215
+ end
216
+
217
+ @notifications = []
218
+ debug_log "Created notifications array."
219
+ chosenDevices.each do |device|
220
+ debug_log "Setting up notification for device: #{device}"
221
+ notification = Houston::Notification.new({})
222
+ notification.token = @devices[device.to_sym][:token]
223
+ notification.alert = @message if @message
224
+ notification.badge = @badge if @badge
225
+ notification.sound = @sound if @sound
226
+ notification.content-available = @newsstand if @newsstand
227
+
228
+ custom_payload = Hash.new
229
+ debug_log "Created custom payload hash."
230
+
231
+ # TODO: Find out what the actual name is for :issue.
232
+ custom_payload.merge!({:issue => "#{@issue_id}"}) if @issue_id
233
+ custom_payload.merge!({:pmps => {:'link-url' => "#{@link}"}}) if @link
234
+ custom_payload.merge!({'alert' => {:body => "#{@message}", :'action-loc-key' => "#{@button}"}}) if @button
235
+
236
+ debug_log "Merging custom payload..."
237
+ notification.custom_data.merge!(custom_payload)
238
+
239
+ debug_log "Adding notification to notifications array..."
240
+ @notifications << notification
241
+ debug_log "Notification added."
242
+ end
243
+ debug_log "All notifications added."
244
+
245
+ debug_log "Creating Houston Client..."
246
+ client = @environment == :production ? Houston::Client.production : Houston::Client.development
247
+ debug_log "Setting certificate..."
248
+ client.certificate = File.read(@app.nil? ? "cert.pem" : "#{@app}.pem")
249
+ # client.passphrase = password("Please enter the password for the #{@app.capitalize} application certificate:", '*')
250
+
251
+ debug_log "Beginning push operation..."
252
+ begin
253
+ client.push(*@notifications)
254
+ rescue => message
255
+ say_error "Exception sending notification: #{message}".red and abort
256
+ end
257
+ debug_log "Push complete."
258
+
259
+ say_ok "Push notification send successful!".green
260
+ end
261
+ end
262
+
263
+
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: PushIt
3
+ version: !ruby/object:Gem::Version
4
+ version: "1.0"
5
+ platform: ruby
6
+ authors:
7
+ - Oletha Lai
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2013-06-08 00:00:00 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: houston
16
+ prerelease: false
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - &id002
20
+ - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ type: :runtime
24
+ version_requirements: *id001
25
+ - !ruby/object:Gem::Dependency
26
+ name: colored
27
+ prerelease: false
28
+ requirement: &id003 !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - *id002
31
+ type: :runtime
32
+ version_requirements: *id003
33
+ description: Uses Houston (https://github.com/nomad/houston/) to send push notifications to iOS devices.
34
+ email: oletha@gmail.com
35
+ executables:
36
+ - pushit
37
+ extensions: []
38
+
39
+ extra_rdoc_files: []
40
+
41
+ files:
42
+ - bin/pushit
43
+ homepage:
44
+ licenses: []
45
+
46
+ metadata: {}
47
+
48
+ post_install_message:
49
+ rdoc_options: []
50
+
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - *id002
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - *id002
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 2.0.3
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: Sends push notifications from the command line.
66
+ test_files: []
67
+