async Task SaveMessage(StreamWriter filew, StreamWriter indexw, String mailbox, String message, String msgid, String msgnum) { try { String status = (String)lbStatus.Items[lbStatus.Items.Count - 1]; Regex re = new Regex("^((\"[^\"]+\")|([^\" ]+) - [0-9]+ messages: )"); Match m = re.Match(status); if (m.Success) { Status(true, "", "{0} {1}", m.Groups[1].Value, msgnum); } try { String postmark = EmailParser.MakePostmark(message); await filew.WriteAsync(postmark); await filew.WriteAsync("\r\n"); } catch (AlreadyExistsException) { } await filew.WriteAsync("X-Gmail-Labels: " + mailbox); await filew.WriteAsync("\r\n"); await indexw.WriteLineAsync(mailbox + (msgid != "" ? " " + msgid : "")); } finally { await filew.WriteAsync(message); if (message.Length > 0 && message[message.Length - 1] != '\n') { await filew.WriteAsync("\r\n"); } } }
async Task <bool> Resume(String addr) { if (File.Exists(txtDownload.Text) == false) { System.Windows.Forms.MessageBox.Show("Enter file to resume download"); return(false); } await EmailParser.ParseToResume(cancelSrc.Token, addr, txtUser.Text, txtDownload.Text, (f, o) => { Status(false, "", f, o); }, (v) => { prBar.Value = v; }); return(cancelSrc.Token.IsCancellationRequested == false); }
public async Task <ParseResult> Parse(MessageReader reader) { String line = null; while ((line = await reader.ReadLineAsync()) != null) { if (EmailParser.IsPostmark(line)) { WriteWithCrlf(line); // assume the Postmark always starts with 0 position size = (int)entity.Position; return(ParseResult.Ok); } } return(ParseResult.Failed); }
protected async Task ConsumeToEnd(MessageReader reader) { ParseResult res = ParseResult.Ok; while (res != ParseResult.Eof) { String line = await reader.ReadLineAsync(); if (line == null) { break; } else if (EmailParser.IsPostmark(line)) { reader.PushCacheLine(line); break; } else { WriteWithCrlf(line); } } }
public async Task Start(String dir, String file, StatusCb status, ProgressCb pcb) { StreamWriter filew = null; try { status(false, "", "Started statistics processing."); MessageReader reader = new MessageReader(file); long size = reader.BaseStream.Length; double progress = .0; StringBuilder sb = new StringBuilder(); sb = new StringBuilder(); sb.AppendFormat(@"{0}\stats{1}.out", dir, DateTime.Now.ToFileTime()); file = sb.ToString(); filew = new StreamWriter(file); DateTime start_time = DateTime.Now; await WriteStatsLine(filew, "archive size: {0}\n", size); int count = 1; await EmailParser.ParseMessages(token, reader, async delegate(Message message, Exception reason) { status(true, "^message:", "message: {0}", count++); try { if (null == message) { status(false, "", "message parsing failed: " + (null != reason ? reason.Message : "")); await WriteStatsLine(filew, "--> start"); await WriteStatsLine(filew, "<-- end failed to process: {0}", (null != reason) ? reason.Message : ""); return; } // display progress progress += message.size; double pct = (100.0 * progress / (double)size); pcb(pct); // get required headers Dictionary <String, String> headers = message.email.headers.GetDictionary(new Dictionary <string, string>() { { "from", "" }, { "cc", "" }, { "subject", "" }, { "date", "" }, { "to", "" }, { "bcc", "" }, { "in-reply-to", "" }, { "reply-to", "" }, { "content-type", "" }, { "message-id", "" }, { "x-gmail-labels", "" } }); String msgid = headers["message-id"]; // get unique messages if (msgid != null && msgid != "" && MessageidUnique(msgid) == false) { return; } await WriteStatsLine(filew, "--> start"); int csize = await CompressedSize(message.GetBytes()); await WriteStatsLine(filew, "Full Message: {0} {1}", message.size, csize); await WriteStatsLine(filew, "Hdrs"); await WriteStatsLine(filew, "from: {0}", Sha1(EmailAddr(headers["from"]))); await WriteStatsLine(filew, "to: {0}", GetAddrList(headers["to"])); await WriteStatsLine(filew, "cc: {0}", GetAddrList(headers["cc"])); await WriteStatsLine(filew, "bcc: {0}", GetAddrList(headers["bcc"])); await WriteStatsLine(filew, "date: {0}", headers["date"]); await WriteStatsLine(filew, "subject: {0}", GetSubject(headers["subject"])); await WriteStatsLine(filew, "mailbox: {0}", GetMailbox(headers["x-gmail-labels"])); await WriteStatsLine(filew, "messageid: {0}", GetMessageId(headers["message-id"])); await WriteStatsLine(filew, "inreplyto: {0}", GetInReplyTo(headers["in-reply-to"])); await WriteStatsLine(filew, "replyto: {0}", GetAddrList(headers["reply-to"])); await WriteStatsLine(filew, "Parts:"); await TraverseEmail(filew, 0, 0, message.email); await WriteStatsLine(filew, "<-- end"); } catch (Exception ex) { await WriteStatsLine(filew, "<-- end failed to process: {0}, {1}", ex.Message, ex.StackTrace); } }); status(false, "", "Statistics is generated in file {0}", file); TimeSpan span = DateTime.Now - start_time; status(false, "", "Processing time: {0} seconds", span.TotalSeconds); } catch (Exception ex) { status(false, "", "Statistics failed: {0}", ex.Message); } finally { if (filew != null) { filew.Close(); } } }
public async Task <ParseResult> Parse(MessageReader reader, ContentType type = ContentType.Text, ContentSubtype subtype = ContentSubtype.Plain, Boundary boundary = null) { if (type == ContentType.Multipart) { dataType = DataType.Multipart; while (true) { String line = await reader.ReadLineAsync(); if (line == null) { SetSize(); return(ParseResult.Eof); } else if (EmailParser.IsPostmark(line)) { // consumed too much, probably missing boundary? reader.PushCacheLine(line); SetSize(); return(ParseResult.Postmark); } WriteWithCrlf(line); // find open boundary if (boundary.IsOpen(line)) { Email email = null; ParseResult res; do { // consume all parts, consisting of header (optional) and content // the boundary token delimets the part // the close boundary completes multipart parsing // content in the multipart is responsible for consuming it's delimeter (end) // exception is the last part which is also multipart email = new Email(entity); Add(email); } while ((res = await email.Parse(reader, type, subtype, boundary)) == ParseResult.OkMultipart); // Ok // if the last part is a multipart or message? itself then it doesn't consume the close boundary // or more parts, continue parsing until all parts and close boundary are consumed /*if (Ok(res) && (data.Last<Email>().content.dataType == DataType.Multipart || * data.Last<Email>().content.dataType == DataType.Message))*/ if (res == ParseResult.Ok && boundary.NotClosed()) { continue; } if (res != ParseResult.Failed) { SetSize(); } return(res); } else if (boundary.IsClose(line, reader)) { SetSize(); return(ParseResult.Ok); // OkMultipart } } } else if (type == ContentType.Message) { dataType = DataType.Message; Email email = new Email(entity); Add(email); ParseResult res = await email.Parse(reader, type, subtype, boundary); if (res != ParseResult.Failed) { SetSize(); } return(res); } else { dataType = DataType.Data; while (true) { String line = await reader.ReadLineAsync(); if (line == null) { SetSize(); return(ParseResult.Eof); } else if (EmailParser.IsPostmark(line)) { // consumed too much, probably closing boundary is missing ? reader.PushCacheLine(line); SetSize(); return(ParseResult.Postmark); } else if (boundary != null && boundary.IsOpen(line)) { SetSize(); RewindLastCrlfSize(); WriteWithCrlf(line); return(ParseResult.OkMultipart); //Ok } else if (boundary != null && boundary.IsClose(line, reader)) { SetSize(); RewindLastCrlfSize(); WriteWithCrlf(line); return(ParseResult.Ok); //OkMultipart } else { WriteWithCrlf(line); } } } }