pushover 0.99.0 → 0.99.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/README.md +1 -0
- data/bin/pushover +14 -13
- data/lib/pushover.rb +37 -24
- data/lib/pushover/version.rb +1 -1
- data/spec/bin/pushover_spec.rb +56 -2
- data/spec/cli_spec_helper.rb +99 -0
- data/whatsnew.md +9 -2
- metadata +4 -2
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Pushover
|
2
2
|
**Master** [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/erniebrodeur/pushover) [![Build Status](https://travis-ci.org/erniebrodeur/pushover.png?branch=master)](https://travis-ci.org/erniebrodeur/pushover) [![Dependency Status](https://gemnasium.com/erniebrodeur/pushover.png)](https://gemnasium.com/erniebrodeur/pushover)
|
3
|
+
|
3
4
|
**Development** [![Build Status](https://travis-ci.org/erniebrodeur/pushover.png?branch=development)](https://travis-ci.org/erniebrodeur/pushover)
|
4
5
|
|
5
6
|
This gem provides a CLI and an API interface to http://pushover.net.
|
data/bin/pushover
CHANGED
@@ -5,7 +5,7 @@ require 'pushover'
|
|
5
5
|
include Bini
|
6
6
|
include Pushover
|
7
7
|
Options.on("-u", "--user USER", "Which user, can be a saved name or token.") { |o| Options[:user] = o}
|
8
|
-
Options.on("-a", "--app APPKEY", "Which app to notify, can be a saved name or apikey.") { |o| Options[:
|
8
|
+
Options.on("-a", "--app APPKEY", "Which app to notify, can be a saved name or apikey.") { |o| Options[:token] = o}
|
9
9
|
Options.on("-t", "--title [TITLE]", "Set the title of the notification (optional).") { |o| Options[:title] = o}
|
10
10
|
Options.on("-p", "--priority [PRIORITY]", "Set the priority of the notification from (low,normal,high) (optional).") { |o| Options[:priority] = o}
|
11
11
|
Options.on("-d", "--device [DEVICE]", "Specify the device to send the notifcation to. (optional).") { |o| Options[:device] = o}
|
@@ -17,34 +17,32 @@ Options.on("--save-app NAME", "Saves the application to the config file under NA
|
|
17
17
|
Options.on("--save-user NAME", "Saves the user to the config file under NAME.") { |o| Options[:save_user] = [Options[:user], o]}
|
18
18
|
|
19
19
|
Options.parse!
|
20
|
+
bail = false
|
20
21
|
|
21
22
|
# Order is important.
|
22
23
|
if Options[:config_file]
|
23
|
-
|
24
|
-
|
24
|
+
Bini::Config.file = Options[:config_file]
|
25
|
+
puts "Selected config file: #{Options[:config_file]}"
|
25
26
|
end
|
26
27
|
|
27
28
|
if Options[:save_app]
|
28
|
-
puts "Saving application #{Options[:save_app][0]} to #{Options[:save_app][1]}."
|
29
29
|
App.add Options[:save_app][1], Options[:save_app][0]
|
30
|
-
puts "
|
31
|
-
|
30
|
+
puts "Saved application #{Options[:save_app][0]} to #{Options[:save_app][1]}."
|
31
|
+
bail = true
|
32
32
|
end
|
33
33
|
|
34
34
|
if Options[:save_user]
|
35
|
-
puts "Saving user #{Options[:save_user][0]} to #{Options[:save_user][1]}."
|
36
35
|
User.add Options[:save_user][1], Options[:save_user][0]
|
37
|
-
puts "
|
38
|
-
|
36
|
+
puts "Saved user #{Options[:save_user][0]} to #{Options[:save_user][1]}."
|
37
|
+
bail = true
|
39
38
|
end
|
40
39
|
|
41
40
|
if ARGV.empty?
|
42
41
|
puts "You must supply a message."
|
43
|
-
|
42
|
+
bail = true
|
44
43
|
end
|
45
|
-
bail = false
|
46
|
-
message = ARGV.join(" ")
|
47
44
|
|
45
|
+
message = ARGV.join(" ")
|
48
46
|
if !message
|
49
47
|
puts "Must supply a message to be sent."
|
50
48
|
bail = true
|
@@ -60,6 +58,7 @@ if !User.current_user?
|
|
60
58
|
puts "Couldn't find a user via the cli or save file."
|
61
59
|
bail = true
|
62
60
|
end
|
61
|
+
|
63
62
|
exit if bail
|
64
63
|
|
65
64
|
# I do both just as an example, you can configure it this way and have it
|
@@ -71,7 +70,7 @@ end
|
|
71
70
|
|
72
71
|
# Or in real time, which will also overwrite the .configure block.
|
73
72
|
options = Options[].select { |k,v| v}
|
74
|
-
|
73
|
+
options.delete :config_file
|
75
74
|
options.merge! message:message
|
76
75
|
response = Pushover.notification options
|
77
76
|
|
@@ -81,3 +80,5 @@ else
|
|
81
80
|
j = Yajl.load response.body
|
82
81
|
puts "ErrorCode (#{response.code}): #{j['errors'].first}."
|
83
82
|
end
|
83
|
+
|
84
|
+
|
data/lib/pushover.rb
CHANGED
@@ -32,17 +32,7 @@ module Pushover
|
|
32
32
|
attr_reader :timestamp
|
33
33
|
attr_reader :priority
|
34
34
|
def priority=(level)
|
35
|
-
|
36
|
-
if level =~ /^[lL]/
|
37
|
-
@priority = -1
|
38
|
-
elsif level =~ /^[hH]/
|
39
|
-
@priority = 1
|
40
|
-
else
|
41
|
-
@priority = 0
|
42
|
-
end
|
43
|
-
elsif level.class == Fixnum
|
44
|
-
@priority = level
|
45
|
-
end
|
35
|
+
@priority = priority_magic level
|
46
36
|
end
|
47
37
|
|
48
38
|
# Stdlib time, seems to take a shitload of options.
|
@@ -51,16 +41,7 @@ module Pushover
|
|
51
41
|
# Time.parse 'Aug 13, 1979 6:30'
|
52
42
|
# Time.parse '1979/08/13, 6:30:50 UTC'
|
53
43
|
def timestamp=(time_string)
|
54
|
-
|
55
|
-
begin
|
56
|
-
@timestamp = Time.parse(time_string).to_i
|
57
|
-
rescue ArgumentError
|
58
|
-
@timestamp = time_string.to_i
|
59
|
-
end
|
60
|
-
elsif
|
61
|
-
time_string.class == Fixnum
|
62
|
-
@timestamp = time_string
|
63
|
-
end
|
44
|
+
@timestamp = timestamp_magic time_string
|
64
45
|
end
|
65
46
|
|
66
47
|
# push a message to pushover, must supply all variables.
|
@@ -72,10 +53,12 @@ module Pushover
|
|
72
53
|
# @param [optional, String] user the user token.
|
73
54
|
# @return [String] the response from pushover.net, in json.
|
74
55
|
def notification(tokens={})
|
75
|
-
tokens
|
56
|
+
tokens[:timestamp] = timestamp_magic tokens[:timestamp] if tokens[:timestamp]
|
57
|
+
tokens[:priority] = priority_magic tokens[:priority] if tokens[:priority]
|
58
|
+
|
76
59
|
url = URI.parse("https://api.pushover.net/1/messages.json")
|
77
|
-
req = Net::HTTP::Post.new(url.path)
|
78
|
-
req.set_form_data(params)
|
60
|
+
req = Net::HTTP::Post.new(url.path, {'User-Agent' => "Ruby pushover gem: #{Pushover::VERSION}"})
|
61
|
+
req.set_form_data(params.merge(tokens).select {|k,v| v != nil})
|
79
62
|
res = Net::HTTP.new(url.host, url.port)
|
80
63
|
res.use_ssl = true
|
81
64
|
res.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
@@ -112,4 +95,34 @@ module Pushover
|
|
112
95
|
def keys
|
113
96
|
keys ||= [:token, :user, :message, :title, :priority, :device, :timestamp, :url, :url_title]
|
114
97
|
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def timestamp_magic(time_string)
|
102
|
+
if time_string.class == String
|
103
|
+
begin
|
104
|
+
return Time.parse(time_string).to_i
|
105
|
+
rescue ArgumentError
|
106
|
+
return time_string.to_i
|
107
|
+
end
|
108
|
+
elsif
|
109
|
+
time_string.class == Fixnum
|
110
|
+
return time_string
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def priority_magic(level)
|
115
|
+
if level.class == String
|
116
|
+
if level =~ /^[lL]/
|
117
|
+
return -1
|
118
|
+
elsif level =~ /^[hH]/
|
119
|
+
return 1
|
120
|
+
else
|
121
|
+
return 0
|
122
|
+
end
|
123
|
+
elsif level.class == Fixnum
|
124
|
+
return level
|
125
|
+
end
|
126
|
+
end
|
115
127
|
end
|
128
|
+
|
data/lib/pushover/version.rb
CHANGED
data/spec/bin/pushover_spec.rb
CHANGED
@@ -1,4 +1,58 @@
|
|
1
|
-
#
|
1
|
+
# Since this testing requires an actual account, and a working internet, we don't
|
2
|
+
# run it as part of the standard suite.
|
3
|
+
# If you want to run these tests, add ENV["TEST_CLI"]
|
4
|
+
# If you have a credentials file already, you might find it beeps you.
|
2
5
|
|
3
|
-
#
|
6
|
+
CRED_FILE = "#{Dir.home}/.config/pushover/credentials.yaml"
|
7
|
+
FAKE_CRED_FILE = 'tmp/fake_credentials.yaml'
|
8
|
+
CMD = 'bundle exec bin/pushover'
|
4
9
|
|
10
|
+
require 'spec_helper.rb'
|
11
|
+
require 'cli_spec_helper.rb'
|
12
|
+
|
13
|
+
if ENV["TEST_CLI"] =~ /^t/
|
14
|
+
describe "CLI Interface" do
|
15
|
+
describe 'help' do
|
16
|
+
it 'has options' do
|
17
|
+
p = CLIProcess.new "#{CMD} --help"
|
18
|
+
p.run!
|
19
|
+
words = /user|app|title|priority|url|url_title|save-app|save-user|time|version/
|
20
|
+
p.stdout.should =~ words
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "send" do
|
25
|
+
if !File.exist? CRED_FILE
|
26
|
+
it "sends messages (no credentials file)"
|
27
|
+
else
|
28
|
+
it "sends messages" do
|
29
|
+
p = CLIProcess.new "#{CMD} --config_file #{CRED_FILE} a message", 3, 3
|
30
|
+
p.run!
|
31
|
+
#binding.pry
|
32
|
+
p.stdout.should include("success"), "#{p.stderr}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "lets me know when a message fails" do
|
37
|
+
p = CLIProcess.new "#{CMD} --app fail --user now message goes here", 3, 3
|
38
|
+
p.run!
|
39
|
+
p.stdout.should include "ErrorCode"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "saving" do
|
44
|
+
it "saves app:key pairs" do
|
45
|
+
p = CLIProcess.new "#{CMD} --config_file #{FAKE_CRED_FILE} --save-app default --app default"
|
46
|
+
p.run!
|
47
|
+
p.stdout.should include 'Saved'
|
48
|
+
open(FAKE_CRED_FILE).read.should include 'default'
|
49
|
+
end
|
50
|
+
it "saves user:token pairs" do
|
51
|
+
p = CLIProcess.new "#{CMD} --config_file #{FAKE_CRED_FILE} --save-user default --user default"
|
52
|
+
p.run!
|
53
|
+
p.stdout.should include 'Saved'
|
54
|
+
open(FAKE_CRED_FILE).read.should include 'default'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# Ripped without remorse from: https://github.com/cucumber/aruba/blob/master/lib/aruba/process.rb
|
2
|
+
# slightly modified for my purposes.
|
3
|
+
require 'childprocess'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'shellwords'
|
6
|
+
|
7
|
+
class CLIProcess
|
8
|
+
include Shellwords
|
9
|
+
|
10
|
+
def initialize(cmd, exit_timeout = 0, io_wait = 1)
|
11
|
+
@exit_timeout = exit_timeout
|
12
|
+
@io_wait = io_wait
|
13
|
+
@io_waited = false
|
14
|
+
|
15
|
+
@cmd = cmd
|
16
|
+
@process = nil
|
17
|
+
@exit_code = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def run!(&block)
|
21
|
+
@process = ChildProcess.build(*shellwords(@cmd))
|
22
|
+
@out = Tempfile.new("binary-out")
|
23
|
+
@err = Tempfile.new("binary-err")
|
24
|
+
@process.io.stdout = @out
|
25
|
+
@process.io.stderr = @err
|
26
|
+
@process.duplex = true
|
27
|
+
@exit_code = nil
|
28
|
+
begin
|
29
|
+
@process.start
|
30
|
+
rescue ChildProcess::LaunchError => e
|
31
|
+
raise LaunchError.new(e.message)
|
32
|
+
end
|
33
|
+
yield self if block_given?
|
34
|
+
end
|
35
|
+
|
36
|
+
def stdin
|
37
|
+
@process.io.stdin
|
38
|
+
end
|
39
|
+
|
40
|
+
def output(keep_ansi = false)
|
41
|
+
stdout(keep_ansi) + stderr(keep_ansi)
|
42
|
+
end
|
43
|
+
|
44
|
+
def stdout(keep_ansi = false)
|
45
|
+
wait_for_io do
|
46
|
+
@out.rewind
|
47
|
+
filter_ansi(@out.read, keep_ansi)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def stderr(keep_ansi = false)
|
52
|
+
wait_for_io do
|
53
|
+
@err.rewind
|
54
|
+
filter_ansi(@err.read, keep_ansi)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def read_stdout(keep_ansi = false)
|
59
|
+
wait_for_io do
|
60
|
+
@process.io.stdout.flush
|
61
|
+
content = filter_ansi(open(@out.path).read, keep_ansi)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def stop(reader, keep_ansi)
|
66
|
+
return @exit_code unless @process
|
67
|
+
unless @process.exited?
|
68
|
+
@process.poll_for_exit(@exit_timeout)
|
69
|
+
end
|
70
|
+
reader.stdout stdout(keep_ansi)
|
71
|
+
reader.stderr stderr(keep_ansi)
|
72
|
+
@exit_code = @process.exit_code
|
73
|
+
@process = nil
|
74
|
+
@exit_code
|
75
|
+
end
|
76
|
+
|
77
|
+
def terminate(keep_ansi = false)
|
78
|
+
if @process
|
79
|
+
stdout(keep_ansi = false) && stderr(keep_ansi) # flush output
|
80
|
+
@process.stop
|
81
|
+
stdout(keep_ansi) && stderr(keep_ansi) # flush output
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def wait_for_io(&block)
|
88
|
+
if @process && !@io_waited
|
89
|
+
sleep @io_wait
|
90
|
+
@io_waited = true
|
91
|
+
end
|
92
|
+
yield
|
93
|
+
end
|
94
|
+
|
95
|
+
def filter_ansi(string, keep_ansi)
|
96
|
+
keep_ansi ? string : string.gsub(/\e\[\d+(?>(;\d+)*)m/, '')
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
data/whatsnew.md
CHANGED
@@ -1,4 +1,11 @@
|
|
1
|
-
## 0.99.
|
1
|
+
## 0.99.1:
|
2
|
+
* Big one here, properly testing bin/pushover now.
|
3
|
+
* Fixed a bug in the bin/pushover so --config_file and --app work as expected.
|
4
|
+
* Empty params will no longer be sent to pushover.net
|
5
|
+
* Fixed Pushover#notification, no longer overwrites params with it's arguments.
|
6
|
+
* Added a user-agent to the POST's sent to pushover.net
|
7
|
+
|
8
|
+
## 0.99.0:
|
2
9
|
* Added url and a url_title.
|
3
10
|
* Added time, we can take an epoch or string. The string is run through stdlib Time#parse, so effectively takes rfc822, html, xml, and a bunch of random bits.
|
4
11
|
* Added gemnasium to the readme.
|
@@ -9,7 +16,7 @@
|
|
9
16
|
## 0.5.1:
|
10
17
|
* SimpleCov and 100% test coverage
|
11
18
|
* Webmock based testing for Pushover##notification.
|
12
|
-
* Added
|
19
|
+
* Added integration to http://travis-ci.org
|
13
20
|
|
14
21
|
## 0.5.0:
|
15
22
|
* Switched the order of App and it's derivatives so that it's name, api_key to make it more human readable.
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pushover
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.99.
|
4
|
+
version: 0.99.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-02-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: yajl-ruby
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- lib/pushover/version.rb
|
68
68
|
- pushover.gemspec
|
69
69
|
- spec/bin/pushover_spec.rb
|
70
|
+
- spec/cli_spec_helper.rb
|
70
71
|
- spec/lib/pushover/app_spec.rb
|
71
72
|
- spec/lib/pushover/pushover_spec.rb
|
72
73
|
- spec/lib/pushover/user_spec.rb
|
@@ -105,6 +106,7 @@ specification_version: 3
|
|
105
106
|
summary: This gem provides both an API and CLI interface to pushover.net.
|
106
107
|
test_files:
|
107
108
|
- spec/bin/pushover_spec.rb
|
109
|
+
- spec/cli_spec_helper.rb
|
108
110
|
- spec/lib/pushover/app_spec.rb
|
109
111
|
- spec/lib/pushover/pushover_spec.rb
|
110
112
|
- spec/lib/pushover/user_spec.rb
|