Wednesday, June 22, 2011

Email attachment downloader

This simple java program uses java mail to connect to a pop mail server and reads inbox, iterates through the inbox messages and then downloads the message attachments if any.

Steps:
1. Make a session with aunthenticator
2. Get the Store and call store the connect.
3. Get the folder "INBOX" from the store and open it for read and write.
4. Read the attachement Part by part.getInputStream()
5. write the read bytes to the output file stream

Some properties values to be used:
a. user : name of the user on the email server like abc.kk@abcmail.com
b. password : user's passoword for authentication
c. protocol : pop3 or any other protocol for reading mails
d. attachment : directory location for attachment downloads




public void doEMailDownload( ) throws Exception {
// Create empty properties
// Properties props = new Properties();

Properties props = new Properties();

// Get the session
// Session session = Session.getInstance(props, null);
Session session = Session.getDefaultInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication( receiving_user, receiving_pass );
}
});

// Get the store
Store store = session.getStore(receiving_protocol);
store.connect(receiving_host, receiving_user, receiving_pass);

// Get folder
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_WRITE);

try {

// Get directory listing
Message messages[] = folder.getMessages();
EmailPolicy emailPolicy = new EmailPolicy();

for (int i=0; i < messages.length; i++) {
// get the details of the message:
EMail email = new EMail();

email.subject = messages[i].getSubject();

/* filter Email Inbox as per some download policy */

if ( ! emailPolicy.checkAllPolicies( messages[i] ) ) {
continue;
}

email.fromaddr = messages[i].getFrom()[0].toString();
Address[] to = messages[i].getRecipients(Message.RecipientType.TO);
email.toaddr = "";
for(int j = 0; j < to.length; j++){
email.toaddr += to[j].toString() + "; ";
}
Address[] cc;
try {
cc = messages[i].getRecipients(Message.RecipientType.CC);
} catch (Exception e){
System.out.println("Exception retrieving CC addrs: %s" + e.getLocalizedMessage());
cc = null;
}
email.cc = "";
if(cc != null){
for(int j = 0; j < cc.length; j++){
email.cc += cc[j].toString() + "; ";
}
}
email.subject = messages[i].getSubject();
if(messages[i].getReceivedDate() != null){
email.received_when = messages[i].getReceivedDate().getTime();
} else {
email.received_when = new java.util.Date().getTime();
}


email.body = "";
Vector vema = new Vector();
Object content = messages[i].getContent();
if(content instanceof java.lang.String){
email.body = (String)content;
} else if(content instanceof Multipart){
Multipart mp = (Multipart)content;

for (int j=0; j < mp.getCount(); j++) {
Part part = mp.getBodyPart(j);

String disposition = part.getDisposition();

if (disposition == null) {
// Check if plain
MimeBodyPart mbp = (MimeBodyPart)part;
if (mbp.isMimeType("text/plain")) {

email.body += (String)mbp.getContent();
} else {
// Special non-attachment cases here of
// image/gif, text/html, ...
EMailAttach ema = new EMailAttach();
ema.name = decodeName(part.getFileName());

if ( ! isAllowedAttachment( ema.name ) ) continue;

File savedir = new File(receiving_attachments);
if ( savedir.exists() ) {
savedir.mkdirs();
}
//File savefile = File.createTempFile("emailattach", ".atch", savedir );
File savefile = new File( savedir, ema.name );
ema.path = savefile.getAbsolutePath();
ema.size = part.getSize();
vema.add(ema);
ema.size = saveFile(savefile, part);
}
} else if ((disposition != null) &&
(disposition.equals(Part.ATTACHMENT) || disposition.equals(Part.INLINE) )
){
// Check if plain
MimeBodyPart mbp = (MimeBodyPart)part;
if (mbp.isMimeType("text/plain")) {
System.out.println("Mime type is plain");
email.body += (String)mbp.getContent();
} else {
System.out.println("Save file (%s)" + part.getFileName() );
EMailAttach ema = new EMailAttach();
ema.name = decodeName(part.getFileName());
File savedir = new File(receiving_attachments);
savedir.mkdirs();
//File savefile = File.createTempFile("emailattach", ".atch", savedir );
File savefile = new File( savedir, ema.name );
ema.path = savefile.getAbsolutePath();
ema.size = part.getSize();
vema.add(ema);
ema.size = saveFile( savefile, part);
}
}
}
}


// Finally delete the message from the server.
//messages[i].setFlag(Flags.Flag.DELETED, true);
}

// Close connection
folder.close(true); // true tells the mail server to expunge deleted messages.
store.close();
} catch (Exception e){
folder.close(true); // true tells the mail server to expunge deleted messages.
store.close();
throw e;
}

}

public static class EMail {
public String fromaddr;
public String toaddr;
public String cc;
public String subject;
public long received_when;
public String body;
}

/**
*
*/
public static class EMailAttach {
public String name;
public String path;
public int size;
}

/**
*
* @param saveFile
* @param part
* @return
* @throws Exception
*/
protected int saveFile(File saveFile, Part part) throws Exception {

BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(saveFile) );

byte[] buff = new byte[2048];
InputStream is = part.getInputStream();
int ret = 0, count = 0;
while( (ret = is.read(buff)) > 0 ){
bos.write(buff, 0, ret);
count += ret;
}
bos.close();
is.close();
return count;
}

protected String decodeName( String name ) throws Exception {
if(name == null || name.length() == 0){
return "unknown";
}
String ret = java.net.URLDecoder.decode( name, "UTF-8" );

// also check for a few other things in the string:
ret = ret.replaceAll("=\\?utf-8\\?q\\?", "");
ret = ret.replaceAll("\\?=", "");
ret = ret.replaceAll("=20", " ");

return ret;
}