// 最新版本:3线程同时处理邮件正文、附件
// 以后可以改的地方就是把3线程改成线程池
// 我说为什么这个代码跑得没有foxmail快,估计就是这个原因了
import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.Message;
import javax.mail.Flags.Flag;
import javax.mail.internet.*;
import javax.mail.search.*;
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPMessage;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.PrintWriter;
import java.io.FileWriter;
import java.io.IOException;
class customMsg {
public int total;
public int seq;
public int number;
public customMsg(){}
public customMsg(int total, int seq, int number) {
this.total = total;
this.seq = seq;
this.number = number;
}
};
class Savemail implements Runnable {
public Message msg = null;
public StringBuffer filename = null;
public StringBuffer head = null;
public StringBuffer body = null;
public StringBuffer attachment = null;
public String path = null;
public customMsg cm = null;
final String[] versions = { "", "1.0", "1.1", "1.2", "1.3", "1.4",
"1.5" };
public Savemail() {}
public boolean fileExist(String path, String filename) {
File textFile, attachFile;
for (String ver : versions) {
attachFile = new File(path + "/" + ver + "/" + filename
+ ".attach.txt");
textFile = new File(path + "/" + ver + "/" + filename + ".text.txt");
if (attachFile.exists() || textFile.exists()) {
return true;
}
}
return false;
}
public boolean init() throws Exception{
head = new StringBuffer();
filename = new StringBuffer();
body = new StringBuffer();
attachment = new StringBuffer();
Date d = msg.getReceivedDate();
filename.append("" + (d.getMonth() + 1) + "-" + d.getDate()
+ "-");
filename.append(cm.number);
if (fileExist(path, filename.toString())) {
System.out.println("warning[ "+cm.seq + " already exist! ]");
return false;
}
head.append("Subject: " + msg.getSubject());
head.append("\nFrom: " + msg.getFrom()[0]);
head.append("\nTo: " + msg.getAllRecipients()[0]);
head.append("\nDate: " + msg.getReceivedDate());
return true;
}
public Savemail(Message msg, customMsg cm, String path) {
this.msg = msg;
this.path = path;
this.cm = cm;
}
public String ripHtml(String html) {
StringBuffer sb = new StringBuffer();
String tag = "";
int a = 0, s = 1, t = 1;
while (s >= 0) {
s = html.indexOf("<", a);
t = html.indexOf(">", s);
if (s < 0 || t < 0) {
if (a < html.length())
sb.append(html.substring(a, html.length()));
break;
}
tag = html.substring(s + 1, t);
sb.append(html.substring(a, s));
if (tag.indexOf("br") != -1) {
sb.append("\n");
}
a = t + 1;
}
return sb.toString();
}
public boolean isAttachment(Part part) {
try {
String contenttype = part.getContentType();
String disposition = part.getDisposition();
String filename = part.getFileName();
contenttype = contenttype == null ? "" : contenttype.toLowerCase();
disposition = disposition == null ? "" : disposition.toLowerCase();
filename = filename == null ? "" : filename.toLowerCase();
if (contenttype.indexOf("name") != -1
|| ((disposition.indexOf("attachment") != -1) && (filename
.length() > 0)))
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public void getMailContent(Part part, StringBuffer bodytext,
StringBuffer attachment) throws Exception {
boolean conname = isAttachment(part);
if ((part.isMimeType("text/plain")) && !conname) {
if (bodytext.length() > 0)
bodytext.delete(0, bodytext.length());
bodytext.append((String) part.getContent());
} else if (part.isMimeType("text/html") && !conname) {
if (bodytext.length() == 0)
bodytext.append(ripHtml((String) part.getContent()));
} else if (part.isMimeType("multipart/*")) {
Multipart multipart = (Multipart) part.getContent();
int counts = multipart.getCount();
for (int i = 0; i < counts; i++) {
getMailContent(multipart.getBodyPart(i), bodytext, attachment);
}
} else if (part.isMimeType("message/rfc822")) {
getMailContent((Part) part.getContent(), bodytext, attachment);
} else if (conname && part.isMimeType("text/plain")) {
String contentType = part.getContentType();
String charset = "";
Pattern p = Pattern.compile("charset=([0-9a-zA-Z]*);");
Matcher m = p.matcher(contentType);
if (m.find()) {
charset = m.group(1);
}
if (charset.equalsIgnoreCase("cp932")) {
InputStream is = part.getInputStream();
// filename
char[] temp = new char[1000];
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
int status = reader.read(temp);
while (status != -1) {
attachment.append(temp);
status = reader.read(temp);
}
} else
attachment.append((String) part.getContent());
}
}
public String getVersionName(String body) {
Pattern p = Pattern.compile("VersionName=([0-9\\.]*)");
Matcher m = p.matcher(body);
if (m.find()) {
return m.group(1);
}
return new String("");
}
public void writeToFile(StringBuffer filename, StringBuffer body,
StringBuffer attach, String path) throws Exception {
String versionName = getVersionName(body.toString());
PrintWriter pw1 = null;
PrintWriter pw2 = null;
try {
File file = new File(path + "/" + versionName);
file.mkdirs();
pw1 = new PrintWriter(new FileWriter(path + "/" + versionName + "/"
+ filename.toString() + ".attach.txt"));
pw2 = new PrintWriter(new FileWriter(path + "/" + versionName + "/"
+ filename.toString() + ".text.txt"));
pw1.println(attach.toString());
pw2.println(body.toString());
} catch (IOException e) {
throw e;
} finally {
if (pw1 != null)
pw1.close();
if (pw2 != null)
pw2.close();
}
}
public void run() {
try {
System.out.println("# MESSAGE " + cm.seq + "/"
+ cm.total + " , " + cm.number);
if(!init())
return;
getMailContent(msg, body, attachment);
writeToFile(filename, head.append(body), attachment, path);
} catch (Exception e) {
System.out.println(head);
System.out.println(filename);
e.printStackTrace();
}
}
}
public class FolderFetchIMAP {
IMAPFolder folder = null;
Store store = null;
Flag flag = null;
public static Thread th1 = null;
public static Thread th2 = null;
public static Thread th3 = null;
public void init(String username, String password) {
// init...
try {
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
Session session = Session.getDefaultInstance(props, null);
store = session.getStore("imaps");
store.connect("imap.googlemail.com", username, password);
folder = (IMAPFolder) store.getFolder("inbox");
if (!folder.isOpen())
folder.open(Folder.READ_ONLY);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
public Message[] getMsgAfterDate(String date) {
try {
SearchTerm st = new SentDateTerm(SentDateTerm.GT,
getSearchDate(date));
return folder.search(st);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private void fetchMail(String username, String password, String date,
String path) throws MessagingException, IOException {
try {
init(username, password);
Message[] messages = getMsgAfterDate(date);
System.out.println("Num of Messages : " + messages.length);
for (int i = 0; i < messages.length; i++) {
if(i<2198) continue;
Message msg = messages[i];
customMsg cm = new customMsg(messages.length, i+1, msg.getMessageNumber());
try {
Savemail h1 = new Savemail(msg, cm, path);
while (true) {
if (th1 == null || !th1.isAlive()) {
th1 = new Thread(h1);
th1.start();
break;
}
if (th2 == null || !th2.isAlive()) {
th2 = new Thread(h1);
th2.start();
break;
}
if (th3 == null || !th3.isAlive()) {
th3 = new Thread(h1);
th3.start();
break;
}
}
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
boolean ending = true;
while(th1.isAlive() || th2.isAlive())
{
if(ending) {
System.out.println("Will exit soon...");
ending = false;
}
}
if (folder != null && folder.isOpen()) {
folder.close(true);
}
if (store != null) {
store.close();
}
}
}
private Date getSearchDate(String date) {
String[] ymd = date.split("-");
int year, month, day;
Date srchdate = null;
try {
year = Integer.parseInt(ymd[0]);
month = Integer.parseInt(ymd[1]) - 1;
day = Integer.parseInt(ymd[2]);
Calendar cal = Calendar.getInstance();
cal.set(year, month, day);
srchdate = cal.getTime();
} catch (Exception ex) {
ex.printStackTrace();
}
return srchdate;
}
public static void main(String[] args) throws MessagingException,
IOException {
FolderFetchIMAP mail = new FolderFetchIMAP();
if (args.length >= 3) {
String path = "";
if (args.length == 4)
path = args[3];
mail.fetchMail(args[0], args[1], args[2], path);
}
}
}