/// <summary> /// Export all messages for MessageGroup in backup file into HTML file. (THREAD) /// </summary> private void exportHTMLForMessageGroup(iPhoneBackup.MessageGroup group) { StringBuilder sb = new StringBuilder(); //string group = string.Join(",", grp.Ids); //bool isGroupMessage = group.Ids.Count > 1; // (group.Contains(",")) ? true : false; // query database if (dbFile != null) { // open SQLite data file SQLiteConnection m_dbConnection; m_dbConnection = new SQLiteConnection("Data Source=" + dbFile + ";Version=3;Read Only=True;FailIfMissing=True;"); m_dbConnection.Open(); int totalMessages = 1; Stopwatch sw = Stopwatch.StartNew(); List <iPhoneBackup.Message> msgs = _backup.GetMessages(group.ChatId); List <iPhoneBackup.MessageGroup> chats = _backup.GetChats(); iPhoneBackup.MessageGroup chat; totalMessages = msgs.Count; TraceInformation("get messages: {0} ms", sw.ElapsedMilliseconds); sw.Restart(); sb.AppendLine(iPhoneSMS.Properties.Resources.HTMLHeaders); // add html headers sb.AppendLine("<BODY>"); sb.AppendFormat("<H1>Messages from {0}</H1>\n", group.ToString()); sb.AppendFormat("<H2>as of {0}</H2>\n", dbFileDate); sb.AppendLine("<DIV id=\"messages\">"); // fields: date, service, direction, id, text, filereflist int i = 0; string mFile; foreach (iPhoneBackup.Message row in msgs) { string content = row.Text; // (string)row["text"]; sb.AppendFormat("<DIV class=\"message message-{0}-{1}\">\n", row.Incoming ? "RCVD" : "SENT", row.Type); // row["direction"], row["service"]); sb.AppendFormat("<DIV class=\"timestamp-placeholder\"></DIV><DIV class=\"timestamp\">{0}</DIV>\n", row.Timestamp); // row["date"]); //Assert(isGroupMessage == row.IsGroup); chat = chats.Find(q => q.ChatId == row.ChatId); if (chat.Ids.Count > 1) // it's a group chat { sb.AppendFormat("<DIV class=\"sender\">{0}</DIV>\n", _iPhone.IdToName(row.Sender)); // row["id"]); } // replace image placeholders () with image files //if (row["filereflist"].ToString().Length > 0) if (row.Attachments != null && row.Attachments.Count > 0) { //List<string> mediaFileList = row["filereflist"].ToString().Split(',').ToList(); foreach (var mediaFile in row.Attachments) { mFile = mediaFile.FileName; if (mFile.StartsWith("~")) { mFile = "MediaDomain-" + mFile.Substring(2); } else { mFile = "MediaDomain-" + mFile.Substring(12); } mFile = MiscUtil.getSHAHash(mFile); mFile = mFile.Substring(0, 2) + "\\" + mFile; mFile = Path.Combine(dbFileDir, mFile); string replace = null; // get extension of mediaFile switch (mediaFile.FileName.Substring(mediaFile.FileName.LastIndexOf('.')).ToLower()) { // image case ".jpeg": case ".jpg": case ".png": replace = string.Format("<img src=\"{0}\"><!-- {1}//-->", mFile, mediaFile); break; case ".mov": replace = string.Format("<video controls='controls' width='300' name='video' src='{0}'></video>", mFile); break; case ".vcf": string contents = File.ReadAllText(mFile); int j = contents.IndexOf("FN:"); int k = contents.IndexOf("\r", j + 3); contents = contents.Substring(j + 3, k - j - 3); replace = "Contact: " + contents; break; case ".pluginpayloadattachment": replace = string.Format("<p>Link: {0}</p>", mFile); replace = content; break; default: replace = ""; break; } // do switch statement for replacement string Regex rgx = new Regex(@"\[MEDIA\]"); content = rgx.Replace(content, replace, 1); } } sb.AppendFormat("<DIV class=\"content\">{0}</DIV>\n", content); sb.AppendLine("</DIV>"); i++; backgroundWorker1.ReportProgress(i * 100 / totalMessages); } sb.AppendLine("</DIV>"); sb.AppendLine("</BODY>"); sb.AppendLine("</HTML>"); TraceInformation("Creating html: {0} ms", sw.ElapsedMilliseconds); //set.Dispose(); //adpt.Dispose(); m_dbConnection.Close(); } // regex replacements // REGEX: change phone number format (+12257490000 => (225)749-0000) string htmlOutput = sb.ToString(); htmlOutput = Regex.Replace(htmlOutput, @"\+1(\d{3})(\d{3})(\d{4})\b", "($1) $2-$3"); // REGEX: change date format (2015-01-01 00:00 => 01/01/2015 12:00am) htmlOutput = Regex.Replace(htmlOutput, @"(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})", delegate(Match match) { int hour = int.Parse(match.ToString().Substring(11, 2)); string suffix = (hour < 12) ? "am" : "pm"; if (hour == 0) { hour += 12; } else if (hour > 12) { hour -= 12; } string replace = "$2/$3/$1 " + hour + ":$5" + suffix; return(match.Result(replace)); }); // output html data string file = Path.GetTempFileName() + ".html"; File.WriteAllText(file, htmlOutput); ShowBrowser(file); return; }