-
-
Save tshakah/990b4effaab8b7b3aa6d to your computer and use it in GitHub Desktop.
Imap mail statistic with Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# This groups emails into senders and then calculates some basic stats for the | |
# times of those emails - the earliest, latest and average | |
# | |
# Note that there is some oddity relating to my specific needs around timezone | |
# handling - this is in the code below the comment starting "Normalise" | |
# These two are for debugging | |
#require 'awesome_print' | |
#require 'byebug' | |
require 'net/imap' | |
require 'progressbar' | |
require 'active_support/all' | |
require 'yaml' | |
require 'yaml/store' | |
begin | |
# Make sure we have everything we need to connect | |
fail IOError unless File.exist?('settings.yml') | |
settings = YAML.load_file('settings.yml') | |
password = ENV['ES_PASSWORD'] | |
fail ArgumentError unless password | |
fail NameError unless settings['server'] && settings['email'] | |
# Connect and login to the server | |
imap = Net::IMAP.new(settings['server'], 993, true) | |
imap.login(settings['email'], password) | |
imap.select('INBOX.Prices') | |
# Get all mail in the folder | |
mail_ids = imap.search(['ALL']) | |
puts "Found #{mail_ids.count} emails. Fetching mail headers..." | |
# Create a new progressbar | |
bar = ProgressBar.new 'progress', mail_ids.count | |
time_regex = /\d{2}:\d{2}:\d{2}\s([+-]\d{4}|UTC)/ | |
# Fetch mail details | |
stats = imap.fetch(mail_ids, 'ENVELOPE').map do |mail| | |
bar.inc | |
sender = mail.attr['ENVELOPE'].sender.first | |
time = Time.parse(mail.attr.first.second.date.match(time_regex).to_s).utc | |
# Normalise the days for my use case | |
time += 1.day if time.hour < 6 && time.day == Date.current.day || | |
time.day == Date.yesterday.day | |
["#{sender.mailbox}@#{sender.host}", time.to_i] | |
end | |
# Calculate the stats for the emails | |
stats = stats.group_by { |sender, _| sender } | |
parsed_stats = Hash[stats.map do |group, details| | |
times = details.map(&:last).sort | |
[group, { | |
earliest: Time.at(times.first), | |
latest: Time.at(times.last), | |
average: Time.at(times.sum.to_f / times.count) | |
}] | |
end] | |
# Output results | |
bar.finish | |
puts '' | |
parsed_stats.map do |address, numbers| | |
puts address | |
puts '-----------------------------' | |
puts numbers[:earliest].strftime('%H:%M') | |
puts numbers[:latest].strftime('%H:%M') | |
puts numbers[:average].strftime('%H:%M') | |
puts '' | |
end | |
rescue IOError | |
# The setting file doesn't exist, so create it | |
store = YAML::Store.new('settings.yml') | |
store.transaction do | |
store['server'] = nil | |
store['email'] = nil | |
end | |
puts 'Created configuration file - please update it and try again.' | |
rescue ArgumentError | |
# Probably no password supplied | |
puts 'Password not supplied - please supply a value in the ES_PASSWORD ' \ | |
'environment variable' | |
rescue NameError | |
# Probably invalid settings | |
puts 'Settings are invalid. Please check the settings file for server and ' \ | |
'email options' | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment