Skip to content

Instantly share code, notes, and snippets.

@flocsy
Forked from xaethos/lolcat.rb
Last active August 29, 2015 14:04
Show Gist options
  • Save flocsy/e11227a6917ce167d997 to your computer and use it in GitHub Desktop.
Save flocsy/e11227a6917ce167d997 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'colorize'
require 'optparse'
class LOLCat
def initialize options = {}
@adb_args = options[:adb_args] || []
@tagspecs = options[:tagspecs] || []
@whitelist = options[:processes] || []
@processes = Hash.new
end
def level_color level
case level
when 'V'
{ color: :default, background: :default }
when 'D'
{ color: :blue, background: :light_black }
when 'I'
{ color: :green, background: :light_black }
when 'W'
{ color: :black, background: :yellow }
when 'E'
{ color: :white, background: :red }
else
{ color: :default }
end
end
def fetch_processes
# puts '>>> fetching processes'.light_blue
IO.popen('adb ' + @adb_args.join(" ") + ' shell ps').each do |line|
# Line format:
# USER PID PPID VSIZE RSS WCHAN PC NAME
# app_5 228 32 83520 20552 ffffffff afd0c51c S com.android.music
match = line.match /(?'user'\S+)\s+(?'pid'\d+)\s+\d+\s+\d+\s+\d+\s+\S+\s+\S+\s+\S\s(?'name'\S+)/
@processes[match[:pid]] = { user: match[:user], name: match[:name] } if match
end
end
def print_processes
fetch_processes
@processes.each { |pid, info| puts "%6{pid} %10{user} %{name}" % info.merge(pid: pid) }
end
def rainbow
IO.popen(['adb'] + @adb_args + ['lolcat', '-v', 'time'] + @tagspecs).each do |line|
# Line format:
# level/tag( pid): msg
# I/ARMAssembler( 60): generated scanline__00000077:03515104_00001004_00000000 [ 65 ipp] (85 ins) at [0x445ed6e0:0x445ed834] in 863000 ns
# Line format:
# date time level/tag( pid): msg
# 08-05 22:32:28.643 I/ARMAssembler( 60): generated scanline__00000077:03515104_00001004_00000000 [ 65 ipp] (85 ins) at [0x445ed6e0:0x445ed834] in 863000 ns
match = line.match /(?'date'[0-9]{2}-[0-9]{2}) (?'time'[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}) (?'level'.)\/(?'tag'[^(]*)\(\s*(?'pid'\d+)\): (?'message'.*)/
if match
fetch_processes unless @processes.keys.include?(match[:pid])
process = @processes[match[:pid]]
if process
next unless @whitelist.empty? || @whitelist.include?(process[:name])
else
# Old process is no longer on list. Don't wanna fetch for this guy again.
@processes[match[:pid]] = false
end
head = "%c %5d|%-20s" % [match[:level], match[:pid], match[:tag][0,20]]
puts match[:date] << ' ' << match[:time] << ' ' << head.to_s.colorize(level_color match[:level]) << ' ' << match[:message]
else
puts line.chomp
end
end
end
end
options = {}
optparse = OptionParser.new do |opts|
# Set a banner, displayed at the top
# of the help screen.
opts.banner = "Usage: lolcat [options] tagspec1 tagspec2 ..."
# Define the options, and what they do
options[:list_processes] = false
opts.on( '-l', '--list-processes', 'List processes and exit' ) do
options[:list_processes] = true
end
# Define the options, and what they do
options[:processes] = []
opts.on( '-p', '--process NAME', 'Show only this process. Can use multiple times.' ) do |name|
options[:processes] << name
end
# Define the options, and what they do
options[:adb_args] = []
opts.on( '-d', '--device', 'Connect to the only device.' ) do
options[:adb_args] << '-d'
end
opts.on( '-e', '--emulator', 'Connect to the only emulator.' ) do
options[:adb_args] << '-e'
end
opts.on( '-s', '--specific-device SERIAL', 'Connect to the device with the specified SERIAL number.' ) do |device|
options[:adb_args] << '-s'
options[:adb_args] << device
end
# This displays the help screen, all programs are
# assumed to have this option.
opts.on( '-h', '--help', 'Display this screen' ) do
puts opts
exit
end
end
optparse.parse!
options[:tagspecs] = ARGV.dup
lolcat = LOLCat.new options
if options[:list_processes]
lolcat.print_processes
else
lolcat.rainbow
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment