Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

219 lines (187 sloc) 4.283 kB
class Terminal
attr_reader :client
def initialize given_uri, id_amount = nil
check_highline_gem
check_picky_client_gem
require 'uri'
uri = URI.parse given_uri
# If the user gave a whole url without http, add that and reparse.
#
unless uri.path
uri = URI.parse "http://#{given_uri}"
end
# If the user gave a path without / in front, add one.
#
unless uri.path =~ /^\//
uri.path = "/#{uri.path}"
end
@searches = 0
@durations = 0
@current_text = ''
@cursor_offset = 0
@last_ids = ''
@id_amount = id_amount && Integer(id_amount) || 20
@client = Picky::Client.new :host => (uri.host || 'localhost'), :port => (uri.port || 8080), :path => uri.path
install_trap
end
def check_highline_gem # :nodoc:
require "highline/system_extensions"
extend HighLine::SystemExtensions
rescue LoadError
warn_gem_missing 'highline', 'the terminal interface'
exit 1
end
def check_picky_client_gem # :nodoc:
require 'picky-client'
rescue LoadError
warn_gem_missing 'picky-client', 'the terminal interface'
exit 1
end
# Install the Ctrl-C handler.
#
def install_trap
Signal.trap('INT') do
print "\e[100D"
flush
puts "\n"
puts "You performed #{@searches} searches, totalling #{"%.3f" % @durations} seconds."
print "\e[100D"
flush
exit
end
end
# Flush to STDOUT.
#
def flush
STDOUT.flush
end
# Position cursor amount to the left.
#
def left amount = 1
print "\e[#{amount}D"
flush
end
# Position cursor amount to the right.
#
def right amount = 1
print "\e[#{amount}C"
flush
end
# Move cursor to position.
#
def move_to position
relative = position - @cursor_offset
if relative > 0
right relative
else
left relative
end
@cursor_offset = position
flush
end
# Delete one character.
#
def backspace
chop_text
print "\e[1D \e[1D"
flush
end
# Write the text to the input area.
#
def write text
@cursor_offset += text.size
print text
flush
end
# Chop off one character.
#
def chop_text
@current_text.chop!
end
# Add the given text to the current text.
#
def add_text text
@current_text << text
end
# Type the given text into the input area.
#
def type_search character
add_text character
write character
end
# Write the amount of result ids.
#
def write_results results
move_to 0
write "%9d" % (results && results.total || 0)
move_to 10 + @current_text.size
end
# Move to the id area.
#
def move_to_ids
move_to 12 + @current_text.size
end
# Write the result ids.
#
def write_ids results
move_to_ids
write "=> #{results.total ? results.ids(@id_amount) : []}"
rescue StandardError => e
p e.message
p e.backtrace
end
# Clear the result ids.
#
def clear_ids
move_to_ids
write @ids_clearing_string ||= " "*200
end
# Log a search.
#
def log results
@searches += 1
@durations += (results[:duration] || 0)
end
# Perform a search.
#
def search full = false
client.search @current_text, :ids => (full ? @id_amount : 0)
end
# Perform a search and write the results.
#
# Handles 404s and connection problems.
#
def search_and_write full = false
results = search full
results.extend Picky::Convenience
log results
full ? write_ids(results) : clear_ids
write_results results
rescue Errno::ECONNREFUSED => e
write "Please start a Picky server listening to #{@client.path}."
rescue Yajl::ParseError => e
write "Got a 404. Maybe the path #{@client.path} isn't a correct one?"
end
# Run the terminal.
#
# Note: Uses a simple loop to handle input.
#
def run
puts "Type and see the result count update. Press enter for the first #{@id_amount} result ids."
puts "Break with Ctrl-C."
search_and_write
loop do
input = get_character
case input
when 127
backspace
search_and_write
when 13
search_and_write true
else # All other.
type_search input.chr
search_and_write
end
end
end
end
Jump to Line
Something went wrong with that request. Please try again.