Class: Mailmate::AppleScriptDriver
- Inherits:
-
Object
- Object
- Mailmate::AppleScriptDriver
- Defined in:
- lib/mailmate/applescript_driver.rb
Overview
Build and run AppleScript calls against MailMate. macOS-only.
A class (not a module like the stateless utilities ‘HeaderReader`, `MidUrl`, `Identity`, etc.) because each driver carries per-invocation state — `dry_run`, `output`, `errput`. The rule throughout the gem: stateless surface → module with `extend self`; state-bearing → class.
Defined Under Namespace
Classes: Error
Instance Attribute Summary collapse
- #dry_run ⇒ Object readonly
Instance Method Summary collapse
-
#applescript_escape(s, allow_controls: false) ⇒ Object
Escape a Ruby string for inclusion inside an AppleScript double-quoted string literal.
-
#build_perform_script(selector, args) ⇒ Object
Internal — build the ‘tell application “MailMate” to perform { … }` script with proper quoting.
-
#close_windows(ids) ⇒ Object
Close every window in ‘ids`.
-
#initialize(dry_run: false, output: $stdout, errput: $stderr) ⇒ AppleScriptDriver
constructor
A new instance of AppleScriptDriver.
-
#open_url(url) ⇒ Object
Open a URL in MailMate (used for ‘mid:` URLs to select a message).
-
#perform(selector, *args) ⇒ Object
Drive a MailMate selector against the current selection.
-
#window_ids ⇒ Object
Return the array of MailMate’s current window IDs (integers).
Constructor Details
#initialize(dry_run: false, output: $stdout, errput: $stderr) ⇒ AppleScriptDriver
Returns a new instance of AppleScriptDriver.
19 20 21 22 23 |
# File 'lib/mailmate/applescript_driver.rb', line 19 def initialize(dry_run: false, output: $stdout, errput: $stderr) @dry_run = dry_run @output = output @errput = errput end |
Instance Attribute Details
#dry_run ⇒ Object (readonly)
17 18 19 |
# File 'lib/mailmate/applescript_driver.rb', line 17 def dry_run @dry_run end |
Instance Method Details
#applescript_escape(s, allow_controls: false) ⇒ Object
Escape a Ruby string for inclusion inside an AppleScript double-quoted string literal. Order matters: backslash first, then quote. Newlines/ tabs are rejected unless ‘allow_controls: true`.
83 84 85 86 87 88 |
# File 'lib/mailmate/applescript_driver.rb', line 83 def applescript_escape(s, allow_controls: false) if !allow_controls && s.match?(/[\r\n\t]/) raise Error, "AppleScript arg contains control character (\\r/\\n/\\t): #{s.inspect}" end s.gsub("\\", "\\\\\\\\").gsub('"', '\\"') end |
#build_perform_script(selector, args) ⇒ Object
Internal — build the ‘tell application “MailMate” to perform { … }` script with proper quoting. AppleScript string literals require:
\ → \\ (single backslash becomes \\, otherwise it interprets
\b / \n / \t / etc. as control-character escapes)
" → \" (terminates the string otherwise)
Newlines and tabs in args are rejected — they have no defensible meaning inside an AppleScript single-line script and almost certainly indicate data the caller doesn’t want injected.
70 71 72 73 74 75 76 77 78 |
# File 'lib/mailmate/applescript_driver.rb', line 70 def build_perform_script(selector, args) escaped_selector = applescript_escape(selector.to_s, allow_controls: false) if args.empty? %(tell application "MailMate" to perform {"#{escaped_selector}"}) else list = args.map { |a| %("#{applescript_escape(a.to_s)}") }.join(", ") %(tell application "MailMate" to perform {"#{escaped_selector}", #{list}}) end end |
#close_windows(ids) ⇒ Object
Close every window in ‘ids`. No-op for IDs that no longer exist.
55 56 57 58 59 60 |
# File 'lib/mailmate/applescript_driver.rb', line 55 def close_windows(ids) return if dry_run Array(ids).each do |id| `osascript -e 'tell application "MailMate" to close window id #{id}' >/dev/null 2>&1` end end |
#open_url(url) ⇒ Object
Open a URL in MailMate (used for ‘mid:` URLs to select a message).
35 36 37 38 39 40 41 42 43 |
# File 'lib/mailmate/applescript_driver.rb', line 35 def open_url(url) Mailmate::PlatformError.check_darwin!(component: "AppleScriptDriver") unless dry_run if dry_run @output.puts "DRY: open -a MailMate #{url.inspect}" return end success = system("open", "-a", "MailMate", url) raise Error, "open command failed for #{url}" unless success end |
#perform(selector, *args) ⇒ Object
Drive a MailMate selector against the current selection. ‘selector` is the key-binding selector name (`“markAsRead:”`, `“setTag:”`, etc.). `args` are positional arguments passed alongside.
28 29 30 31 32 |
# File 'lib/mailmate/applescript_driver.rb', line 28 def perform(selector, *args) Mailmate::PlatformError.check_darwin!(component: "AppleScriptDriver") unless dry_run script = build_perform_script(selector, args) run_apple_script(script) end |
#window_ids ⇒ Object
Return the array of MailMate’s current window IDs (integers). Empty array if MailMate isn’t running or ‘osascript` errors.
47 48 49 50 51 52 |
# File 'lib/mailmate/applescript_driver.rb', line 47 def window_ids return [] if dry_run out = `osascript -e 'tell application "MailMate" to get id of every window' 2>&1` return [] unless $?.success? out.strip.split(",").map { |s| s.strip.to_i } end |