Ejemplo n.º 1
0
        public static async Task <string> GetRootFilePathAsync(IZipArchive epubArchive)
        {
            const string     EPUB_CONTAINER_FILE_PATH = "META-INF/container.xml";
            IZipArchiveEntry containerFileEntry       = epubArchive.GetEntry(EPUB_CONTAINER_FILE_PATH);

            if (containerFileEntry == null)
            {
                throw new Exception(string.Format(CultureInfo.InvariantCulture, "EPUB parsing error: {0} file not found in archive.", EPUB_CONTAINER_FILE_PATH));
            }

            XDocument containerDocument;

            using (Stream containerStream = containerFileEntry.Open())
            {
                containerDocument = await XmlUtils.LoadDocumentAsync(containerStream).ConfigureAwait(false);
            }

            XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(new NameTable());

            xmlNamespaceManager.AddNamespace("cns", "urn:oasis:names:tc:opendocument:xmlns:container");

            //XElement rootFileNode = containerDocument.XPathSelectElement("/cns:container/cns:rootfiles/cns:rootfile", xmlNamespaceManager);
            IXPather xPather      = DependencyService.Get <IXPather>();
            XElement rootFileNode = xPather.SelectElement(containerDocument, "/cns:container/cns:rootfiles/cns:rootfile", xmlNamespaceManager);

            XAttribute attribute    = rootFileNode.Attribute("full-path");
            string     rootFilePath = attribute.Value;

            return(rootFilePath);
        }
Ejemplo n.º 2
0
        public virtual String GetEntryAsString( IZipArchive archive, string entry )
        {
            var zipEntry = GetZipEntry( archive, entry );

            using ( var reader = _streamReaderWrapperFactory.BuildStreamReaderWrapper( zipEntry.Open() ) )
            {
                return reader.ReadToEnd();
            }
        }
Ejemplo n.º 3
0
        public virtual String GetEntryAsString(IZipArchive archive, string entry)
        {
            var zipEntry = GetZipEntry(archive, entry);

            using (var reader = _streamReaderWrapperFactory.BuildStreamReaderWrapper(zipEntry.Open()))
            {
                return(reader.ReadToEnd());
            }
        }
Ejemplo n.º 4
0
 public virtual OdfHandlerService.FileType GetFileType( IZipArchive file )
 {
     var mimetypeIdentifier = GetEntryAsString( file, "mimetype" );
     switch( mimetypeIdentifier )
     {
         case "application/vnd.oasis.opendocument.spreadsheet":
             return OdfHandlerService.FileType.Ods;
         case "application/vnd.oasis.opendocument.text":
             return OdfHandlerService.FileType.Odt;
     }
     throw new NotSupportedException(
         "Unknown or unexpected file type. Only ODT and ODS files are supported as input at this time." );
 }
        /// <inheritdoc/>
        public void Write(Stream stream, IZipArchive archive)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (archive == null)
            {
                throw new ArgumentNullException(nameof(archive));
            }

            archive.Save(stream);
        }
        public void CreateEntryFromFile_CompressionLevel_ShouldCreateZipArchiveWithFile(CompressionLevel level)
        {
            File.WriteAllLines(FileName, new[] { "this is the only line" });

            using (IZipArchive newZipArchive = mZipFile.Open(ArchiveFileName, ZipArchiveMode.Create))
            {
                newZipArchive.CreateEntryFromFile(FileName, FileName, level);
            }

            using (IZipArchive zipArchive = mZipFile.OpenRead(ArchiveFileName))
            {
                Assert.AreEqual(1, zipArchive.Entries.Count);
            }
        }
Ejemplo n.º 7
0
        public virtual OdfHandlerService.FileType GetFileType(IZipArchive file)
        {
            var mimetypeIdentifier = GetEntryAsString(file, "mimetype");

            switch (mimetypeIdentifier)
            {
            case "application/vnd.oasis.opendocument.spreadsheet":
                return(OdfHandlerService.FileType.Ods);

            case "application/vnd.oasis.opendocument.text":
                return(OdfHandlerService.FileType.Odt);
            }
            throw new NotSupportedException(
                      "Unknown or unexpected file type. Only ODT and ODS files are supported as input at this time.");
        }
        public void ExtractToFile_ShouldThrowIoException_WhenOverwriteIsFalse_AndFileAlreadyExists()
        {
            File.WriteAllLines(FileName, new[] { "this is the only line" });

            using (IZipArchive newZipArchive = mZipFile.Open(ArchiveFileName, ZipArchiveMode.Create))
            {
                newZipArchive.CreateEntryFromFile(FileName, FileName);
            }

            File.WriteAllLines(ExtractionFile, new[] { "a different line" });

            using (IZipArchive zipArchive = mZipFile.OpenRead(ArchiveFileName))
            {
                Assert.Throws <IOException>(() => zipArchive.Entries[0].ExtractToFile(ExtractionFile, false));
            }
        }
Ejemplo n.º 9
0
        public static async Task <EpubSchema> ReadSchemaAsync(IZipArchive epubArchive)
        {
            EpubSchema result       = new EpubSchema();
            string     rootFilePath = await RootFilePathReader.GetRootFilePathAsync(epubArchive).ConfigureAwait(false);

            string contentDirectoryPath = ZipPathUtils.GetDirectoryPath(rootFilePath);

            result.ContentDirectoryPath = contentDirectoryPath;
            EpubPackage package = await PackageReader.ReadPackageAsync(epubArchive, rootFilePath).ConfigureAwait(false);

            result.Package = package;
            EpubNavigation navigation = await NavigationReader.ReadNavigationAsync(epubArchive, contentDirectoryPath, package).ConfigureAwait(false);

            result.Navigation = navigation;
            return(result);
        }
        /// <inheritdoc/>
        public async Task AddFilesAsync <T>(
            IEnumerable <T> items,
            Func <T, string> diskFilePathFunc,
            Func <T, string> entryNameFunc,
            IZipArchive archive,
            CancellationToken ct)
        {
            Ensure.ArgumentNotNull(items, nameof(items));
            Ensure.ArgumentNotNull(diskFilePathFunc, nameof(diskFilePathFunc));
            Ensure.ArgumentNotNull(entryNameFunc, nameof(entryNameFunc));
            Ensure.ArgumentNotNull(archive, nameof(archive));
            Ensure.ArgumentNotNull(ct, nameof(ct));

            foreach (T item in items)
            {
                ct.ThrowIfCancellationRequested();

                string entryName = entryNameFunc(item);
                if (string.IsNullOrEmpty(entryName))
                {
                    continue;
                }

                string diskFilePath = diskFilePathFunc(item);
                if (string.IsNullOrEmpty(diskFilePath))
                {
                    continue;
                }

                if (archive.ContainsEntry(entryName))
                {
                    continue;
                }

                var fs = fileSystemStrategy.Create(diskFilePath);
                if (fs == null)
                {
                    throw new UnexpectedNullException("Filesystem could not be created based on the disk file path.");
                }

                Stream stream = fs.File.OpenRead(diskFilePath);
                archive.AddEntry(entryName, stream);
            }

            await Task.CompletedTask;
        }
        public void ExtractToFile_ShouldExtractToFile_WhenOverwriteIsTrue_AndFileAlreadyExists()
        {
            File.WriteAllLines(FileName, new[] { "this is the only line" });

            using (IZipArchive newZipArchive = mZipFile.Open(ArchiveFileName, ZipArchiveMode.Create))
            {
                newZipArchive.CreateEntryFromFile(FileName, FileName);
            }

            File.WriteAllLines(ExtractionFile, new[] { "a different line" });

            using (IZipArchive zipArchive = mZipFile.OpenRead(ArchiveFileName))
            {
                zipArchive.Entries[0].ExtractToFile(ExtractionFile, true);
            }

            Assert.AreEqual("this is the only line", File.ReadAllLines(ExtractionFile)[0]);
        }
        public void ExtractToFile_ShouldExtractToFile()
        {
            File.WriteAllLines(FileName, new[] { "this is the only line" });

            using (IZipArchive newZipArchive = mZipFile.Open(ArchiveFileName, ZipArchiveMode.Create))
            {
                newZipArchive.CreateEntryFromFile(FileName, FileName);
            }

            //Test sanity check
            Assert.IsFalse(File.Exists(ExtractionFile));

            using (IZipArchive zipArchive = mZipFile.OpenRead(ArchiveFileName))
            {
                zipArchive.Entries[0].ExtractToFile(ExtractionFile);
            }

            Assert.IsTrue(File.Exists(ExtractionFile));
        }
        public void ExtractToDirectory_ShouldExtractFileToDirectory()
        {
            File.WriteAllLines(FileName, new[] { "this is the only line" });

            using (IZipArchive newZipArchive = mZipFile.Open(ArchiveFileName, ZipArchiveMode.Create))
            {
                newZipArchive.CreateEntryFromFile(FileName, FileName);

                //Test sanity check
                Assert.IsFalse(Directory.Exists(ExtractionDir));
            }

            using (IZipArchive zipArchive = mZipFile.OpenRead(ArchiveFileName))
            {
                zipArchive.ExtractToDirectory(ExtractionDir);

                Assert.IsTrue(Directory.Exists(ExtractionDir));
                Assert.IsTrue(Directory.GetFiles(ExtractionDir)[0].Contains(FileName));
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Opens the book asynchronously without reading its content. Holds the handle to the EPUB file.
        /// </summary>
        /// <param name="filePath">path to the EPUB file</param>
        /// <returns></returns>
        public static async Task <EpubBookRef> OpenBookAsync(string filePath)
        {
            IFiler   filer   = DependencyService.Get <IFiler>();
            IZipFile zipFile = DependencyService.Get <IZipFile>();

            if (!await filer.DoesFileExistAsync(filePath).ConfigureAwait(false))
            {
                throw new FileNotFoundException("Specified epub file not found.", filePath);
            }

            IZipArchive epubArchive = await zipFile.OpenReadAsync(filePath).ConfigureAwait(false);

            EpubBookRef bookRef = new EpubBookRef(epubArchive);

            bookRef.FilePath = filePath;
            bookRef.Schema   = await SchemaReader.ReadSchemaAsync(epubArchive).ConfigureAwait(false);

            bookRef.Title      = bookRef.Schema.Package.Metadata.Titles.FirstOrDefault() ?? String.Empty;
            bookRef.AuthorList = bookRef.Schema.Package.Metadata.Creators.Select(creator => creator.Creator).ToList();
            bookRef.Author     = string.Join(", ", bookRef.AuthorList);
            bookRef.Content    = await Task.Run(() => ContentReader.ParseContentMap(bookRef)).ConfigureAwait(false);

            return(bookRef);
        }
 public void SetUp()
 {
     archive = zipfile.Open(ArchiveFileName, System.IO.Compression.ZipArchiveMode.Update);
 }
Ejemplo n.º 16
0
 public virtual IZipEntry GetZipEntry( IZipArchive archive, string entryName )
 {
     var entry = archive.GetEntry( entryName );
     return entry;
 }
Ejemplo n.º 17
0
        public static async Task <EpubPackage> ReadPackageAsync(IZipArchive epubArchive, string rootFilePath)
        {
            IZipArchiveEntry rootFileEntry = epubArchive.GetEntry(rootFilePath);

            if (rootFileEntry == null)
            {
                throw new Exception("EPUB parsing error: root file not found in archive.");
            }

            XDocument containerDocument;

            using (Stream containerStream = rootFileEntry.Open())
            {
                containerDocument = await XmlUtils.LoadDocumentAsync(containerStream).ConfigureAwait(false);
            }

            XNamespace  opfNamespace     = "http://www.idpf.org/2007/opf";
            XElement    packageNode      = containerDocument.Element(opfNamespace + "package");
            EpubPackage result           = new EpubPackage();
            string      epubVersionValue = packageNode.Attribute("version").Value;

            if (epubVersionValue == "2.0")
            {
                result.EpubVersion = EpubVersion.EPUB_2;
            }
            else
            {
                if (epubVersionValue == "3.0")
                {
                    result.EpubVersion = EpubVersion.EPUB_3;
                }
                else
                {
                    throw new Exception(string.Format(CultureInfo.InvariantCulture, "Unsupported EPUB version: {0}.", epubVersionValue));
                }
            }

            XElement metadataNode = packageNode.Element(opfNamespace + "metadata");

            if (metadataNode == null)
            {
                throw new Exception("EPUB parsing error: metadata not found in the package.");
            }

            EpubMetadata metadata = ReadMetadata(metadataNode, result.EpubVersion);

            result.Metadata = metadata;
            XElement manifestNode = packageNode.Element(opfNamespace + "manifest");

            if (manifestNode == null)
            {
                throw new Exception("EPUB parsing error: manifest not found in the package.");
            }

            EpubManifest manifest = ReadManifest(manifestNode);

            result.Manifest = manifest;
            XElement spineNode = packageNode.Element(opfNamespace + "spine");

            if (spineNode == null)
            {
                throw new Exception("EPUB parsing error: spine not found in the package.");
            }

            EpubSpine spine = ReadSpine(spineNode);

            result.Spine = spine;
            XElement guideNode = packageNode.Element(opfNamespace + "guide");

            if (guideNode != null)
            {
                EpubGuide guide = ReadGuide(guideNode);
                result.Guide = guide;
            }

            return(result);
        }
Ejemplo n.º 18
0
 public static void ExtractToDirectory(this IZipArchive source, string destinationDirectoryName)
 {
     source.Instance.ExtractToDirectory(destinationDirectoryName);
 }
Ejemplo n.º 19
0
 public static IZipArchiveEntry CreateEntryFromFile(this IZipArchive destination, string sourceFileName, string entryName)
 {
     return(new ZipArchiveEntryWrap(destination.Instance.CreateEntryFromFile(sourceFileName, entryName)));
 }
Ejemplo n.º 20
0
        public virtual IZipEntry GetZipEntry(IZipArchive archive, string entryName)
        {
            var entry = archive.GetEntry(entryName);

            return(entry);
        }
Ejemplo n.º 21
0
 public EpubBookRef(IZipArchive epubArchive)
 {
     this.epubArchive = epubArchive;
     isDisposed       = false;
 }
        public static async Task <EpubNavigation> ReadNavigationAsync(IZipArchive epubArchive, string contentDirectoryPath, EpubPackage package)
        {
            EpubNavigation result = new EpubNavigation();
            string         tocId  = package.Spine.Toc;

            if (String.IsNullOrEmpty(tocId))
            {
                throw new Exception("EPUB parsing error: TOC ID is empty.");
            }

            EpubManifestItem tocManifestItem = package.Manifest.FirstOrDefault(item => String.Compare(item.Id, tocId, StringComparison.OrdinalIgnoreCase) == 0);

            if (tocManifestItem == null)
            {
                throw new Exception(string.Format(CultureInfo.InvariantCulture, "EPUB parsing error: TOC item {0} not found in EPUB manifest.", tocId));
            }

            string           tocFileEntryPath = ZipPathUtils.Combine(contentDirectoryPath, tocManifestItem.Href);
            IZipArchiveEntry tocFileEntry     = epubArchive.GetEntry(tocFileEntryPath);

            if (tocFileEntry == null)
            {
                throw new Exception(string.Format(CultureInfo.InvariantCulture, "EPUB parsing error: TOC file {0} not found in archive.", tocFileEntryPath));
            }

            if (tocFileEntry.Length > Int32.MaxValue)
            {
                throw new Exception(string.Format(CultureInfo.InvariantCulture, "EPUB parsing error: TOC file {0} is bigger than 2 Gb.", tocFileEntryPath));
            }

            XDocument containerDocument;

            using (Stream containerStream = tocFileEntry.Open())
            {
                containerDocument = await XmlUtils.LoadDocumentAsync(containerStream).ConfigureAwait(false);
            }

            XNamespace ncxNamespace = "http://www.daisy.org/z3986/2005/ncx/";
            XElement   ncxNode      = containerDocument.Element(ncxNamespace + "ncx");

            if (ncxNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain ncx element.");
            }

            XElement headNode = ncxNode.Element(ncxNamespace + "head");

            if (headNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain head element.");
            }

            EpubNavigationHead navigationHead = ReadNavigationHead(headNode);

            result.Head = navigationHead;
            XElement docTitleNode = ncxNode.Element(ncxNamespace + "docTitle");

            if (docTitleNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain docTitle element.");
            }

            EpubNavigationDocTitle navigationDocTitle = ReadNavigationDocTitle(docTitleNode);

            result.DocTitle   = navigationDocTitle;
            result.DocAuthors = new List <EpubNavigationDocAuthor>();

            foreach (XElement docAuthorNode in ncxNode.Elements(ncxNamespace + "docAuthor"))
            {
                EpubNavigationDocAuthor navigationDocAuthor = ReadNavigationDocAuthor(docAuthorNode);
                result.DocAuthors.Add(navigationDocAuthor);
            }

            XElement navMapNode = ncxNode.Element(ncxNamespace + "navMap");

            if (navMapNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain navMap element.");
            }

            EpubNavigationMap navMap = ReadNavigationMap(navMapNode);

            result.NavMap = navMap;
            XElement pageListNode = ncxNode.Element(ncxNamespace + "pageList");

            if (pageListNode != null)
            {
                EpubNavigationPageList pageList = ReadNavigationPageList(pageListNode);
                result.PageList = pageList;
            }

            result.NavLists = new List <EpubNavigationList>();

            foreach (XElement navigationListNode in ncxNode.Elements(ncxNamespace + "navList"))
            {
                EpubNavigationList navigationList = ReadNavigationList(navigationListNode);
                result.NavLists.Add(navigationList);
            }

            return(result);
        }