Created
December 5, 2011 15:39
-
-
Save mxswd/1433997 to your computer and use it in GitHub Desktop.
Statistics on email activity.
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 | |
# 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