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 CHANGED
@@ -22,6 +22,7 @@ group :test do
22
22
  gem "rspec"
23
23
  gem "rake"
24
24
  gem "webmock"
25
+ gem "childprocess"
25
26
  gem 'simplecov', :require => false
26
27
  gem 'simplecov-rcov', :require => false
27
28
  end
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.
@@ -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[:appkey] = o}
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
- puts "Selecting config file: #{Options[:config_file]}"
24
- Pushover::Config.save_file = Options[:config_file]
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 "Save successful."
31
- exit
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 "Save successful."
38
- exit
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
- exit
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
+
@@ -32,17 +32,7 @@ module Pushover
32
32
  attr_reader :timestamp
33
33
  attr_reader :priority
34
34
  def priority=(level)
35
- if level.class == String
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
- if time_string.class == String
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.each {|k,v| send("#{k}=", tokens[k])}
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
+
@@ -1,4 +1,4 @@
1
1
  module Pushover
2
2
  # The current version of Pushover.
3
- VERSION = "0.99.0"
3
+ VERSION = "0.99.1"
4
4
  end
@@ -1,4 +1,58 @@
1
- # describe "CLI Interface" do
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
- # end
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
@@ -1,4 +1,11 @@
1
- ## 0.99.0 (unreleased):
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 intergration to http://travis-ci.org
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.0
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: 2012-12-23 00:00:00.000000000 Z
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