Skip to content

Instantly share code, notes, and snippets.

@mcxiaoke
Forked from xaethos/lolcat.rb
Created September 6, 2013 06:06
Show Gist options
  • Select an option

  • Save mcxiaoke/6460105 to your computer and use it in GitHub Desktop.

Select an option

Save mcxiaoke/6460105 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'colorize'
require 'optparse'
class LOLCat
def initialize options = {}
@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 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(%w[adb lolcat] + @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
match = line.match /(?'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 = "%5d|%-20s" % [match[:pid], match[:tag][0,20]]
puts 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
# 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