Skip to content

Instantly share code, notes, and snippets.

@dnpp73
Created April 19, 2011 14:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dnpp73/928111 to your computer and use it in GitHub Desktop.
Save dnpp73/928111 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
#設定用の定数とか
Ext = true
LogDIR = '/Users/dnpp/Dropbox/TiarraLog/Log'
Channel = '#must@Tw'
Date = '2011.04.28'
LimeChatCSS = '/Users/dnpp/Dropbox/MacSettings/HOME/Library/Application Support/LimeChat/Themes/vicutake.css'
ExtCSS = '/Users/dnpp/Dropbox/Programming/ruby/twitter/tiarralog2html/ext.css'
Keyword = 'DNPP|dnpp|ゆうすけ|ゆーすけ|ユウスケ|ユースケ'
TargetTXT = LogDIR + '/' + Channel + '/' + Date + '.txt'
#弄る必要の無い定数とか
Header = <<EOS
<html class="normal" type="channel" channelname="#{Channel}">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta http-equiv="Content-Style-Type" content="text/css">
<style>html {font-family:'Osaka-Mono';font-size:10pt;background-color:white;color:black;word-wrap:break-word;margin:0;padding:3px 4px 10px 4px;}body {margin:0;padding:0}img {border:1px solid #aaa;vertical-align:top;}object {vertical-align:top;}hr {margin:0.5em 2em;}.line {margin:0 -4px; padding:0 4px 1px 4px; clear:both;}.line[alternate=even] {}.line[alternate=odd] {}.line[type=action] .sender:before {content: '• ';white-space: nowrap;}.inlineimage {margin: 10px 0 15px 40px;max-width: 200px;max-height: 150px;-webkit-box-shadow: 2px 2px 2px #888;}.avatar {display: inline;max-width: 24px;max-height: 24px;margin-right: 3px;vertical-align: middle;}.url { word-break: break-all; }.address { text-decoration: underline; word-break: break-all; }.highlight { color: #f0f; font-weight: bold; }.time { color: #048; }.place { color: #008; }.sender[type=myself] { color: #66a; }.sender[type=normal] { color: #008; }.message[type=system] { color: #080; }.message[type=error] { color: #f00; font-weight: bold; }.message[type=reply] { color: #088; }.message[type=error_reply] { color: #f00; }.message[type=dcc_send_send] { color: #088; }.message[type=dcc_send_receive] { color: #00c; }.message[type=privmsg] {}.message[type=notice] { color: #888; }.message[type=action] {}.message[type=join] { color: #080; }.message[type=part] { color: #080; }.message[type=kick] { color: #080; }.message[type=quit] { color: #080; }.message[type=kill] { color: #080; }.message[type=nick] { color: #080; }.message[type=mode] { color: #080; }.message[type=topic] { color: #080; }.message[type=invite] { color: #080; }.message[type=wallops] { color: #080; }.message[type=debug_send] { color: #aaa; }.message[type=debug_receive] { color: #444; }.effect[color-number='0'] { color: #fff; }.effect[color-number='1'] { color: #000; }.effect[color-number='2'] { color: #008; }.effect[color-number='3'] { color: #080; }.effect[color-number='4'] { color: #f00; }.effect[color-number='5'] { color: #800; }.effect[color-number='6'] { color: #808; }.effect[color-number='7'] { color: #f80; }.effect[color-number='8'] { color: #ff0; }.effect[color-number='9'] { color: #0f0; }.effect[color-number='10'] { color: #088; }.effect[color-number='11'] { color: #0ff; }.effect[color-number='12'] { color: #00f; }.effect[color-number='13'] { color: #f0f; }.effect[color-number='14'] { color: #888; }.effect[color-number='15'] { color: #ccc; }.effect[bgcolor-number='0'] { background-color: #fff; }.effect[bgcolor-number='1'] { background-color: #000; }.effect[bgcolor-number='2'] { background-color: #008; }.effect[bgcolor-number='3'] { background-color: #080; }.effect[bgcolor-number='4'] { background-color: #f00; }.effect[bgcolor-number='5'] { background-color: #800; }.effect[bgcolor-number='6'] { background-color: #808; }.effect[bgcolor-number='7'] { background-color: #f80; }.effect[bgcolor-number='8'] { background-color: #ff0; }.effect[bgcolor-number='9'] { background-color: #0f0; }.effect[bgcolor-number='10'] { background-color: #088; }.effect[bgcolor-number='11'] { background-color: #0ff; }.effect[bgcolor-number='12'] { background-color: #00f; }.effect[bgcolor-number='13'] { background-color: #f0f; }.effect[bgcolor-number='14'] { background-color: #888; }.effect[bgcolor-number='15'] { background-color: #ccc; }</style>
<link href="#{LimeChatCSS}" rel="stylesheet" type="text/css">
</head>
<body class="normal" type="channel" channelname="#{Channel}">
EOS
Footer = '</body></html>'
require 'cgi'
#ログの読み込みとか分析とか
log_raw = Array.new
open(TargetTXT,'r') {|file| log_raw = file.readlines }
statuses = Array.new
is_first_other_priv_ary = Array.new
is_first_my_priv_ary = Array.new
is_first_notice_ary = Array.new
span_time = 'class=time'
alternate = 'even'
line_id = 1
def replace(source,highlight)
source = source.gsub(/\x03(1[0-5]|[0-9])/,'<span class="effect" style="" color-number="\1">').gsub(/\x03/,'</span>')
source = source.gsub(/(?:h?ttps?|ftp):\/\/(?:[^\.\/]+\.)+(?:[\w\/\.\-\;\?\!\:@\&\=\+\$\,\%\#\|\~]*)/) do |hit|
hit = '<a href="' + hit + '" class="url" oncontextmenu="on_url()">' + hit + '</a>' if !Ext
hit = '<a href="' + hit + '" class="url" oncontextmenu="on_url()" target="_blank">' + hit + '</a>' if Ext
end
source = source.gsub(Regexp.new(Keyword),'<strong class="highlight">\0</strong>') if highlight
source = source.gsub(/@\w+\.?/){|screen_name| !screen_name.index('.') ? '<a href="https://twitter.com/' + screen_name.delete('@') + '" class="screen_name" target="_blank">' + screen_name + '</a>' : screen_name } if Ext
return source
end
log_raw.each do |line|
tmp = line.split(' ')
time = tmp[0]
judge = tmp[1]
#judge
#'+' で join '+ hoge (host) to #Channel'
#'-' で part '+ hoge from #Channel'
#'!' で leave '! hoge ("Leaving...")'
#'Topic of Channel #Channel by nick content'
#'Mode by hoge:#Channel +o fuga'
#'hoge -> fuga' で nick 変更
#'<#Channel:nick>' で privmsg
#'>#Channel:nick<' で自分の privmsg
#'(#Channel:nick)' で notice
#
#まだ未実装なの
#span_sender の colornumber="/[0-9]/"
#span_message の channel
#
if judge == '+' #join
kind = 'join'
nick = tmp[2]
content = "#{nick} has joined #{tmp[3]}"
content = CGI.escapeHTML(content)
div = "highlight=\"false\" class=\"line event\" type=\"join\" alternate=\"#{alternate}\" id=\"line#{line_id}\""
span_avatar = nil
span_sender = nil
span_message = 'class="message" type="join"'
html = "<div #{div}><span #{span_time}>#{time}</span><span #{span_message}>#{content}</span></div>"
elsif judge == '-' #part
kind = 'part'
nick = tmp[2]
content = "#{nick} has left #{tmp[4,(tmp.size)].join(' ')}"
content = CGI.escapeHTML(content)
div = "highlight=\"false\" class=\"line event\" type=\"part\" alternate=\"#{alternate}\" id=\"line#{line_id}\""
span_avatar = nil
span_sender = nil
span_message = 'class="message" type="part"'
html = "<div #{div}><span #{span_time}>#{time}</span><span #{span_message}>#{content}</span></div>"
elsif judge == '!' #leave
kind = 'leave'
nick = tmp[2]
content = "#{nick} has left IRC #{tmp[3,(tmp.size)].join(' ')}"
content = CGI.escapeHTML(content)
div = "highlight=\"false\" class=\"line event\" type=\"quit\" alternate=\"#{alternate}\" id=\"line#{line_id}\""
span_avatar = nil
span_sender = nil
span_message = 'class="message" type="quit"'
html = "<div #{div}><span #{span_time}>#{time}</span><span #{span_message}>#{content}</span></div>"
elsif judge == 'Topic' #Topic
kind = 'Topic'
nick = tmp[6].delete(':')
content = "#{nick} has set topic: #{tmp[7,(tmp.size)].join(' ')}"
content = CGI.escapeHTML(content)
div = "highlight=\"false\" class=\"line event\" type=\"topic\" alternate=\"#{alternate}\" id=\"line#{line_id}\""
span_avatar = nil
span_sender = nil
span_message = 'class="message" type="topic"'
html = "<div #{div}><span #{span_time}>#{time}</span><span #{span_message}>#{content}</span></div>"
elsif judge == 'Mode' #Mode
kind = 'Mode'
nick = tmp[3].delete(':')
content = "#{nick} has changed mode: +o #{tmp[6]}"
content = CGI.escapeHTML(content)
div = "highlight=\"false\" class=\"line event\" type=\"mode\" alternate=\"#{alternate}\" id=\"line#{line_id}\""
span_avatar = nil
span_sender = nil
span_message = 'class="message" type="mode"'
html = "<div #{div}><span #{span_time}>#{time}</span><span #{span_message}>#{content}</span></div>"
elsif judge =~ /^[\w\-@]+$/ #nick_change
kind = 'nick_change'
nick = nil
content = nil
div = nil
span_avatar = nil
span_sender = nil
span_message = nil
html = nil
elsif judge =~ /^<#[^ :]+?:[\w\-]+>$/ #other_priv
kind = 'other_priv'
nick = judge.split(':')[1].delete('>')
content = tmp[2,(tmp.size)].join(' ')
if content =~ Regexp.new(Keyword)
highlight = true
else
highlight = false
end
content = CGI.escapeHTML(content)
content = replace(content,highlight)
if is_first_other_priv_ary.index(nick)
is_first_other_priv = false
else
is_first_other_priv = true
is_first_other_priv_ary << nick
end
div = "highlight=\"#{highlight}\" nick=\"#{nick}\" class=\"line text\" type=\"privmsg\" alternate=\"#{alternate}\" id=\"line#{line_id}\""
span_avatar = "class=avatar src=\"http://img.tweetimag.es/i/#{nick}\""
span_sender = "class=\"sender\" type=\"normal\" oncontextmenu=\"on_nick()\" identified=\"false\" colornumber=\"0\" first=\"#{is_first_other_priv}\""
span_message = 'class="message" type="privmsg"'
html = "<div #{div}><span #{span_time}>#{time}</span><img #{span_avatar}><span #{span_sender}>#{nick} : </span><span #{span_message}>#{content}</span></div>"
elsif judge =~ /^>#[^ :]+?:[\w\-]+<$/ #my_priv
kind = 'my_priv'
nick = judge.split(':')[1].delete('<')
content = tmp[2,(tmp.size)].join(' ')
content = CGI.escapeHTML(content)
content = replace(content,false)
if is_first_my_priv_ary.index(nick)
is_first_my_priv = false
else
is_first_my_priv = true
is_first_my_priv_ary << nick
end
div = "highlight=\"false\" nick=\"#{nick}\" class=\"line text\" type=\"privmsg\" alternate=\"#{alternate}\" id=\"line#{line_id}\""
span_avatar = "class=avatar src=\"http://img.tweetimag.es/i/#{nick}\""
span_sender = "class=\"sender\" type=\"normal\" oncontextmenu=\"on_nick()\" identified=\"false\" colornumber=\"0\" first=\"#{is_first_my_priv}\""
span_message = 'class="message" type="privmsg"'
html = "<div #{div}><span #{span_time}>#{time}</span><img #{span_avatar}><span #{span_sender}>#{nick} : </span><span #{span_message}>#{content}</span></div>"
elsif judge =~ /^\(#[^ :]+?:[\w\-]+\)$/ #notice
kind = 'notice'
nick = judge.split(':')[1].delete(')')
content = tmp[2,(tmp.size)].join(' ')
content = CGI.escapeHTML(content)
content = replace(content,false)
if is_first_notice_ary.index(nick)
is_first_notice = false
else
is_first_notice = true
is_first_notice_ary << nick
end
div = "'highlight=\"false\" nick=\"#{nick}\" class=\"line text\" type=\"notice\" alternate=\"#{alternate}\" id=\"line#{line_id}\""
span_avatar = "class=\"sender\" type=\"normal\" oncontextmenu=\"on_nick()\" identified=\"false\" colornumber=\"0\" first=\"#{is_first_notice}\""
span_sender = nil
span_message = 'class="message" type="notice"'
html = "<div #{div}><span #{span_time}>#{time}</span><span #{span_sender}>#{nick} : </span><span #{span_message}>#{content}</span></div>"
else
kind = '???'
nick = nil
content = nil
div = nil
span_avatar = nil
span_sender = nil
span_message = nil
html = nil
end
if alternate == 'even'
alternate = 'odd'
elsif alternate == 'odd'
alternate = 'even'
end
line_id += 1
statuses << [kind,[time,nick,content],[div,span_avatar,span_sender,span_message],line,html]
end
#書き出して終わり
open(Date+'-'+Channel.delete('#')+'.html','w') do |output|
output.puts Header
output.puts "<link href=\"#{ExtCSS}\" rel=\"stylesheet\" type=\"text/css\">" if Ext
output.puts statuses.collect{|status|status[4]}
output.puts Footer
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment