/// <summary> /// Appends a downloaded external binary file to our MhtBuilder using Base64 encoding /// </summary> void AppendMhtBinaryFile(MhtWebFile ef) { AppendMhtBoundary(); AppendMhtLine("Content-Type: " + ef.ContentType); AppendMhtLine("Content-Transfer-Encoding: base64"); AppendMhtLine("Content-Location: " + ef.Url); AppendMhtLine(); // note that chunk size is equal to maximum line width (expanded = 75 chars) int len = ef.DownloadedBytes.Length; if (len <= _ChunkSize) { AppendMhtLine(Convert.ToBase64String(ef.DownloadedBytes, 0, len)); } else { int i = 0; while ((i + _ChunkSize) < len) { AppendMhtLine(Convert.ToBase64String(ef.DownloadedBytes, i, _ChunkSize)); i += _ChunkSize; } if (i != len) { AppendMhtLine(Convert.ToBase64String(ef.DownloadedBytes, i, len - i)); } } }
/// <summary> /// Download a single externally referenced file (if we haven't already downloaded it) /// </summary> void DownloadExternalFile(string url, string targetFolder, bool recursive) { bool isNew; MhtWebFile wf; // have we already downloaded (or attempted to) this file? if (_Builder.WebFiles.Contains(url) || _Builder.Url == url) { wf = (MhtWebFile)_Builder.WebFiles[url]; isNew = false; } else { wf = new MhtWebFile(_Builder, url); isNew = true; } wf.Download(); if (isNew) { // add this (possibly) downloaded file to our shared collection _Builder.WebFiles.Add(wf.UrlUnmodified, wf); // if this is an HTML file, it has dependencies of its own; // download them into a subfolder if ((wf.IsHtml || wf.IsCss) && recursive) { wf.DownloadExternalFiles(recursive); } } }
/// <summary> /// Appends a downloaded external text file to our MhtBuilder using Quoted-Printable encoding /// </summary> void AppendMhtTextFile(MhtWebFile ef) { AppendMhtBoundary(); AppendMhtLine("Content-Type: " + ef.ContentType + ";"); AppendMhtLine(Convert.ToChar(9).ToString() + @"charset="" + ef.TextEncoding.WebName + @"""); AppendMhtLine("Content-Transfer-Encoding: quoted-printable"); AppendMhtLine("Content-Location: " + ef.Url); AppendMhtLine(); AppendMhtLine(QuotedPrintableEncode(ef.ToString(), ef.TextEncoding)); }
/// <summary> /// Appends a downloaded external file to our MhtBuilder /// </summary> void AppendMhtFile(MhtWebFile ef) { if (ef.WasDownloaded && !ef.WasAppended) { if (ef.IsBinary) { AppendMhtBinaryFile(ef); } else { AppendMhtTextFile(ef); } } ef.WasAppended = true; }
/// <summary> /// appends the Mht header, which includes the root HTML /// </summary> void AppendMhtHeader(MhtWebFile ef) { // clear the stringbuilder contents _MhtBuilder = new StringBuilder(); //AppendMhtLine("From: <Saved by " + Environment.UserName + " on " + Environment.MachineName + ">"); //AppendMhtLine("Subject: " + ef.HtmlTitle); // For the title, reduces its size if too long and removes line breaks if any. string title = ef.HtmlTitle; if (title != null) { if (title.Length > 260) { title = title.Substring(0, 260); } if (title.IndexOf('\n') != -1) { title = title.Replace('\n', ' '); } if (title.IndexOf(Environment.NewLine) != -1) { title = title.Replace(Environment.NewLine, " "); } } AppendMhtLine("From: <Saved by " + Environment.UserName + " on " + Environment.MachineName + ">"); AppendMhtLine("Subject: " + title); AppendMhtLine("Date: " + DateTime.Now.ToString("ddd, dd MMM yyyy HH:mm:ss zzz")); AppendMhtLine("MIME-Version: 1.0"); AppendMhtLine("Content-Type: multipart/related;"); AppendMhtLine(Convert.ToChar(9).ToString() + "type=\"text/html\";"); AppendMhtLine(Convert.ToChar(9).ToString() + "boundary=\"----=_NextPart_000_00\""); AppendMhtLine("X-MimeOLE: Produced by " + this.GetType().ToString() + " " + Assembly.GetExecutingAssembly().GetName().Version.ToString()); AppendMhtLine(""); AppendMhtLine("This is a multi-part message in MIME format."); AppendMhtFile(ef); }
/// <summary> /// converts all external Html files (gif, jpg, css, etc) to local refs /// external ref: /// <img src="http://mywebsite/myfolder/myimage.gif"> /// into local refs: /// <img src="mypage_files/myimage.gif"> /// </summary> public void ConvertReferencesToLocal() { if (!this.IsHtml && !this.IsCss) { throw new Exception("Converting references only makes sense for HTML or CSS files; this file is of type '" + this.ContentType + "'"); } // get a list of all external references string html = this.ToString(); NameValueCollection fileCollection = this.ExternalHtmlFiles(); // no external refs? nothing to do if (fileCollection.Count == 0) { return; } string[] keys = fileCollection.AllKeys; for (int idx = 0; idx < keys.Length; idx++) { string delimitedUrl = keys[idx]; string fileUrl = fileCollection[delimitedUrl]; if (_Builder.WebFiles.Contains(fileUrl)) { MhtWebFile wf = (MhtWebFile)_Builder.WebFiles[fileUrl]; string newPath = this.ExternalFilesFolder + "/" + wf.DownloadFilename; string delimitedReplacement = Regex.Replace(delimitedUrl, @"^(?<StartDelim>""|'|\()*(?<Value>[^'"")]*)(?<EndDelim>""|'|\))*$", "${StartDelim}" + newPath + "${EndDelim}"); // correct original Url references in Html so they point to our local files html = html.Replace(delimitedUrl, delimitedReplacement); } } _DownloadedBytes = _TextEncoding.GetBytes(html); }
public MhtBuilder() { _HtmlFile = new MhtWebFile(this); }