1#!/usr/bin/env ruby 2 3require "parsedate" 4require "base64" 5 6include ParseDate 7 8class Mail 9 def Mail.new(f) 10 if !f.kind_of?(IO) 11 f = open(f, "r") 12 me = super(f) 13 f.close 14 else 15 me = super 16 end 17 return me 18 end 19 20 def initialize(f) 21 @header = {} 22 @body = [] 23 while line = f.gets() 24 $_.chop! 25 next if /^From / =~ line # skip From-line 26 break if /^$/ =~ line # end of header 27 if /^(\S+):\s*(.*)/ =~ line 28 @header[attr = $1.capitalize] = $2 29 elsif attr 30 sub(/^\s*/, '') 31 @header[attr] += "\n" + $_ 32 end 33 end 34 35 return unless $_ 36 37 while line = f.gets() 38 break if /^From / =~ line 39 @body.push($_) 40 end 41 end 42 43 def header 44 return @header 45 end 46 47 def body 48 return @body 49 end 50 51end 52 53if ARGV.length == 0 54 if ENV['MAIL'] 55 ARGV[0] = ENV['MAIL'] 56 elsif ENV['USER'] 57 ARGV[0] = '/var/spool/mail/' + ENV['USER'] 58 elsif ENV['LOGNAME'] 59 ARGV[0] = '/var/spool/mail/' + ENV['LOGNAME'] 60 end 61end 62 63require "tk" 64list = scroll = nil 65TkFrame.new{|f| 66 list = TkListbox.new(f) { 67 yscroll proc{|*idx| 68 scroll.set *idx 69 } 70 relief 'raised' 71# geometry "80x5" 72 width 80 73 height 5 74 setgrid 'yes' 75 pack('side'=>'left','fill'=>'both','expand'=>'yes') 76 } 77 scroll = TkScrollbar.new(f) { 78 command proc{|idx| 79 list.yview *idx 80 } 81 pack('side'=>'right','fill'=>'y') 82 } 83 pack 84} 85root = Tk.root 86TkButton.new(root) { 87 text 'Dismiss' 88 command proc {exit} 89 pack('fill'=>'both','expand'=>'yes') 90} 91root.bind "Control-c", proc{exit} 92root.bind "Control-q", proc{exit} 93root.bind "space", proc{exit} 94 95$outcount = 0; 96for file in ARGV 97 next unless File.exist?(file) 98 atime = File.atime(file) 99 mtime = File.mtime(file) 100 f = open(file, "r") 101 begin 102 until f.eof 103 mail = Mail.new(f) 104 date = mail.header['Date'] 105 next unless date 106 from = mail.header['From'] 107 subj = mail.header['Subject'] 108 y = m = d = 0 109 y, m, d = parsedate(date) if date 110 from = "sombody@somewhere" unless from 111 subj = "(nil)" unless subj 112 from = decode_b(from) 113 subj = decode_b(subj) 114 list.insert 'end', format('%-02d/%02d/%02d [%-28.28s] %s',y,m,d,from,subj) 115 $outcount += 1 116 end 117 ensure 118 f.close 119 File.utime(atime, mtime, file) 120 list.see 'end' 121 end 122end 123 124limit = 10000 125if $outcount == 0 126 list.insert 'end', "You have no mail." 127 limit = 2000 128end 129Tk.after limit, proc{ 130 exit 131} 132Tk.mainloop 133