#! /usr/bin/env ruby # # mailhist - generate a histogram of the number of mails per day. # # Copyright (C) 2003 Satoru Takabayashi # All rights reserved. # This is free software with ABSOLUTELY NO WARRANTY. # # You can redistribute it and/or modify it under the terms of # the GNU General Public License version 2. # require 'find' require 'time' require 'mailread' require 'getoptlong' class Time def yymmdd self.strftime("%Y-%m-%d") end end def show_histogram (stat) first_day = Time.parse(stat.keys.sort.first) last_day = Time.parse(stat.keys.sort.last) first_day.to_i.step(last_day.to_i, 86400) {|time| date = Time.at(time).yymmdd stat[date] = 0 unless stat[date] } ndays = 0 total = 0 hist = [] stat.each {|key, value| hist[value] = 0 unless hist[value] hist[value] += 1 ndays += 1 total += value } puts "一日に出したメールの数の棒グラフ" printf("%s 〜 %s (全%d日, 全%d通, 平均%.2f通/日)\n", first_day.yymmdd, last_day.yymmdd, ndays, total, total.to_f / ndays) max_day = stat.values.max ratio = 60.0 / hist.find_all{|x| x}.max ratio = 1.0 if ratio > 1.0 (0..max_day).each {|i| val = (hist[i] or 0) printf("%4d通 %4d日 %s\n", i, val, "*" * (val * ratio)) } puts end def parse_options options = Hash.new parser = GetoptLong.new parser.set_options(['--from', '-f', GetoptLong::REQUIRED_ARGUMENT]) parser.each_option {|name, arg| options[name.sub(/^--/, "")] = arg } if ARGV.empty? puts "Usage: mailhist [OPTION] FOLDER..." puts(" -f, --from=RE count mails only matching RE in From:") exit(1) end return options end def collect_timestamps (folders, from_re) timestamps = [] folders.each {|folder| Find.find(folder) {|file_name| next unless File.file?(file_name) begin mail = Mail.new(file_name) if from_re.match(mail['From']) timestamp = Time.parse(mail['Date']) timestamps.push(timestamp) end rescue # malformed mail? end } } return timestamps.sort end def process (timestamps) prev_year = timestamps.first.year first_year = prev_year total_stat = {} yearly_stat = {} timestamps.each {|timestamp| if timestamp.year != prev_year show_histogram(yearly_stat) yearly_stat = {} end date = timestamp.yymmdd yearly_stat[date] = 0 unless yearly_stat[date] yearly_stat[date] += 1 total_stat[date] = 0 unless total_stat[date] total_stat[date] += 1 prev_year = timestamp.year } show_histogram(yearly_stat) show_histogram(total_stat) if first_year != prev_year end def main options = parse_options folders = ARGV from_re = if options['from'] then Regexp.new(options['from']) else // end timestamps = collect_timestamps(folders, from_re) process(timestamps) end main