class MacWifi::CommandLineInterface

Constants

HELP_TEXT

Help text to be used when requested by 'h' command, in case of unrecognized or nonexistent command, etc.

OPEN_RESOURCES

Attributes

interactive_mode[R]
model[R]
open_resources[R]
options[R]

Public Class Methods

new(options) click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 89
def initialize(options)
  @options = options
  @model = MacOsModel.new(verbose_mode)
  @interactive_mode = !!(options.interactive_mode)
  run_shell if @interactive_mode
end

Public Instance Methods

awesome_print_available?() click to toggle source

@return true if awesome_print is available (after requiring it), else false after requiring 'pp'. We'd like to use awesome_print if it is available, but not require it. So, we try to require it, but if that fails, we fall back to using pp (pretty print), which is included in Ruby distributions without the need to install a gem.

# File lib/mac-wifi/command_line_interface.rb, line 113
def awesome_print_available?
  if @awesome_print_available.nil?  # first time here
    begin
      require 'awesome_print'
      @awesome_print_available = true
    rescue LoadError
      require 'pp'
      @awesome_print_available = false
    end
  end

  @awesome_print_available
end
call() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 449
def call
  validate_command_line
  begin
    process_command_line(ARGV[0], ARGV[1..-1])
  rescue BadCommandError => error
    separator_line = "! #{'-' * 75} !\n"
    puts '' << separator_line << error.to_s << "\n" << separator_line
    exit(-1)
  end
end
cmd_a() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 226
def cmd_a
  info = model.available_network_names
  if interactive_mode
    info
  else
    if post_processor
      puts post_processor.(info)
    else
      puts model.wifi_on? \
          ? "Available networks are:\n\n#{fancy_string(info)}" \
          : "Wifi is off, cannot see available networks."
    end
  end
end
cmd_ci() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 242
def cmd_ci
  connected = model.connected_to_internet?
  if interactive_mode
    connected
  else
    puts (post_processor ? post_processor.(connected) : "Connected to Internet: #{connected}")
  end
end
cmd_co(network, password = nil) click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 252
def cmd_co(network, password = nil)
  model.connect(network, password)
end
cmd_cy() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 257
def cmd_cy
  model.cycle_network
end
cmd_d() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 262
def cmd_d
  model.disconnect
end
cmd_h() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 267
def cmd_h
  print_help
end
cmd_i() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 272
def cmd_i
  info = model.wifi_info
  if interactive_mode
    info
  else
    if post_processor
      puts post_processor.(info)
    else
      puts fancy_string(info)
    end
  end
end
cmd_lsa() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 286
def cmd_lsa
  info = model.available_network_info
  if interactive_mode
    info
  else
    if post_processor
      puts post_processor.(info)
    else
      message = model.wifi_on? ? fancy_string(info) : "Wifi is off, cannot see available networks."
      puts(message)
    end
  end
end
cmd_n() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 301
def cmd_n
  name = model.current_network
  if interactive_mode
    name
  else
    display_name = name ? name : '[none]'
    puts (post_processor ? post_processor.(name) : %Q{Network (SSID) name: "#{display_name}"})
  end
end
cmd_of() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 312
def cmd_of
  model.wifi_off
end
cmd_on() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 317
def cmd_on
  model.wifi_on
end
cmd_pa(network) click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 332
def cmd_pa(network)
  password = model.preferred_network_password(network)

  if interactive_mode
    password
  else
    if post_processor
      puts post_processor.(password)
    else
      output =  %Q{Preferred network "#{model.connected_network_name}" }
      output << (password ? %Q{stored password is "#{password}".} : "has no stored password.")
      puts output
    end
  end
end
cmd_pr() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 349
def cmd_pr
  networks = model.preferred_networks
  if interactive_mode
    networks
  else
    puts (post_processor ? post_processor.(networks) : fancy_string(networks))
  end
end
cmd_pu() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 359
def cmd_pu
  `open https://www.whatismyip.com/`
end
cmd_q() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 364
def cmd_q
  quit
end
cmd_r(*options) click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 369
def cmd_r(*options)
  removed_networks = model.remove_preferred_networks(*options)
  if interactive_mode
    removed_networks
  else
    puts (post_processor ? post_processor.(removed_networks) : "Removed networks: #{removed_networks.inspect}")
  end
end
cmd_ro(*resource_codes) click to toggle source

Use Mac OS 'open' command line utility

# File lib/mac-wifi/command_line_interface.rb, line 323
def cmd_ro(*resource_codes)
  resource_codes.each do |code|
    resource = OPEN_RESOURCES.find_by_code(code)
    if resource
      model.run_os_command("open #{resource.resource}")
    end
  end
end
cmd_t(*options) click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 379
def cmd_t(*options)
  target_status = options[0].to_sym
  wait_interval_in_secs = (options[1] ? Float(options[1]) : nil)
  model.till(target_status, wait_interval_in_secs)
end
cmd_w() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 386
def cmd_w
  on = model.wifi_on?
  if interactive_mode
    on
  else
    puts (post_processor ? post_processor.(on) : "Wifi on: #{on}")
  end
end
cmd_x() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 396
def cmd_x
  quit
end
commands() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 401
def commands
  @commands_ ||= [
      Command.new('a',   'avail_nets',    -> (*_options) { cmd_a             }),
      Command.new('ci',  'ci',            -> (*_options) { cmd_ci            }),
      Command.new('co',  'connect',       -> (*options)  { cmd_co(*options)  }),
      Command.new('cy',  'cycle',         -> (*_options) { cmd_cy            }),
      Command.new('d',   'disconnect',    -> (*_options) { cmd_d             }),
      Command.new('h',   'help',          -> (*_options) { cmd_h             }),
      Command.new('i',   'info',          -> (*_options) { cmd_i             }),
      Command.new('l',   'ls_avail_nets', -> (*_options) { cmd_lsa           }),
      Command.new('n',   'network_name',  -> (*_options) { cmd_n             }),
      Command.new('of',  'off',           -> (*_options) { cmd_of            }),
      Command.new('on',  'on',            -> (*_options) { cmd_on            }),
      Command.new('ro',  'ropen',         -> (*options)  { cmd_ro(*options)  }),
      Command.new('pa',  'password',      -> (*options)  { cmd_pa(*options)  }),
      Command.new('pr',  'pref_nets',     -> (*_options) { cmd_pr            }),
      Command.new('q',   'quit',          -> (*_options) { cmd_q             }),
      Command.new('r',   'rm_pref_nets',  -> (*options)  { cmd_r(*options)   }),
      Command.new('t',   'till',          -> (*options)  { cmd_t(*options)   }),
      Command.new('w',   'wifion',        -> (*_options) { cmd_w             }),
      Command.new('x',   'xit',           -> (*_options) { cmd_x             })
  ]
end
fancy_puts(object) click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 133
def fancy_puts(object)
  puts fancy_string(object)
end
Also aliased as: fp
fancy_string(object) click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 128
def fancy_string(object)
  awesome_print_available? ? object.ai : object.pretty_inspect
end
find_command_action(command_string) click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 426
def find_command_action(command_string)
  result = commands.detect do |cmd|
    cmd.max_string.start_with?(command_string) \
    && \
    command_string.length >= cmd.min_string.length  # e.g. 'c' by itself should not work
  end

  result ? result.action : nil
end
fp(object)
Alias for: fancy_puts
method_missing(method_name, *options) click to toggle source

For use by the shell; when typing a command and options, it is passed to process_command_line

# File lib/mac-wifi/command_line_interface.rb, line 188
def method_missing(method_name, *options)
  method_name = method_name.to_s
  method_exists = !! find_command_action(method_name)
  if method_exists
    process_command_line(method_name, options)
  else
    puts(%Q{"#{method_name}" is not a valid command or option. If you intend for this to be a string literal, use quotes or %q/Q{}.})
  end
end
post_process(object) click to toggle source

If a post-processor has been configured (e.g. YAML or JSON), use it.

# File lib/mac-wifi/command_line_interface.rb, line 438
def post_process(object)
  post_processor ? post_processor.(object) : object
end
post_processor() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 444
def post_processor
  options.post_processor
end
print_help() click to toggle source
process_command_line(command, options) click to toggle source

Processes the command (ARGV) and any relevant options (ARGV).

CAUTION! In interactive mode, any strings entered (e.g. a network name) MUST be in a form that the Ruby interpreter will recognize as a string, i.e. single or double quotes, %q, %Q, etc. Otherwise it will assume it's a method name and pass it to method_missing!

# File lib/mac-wifi/command_line_interface.rb, line 205
def process_command_line(command, options)
  action = find_command_action(command)
  if action
    action.(*options)
  else
    print_help
    raise BadCommandError.new(
        %Q{Unrecognized command. Command was "#{command}" and options were #{options.inspect}.})
  end
end
quit() click to toggle source
# File lib/mac-wifi/command_line_interface.rb, line 217
def quit
  if interactive_mode
    exit(0)
  else
    puts "This command can only be run in shell mode."
  end
end
run_pry() click to toggle source

Pry will output the content of the method from which it was called. This small method exists solely to reduce the amount of pry's output that is not needed here.

# File lib/mac-wifi/command_line_interface.rb, line 152
def run_pry
  binding.pry

  # the seemingly useless line below is needed to avoid pry's exiting
  # (see https://github.com/deivid-rodriguez/pry-byebug/issues/45)
  _a = nil
end
run_shell() click to toggle source

Runs a pry session in the context of this object. Commands and options specified on the command line can also be specified in the shell.

# File lib/mac-wifi/command_line_interface.rb, line 163
def run_shell
  begin
    require 'pry'
  rescue LoadError
    puts "The 'pry' gem and/or one of its prerequisites, required for running the shell, was not found." +
             " Please `gem install pry` or, if necessary, `sudo gem install pry`."
    exit(-1)
  end

  print_help

  # Enable the line below if you have any problems with pry configuration being loaded
  # that is messing up this runtime use of pry:
  # Pry.config.should_load_rc = false

  # Strangely, this is the only thing I have found that successfully suppresses the
  # code context output, which is not useful here. Anyway, this will differentiate
  # a pry command from a DSL command, which _is_ useful here.
  Pry.config.command_prefix = '%'

  run_pry
end
validate_command_line() click to toggle source

Asserts that a command has been passed on the command line.

# File lib/mac-wifi/command_line_interface.rb, line 140
def validate_command_line
  if ARGV.empty?
    puts "Syntax is: #{__FILE__} [options] command [command_options]"
    print_help
    exit(-1)
  end
end
verbose_mode() click to toggle source

Until command line option parsing is added, the only way to specify verbose mode is in the environment variable MAC_WIFI_OPTS.

# File lib/mac-wifi/command_line_interface.rb, line 99
def verbose_mode
  options.verbose
end