Skip to content

Instantly share code, notes, and snippets.

@mxswd
Created December 5, 2011 15:39
Show Gist options
  • Save mxswd/1433997 to your computer and use it in GitHub Desktop.
Save mxswd/1433997 to your computer and use it in GitHub Desktop.
Statistics on email activity.
#!/usr/bin/env ruby
# email_stats.rb
# ======================`README.md`========================
#
# Email Stats
# ===========
#
# Requirements
# ------------
#
# You need **MongoDB** installed and the **bundler** gem.
#
# bundle install # installs gem dependencies
#
# It uses a database called email-stats in **MongoDB**.
#
# Usage
# -----
#
# You need to set your **IMAP\_USERNAME** and **IMAP\_PASSWORD** environment variable.
#
# To download all your mail
#
# [email protected] IMAP_PASSWORD=password ruby email_stats.rb
#
# To load up the environment to query with
#
# irb -r ./email_models.rb
#
# Or you can use the **Rakefile**
#
# [email protected] IMAP_PASSWORD=password rake download
# rake console
#
# *Fancy!*
#
# For some stats
#
# rake top_senders # See who sends you the most emails
# LIMIT=20 rake top_senders # See the top 20!
# rake emails_from # See a list of emails form someone.
# rake reset # It will delete your data!
#
#
# TODO
# ----
#
# - multiple threads
# - homedir config. encrypt?
# - graph frequency on gnuplot
#
# Gems Needed
# -----------
#
# - mongo_mapper
# - bson_ext
# - colored
#
# ======================`Rakefile`=========================
#
# desc "open a console to script with the database with"
# task :console do
# sh "bundle exec irb -r ./email_models.rb"
# end
#
# desc "start downloading emails"
# task :download do
# require "./email_stats.rb"
# end
#
# task :env do
# require './email_models.rb'
# end
#
# desc "find the top senders"
# task :top_senders => [:env] do
# limit = ENV["LIMIT"].to_i | 9 # The total amount of records to display
#
# hosts = {}
# Email.all.each do |email|
# hosts[email.address.host] = 0 unless hosts[email.address.host]
# hosts[email.address.host] += 1
# end
#
# result = hosts.sort {|a,b| -1*(a[1] <=> b[1])}
#
# limit = result.count if limit > result.count
# result[0..limit].each do |r|
# puts "#{r[1]}: \t#{r[0]}"
# end
# end
#
# desc "emails from someone"
# task :emails_from => [:env] do
# print "From who: "
# sender = STDIN.gets.chomp
# mails = Address.where(:email => sender).first.emails
# puts "Total: #{mails.count}"
# mails.each do |mail|
# puts "#{mail.time.strftime("%x %X")}: \t#{truncate(mail.subject)}"
# end
# end
#
# desc "reset database"
# task :reset => [:env] do
# # To reset the database
# Email.delete_all
# Address.delete_all
# end
#
# def truncate(message)
# if message.size > 56
# r = message[0..52] + "..."
# else
# r = message
# end
# r
# end
#
# =========================================================
# ======================`email_stats.rb`===================
require "rubygems"
require "bundler/setup"
# Mongo Mapper
require "rubygems"
require "bundler/setup"
require 'mongo_mapper'
MongoMapper.connection = Mongo::Connection.new("localhost", 27017)
MongoMapper.database = 'email-stats'
class Address
include MongoMapper::Document
safe
key :name, String
key :email, String
def host
email.split("@")[1]
end
def mail_name
email.split("@")[0]
end
many :emails
end
class Email
include MongoMapper::Document
safe
key :time, Time, :required => true
key :subject, String
key :message_id, String, :unique => true
belongs_to :address
end
require 'colored'
require 'net/imap'
# Imap settings
# Change gmail to whatever address you want to use
imap = Net::IMAP.new("imap.gmail.com", 993, true)
imap.login ENV['IMAP_USERNAME'], ENV['IMAP_PASSWORD']
# See all mailboxes
# p imap.list("", "%/%")
# Gmail's All Mail inbox.
# Change accordingly depending on
imap.examine('[Gmail]/All Mail')
# Get the search query from start or last email done
search_query = "ALL"
if Email.count > 0
search_query = ["SINCE", (Email.all(:order => :time).last.time).strftime("%d-%b-%Y")]
puts "Expect the first few records to be RED if you are resuming."
end
# - 86400 to get the day before
puts "Searching for: #{search_query}"
imap.search(search_query).each do |message_id|
envelope = imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"]
# The sender of the email
f = envelope.from[0]
address = Address.find_or_initialize_by_email([f.mailbox, f.host].join "@")
if address.id
address.name = f.name
address.save
end
# Make a new email
mail = address.emails.build
# somehow some of my emails didn't have a date
mail.time = Time.parse( envelope.date) if envelope.date
mail.subject = envelope.subject
mail.message_id = envelope.message_id
env_name = "#{envelope.date}: \t#{envelope.subject[0..37] rescue "NO SUBJECT"}"
# Save the new email
if mail.save
puts env_name.green
else
puts env_name.red
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment