Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
A grep for Skype HTML log written in Ruby
#! /usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'optparse'
require 'rubygems' unless defined? Gem
require 'nokogiri'
require 'highline'
$KCODE = 'u' unless defined? Encode
class Skype_Html_Log_Parser
def initialize
@date = nil
@datelist = nil
@key = nil
@regexp = nil
@regexo = []
end
def run
args.parse!( ARGV )
expand( grep( messages( detect_chatdate() ) ) )
end
def grep( messages )
regex = Regexp.new( @regexp, @regexo.inject( 0 ) { |r, i| r | i } )
messages.find_all { |e|
e[@key.to_sym].match( regex )
}
end
#
# [ { :name => name,
# :message => message,
# :time => time },
# {},
# {}
# ]
#
def messages( date )
result = []
ele = parser( html_log ).search( 'h3' ).find { |e|
e.text == date
}
message = {}
while ( ele = ele.next_sibling )
content = text( ele )
if ( content )
content.keys.each { |k|
if ( message.has_key?( k ) )
result << message
message = {}
end
message[k] = content[k]
}
else
break
end
end
return result
end
def text( ele )
case ( ele.name )
when 'dt'
ele.text.match( /\A(.+): (.+)\z/ )
{ :name => $1,
:time => $2 }
when 'dd'
{ :message => ele.text }
when 'h3'
false
end
end
#
# [Return] Hash
#
def datelist
if ( !@datelist )
list = parser( html_log ).search( 'h3' ).reverse.map { |e|
e.inner_text().strip
}
@datelist = Hash[*(1..list.size).to_a.zip( list ).flatten]
end
return @datelist
end
def detect_chatdate
if ( STDIN.tty? )
return _chatdate_from_tty
else
return _chatdate_from_cmdopt
end
end
def _chatdate_from_tty
puts "logged days below:"
datelist.each_pair{ |k, v|
printf( "% 3d : %s\n", k, v )
}
answer = HighLine.new.ask( "choose a day [ 1 - #{datelist.size} ] :",
Integer ) { |num|
num.in = datelist.keys
}
return datelist[answer]
end
def _chatdate_from_cmdopt
if ( datelist.has_value?( @date ) )
return @date
else
return _default_chatdate()
end
end
def _default_chatdate
return datelist[datelist.keys.min]
end
def html_log
ARGV.size > 0 ? open( ARGV.shift ) : STDIN
end
def parser( strio = nil )
if ( !@parser and strio )
@parser = Nokogiri( strio.read )
end
return @parser
end
def args
OptionParser.new { |opt|
opt.on( '-d DATE' ) { |date|
@date = date
}
opt.on( '-k KEY' ) { |key|
@key = key
}
opt.on( '-r REGEXP' ) { |regexp|
@regexp = regexp
}
opt.on( '-i', '--ignorecase' ) {
@regexo << Regexp::IGNORECASE
}
opt.on( '-m', '--multiline' ) {
@regexo << Regexp::MULTILINE
}
opt.on( '-x', '--extended' ) {
@regexo << Regexp::EXTENDED
}
}
end
def expand( messages )
messages.map { |e|
sprintf( '%s : %s : %s', e[:time], e[:name], e[:message] )
}
end
end
if ( __FILE__ == $0 )
puts Skype_Html_Log_Parser.new.run
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment