void BackupToXML() { var foo = GetiPhoneBackupMessages(); //int count = 0; //int good = 0; //foreach (var item in foo.mms) //{ // if (item.Parts.Count == 1 && item.Parts[0].ct == "test/plain") // continue; // foreach (var p in item.Parts) // { // string f = MiscUtil.getSHAHash(p.cd); // f = f.Substring(0, 2) + "\\" + f; // f = Path.Combine(dbFileDir, f); // if (File.Exists(f)) // good++; // } // count += item.Parts.Count; //} //WriteLine(string.Format("{0} attachments found, {1} good.", count, good)); AndroidXml xml = new AndroidXml() { MMSMessages = foo.mms, SMSMessages = foo.sms }; xml.SortMMS(); xml.SortSMS(); string mFile; string path = Path.Combine(_outputFolder, "Files"); string file; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } bool changedname = false; foreach (AndroidMMS item in xml.WriteAndroidXMLFillingMMS(Path.Combine(_outputFolder, string.Format("sms_iPhoneSMS_{0:yyMMddhhmmss}.xml", DateTime.Now)))) { foreach (Part part in item.Parts) { changedname = false; if (item.Parts.Count == 1 && item.Parts[0].ct == "text/plain" || string.IsNullOrEmpty(part.name)) { // this is a text-only mms group message continue; } mFile = MiscUtil.getSHAHash(part.cd); mFile = mFile.Substring(0, 2) + "\\" + mFile; mFile = Path.Combine(dbFileDir, mFile); if (!File.Exists(mFile)) { // almost all the missing files are vcards or vlocations; nothing to do about this--iPhone doesn't keep them apparently WriteLine("Couldn't find file " + mFile); part.cd = "null"; continue; } file = Path.Combine(path, item.date.ToString("yyMMddhhmmss")); if (!Directory.Exists(file)) { Directory.CreateDirectory(file); } file = Path.Combine(file, part.name); while (!File.Exists(file)) { File.Copy(mFile, file); //changedname = true; //int i = file.LastIndexOf("."); //int j = i - 1; //while (j > 0 && file[j] != '(') // j--; //if (j == 0) // file = file.Substring(0, i) + "(2)" + file.Substring(i); //else // file = file.Substring(0, j) + "(" + (int.Parse(file.Substring(j + 1, i - 2 - j)) + 1).ToString() + ")" + file.Substring(i); } //if (changedname) // WriteLine(file); part.cd = "null"; switch (part.ct) { case "audio/amr": case "video/3gpp": case "video/mp4": case "image/gif": case "image/jpeg": case "image/png": case "video/quicktime": //part.data = Convert.ToBase64String(File.ReadAllBytes(mFile)); break; case "text/plain": case "text/vcard": case "text/x-vcard": case "text/x-vlocation": break; } } } //xml.WriteAndroidXML(Path.Combine(_outputFolder, string.Format("sms_iPhoneSMS_{0}.xml", DateTime.Now))); }
/// <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; }