PushIt 1.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.
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
+