public void CompressDirectory_CompressBookWithExtraHtmlFiles_ExtrasAreIgnored() { // Seeing w:stdPr (part of urn:schemas-microsoft-com:office:word) would cause XmlHtmlConvert.GetXmlDomFromHtml to crash string htmContents = "<html><body><w:sdtPr></w:sdtPr></body></html>"; // Setup // SetupDirectoryWithHtml(kMinimumValidBookHtml, actionsOnFolderBeforeCompressing: folderPath => { // We expect this file to just be passed through, but not parsed string extraHtmDir = Path.Combine(folderPath, "unnecessaryExtraFiles"); Directory.CreateDirectory(extraHtmDir); File.WriteAllText(Path.Combine(extraHtmDir, "causesException.htm"), htmContents); }); if (_bookFolder == null) { Assert.Fail("Test setup error: Test setup failed to initialize bookFolder."); } // System Under Test // using (var bloomPubTempFile = TempFile.WithFilenameInTempFolder("BookCompressorBloomPub" + BookCompressor.BloomPubExtensionWithDot)) { BookCompressor.CompressBookDirectory(bloomPubTempFile.Path, _bookFolder.Path, ""); } // Verification // // Just make sure it didn't crash return; }
/// <summary> /// Makes a BloomPack of the specified dir. /// </summary> /// <param name="path">The path to write to. Precondition: Must not exist.</param> internal void MakeBloomPackInternal(string path, string dir, string dirNamePrefix, bool forReaderTools, bool isCollection) { var excludeAudio = true; // don't want audio in bloompack if (isCollection) { BookCompressor.CompressCollectionDirectory(path, dir, dirNamePrefix, forReaderTools, excludeAudio); } else { BookCompressor.CompressBookDirectory(path, dir, dirNamePrefix, forReaderTools, excludeAudio); } }
/// <summary> /// Create a Bloom Digital book (the zipped .bloompub file) as used by BloomReader (and Bloom Library etc) /// </summary> /// <param name="outputPath">The path to create the zipped .bloompub output file at</param> /// <param name="bookFolderPath">The path to the input book</param> /// <param name="bookServer"></param> /// <param name="backColor"></param> /// <param name="progress"></param> /// <param name="tempFolder">A temporary folder. This function will not dispose of it when done</param> /// <param name="creator">value for <meta name="creator" content="..."/> (defaults to "bloom")</param> /// <param name="isTemplateBook"></param> /// <param name="settings"></param> /// <returns>Path to the unzipped .bloompub</returns> public static string CreateBloomPub(string outputPath, string bookFolderPath, BookServer bookServer, IWebSocketProgress progress, TemporaryFolder tempFolder, string creator = kCreatorBloom, bool isTemplateBook = false, AndroidPublishSettings settings = null) { var modifiedBook = PrepareBookForBloomReader(bookFolderPath, bookServer, tempFolder, progress, isTemplateBook, creator, settings); // We want at least 256 for Bloom Reader, because the screens have a high pixel density. And (at the moment) we are asking for // 64dp in Bloom Reader. BookCompressor.MakeSizedThumbnail(modifiedBook, modifiedBook.FolderPath, 256); BookCompressor.CompressBookDirectory(outputPath, modifiedBook.FolderPath, "", reduceImages: true, omitMetaJson: false, wrapWithFolder: false, pathToFileForSha: BookStorage.FindBookHtmlInFolder(bookFolderPath)); return(modifiedBook.FolderPath); }
public void CompressDirectory_CompressBooksWithBackgroundAudioFiles() { // Setup // var bookHtml = @"<html><head><link rel='stylesheet' href='Basic Book.css' type='text/css'></link></head><body> <div class='bloom-page' id='guid1' data-backgroundaudio='musicfile1.mp3'></div> <div class='bloom-page' id='guid2' data-backgroundaudio='musicfile2.ogg'></div> <div class='bloom-page' id='guid3' data-backgroundaudio='musicfile3.wav'></div> </body></html>" ; SetupDirectoryWithHtml(bookHtml, actionsOnFolderBeforeCompressing: folderPath => { // We expect this file to just be passed through, but not parsed string audioDir = Path.Combine(folderPath, "audio"); Directory.CreateDirectory(audioDir); File.WriteAllText(Path.Combine(audioDir, "musicfile1.mp3"), "dummy mp3 content"); File.WriteAllText(Path.Combine(audioDir, "musicfile2.ogg"), "dummy ogg content"); File.WriteAllText(Path.Combine(audioDir, "musicfile3.wav"), "dummy wav content"); File.WriteAllText(Path.Combine(audioDir, "narration.mp3"), "more dummy mp3 content"); // file should be included (even though not referenced) File.WriteAllText(Path.Combine(audioDir, "narration.wav"), "more dummy wav content"); // file should not be included File.WriteAllText(Path.Combine(folderPath, "temp.tmp"), "dummy temporary file data"); // file should not be included }); // System Under Test // using (var bloomPubTempFile = TempFile.WithFilenameInTempFolder("BookCompressorWithAudio" + BookCompressor.BloomPubExtensionWithDot)) { BookCompressor.CompressBookDirectory(bloomPubTempFile.Path, _bookFolder.Path, ""); // Test by looking at the temp file content. using (var zippedFile = new ZipFile(bloomPubTempFile.Path)) { var count = 0; foreach (ZipEntry zipEntry in zippedFile) { ++count; //Console.Out.WriteLine($"DEBUG: name={zipEntry.Name}, IsFile={zipEntry.IsFile}"); Assert.Contains(zipEntry.Name, new[] { "book/book.htm", "book/audio/musicfile1.mp3", "book/audio/musicfile2.ogg", "book/audio/musicfile3.wav", "book/audio/narration.mp3" }); } Assert.AreEqual(5, count, "Should be five files stored in test .bloompub file"); } } }
public void CompressDirectory_CompressBooksWithExtraFiles() { // Setup // var bookHtml = @"<html><head><link rel='stylesheet' href='Basic Book.css' type='text/css'></link></head><body> <div class='bloom-page' id='guid1'></div> <div class='bloom-page' id='guid2' data-backgroundaudio='musicfile.ogg'></div> <div class='bloom-page' id='guid3'></div> </body></html>" ; SetupDirectoryWithHtml(bookHtml, actionsOnFolderBeforeCompressing: folderPath => { // Extra top-level book files should get ignored (non-whitelisted extensions). File.WriteAllText(Path.Combine(folderPath, "temp.tmp"), "dummy temporary file data"); File.WriteAllText(Path.Combine(folderPath, "temp.xyz"), "dummy temporary file data"); // Valid entries should get through. File.WriteAllText(Path.Combine(folderPath, "meta.json"), "dummy meta.json file"); File.WriteAllText(Path.Combine(folderPath, "thumbnail.png"), "dummy thumbnail file"); string audioDir = Path.Combine(folderPath, "audio"); Directory.CreateDirectory(audioDir); File.WriteAllText(Path.Combine(audioDir, "musicfile.ogg"), "dummy ogg content"); // These 2 should not be included (non-whitelisted extensions) File.WriteAllText(Path.Combine(audioDir, "midiMusic.mid"), "dummy midi file data"); File.WriteAllText(Path.Combine(audioDir, "other.aif"), "dummy audio file data"); // This subsubfolder should be completely ignored (only 'activities' can have // subsubfolders). string subAudioDir = Path.Combine(audioDir, "audio2"); Directory.CreateDirectory(subAudioDir); File.WriteAllText(Path.Combine(subAudioDir, "other.mp3"), "dummy audio file data"); string videoDir = Path.Combine(folderPath, "video"); Directory.CreateDirectory(videoDir); File.WriteAllText(Path.Combine(videoDir, "signlanguageVid.mp4"), "dummy video content"); // These 2 should not be included (non-whitelisted extensions) File.WriteAllText(Path.Combine(videoDir, "sign.mov"), "dummy movie file data"); File.WriteAllText(Path.Combine(videoDir, "sign.wmv"), "dummy movie file data"); // This subsubfolder should be completely ignored (only 'activities' can have // subsubfolders). string subVideoDir = Path.Combine(videoDir, "video2"); Directory.CreateDirectory(subVideoDir); File.WriteAllText(Path.Combine(subVideoDir, "other.mp4"), "dummy video file data"); // We don't know all the file types that might be in a widget, // so we expect to pass through every file and folder within the 'activities' folder. string activityDir = Path.Combine(folderPath, "activities"); Directory.CreateDirectory(activityDir); string widgetDir = Path.Combine(activityDir, "My Widget"); Directory.CreateDirectory(widgetDir); File.WriteAllText(Path.Combine(widgetDir, "odd.html"), "dummy html content"); File.WriteAllText(Path.Combine(widgetDir, "strange.js"), "dummy js content"); var widgetResources = Path.Combine(widgetDir, "Resources"); Directory.CreateDirectory(widgetResources); File.WriteAllText(Path.Combine(widgetResources, "includable.blob"), "some unknown blob-type file contents"); // We expect this folder to be excluded completely (non-whitelisted book subfolder). string bookWithinABookDir = Path.Combine(folderPath, "Book Within A Book"); Directory.CreateDirectory(bookWithinABookDir); File.WriteAllText(Path.Combine(bookWithinABookDir, "extra book.html"), "dummy html content"); }); // System Under Test // using (var bloomPubTempFile = TempFile.WithFilenameInTempFolder("BookCompressorWithExtraFiles" + BookCompressor.BloomPubExtensionWithDot)) { BookCompressor.CompressBookDirectory(bloomPubTempFile.Path, _bookFolder.Path, ""); // Test by looking at the temp file content. using (var zippedFile = new ZipFile(bloomPubTempFile.Path)) { var count = 0; foreach (ZipEntry zipEntry in zippedFile) { ++count; //Console.Out.WriteLine($"DEBUG: name={zipEntry.Name}, IsFile={zipEntry.IsFile}"); Assert.Contains(zipEntry.Name, new[] { "book/book.htm", "book/meta.json", "book/thumbnail.png", "book/audio/musicfile.ogg", "book/video/signlanguageVid.mp4", "book/activities/My Widget/odd.html", "book/activities/My Widget/strange.js", "book/activities/My Widget/Resources/includable.blob" }); } Assert.AreEqual(8, count, "Should be eight files stored in test .bloompub file"); } } }