Monday, September 28, 2009

Updated Gmail message delete script written for a friend


#!/usr/bin/ruby
#
# usage:
# ------
# delete all messages older than 30 days in myLabel and empty the trash
# ruby g.rb --deletetrash user@gmail.com password myLabel
#
# delete all messages (don't empty trash) older than 30 days old
# ruby g.rb user@gmail.com password
#
#
# notes:
# ------
# earlier version i wrote didn't have a 30 day rule and didn't take
# advantage of the fact the copy and store methods accept sets (ranges)
# so i dropped the multi-threading and iterating through the results array
#
# warning:
# --------
# i was too lazy to test this so if it doesn't work you may have to fix it.
#


# load modules
require 'net/imap'
require 'date'

# declare globals
result = nil
user = ''
pass = ''
label = '[Gmail]/All Mail' # default: process all messages
deletetrash = false # default: make user manually 'Empty Trash now' via web
deletespam = false # default: we don't care about the 'Spam' folder much

# process command line arguments
if(ARGV.size > 1)
if(ARGV[0] == '--deletetrash')
deletetrash = true
ARGV.shift
end
if(ARGV[0] == '--deletetrashspam')
deletetrash = true
deletespam = true
ARGV.shift
end
user = ARGV[0]
pass = ARGV[1]
if(ARGV.size == 3)
label = ARGV[2]
end
else
puts "Usage: ruby g.rb [--deletetrash|--deletetrashspam] <user@gmail.com> <password> [<label>]"
exit(1)
end

# connect to the server
puts "Started at #{Time.now}"
imap = Net::IMAP.new('imap.gmail.com', '993', true)
imap.login(user, pass)
imap.select(label)

# select messages from before date
date = DateTime.now - 4096
result = imap.search(["BEFORE", date.strftime('%d-%b-%Y')])
puts "#{result.length} messages found in "+label+" from before "+date.strftime('%d-%b-%Y')

# move messages to trash
imap.copy(1..result.length, '[Gmail]/Trash')
imap.store(1..result.length, "+FLAGS", [:Deleted])

# expunge (required to finalize move to trash on the server)
puts "Attempting to move #{result.length} messages to trash"
imap.expunge

# do we have to empty the trash, too?
if deletetrash
imap.select('[Gmail]/Trash')
result = imap.search(["SINCE", '1-Jan-1900'])
puts "Attempting to delete all #{result.length} messages in trash..."
imap.store(1..result.length, "+FLAGS", [:Deleted])
imap.expunge
end

# did the user want to clean out the spam folder, too?
if deletespam
imap.select('[Gmail]/Spam')
result = imap.search(["SINCE", '1-Jan-1900'])
puts "Attempting to delete all #{result.length} messages in spam folder..."
imap.store(1..result.length, "+FLAGS", [:Deleted])
imap.expunge
end

# end imap session
imap.logout
# does logout do a disconnect? because calling this throws a socket not connected error
#imap.disconnect

# tell the user we finished
puts "Ended at #{Time.now}"