Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement