Wednesday, August 3, 2011

Groovy Script to Tame Gmail Attachments

I like Gmail but it has a big short coming: you can't sort mail by attachment size. This means that if you are running out of space in your Gmail account, you can't easily find large attachments like that 25MB video that your friend sent you of his kid's graduation or other large attachment that you really would like to get rid of. There are sites like findbigmail.com that will help you find large attachments, but the downside is that you have to trust them and allow them to read all of your email. I'm a little paranoid so that wasn't something I was willing to do.

I also like Groovy and so I wrote a little Groovy script that finds large attachments in Gmail and gives them a custom label so you can easily find them. The script uses JavaMail which depends on the JavaBeans Activation Framework (activation.jar). Both jars need to be in the classpath along with the Groovy jar.

The first part of the code makes a connection to Gmail.

import javax.mail.*
import java.util.Properties
def emailAddress = "you@gmail.com"
def password = "password"
def server = "imap.gmail.com"
def port = 993
def OneMB = 1024000
def FiveMB = 5120000
def props = new Properties()
props.setProperty("mail.store.protocol", "imaps")
props.setProperty("mail.imaps.host", server)
props.setProperty("mail.imaps.port", port.toString())
def session = Session.getDefaultInstance(props,null)
def store = session.getStore("imaps")
store.connect(emailAddress, password)
println "connected to Gmail"
Then we define the labels that we want to add. Labels in Gmail are called folders in JavaMail.
def bigAttachmentFolder = store.getFolder("1MB+ attachment")
if (!bigAttachmentFolder.exists()) {
bigAttachmentFolder.create(Folder.HOLDS_MESSAGES)
}
def hugeAttachmentFolder = store.getFolder("5MB+ attachment")
if (!hugeAttachmentFolder.exists()) {
hugeAttachmentFolder.create(Folder.HOLDS_MESSAGES)
}
Next the script iterates through all of the emails looking for attachments. If a large attachment is found, it is copied into a folder which in Gmail adds the appropriate label to it.
def folder = store.getFolder("[Gmail]/All Mail")
folder.open(Folder.READ_ONLY)
folder.messages.each { msg ->
try {
def content = msg.content
if (content instanceof Multipart) {
for (i in 0..(content.count - 1)) {
BodyPart bodyPart = content.getBodyPart(i)
if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.disposition)
&& bodyPart.size > OneMB) {
println "big attachment: ${bodyPart.fileName} = ${bodyPart.size}"
folder.copyMessages([msg] as Message[], bigAttachmentFolder);
if (bodyPart.size > FiveMB) {
folder.copyMessages([msg] as Message[], hugeAttachmentFolder);
}
}
}
}
} catch (Exception ignore) {
println "error processing message, no big deal, moving on"
}
}
println "-----------done------------"
That's it! If you modify the script with your email address and password, and then run it, your Gmail account will get 2 new labels: "1MB+ attachments" and "5MB+ attachments" that will allow you find and delete big attachments quickly. The code is pretty concise, and the JavaMail API looks better in Groovy in my opinion.

2 comments:

  1. Hi Joel!

    I have been looking for a solution to get rid of big attachments in Gmail for quite a while and finally stumbled upon your blog post, which sounds like a great solution. Unfortunately, I am not a programmer so I can not directly use you suggestion. But I will certainly invest some time to set up the required tools. I would be very grateful if you can give me a hint how to get started.

    Thank you,
    Peter

    ReplyDelete
  2. I managed to get it running! Google really is my friend. ;-) And you, Joel, of course. Thank you!

    ReplyDelete