lib/birdwatcher/console.rb in birdwatcher-0.3.1 vs lib/birdwatcher/console.rb in birdwatcher-0.4.0
- old
+ new
@@ -1,36 +1,43 @@
module Birdwatcher
class Console
include Singleton
DEFAULT_AUTO_COMPLETION_STRINGS = [].freeze
- DB_MIGRATIONS_PATH = File.expand_path("../../../db/migrations", __FILE__).freeze
- LINE_SEPARATOR = ("=" * 80).freeze
+ DB_MIGRATIONS_PATH = File.expand_path("../../../db/migrations", __FILE__).freeze
+ LINE_SEPARATOR = ("=" * 80).freeze
+ HISTORY_FILE_NAME = ".birdwatcher_history".freeze
+ HISTORY_FILE_LOCATION = File.join(Dir.home, HISTORY_FILE_NAME).freeze
- attr_accessor :current_workspace, :current_module
+ attr_accessor :current_workspace, :current_module, :spool
attr_reader :database
def initialize
@output_mutex = Mutex.new
+ @spool_mutex = Mutex.new
end
def start!
print_banner
bootstrap!
Readline.completion_proc = proc do |s|
expanded_s = File.expand_path(s)
Birdwatcher::Console.instance.auto_completion_strings.grep(/\A#{Regexp.escape(s)}/) + Dir["#{expanded_s}*"].grep(/^#{Regexp.escape(expanded_s)}/)
end
Readline.completion_append_character = ""
+ load_command_history
while input = Readline.readline(prompt_line, true)
+ save_to_spool(prompt_line)
input = input.to_s.strip
handle_input(input) unless input.empty?
end
end
def handle_input(input)
input.strip!
+ save_command_to_history(input)
+ save_to_spool("#{input}\n")
command_name, argument_line = input.split(" ", 2).map(&:strip)
command_name.downcase
commands.each do |command|
next unless command.has_name?(command_name)
command.new.execute(argument_line)
@@ -50,18 +57,19 @@
end
def output(data, newline = true)
data = "#{data}\n" if newline
with_output_mutex { print data }
+ save_to_spool(data)
end
def output_formatted(*args)
- with_output_mutex { printf(*args) }
+ output(sprintf(*args), false)
end
def newline
- with_output_mutex { puts }
+ output ""
end
def line_separator
output LINE_SEPARATOR
end
@@ -75,10 +83,11 @@
yield block
output " done".bold.light_green
rescue => e
output " failed".bold.light_red
error "#{e.class}: ".bold + e.message
+ e.backtrace.each { |l| error l } if debugging_enabled?
exit(1) if fatal
end
def error(message)
output "[-] ".bold.light_red + message
@@ -90,10 +99,28 @@
def fatal(message)
output "[-]".white.bold.on_red + " #{message}"
end
+ def confirm(question)
+ question = "#{question} (y/n) "
+ save_to_spool(question)
+ if HighLine.agree("#{question}")
+ save_to_spool("y\n")
+ true
+ else
+ save_to_spool("n\n")
+ false
+ end
+ end
+
+ def page_text(text)
+ save_to_spool(text)
+ ::TTY::Pager::SystemPager.new.page(text)
+ rescue Errno::EPIPE
+ end
+
def twitter_client
if !@twitter_clients
@twitter_clients = create_twitter_clients!
end
@twitter_clients.sample
@@ -177,10 +204,14 @@
def with_output_mutex
@output_mutex.synchronize { yield }
end
+ def with_spool_mutex
+ @spool_mutex.synchronize { yield }
+ end
+
def create_twitter_clients!
clients = []
configuration.get!(:twitter).each do |keypair|
clients << Twitter::REST::Client.new do |config|
config.consumer_key = keypair["consumer_key"]
@@ -194,8 +225,44 @@
clients = []
configuration.get(:klout).each do |key|
clients << Birdwatcher::KloutClient.new(key)
end
clients
+ end
+
+ def load_command_history
+ if File.exist?(HISTORY_FILE_LOCATION)
+ if File.readable?(HISTORY_FILE_LOCATION)
+ File.open(HISTORY_FILE_LOCATION).each_line do |command|
+ Readline::HISTORY << command.strip
+ end
+ else
+ warn("Cannot load command history: #{HISTORY_FILE_LOCATION} is not readable")
+ end
+ end
+ end
+
+ def save_command_to_history(command)
+ if File.exist?(HISTORY_FILE_LOCATION) && !File.writable?(HISTORY_FILE_LOCATION)
+ warn("Cannot save command to history: #{HISTORY_FILE_LOCATION} is not writable")
+ return
+ end
+ File.open(HISTORY_FILE_LOCATION, "a") do |file|
+ file.puts(command)
+ end
+ end
+
+ def save_to_spool(string)
+ return unless spool_enabled?
+ string = string.to_s.uncolorize
+ with_spool_mutex { self.spool.write(string) }
+ end
+
+ def spool_enabled?
+ self.spool && self.spool.is_a?(File)
+ end
+
+ def debugging_enabled?
+ ENV.key?("BIRDWATCHER_DEBUG")
end
end
end