예제 #1
0
        public static byte[] ZipPage(string html, IMapPathResolver mapPathResolver, string webRoot, string pagePath)
        {
            var parser = new AngleSharp.Parser.Html.HtmlParser();
            var doc    = parser.Parse(html);
            var images = doc.Images
                         .Where(x => x.HasAttribute("src"));
            var styles = doc.GetElementsByTagName("link")
                         .Where(l => l.Attributes["rel"].Value.Trim().ToLower() == "stylesheet")
                         .Where(c => c.HasAttribute("href"));
            var scripts = doc.GetElementsByTagName("script")
                          .Where(x => x.HasAttribute("src"));
            var serialAssets = new Dictionary <string, string>();

            serialAssets.AddSerializedAssets(images, "src");
            serialAssets.AddSerializedAssets(scripts, "src");
            var serialStyles = new Dictionary <string, string>();

            serialStyles.AddSerializedAssets(styles, "href");

            var newHtml    = doc.ToHtml(new HtmlMarkupFormatter());
            var doneAssets = new List <string>();

            using (var ms = new MemoryStream())
            {
                using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
                {
                    //foreach (var attachment in attachmentFiles)
                    {
                        var entry = zipArchive.CreateEntry("index.html", CompressionLevel.Fastest);
                        using (StreamWriter writer = new StreamWriter(entry.Open()))
                        {
                            try
                            {
                                writer.Write(newHtml);
                            }
                            catch (Exception ex)
                            {
                                EventLog.WriteEntry("RotativaHQ", ex.Message);
                                throw;
                            }
                            doneAssets.Add("index.html");
                        }
                    }
                    foreach (var serialStyle in serialStyles)
                    {
                        if (!doneAssets.Contains(serialStyle.Value))
                        {
                            var style =
                                GetStringAsset(serialStyle.Key, mapPathResolver, webRoot, pagePath);
                            if (!string.IsNullOrEmpty(style))
                            {
                                var urls = ExtaxtUrlsFromStyle(style);
                                foreach (var url in urls)
                                {
                                    var localPath = ReturnLocalPath(url);
                                    var suffix    = localPath.Split('.').Last();
                                    var newUrl    = Guid.NewGuid().ToString().Replace("-", "") + "." + suffix;
                                    style = style.Replace(url, newUrl);
                                    if (!doneAssets.Contains(newUrl))
                                    {
                                        zipArchive.AddBinaryAssetToArchive(newUrl, localPath, mapPathResolver, webRoot, serialStyle.Key);
                                        doneAssets.Add(newUrl);
                                    }
                                }
                                var sentry = zipArchive.CreateEntry(serialStyle.Value, CompressionLevel.Fastest);
                                using (StreamWriter writer = new StreamWriter(sentry.Open()))
                                {
                                    writer.Write(style);
                                }
                                doneAssets.Add(serialStyle.Value);
                            }
                        }
                    }
                    foreach (var serialAsset in serialAssets)
                    {
                        if (!doneAssets.Contains(serialAsset.Value))
                        {
                            zipArchive.AddBinaryAssetToArchive(
                                serialAsset.Value, serialAsset.Key, mapPathResolver, webRoot, pagePath);
                            doneAssets.Add(serialAsset.Value);
                        }
                    }
                }
                return(ms.ToArray());
            }
        }