terminal-notifier 2.0.0 → 3.0.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.
- checksums.yaml +5 -5
- data/README.markdown +53 -2
- data/bin/terminal-notifier +4 -9
- data/lib/terminal-notifier/cli.rb +21 -0
- data/lib/terminal-notifier/version.rb +10 -0
- data/lib/terminal-notifier.rb +174 -38
- data/vendor/terminal-notifier/terminal-notifier.app/Contents/Info.plist +3 -32
- data/vendor/terminal-notifier/terminal-notifier.app/Contents/MacOS/terminal-notifier +0 -0
- data/vendor/terminal-notifier/terminal-notifier.app/Contents/Resources/en.lproj/InfoPlist.strings +0 -0
- data/vendor/terminal-notifier/terminal-notifier.app/Contents/_CodeSignature/CodeResources +146 -0
- metadata +18 -88
- data/vendor/terminal-notifier/LICENSE.md +0 -9
- data/vendor/terminal-notifier/README.markdown +0 -256
- data/vendor/terminal-notifier/Ruby/Gemfile +0 -2
- data/vendor/terminal-notifier/Ruby/Gemfile.lock +0 -23
- data/vendor/terminal-notifier/Ruby/README.markdown +0 -48
- data/vendor/terminal-notifier/Ruby/Rakefile +0 -48
- data/vendor/terminal-notifier/Ruby/bin/terminal-notifier +0 -13
- data/vendor/terminal-notifier/Ruby/lib/terminal-notifier.rb +0 -124
- data/vendor/terminal-notifier/Ruby/spec/terminal-notifier_spec.rb +0 -79
- data/vendor/terminal-notifier/Ruby/terminal-notifier.gemspec +0 -26
- data/vendor/terminal-notifier/Terminal Notifier/AppDelegate.h +0 -4
- data/vendor/terminal-notifier/Terminal Notifier/AppDelegate.m +0 -382
- data/vendor/terminal-notifier/Terminal Notifier/Terminal Notifier-Info.plist +0 -43
- data/vendor/terminal-notifier/Terminal Notifier/Terminal Notifier-Prefix.pch +0 -7
- data/vendor/terminal-notifier/Terminal Notifier/en.lproj/Credits.rtf +0 -29
- data/vendor/terminal-notifier/Terminal Notifier/en.lproj/InfoPlist.strings +0 -2
- data/vendor/terminal-notifier/Terminal Notifier/en.lproj/MainMenu.xib +0 -3387
- data/vendor/terminal-notifier/Terminal Notifier/main.m +0 -6
- data/vendor/terminal-notifier/Terminal Notifier.xcodeproj/project.pbxproj +0 -315
- data/vendor/terminal-notifier/Terminal Notifier.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- data/vendor/terminal-notifier/Terminal Notifier.xcodeproj/project.xcworkspace/xcshareddata/Terminal Notifier.xccheckout +0 -41
- data/vendor/terminal-notifier/Terminal Notifier.xcodeproj/xcshareddata/xcschemes/Terminal Notifier.xcscheme +0 -140
- data/vendor/terminal-notifier/Terminal.icns +0 -0
- data/vendor/terminal-notifier/assets/Example_1.png +0 -0
- data/vendor/terminal-notifier/assets/Example_2.png +0 -0
- data/vendor/terminal-notifier/assets/Example_3.png +0 -0
- data/vendor/terminal-notifier/assets/Example_4.png +0 -0
- data/vendor/terminal-notifier/assets/Example_5.png +0 -0
- data/vendor/terminal-notifier/assets/System_prefs.png +0 -0
- data/vendor/terminal-notifier/terminal-notifier.app/Contents/Resources/en.lproj/Credits.rtf +0 -29
- data/vendor/terminal-notifier/terminal-notifier.app/Contents/Resources/en.lproj/MainMenu.nib +0 -0
- /data/{vendor/terminal-notifier/Ruby/LICENSE → LICENSE} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 78c9a9b889e4da2b6154981a05925abdbc29f29c50591d233e599b0de4cdff08
|
|
4
|
+
data.tar.gz: 07c78da6932247a170a8b30289f7720089f82a1fd7120f769164295be777abdc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 94d37dc8ec053c61311c09931d7ab5d6a37922669fcf355d1a2569d86f0afc7ff913200e977e21d933329d4aaeb56b6e84bbdabe718694e9d8fc8f917e936976
|
|
7
|
+
data.tar.gz: 3552e9814c3a24a63e898d3aaab4c6bbf12c8231d0ab55dfade43db566605dc9f1e18f053c85f2251f90b4c37e6d0bcf3b42d27c4a6bbb90fdc24388235464db
|
data/README.markdown
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
A simple Ruby wrapper around the [`terminal-notifier`][HOMEPAGE] command-line
|
|
4
4
|
tool, which allows you to send User Notifications to the Notification Center on
|
|
5
|
-
macOS 10.
|
|
5
|
+
macOS 10.14, or higher.
|
|
6
|
+
|
|
7
|
+
Requires Ruby 3.2 or newer.
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
## Installation
|
|
@@ -25,8 +27,8 @@ TerminalNotifier.notify('Hello World', :activate => 'com.apple.Safari')
|
|
|
25
27
|
TerminalNotifier.notify('Hello World', :open => 'http://twitter.com/julienXX')
|
|
26
28
|
TerminalNotifier.notify('Hello World', :execute => 'say "OMG"')
|
|
27
29
|
TerminalNotifier.notify('Hello World', :group => Process.pid)
|
|
28
|
-
TerminalNotifier.notify('Hello World', :sender => 'com.apple.Safari')
|
|
29
30
|
TerminalNotifier.notify('Hello World', :sound => 'default')
|
|
31
|
+
TerminalNotifier.notify('Hello World', :contentImage => './logo.png')
|
|
30
32
|
|
|
31
33
|
TerminalNotifier.remove(Process.pid)
|
|
32
34
|
|
|
@@ -34,6 +36,55 @@ TerminalNotifier.list(Process.pid)
|
|
|
34
36
|
TerminalNotifier.list
|
|
35
37
|
```
|
|
36
38
|
|
|
39
|
+
`:sender` and `:appIcon` were removed in 3.0.0. They are still accepted, but the
|
|
40
|
+
tool ignores them and warns on stderr — see the main [README][README].
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
## Asking a question
|
|
44
|
+
|
|
45
|
+
`:action` and `:reply` wait for the user and return what they chose. An option
|
|
46
|
+
whose value is `true` is passed as a bare flag.
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
TerminalNotifier.notify('Deploy to production?', :action => 'Yes,No', :timeout => 30)
|
|
50
|
+
#=> :yes (or :no, :_actionclicked, :_closed, :_timeout)
|
|
51
|
+
|
|
52
|
+
TerminalNotifier.notify("What's your name?", :reply => true, :timeout => 30)
|
|
53
|
+
#=> "Alice" (a String, because :reply was given)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Action results come back symbolised by `notify_result`; a `:reply` result is
|
|
57
|
+
returned as the raw string.
|
|
58
|
+
|
|
59
|
+
A timeout returns `:_timeout` rather than `false`, so it can be told apart from
|
|
60
|
+
the notification failing to send — which is what `false` means.
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
## Return values
|
|
64
|
+
|
|
65
|
+
`notify` and `remove` return whether the command succeeded. `list` returns a
|
|
66
|
+
hash (or an array of hashes for the default `'ALL'` group) with the keys
|
|
67
|
+
`:group`, `:title`, `:subtitle`, `:message` and `:delivered_at`; absent fields
|
|
68
|
+
are `nil`. It returns `nil` when there is nothing to report.
|
|
69
|
+
|
|
70
|
+
Both raise `TerminalNotifier::UnsupportedPlatformError` when run on anything
|
|
71
|
+
other than a supported macOS, and `TerminalNotifier::BinaryNotFoundError` when
|
|
72
|
+
the bundled binary is missing.
|
|
73
|
+
|
|
74
|
+
Set `TERMINAL_NOTIFIER_BIN` to use a binary other than the bundled one.
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
## Development
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
$ cd Ruby
|
|
81
|
+
$ bundle install
|
|
82
|
+
$ bundle exec rspec
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
One example needs the compiled application bundle and is skipped without it.
|
|
86
|
+
Build and vendor it with `bundle exec rake update_build`, which requires Xcode.
|
|
87
|
+
|
|
37
88
|
|
|
38
89
|
## License
|
|
39
90
|
|
data/bin/terminal-notifier
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
|
-
if $
|
|
4
|
-
$:.unshift File.expand_path('../../lib', __FILE__)
|
|
5
|
-
end
|
|
4
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __dir__) if $PROGRAM_NAME == __FILE__
|
|
6
5
|
|
|
7
|
-
require 'terminal-notifier'
|
|
6
|
+
require 'terminal-notifier/cli'
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
ARGV.push(*["-message", STDIN.read.chomp])
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
exec TerminalNotifier::BIN_PATH, *ARGV
|
|
8
|
+
TerminalNotifier::CLI.run
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'terminal-notifier'
|
|
4
|
+
|
|
5
|
+
module TerminalNotifier
|
|
6
|
+
# The bin wrapper's logic, extracted so that it can be tested without
|
|
7
|
+
# spawning a process.
|
|
8
|
+
module CLI
|
|
9
|
+
# Folds piped stdin into a -message option, matching the behaviour of the
|
|
10
|
+
# binary itself when data is piped to it directly.
|
|
11
|
+
def self.argv_for(argv, stdin)
|
|
12
|
+
return argv if argv.include?('-message') || stdin.tty?
|
|
13
|
+
|
|
14
|
+
argv + ['-message', stdin.read.chomp]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.run(argv = ARGV, stdin = $stdin)
|
|
18
|
+
exec TerminalNotifier::BIN_PATH, *argv_for(argv, stdin)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TerminalNotifier
|
|
4
|
+
# The version of this gem, which tracks the version of the bundled
|
|
5
|
+
# terminal-notifier binary.
|
|
6
|
+
#
|
|
7
|
+
# Note: this is *not* TerminalNotifier.version, which returns the macOS
|
|
8
|
+
# product version the tool is running on.
|
|
9
|
+
VERSION = '3.0.0'
|
|
10
|
+
end
|
data/lib/terminal-notifier.rb
CHANGED
|
@@ -1,34 +1,145 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
3
|
require 'rbconfig'
|
|
4
|
+
require 'shellwords'
|
|
5
|
+
require 'time'
|
|
6
|
+
|
|
7
|
+
require 'terminal-notifier/version'
|
|
4
8
|
|
|
9
|
+
# Sends macOS User Notifications by shelling out to the bundled
|
|
10
|
+
# terminal-notifier application.
|
|
11
|
+
#
|
|
12
|
+
# See TerminalNotifier.notify, .remove and .list for the public API.
|
|
5
13
|
module TerminalNotifier
|
|
6
|
-
|
|
14
|
+
# Minimum macOS version supported by the bundled binary. UNUserNotificationCenter,
|
|
15
|
+
# which the tool is built on, is not available before this.
|
|
16
|
+
MINIMUM_MACOS_VERSION = '10.14'
|
|
17
|
+
|
|
18
|
+
# Exit code the binary uses when -timeout expires waiting for -action or
|
|
19
|
+
# -reply. The notification was delivered correctly and the tool reported
|
|
20
|
+
# @TIMEOUT, so this is an outcome to pass on rather than a failure.
|
|
21
|
+
TIMEOUT_EXIT_CODE = 6
|
|
22
|
+
|
|
23
|
+
# Path to the binary inside the vendored application bundle. Overridable so
|
|
24
|
+
# that a Homebrew-installed or self-built copy can be used instead.
|
|
25
|
+
BIN_PATH = ENV.fetch(
|
|
26
|
+
'TERMINAL_NOTIFIER_BIN',
|
|
27
|
+
File.expand_path(
|
|
28
|
+
'../vendor/terminal-notifier/terminal-notifier.app/Contents/MacOS/terminal-notifier',
|
|
29
|
+
__dir__
|
|
30
|
+
)
|
|
31
|
+
)
|
|
7
32
|
|
|
8
33
|
class UnsupportedPlatformError < StandardError; end
|
|
9
|
-
|
|
34
|
+
class BinaryNotFoundError < StandardError; end
|
|
35
|
+
|
|
36
|
+
# Returns whether the current platform is macOS 10.14 or higher.
|
|
10
37
|
def self.available?
|
|
11
|
-
|
|
38
|
+
# Memoise with defined? rather than ||=, so that a false result is cached
|
|
39
|
+
# too and we don't re-shell out on every single call.
|
|
40
|
+
return @available if defined?(@available)
|
|
41
|
+
|
|
42
|
+
@available = macos? && Gem::Version.new(version) >= Gem::Version.new(MINIMUM_MACOS_VERSION)
|
|
12
43
|
end
|
|
13
44
|
|
|
45
|
+
# The macOS product version, or nil when not running on macOS.
|
|
14
46
|
def self.version
|
|
15
|
-
@version
|
|
47
|
+
return @version if defined?(@version)
|
|
48
|
+
|
|
49
|
+
# Only shell out when we already know this is macOS. RbConfig reports the
|
|
50
|
+
# Darwin kernel version, which doesn't map cleanly onto product versions,
|
|
51
|
+
# so sw_vers is still needed for the number itself.
|
|
52
|
+
@version = macos? ? `sw_vers -productVersion`.strip : nil
|
|
16
53
|
end
|
|
17
54
|
|
|
18
|
-
def self.
|
|
19
|
-
if
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
55
|
+
def self.macos?
|
|
56
|
+
return @macos if defined?(@macos)
|
|
57
|
+
|
|
58
|
+
@macos = !(RbConfig::CONFIG['host_os'] =~ /darwin|mac os/).nil?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Builds the argument vector for the binary.
|
|
62
|
+
#
|
|
63
|
+
# A value of `true` becomes a bare flag and `false` omits the option entirely,
|
|
64
|
+
# so switches like :reply and :ignoreDnD don't end up with a stray "true" as
|
|
65
|
+
# their value (which -reply would show as its placeholder text).
|
|
66
|
+
def self.command_for(options)
|
|
67
|
+
arguments = options.flat_map do |key, value|
|
|
68
|
+
case value
|
|
69
|
+
when true then ["-#{key}"]
|
|
70
|
+
when false, nil then []
|
|
71
|
+
else ["-#{key}", escape_value(value.to_s)]
|
|
27
72
|
end
|
|
28
|
-
result
|
|
29
|
-
else
|
|
30
|
-
STDERR.print "terminal-notifier is only supported on macOS 10.10, or higher."
|
|
31
73
|
end
|
|
74
|
+
[BIN_PATH, *arguments]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Prepares a single option value for the binary.
|
|
78
|
+
#
|
|
79
|
+
# This is *not* shell escaping — IO.popen is handed an argv array, so no shell
|
|
80
|
+
# is ever involved. It is the escaping the tool's own README documents as
|
|
81
|
+
# ‘\[’: the binary reads its arguments through NSUserDefaults, which tries to
|
|
82
|
+
# parse each value as a property list, so a value beginning with '[', '(',
|
|
83
|
+
# '{', a quote, a space and so on comes back as nil and the notification is
|
|
84
|
+
# never sent. Prefixing a backslash makes NSUserDefaults treat it as a plain
|
|
85
|
+
# string, and the binary strips that backslash again (see
|
|
86
|
+
# objectForKeyedSubscript: in AppDelegate.m).
|
|
87
|
+
#
|
|
88
|
+
# Shellwords.escape is used purely as a convenient test of "would this
|
|
89
|
+
# character be taken as syntax", which is the same set that matters here.
|
|
90
|
+
def self.escape_value(value)
|
|
91
|
+
return value if value.empty?
|
|
92
|
+
|
|
93
|
+
# A value starting with '-' would be read as the next flag; the binary
|
|
94
|
+
# strips this leading space back off.
|
|
95
|
+
prefix = value.start_with?('-') ? ' ' : ''
|
|
96
|
+
"#{prefix}#{Shellwords.escape(value[0, 1])}#{value[1..]}"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Runs the binary and returns its standard output.
|
|
100
|
+
#
|
|
101
|
+
# Raises UnsupportedPlatformError when not on a supported macOS, and
|
|
102
|
+
# BinaryNotFoundError when the vendored binary is missing.
|
|
103
|
+
def self.execute(verbose, options)
|
|
104
|
+
ensure_usable!
|
|
105
|
+
|
|
106
|
+
output = IO.popen(command_for(options), &:read)
|
|
107
|
+
# Remember the status so callers aren't exposed to races on the global $?.
|
|
108
|
+
Thread.current[:terminal_notifier_last_status] = $?
|
|
109
|
+
$stdout.print output if verbose
|
|
110
|
+
output
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Raises unless this platform and installation can actually run the binary.
|
|
114
|
+
def self.ensure_usable!
|
|
115
|
+
unless available?
|
|
116
|
+
raise UnsupportedPlatformError,
|
|
117
|
+
"terminal-notifier is only supported on macOS #{MINIMUM_MACOS_VERSION} or higher."
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
return if File.executable?(BIN_PATH)
|
|
121
|
+
|
|
122
|
+
raise BinaryNotFoundError,
|
|
123
|
+
"terminal-notifier binary not found at #{BIN_PATH}. " \
|
|
124
|
+
'Set TERMINAL_NOTIFIER_BIN to point at it.'
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# The exit status of the most recent execute call on this thread.
|
|
128
|
+
def self.last_status
|
|
129
|
+
Thread.current[:terminal_notifier_last_status]
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def self.succeeded?
|
|
133
|
+
status = last_status
|
|
134
|
+
!status.nil? && status.success?
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# True when the binary ran and reported an outcome, including a timeout.
|
|
138
|
+
def self.reported?
|
|
139
|
+
status = last_status
|
|
140
|
+
return false if status.nil?
|
|
141
|
+
|
|
142
|
+
status.success? || status.exitstatus == TIMEOUT_EXIT_CODE
|
|
32
143
|
end
|
|
33
144
|
|
|
34
145
|
# Cleans up the result of a notification, making it easier to work it
|
|
@@ -54,18 +165,26 @@ module TerminalNotifier
|
|
|
54
165
|
# notify_result('@timeout', {'reply' => true}) #=> '@timeout'
|
|
55
166
|
# notify_result('I may like pie', {}) #=> :i_may_like_pie
|
|
56
167
|
def notify_result(result, options, always_string = false)
|
|
168
|
+
# The binary terminates its response with a newline. Left on, a reply comes
|
|
169
|
+
# back as "text\n" and an action title symbolises to :title_ because the
|
|
170
|
+
# newline is a non-word character.
|
|
171
|
+
result = result.to_s.chomp
|
|
172
|
+
|
|
57
173
|
if options[:reply] || options['reply'] || always_string
|
|
58
174
|
result
|
|
59
175
|
else
|
|
60
|
-
result
|
|
176
|
+
# NOTE: an empty result yields `true`, not a symbol, because the `||`
|
|
177
|
+
# short-circuits. Odd, but it is the long-standing public contract.
|
|
178
|
+
result.empty? || result.downcase.gsub(/\W+/, '_').to_sym
|
|
61
179
|
end
|
|
62
180
|
end
|
|
63
181
|
module_function :notify_result
|
|
64
182
|
|
|
65
183
|
# Sends a User Notification and returns whether or not it was a success.
|
|
66
184
|
#
|
|
67
|
-
# The available options are `:title`, `:
|
|
68
|
-
# `:execute`, `:
|
|
185
|
+
# The available options are `:title`, `:subtitle`, `:group`, `:activate`,
|
|
186
|
+
# `:open`, `:execute`, `:contentImage`, and `:sound`. For a description of
|
|
187
|
+
# each option see:
|
|
69
188
|
#
|
|
70
189
|
# https://github.com/julienXX/terminal-notifier/blob/master/README.markdown
|
|
71
190
|
#
|
|
@@ -77,13 +196,14 @@ module TerminalNotifier
|
|
|
77
196
|
# TerminalNotifier.notify('Hello World', :activate => 'com.apple.Safari')
|
|
78
197
|
# TerminalNotifier.notify('Hello World', :open => 'http://twitter.com/julienXX')
|
|
79
198
|
# TerminalNotifier.notify('Hello World', :execute => 'say "OMG"')
|
|
80
|
-
# TerminalNotifier.notify('Hello World', :sender => 'com.apple.Safari')
|
|
81
199
|
# TerminalNotifier.notify('Hello World', :sound => 'default')
|
|
82
200
|
#
|
|
83
|
-
# Raises if not supported on the current platform.
|
|
201
|
+
# Raises UnsupportedPlatformError if not supported on the current platform.
|
|
84
202
|
def notify(message, options = {}, verbose = false, always_string = false)
|
|
85
|
-
result = TerminalNotifier.execute(verbose, options.merge(:
|
|
86
|
-
|
|
203
|
+
result = TerminalNotifier.execute(verbose, options.merge(message: message))
|
|
204
|
+
# A timeout counts as a reported outcome: without this it would come back as
|
|
205
|
+
# a bare false, indistinguishable from the notification failing to send.
|
|
206
|
+
TerminalNotifier.reported? && notify_result(result, options, always_string)
|
|
87
207
|
end
|
|
88
208
|
module_function :notify
|
|
89
209
|
|
|
@@ -91,13 +211,15 @@ module TerminalNotifier
|
|
|
91
211
|
# ‘group’ ID, if one exists.
|
|
92
212
|
#
|
|
93
213
|
# If no ‘group’ ID is given, all notifications are removed.
|
|
214
|
+
# rubocop:disable Naming/PredicateMethod -- `remove` is the public API name
|
|
94
215
|
def remove(group = 'ALL', verbose = false)
|
|
95
|
-
TerminalNotifier.execute(verbose, :
|
|
96
|
-
|
|
216
|
+
TerminalNotifier.execute(verbose, remove: group)
|
|
217
|
+
TerminalNotifier.succeeded?
|
|
97
218
|
end
|
|
219
|
+
# rubocop:enable Naming/PredicateMethod
|
|
98
220
|
module_function :remove
|
|
99
221
|
|
|
100
|
-
LIST_FIELDS = [
|
|
222
|
+
LIST_FIELDS = %i[group title subtitle message delivered_at].freeze
|
|
101
223
|
|
|
102
224
|
# If a ‘group’ ID is given, and a notification for that group exists,
|
|
103
225
|
# returns a hash with details about the notification.
|
|
@@ -107,18 +229,32 @@ module TerminalNotifier
|
|
|
107
229
|
#
|
|
108
230
|
# If no information is available this will return `nil`.
|
|
109
231
|
def list(group = 'ALL', verbose = false)
|
|
110
|
-
output = TerminalNotifier.execute(verbose, :
|
|
111
|
-
return if output.strip.empty?
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
notifications = output.split("\n")[1
|
|
115
|
-
LIST_FIELDS.zip(line.split("\t")).inject({}) do |hash, (key, value)|
|
|
116
|
-
hash[key] = key == :delivered_at ? Time.parse(value) : (value unless value == '(null)')
|
|
117
|
-
hash
|
|
118
|
-
end
|
|
119
|
-
end
|
|
232
|
+
output = TerminalNotifier.execute(verbose, list: group)
|
|
233
|
+
return if output.nil? || output.strip.empty?
|
|
234
|
+
|
|
235
|
+
# Drop the header row.
|
|
236
|
+
notifications = output.split("\n")[1..].to_a.map { |line| TerminalNotifier.parse_list_row(line) }
|
|
120
237
|
|
|
121
238
|
group == 'ALL' ? notifications : notifications.first
|
|
122
239
|
end
|
|
123
240
|
module_function :list
|
|
241
|
+
|
|
242
|
+
# Turns one tab-separated -list row into a hash.
|
|
243
|
+
def self.parse_list_row(line)
|
|
244
|
+
LIST_FIELDS.zip(line.split("\t")).each_with_object({}) do |(key, value), hash|
|
|
245
|
+
hash[key] = key == :delivered_at ? parse_time(value) : presence(value)
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def self.parse_time(value)
|
|
250
|
+
Time.parse(value.to_s)
|
|
251
|
+
rescue ArgumentError, TypeError
|
|
252
|
+
nil
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# 3.0.0 emits an empty field for an absent value; earlier binaries emitted the
|
|
256
|
+
# literal string "(null)".
|
|
257
|
+
def self.presence(value)
|
|
258
|
+
value unless value.nil? || value.empty? || value == '(null)'
|
|
259
|
+
end
|
|
124
260
|
end
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
3
|
<plist version="1.0">
|
|
4
4
|
<dict>
|
|
5
|
-
<key>BuildMachineOSBuild</key>
|
|
6
|
-
<string>17A405</string>
|
|
7
5
|
<key>CFBundleDevelopmentRegion</key>
|
|
8
6
|
<string>en</string>
|
|
9
7
|
<key>CFBundleExecutable</key>
|
|
@@ -19,45 +17,18 @@
|
|
|
19
17
|
<key>CFBundlePackageType</key>
|
|
20
18
|
<string>APPL</string>
|
|
21
19
|
<key>CFBundleShortVersionString</key>
|
|
22
|
-
<string>
|
|
20
|
+
<string>3.0.0</string>
|
|
23
21
|
<key>CFBundleSignature</key>
|
|
24
22
|
<string>????</string>
|
|
25
|
-
<key>CFBundleSupportedPlatforms</key>
|
|
26
|
-
<array>
|
|
27
|
-
<string>MacOSX</string>
|
|
28
|
-
</array>
|
|
29
23
|
<key>CFBundleVersion</key>
|
|
30
|
-
<string>
|
|
31
|
-
<key>DTCompiler</key>
|
|
32
|
-
<string>com.apple.compilers.llvm.clang.1_0</string>
|
|
33
|
-
<key>DTPlatformBuild</key>
|
|
34
|
-
<string>9A1004</string>
|
|
35
|
-
<key>DTPlatformVersion</key>
|
|
36
|
-
<string>GM</string>
|
|
37
|
-
<key>DTSDKBuild</key>
|
|
38
|
-
<string>17A360</string>
|
|
39
|
-
<key>DTSDKName</key>
|
|
40
|
-
<string>macosx10.13</string>
|
|
41
|
-
<key>DTXcode</key>
|
|
42
|
-
<string>0901</string>
|
|
43
|
-
<key>DTXcodeBuild</key>
|
|
44
|
-
<string>9A1004</string>
|
|
24
|
+
<string>16</string>
|
|
45
25
|
<key>LSMinimumSystemVersion</key>
|
|
46
|
-
<string>10.
|
|
26
|
+
<string>10.14</string>
|
|
47
27
|
<key>LSUIElement</key>
|
|
48
28
|
<true/>
|
|
49
|
-
<key>NSAppTransportSecurity</key>
|
|
50
|
-
<dict>
|
|
51
|
-
<key>NSAllowsArbitraryLoads</key>
|
|
52
|
-
<true/>
|
|
53
|
-
</dict>
|
|
54
29
|
<key>NSHumanReadableCopyright</key>
|
|
55
30
|
<string>Copyright © 2012-2017 Eloy Durán, Julien Blanchard. All rights reserved.</string>
|
|
56
|
-
<key>NSMainNibFile</key>
|
|
57
|
-
<string>MainMenu</string>
|
|
58
31
|
<key>NSPrincipalClass</key>
|
|
59
32
|
<string>NSApplication</string>
|
|
60
|
-
<key>NSUserNotificationAlertStyle</key>
|
|
61
|
-
<string>banner</string>
|
|
62
33
|
</dict>
|
|
63
34
|
</plist>
|
|
Binary file
|
data/vendor/terminal-notifier/terminal-notifier.app/Contents/Resources/en.lproj/InfoPlist.strings
CHANGED
|
Binary file
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>files</key>
|
|
6
|
+
<dict>
|
|
7
|
+
<key>Resources/Terminal.icns</key>
|
|
8
|
+
<data>
|
|
9
|
+
Oq9GtJM1DqcGF1JCHiEgb0hoN6I=
|
|
10
|
+
</data>
|
|
11
|
+
<key>Resources/en.lproj/InfoPlist.strings</key>
|
|
12
|
+
<dict>
|
|
13
|
+
<key>hash</key>
|
|
14
|
+
<data>
|
|
15
|
+
j6qg+qbNaStgLrdDQMdUxznV6qM=
|
|
16
|
+
</data>
|
|
17
|
+
<key>optional</key>
|
|
18
|
+
<true/>
|
|
19
|
+
</dict>
|
|
20
|
+
</dict>
|
|
21
|
+
<key>files2</key>
|
|
22
|
+
<dict>
|
|
23
|
+
<key>Resources/Terminal.icns</key>
|
|
24
|
+
<dict>
|
|
25
|
+
<key>hash2</key>
|
|
26
|
+
<data>
|
|
27
|
+
zPwPRX277SsWSp9wjhoAAPrY+Jaw1TMrN24rdI8/9SU=
|
|
28
|
+
</data>
|
|
29
|
+
</dict>
|
|
30
|
+
<key>Resources/en.lproj/InfoPlist.strings</key>
|
|
31
|
+
<dict>
|
|
32
|
+
<key>hash2</key>
|
|
33
|
+
<data>
|
|
34
|
+
/rXoINaO0x+HHSva+NFJNe00OnqHXd13TVVW2o39lRo=
|
|
35
|
+
</data>
|
|
36
|
+
<key>optional</key>
|
|
37
|
+
<true/>
|
|
38
|
+
</dict>
|
|
39
|
+
</dict>
|
|
40
|
+
<key>rules</key>
|
|
41
|
+
<dict>
|
|
42
|
+
<key>^Resources/</key>
|
|
43
|
+
<true/>
|
|
44
|
+
<key>^Resources/.*\.lproj/</key>
|
|
45
|
+
<dict>
|
|
46
|
+
<key>optional</key>
|
|
47
|
+
<true/>
|
|
48
|
+
<key>weight</key>
|
|
49
|
+
<real>1000</real>
|
|
50
|
+
</dict>
|
|
51
|
+
<key>^Resources/.*\.lproj/locversion.plist$</key>
|
|
52
|
+
<dict>
|
|
53
|
+
<key>omit</key>
|
|
54
|
+
<true/>
|
|
55
|
+
<key>weight</key>
|
|
56
|
+
<real>1100</real>
|
|
57
|
+
</dict>
|
|
58
|
+
<key>^Resources/Base\.lproj/</key>
|
|
59
|
+
<dict>
|
|
60
|
+
<key>weight</key>
|
|
61
|
+
<real>1010</real>
|
|
62
|
+
</dict>
|
|
63
|
+
<key>^version.plist$</key>
|
|
64
|
+
<true/>
|
|
65
|
+
</dict>
|
|
66
|
+
<key>rules2</key>
|
|
67
|
+
<dict>
|
|
68
|
+
<key>.*\.dSYM($|/)</key>
|
|
69
|
+
<dict>
|
|
70
|
+
<key>weight</key>
|
|
71
|
+
<real>11</real>
|
|
72
|
+
</dict>
|
|
73
|
+
<key>^(.*/)?\.DS_Store$</key>
|
|
74
|
+
<dict>
|
|
75
|
+
<key>omit</key>
|
|
76
|
+
<true/>
|
|
77
|
+
<key>weight</key>
|
|
78
|
+
<real>2000</real>
|
|
79
|
+
</dict>
|
|
80
|
+
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
|
|
81
|
+
<dict>
|
|
82
|
+
<key>nested</key>
|
|
83
|
+
<true/>
|
|
84
|
+
<key>weight</key>
|
|
85
|
+
<real>10</real>
|
|
86
|
+
</dict>
|
|
87
|
+
<key>^.*</key>
|
|
88
|
+
<true/>
|
|
89
|
+
<key>^Info\.plist$</key>
|
|
90
|
+
<dict>
|
|
91
|
+
<key>omit</key>
|
|
92
|
+
<true/>
|
|
93
|
+
<key>weight</key>
|
|
94
|
+
<real>20</real>
|
|
95
|
+
</dict>
|
|
96
|
+
<key>^PkgInfo$</key>
|
|
97
|
+
<dict>
|
|
98
|
+
<key>omit</key>
|
|
99
|
+
<true/>
|
|
100
|
+
<key>weight</key>
|
|
101
|
+
<real>20</real>
|
|
102
|
+
</dict>
|
|
103
|
+
<key>^Resources/</key>
|
|
104
|
+
<dict>
|
|
105
|
+
<key>weight</key>
|
|
106
|
+
<real>20</real>
|
|
107
|
+
</dict>
|
|
108
|
+
<key>^Resources/.*\.lproj/</key>
|
|
109
|
+
<dict>
|
|
110
|
+
<key>optional</key>
|
|
111
|
+
<true/>
|
|
112
|
+
<key>weight</key>
|
|
113
|
+
<real>1000</real>
|
|
114
|
+
</dict>
|
|
115
|
+
<key>^Resources/.*\.lproj/locversion.plist$</key>
|
|
116
|
+
<dict>
|
|
117
|
+
<key>omit</key>
|
|
118
|
+
<true/>
|
|
119
|
+
<key>weight</key>
|
|
120
|
+
<real>1100</real>
|
|
121
|
+
</dict>
|
|
122
|
+
<key>^Resources/Base\.lproj/</key>
|
|
123
|
+
<dict>
|
|
124
|
+
<key>weight</key>
|
|
125
|
+
<real>1010</real>
|
|
126
|
+
</dict>
|
|
127
|
+
<key>^[^/]+$</key>
|
|
128
|
+
<dict>
|
|
129
|
+
<key>nested</key>
|
|
130
|
+
<true/>
|
|
131
|
+
<key>weight</key>
|
|
132
|
+
<real>10</real>
|
|
133
|
+
</dict>
|
|
134
|
+
<key>^embedded\.provisionprofile$</key>
|
|
135
|
+
<dict>
|
|
136
|
+
<key>weight</key>
|
|
137
|
+
<real>20</real>
|
|
138
|
+
</dict>
|
|
139
|
+
<key>^version\.plist$</key>
|
|
140
|
+
<dict>
|
|
141
|
+
<key>weight</key>
|
|
142
|
+
<real>20</real>
|
|
143
|
+
</dict>
|
|
144
|
+
</dict>
|
|
145
|
+
</dict>
|
|
146
|
+
</plist>
|