pushover 0.99.0 → 0.99.1

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.
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