class A4Tools::NetShell

Attributes

env[RW]
processing[RW]
shared[RW]

Public Class Methods

new() click to toggle source
# File lib/net_shell/net_shell.rb, line 14
def initialize
  @history = []
  @env = {}
  @shared = { traffic:[] }
  $config = @env
  $localtalk = File.join(config_dir, "talk.json")

  set_env(:color, "1")
  set_env(:show_async, "1")
  set_env(:serial, stored_serial)

  read_env
  setup_builtins
  setup_support
end

Public Instance Methods

active_client() click to toggle source
# File lib/net_shell/net_shell.rb, line 196
def active_client
  @shared[:client]
end
active_client_name() click to toggle source
# File lib/net_shell/net_shell.rb, line 200
def active_client_name
  @clients.each { |key, client| return key if client == @shared[:client] }
  nil
end
add_to_alert_queue(msg) click to toggle source
# File lib/net_shell/net_shell.rb, line 308
def add_to_alert_queue(msg)
  @alert_queue ||= []
  @alert_queue.push(msg)
end
alert(msg) click to toggle source
# File lib/net_shell/net_shell.rb, line 319
def alert(msg)
  if @processing and not @allow_alerts
    add_to_alert_queue(msg)
    return
  end

  @prompt.clear_line
  @prompt.refresh_prompt
  puts "\r#{msg}"
  @prompt.redraw_line if @alert_queue.nil? and not @processing
end
allow_alerts(allow=true) click to toggle source

Built-in commands

# File lib/net_shell/net_shell.rb, line 60
def allow_alerts(allow=true)
  @allow_alerts = true
end
bad_command(args) click to toggle source

Command prompt

# File lib/net_shell/net_shell.rb, line 209
def bad_command(args)
  "Unrecognized command: #{args[0]}"
end
built_in(name) click to toggle source
# File lib/net_shell/net_shell.rb, line 86
def built_in(name)
  @built_ins[name.to_sym]
end
built_ins(full=false) click to toggle source
# File lib/net_shell/net_shell.rb, line 90
def built_ins(full=false)
  full ? @built_ins.values : @built_ins.keys
end
clean_args(args) click to toggle source
# File lib/net_shell/net_shell.rb, line 256
def clean_args(args)
  index = args.find_index { |arg| is_redirect? arg }
  return args if index.nil?
  args[0 .. index-1]
end
client(key) click to toggle source
# File lib/net_shell/net_shell.rb, line 181
def client(key)
  @clients[key.to_sym]
end
clients() click to toggle source
# File lib/net_shell/net_shell.rb, line 177
def clients
  @clients.keys
end
command_for_line(cmdline, allow_trailing_space=false) click to toggle source
# File lib/net_shell/net_shell.rb, line 288
def command_for_line(cmdline, allow_trailing_space=false)
  cmdline ||= ""
  args = transform_args(split_args(cmdline))
  args.push "" if allow_trailing_space and cmdline.match(/\s+$/)
  Command.new(clean_args(args), get_input(args), get_output(args), get_error(args), self)
end
config_dir() click to toggle source
# File lib/net_shell/net_shell.rb, line 44
def config_dir
  path = File.expand_path("~/.netshell")
  Dir.mkdir(path) unless File.directory? path
  path
end
enter() click to toggle source
# File lib/net_shell/net_shell.rb, line 339
def enter
  @prompt = Prompt.new(:history_file => File.join(config_dir, "history"))
  @prompt.tab = lambda do |cmdline|
    setup_builtins
    command_for_line(cmdline.split("|").last, true).tab_complete
  end
  @prompt.prompt = lambda { prompt_text }
  @processing = false

  while(true) do
    line = @prompt.read_line
    setup_builtins
    @processing = true
    @allow_alerts = false
    exec(line)
    @processing = false
    flush_alert_queue
  end
end
env_is_true?(key) click to toggle source
# File lib/net_shell/net_shell.rb, line 148
def env_is_true?(key)
  value = get_env(key)
  value != nil and value != "0"
end
exec(cmdline) click to toggle source
# File lib/net_shell/net_shell.rb, line 295
def exec(cmdline)
  return if cmdline.match(/^\s+$/)
  commands = cmdline.split("|").map { |subcommand| command_for_line(subcommand) }

  last_cmd = nil
  commands.each do |cmd|
    cmd.input = last_cmd.output unless last_cmd.nil?
    cmd.output = PipeBuffer.new unless cmd == commands.last
    break if cmd.run != 0
    last_cmd = cmd
  end
end
flush_alert_queue() click to toggle source
# File lib/net_shell/net_shell.rb, line 313
def flush_alert_queue
  return if @alert_queue.nil?
  @alert_queue.each { |alert_msg| alert(alert_msg) }
  @alert_queue = nil
end
get_env(key) click to toggle source
# File lib/net_shell/net_shell.rb, line 144
def get_env(key)
  @env[key.to_sym]
end
get_error(args) click to toggle source
# File lib/net_shell/net_shell.rb, line 250
def get_error(args)
  error = StandardOutput.new
  error.color = @env[:color] != "0"
  error
end
get_input(args) click to toggle source
# File lib/net_shell/net_shell.rb, line 225
def get_input(args)
  index = args.find_index { |arg| is_input_redirect? arg }
  return StandardInput.new if (index.nil? or index > args.length - 2)

  case args[index]
  when "<"
    FileReadInput.new(args[index+1])
  end
end
get_output(args) click to toggle source
# File lib/net_shell/net_shell.rb, line 235
def get_output(args)
  index = args.find_index { |arg| is_output_redirect? arg }
  default = StandardOutput.new
  default.color = @env[:color] != "0"
  return default if (index.nil? or index > args.length - 2)

  case args[index]
  when ">"
    FileOverwriteOutput.new(args[index+1])
  when ">>"
    puts "Appending to #{args[index+1]}"
    FileAppendOutput.new(args[index+1])
  end
end
has_built_in?(name) click to toggle source
# File lib/net_shell/net_shell.rb, line 82
def has_built_in?(name)
  return built_in(name) != nil
end
is_input_redirect?(arg) click to toggle source
# File lib/net_shell/net_shell.rb, line 213
def is_input_redirect?(arg)
  arg == "<"
end
is_output_redirect?(arg) click to toggle source
# File lib/net_shell/net_shell.rb, line 217
def is_output_redirect?(arg)
  [ ">", ">>" ].include? arg
end
is_redirect?(arg) click to toggle source
# File lib/net_shell/net_shell.rb, line 221
def is_redirect?(arg)
  is_input_redirect?(arg) || is_output_redirect?(arg)
end
load_builtins_from_directory(dir, userdef) click to toggle source
# File lib/net_shell/net_shell.rb, line 71
def load_builtins_from_directory(dir, userdef)
  Dir[File.join(dir, "*.rb")].map do |file|
    subclass = built_in(File.basename(file, ".rb"))
    if subclass.nil? or subclass.sha1 != Digest::SHA1.hexdigest(IO.read(file))
      subclass = BuiltinCommand.load_command(file, userdef)
      register_built_in(subclass.command, subclass)
    end
    subclass
  end
end
notify_connect(client) click to toggle source
# File lib/net_shell/net_shell.rb, line 370
def notify_connect(client)
  return unless client == active_client
end
notify_disconnect(client) click to toggle source
# File lib/net_shell/net_shell.rb, line 374
def notify_disconnect(client)
  return unless client == active_client
  alert("Disconnected from #{client.uri}")
end
notify_incoming_message(client, message) click to toggle source
# File lib/net_shell/net_shell.rb, line 379
def notify_incoming_message(client, message)
  return unless client == active_client
  alert("server:".magenta + " #{message}") if env_is_true?(:show_async)
end
notify_outgoing_message(client, message) click to toggle source
# File lib/net_shell/net_shell.rb, line 367
def notify_outgoing_message(client, message)
end
password() click to toggle source
# File lib/net_shell/net_shell.rb, line 161
def password
  @env[:usherm_pass]
end
path_for_env(key) click to toggle source

Environment management

# File lib/net_shell/net_shell.rb, line 110
def path_for_env(key)
  File.join(shelldir(:env), key)
end
persist_env(*keys) click to toggle source
# File lib/net_shell/net_shell.rb, line 114
def persist_env(*keys)
  keys = @env.keys if keys.empty?
  keys = keys[0] if keys[0].is_a? Array

  present = keys.reject { |key| get_env(key).nil? }
  absent = keys.select { |key| get_env(key).nil? }
  present.each { |key| File.write(path_for_env(key), get_env(key)) }
  unpersist_env(absent)
end
process_backtick(line) click to toggle source
# File lib/net_shell/net_shell.rb, line 267
def process_backtick(line)
  line = line[1..-2] if line[0] == '`' and line[-1] == '`'
  cmd = command_for_line(line)
  cmd.input = StandardInput.new
  cmd.output = PipeBuffer.new
  cmd.run
  cmd.output.read.chomp
end
prompt_text() click to toggle source
# File lib/net_shell/net_shell.rb, line 331
def prompt_text
  client = self.shared[:client]
  return "net> " if client.nil? or not client.ready
  return "#{client.uri}> " if client.server_info.nil?

  "#{client.uri} #{client.server_info[:appName]}> "
end
read_env() click to toggle source
# File lib/net_shell/net_shell.rb, line 132
def read_env
  Dir[File.join(shelldir(:env), "*")].each { |file| set_env(File.basename(file), File.open(file).read.chomp) }
end
register_built_in(command, cls) click to toggle source
# File lib/net_shell/net_shell.rb, line 94
def register_built_in(command, cls)
  @built_ins[command.to_sym] = cls
end
set_active_client(key) click to toggle source
# File lib/net_shell/net_shell.rb, line 192
def set_active_client(key)
  @shared[:client] = @clients[key.to_sym]
end
set_client(key, client) click to toggle source
# File lib/net_shell/net_shell.rb, line 185
def set_client(key, client)
  @clients ||= {}
  @clients[key] = client
  client.refresh_async rescue ""
  client.on(:error) { |trigger, message| alert("#{key.to_s}: #{message}") }
end
set_env(key, value) click to toggle source
# File lib/net_shell/net_shell.rb, line 136
def set_env(key, value)
  if value.nil?
    @env.delete(key.to_sym)
  else
    @env[key.to_sym] = value
  end
end
setup_builtins() click to toggle source
# File lib/net_shell/net_shell.rb, line 64
def setup_builtins
  @built_ins ||= {}
  dir = File.expand_path("builtin_commands", File.dirname(__FILE__))
  all = load_builtins_from_directory(dir, false) + load_builtins_from_directory(shelldir(:bin), true)
  @built_ins.delete_if { |command, subclass| not(all.include? subclass)  }
end
setup_deployment_connection() click to toggle source
# File lib/net_shell/net_shell.rb, line 171
def setup_deployment_connection
  return if username.nil? or password.nil?
  set_client(:deployment, DeploymentClient.new("http://deployments.acres4.net:8080/deployment/json?wrap", username, password))
  puts "\rAutomatically connecting to Deployment as #{username}"
end
setup_stored_json() click to toggle source
# File lib/net_shell/net_shell.rb, line 40
def setup_stored_json
  ObjectBuilder.load_path(shelldir(:json))
end
setup_support() click to toggle source

Netshell setup

# File lib/net_shell/net_shell.rb, line 34
def setup_support
  setup_stored_json
  setup_deployment_connection
  setup_usherm_connection
end
setup_usherm_connection() click to toggle source
# File lib/net_shell/net_shell.rb, line 165
def setup_usherm_connection
  return if username.nil? or password.nil?
  set_client(:usherm, UsherMgmtClient.new(nil, username, password))
  puts "\rAutomatically connecting to Usher as #{username}"
end
shelldir(dir) click to toggle source
# File lib/net_shell/net_shell.rb, line 50
def shelldir(dir)
  path = File.join(config_dir, dir.to_s)
  Dir.mkdir(path) unless File.directory? path
  path
end
split_args(cmdline) click to toggle source
# File lib/net_shell/net_shell.rb, line 262
def split_args(cmdline)
  return [] if cmdline.nil? or cmdline.empty?
  cmdline.gsub(/`\b/, "\"`").gsub(/\b`/, "`\"").shellsplit_partial
end
stored_serial() click to toggle source
# File lib/net_shell/net_shell.rb, line 384
def stored_serial
  file = File.join(config_dir, "serial")

  begin
    return IO.read(file)
  rescue
    serial = Digest::SHA1.hexdigest(Random.new.bytes(16)).to_s
    File.write(file, serial) rescue nil
    return serial
  end
end
tab_complete_built_in(args) click to toggle source
# File lib/net_shell/net_shell.rb, line 98
def tab_complete_built_in(args)
  return [] unless has_built_in?(args[0])

  built_in = built_in(args[0]).new(self)
  built_in.parse(args)
  built_in.tab
end
transform_args(args) click to toggle source
# File lib/net_shell/net_shell.rb, line 276
def transform_args(args)
  args.map do |arg|
    if arg[0] == "$" then
      get_env(arg[1..-1]) || ""
    elsif arg[0] == '`' and arg[-1] == '`' then
      process_backtick(arg)
    else
      arg
    end
  end
end
unpersist_env(*keys) click to toggle source
# File lib/net_shell/net_shell.rb, line 124
def unpersist_env(*keys)
  keys = keys[0] if keys[0].is_a? Array
  keys.each do |key|
    path = path_for_env(key)
    File.delete(path) if File.exist? path
  end
end
username() click to toggle source

Shared variables

# File lib/net_shell/net_shell.rb, line 157
def username
  @env[:usherm_user]
end
wrap_message(message, sender) click to toggle source

Network listener

# File lib/net_shell/net_shell.rb, line 363
def wrap_message(message, sender)
  { time: Time.now, sender: sender, message: message }
end