Ejemplo n.º 1
0
        private static EpubManifest ReadManifest(XmlNode manifestNode)
        {
            EpubManifest result = new EpubManifest();

            foreach (XmlNode manifestItemNode in manifestNode.ChildNodes)
            {
                if (String.Compare(manifestItemNode.LocalName, "item", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    EpubManifestItem manifestItem = new EpubManifestItem();
                    foreach (XmlAttribute manifestItemNodeAttribute in manifestItemNode.Attributes)
                    {
                        string attributeValue = manifestItemNodeAttribute.Value;
                        switch (manifestItemNodeAttribute.Name.ToLowerInvariant())
                        {
                        case "id":
                            manifestItem.Id = attributeValue;
                            break;

                        case "href":
                            manifestItem.Href = attributeValue;
                            break;

                        case "media-type":
                            manifestItem.MediaType = attributeValue;
                            break;

                        case "required-namespace":
                            manifestItem.RequiredNamespace = attributeValue;
                            break;

                        case "required-modules":
                            manifestItem.RequiredModules = attributeValue;
                            break;

                        case "fallback":
                            manifestItem.Fallback = attributeValue;
                            break;

                        case "fallback-style":
                            manifestItem.FallbackStyle = attributeValue;
                            break;
                        }
                    }
                    if (String.IsNullOrWhiteSpace(manifestItem.Id))
                    {
                        throw new Exception("Incorrect EPUB manifest: item ID is missing");
                    }
                    if (String.IsNullOrWhiteSpace(manifestItem.Href))
                    {
                        throw new Exception("Incorrect EPUB manifest: item href is missing");
                    }
                    if (String.IsNullOrWhiteSpace(manifestItem.MediaType))
                    {
                        throw new Exception("Incorrect EPUB manifest: item media type is missing");
                    }
                    result.Add(manifestItem);
                }
            }
            return(result);
        }
Ejemplo n.º 2
0
        private static Image LoadCoverImage(EpubBook book)
        {
            List <EpubMetadataMeta> metaItems = book.Schema.Package.Metadata.MetaItems;

            if (metaItems == null || !metaItems.Any())
            {
                return(null);
            }
            EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => String.Compare(metaItem.Name, "cover", StringComparison.OrdinalIgnoreCase) == 0);

            if (coverMetaItem == null)
            {
                return(null);
            }
            if (String.IsNullOrEmpty(coverMetaItem.Content))
            {
                throw new Exception("Incorrect EPUB metadata: cover item content is missing");
            }
            EpubManifestItem coverManifestItem = book.Schema.Package.Manifest.FirstOrDefault(manifestItem => String.Compare(manifestItem.Id, coverMetaItem.Content, StringComparison.OrdinalIgnoreCase) == 0);

            if (coverManifestItem == null)
            {
                throw new Exception(String.Format("Incorrect EPUB manifest: item with ID = \"{0}\" is missing", coverMetaItem.Content));
            }
            EpubByteContentFile coverImageContentFile;

            if (!book.Content.Images.TryGetValue(coverManifestItem.Href, out coverImageContentFile))
            {
                throw new Exception(String.Format("Incorrect EPUB manifest: item with href = \"{0}\" is missing", coverManifestItem.Href));
            }
            using (MemoryStream coverImageStream = new MemoryStream(coverImageContentFile.Content))
                return(Image.FromStream(coverImageStream));
        }
Ejemplo n.º 3
0
        public static async Task <byte[]> ReadBookCoverAsync(EpubBookRef bookRef)
        {
            List <EpubMetadataMeta> metaItems = bookRef.Schema.Package.Metadata.MetaItems;

            if (metaItems == null || !metaItems.Any())
            {
                return(null);
            }
            EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => String.Compare(metaItem.Name, "cover", StringComparison.OrdinalIgnoreCase) == 0);

            if (coverMetaItem == null)
            {
                return(null);
            }
            if (String.IsNullOrEmpty(coverMetaItem.Content))
            {
                throw new Exception("Incorrect EPUB metadata: cover item content is missing.");
            }
            EpubManifestItem coverManifestItem = bookRef.Schema.Package.Manifest.FirstOrDefault(manifestItem => String.Compare(manifestItem.Id, coverMetaItem.Content, StringComparison.OrdinalIgnoreCase) == 0);

            if (coverManifestItem == null)
            {
                throw new Exception(String.Format("Incorrect EPUB manifest: item with ID = \"{0}\" is missing.", coverMetaItem.Content));
            }
            if (!bookRef.Content.Images.TryGetValue(coverManifestItem.Href, out EpubByteContentFileRef coverImageContentFileRef))
            {
                throw new Exception(String.Format("Incorrect EPUB manifest: item with href = \"{0}\" is missing.", coverManifestItem.Href));
            }
            byte[] coverImageContent = await coverImageContentFileRef.ReadContentAsBytesAsync().ConfigureAwait(false);

            return(coverImageContent);
        }
Ejemplo n.º 4
0
        public static EpubByteContentFileRef ReadBookCover(EpubSchema epubSchema, Dictionary <string, EpubByteContentFileRef> imageContentRefs)
        {
            List <EpubMetadataMeta> metaItems = epubSchema.Package.Metadata.MetaItems;

            if (metaItems == null || !metaItems.Any())
            {
                return(null);
            }
            EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => metaItem.Name.CompareOrdinalIgnoreCase("cover"));

            if (coverMetaItem == null)
            {
                return(null);
            }
            if (String.IsNullOrEmpty(coverMetaItem.Content))
            {
                throw new Exception("Incorrect EPUB metadata: cover item content is missing.");
            }
            EpubManifestItem coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Id.CompareOrdinalIgnoreCase(coverMetaItem.Content));

            if (coverManifestItem == null)
            {
                throw new Exception($"Incorrect EPUB manifest: item with ID = \"{coverMetaItem.Content}\" is missing.");
            }
            if (!imageContentRefs.TryGetValue(coverManifestItem.Href, out EpubByteContentFileRef coverImageContentFileRef))
            {
                throw new Exception($"Incorrect EPUB manifest: item with href = \"{coverManifestItem.Href}\" is missing.");
            }
            return(coverImageContentFileRef);
        }
Ejemplo n.º 5
0
        public static List <EpubTextContentFileRef> GetReadingOrder(EpubBookRef bookRef)
        {
            List <EpubTextContentFileRef> result = new List <EpubTextContentFileRef>();

            foreach (EpubSpineItemRef spineItemRef in bookRef.Schema.Package.Spine)
            {
                EpubManifestItem manifestItem = bookRef.Schema.Package.Manifest.FirstOrDefault(item => item.Id == spineItemRef.IdRef);
                if (manifestItem == null)
                {
                    throw new Exception($"Incorrect EPUB spine: item with IdRef = \"{spineItemRef.IdRef}\" is missing in the manifest.");
                }
                if (bookRef.Content.Html.TryGetValue(manifestItem.Href, out EpubTextContentFileRef htmlContentFileRef))
                {
                    result.Add(htmlContentFileRef);
                    continue;
                }

                // 2019-08-21 Fix: some ebooks seem to contain two items with id="cover", one of them is an image, and the other an XHTML file
                // thus, if the first attempt to get the HTML item fails, we try for a second item with the same Id
                manifestItem = bookRef.Schema.Package.Manifest.Where(item => item.Id == spineItemRef.IdRef).Skip(1).FirstOrDefault();
                if (manifestItem == null)
                {
                    throw new Exception($"Incorrect EPUB spine: item with IdRef = \"{spineItemRef.IdRef}\" is not HTML content");
                }
                if (bookRef.Content.Html.TryGetValue(manifestItem.Href, out EpubTextContentFileRef htmlContentFileRef2))
                {
                    result.Add(htmlContentFileRef2);
                    continue;
                }
                throw new Exception($"Incorrect EPUB manifest: item with href = \"{spineItemRef.IdRef}\" is missing in the book.");
            }
            return(result);
        }
        public static async Task <Epub3NavDocument> ReadEpub3NavDocumentAsync(ZipArchive epubArchive, string contentDirectoryPath, EpubPackage package)
        {
            Epub3NavDocument result          = new Epub3NavDocument();
            EpubManifestItem navManifestItem =
                package.Manifest.FirstOrDefault(item => item.Properties != null && item.Properties.Contains(ManifestProperty.NAV));

            if (navManifestItem == null)
            {
                if (package.EpubVersion == EpubVersion.EPUB_2)
                {
                    return(null);
                }
                else
                {
                    throw new Exception("EPUB parsing error: NAV item not found in EPUB manifest.");
                }
            }
            string          navFileEntryPath = ZipPathUtils.Combine(contentDirectoryPath, navManifestItem.Href);
            ZipArchiveEntry navFileEntry     = epubArchive.GetEntry(navFileEntryPath);

            if (navFileEntry == null)
            {
                throw new Exception($"EPUB parsing error: navigation file {navFileEntryPath} not found in archive.");
            }
            if (navFileEntry.Length > Int32.MaxValue)
            {
                throw new Exception($"EPUB parsing error: navigation file {navFileEntryPath} is larger than 2 Gb.");
            }
            XDocument navDocument;

            using (Stream containerStream = navFileEntry.Open())
            {
                navDocument = await XmlUtils.LoadDocumentAsync(containerStream).ConfigureAwait(false);
            }
            XNamespace xhtmlNamespace = navDocument.Root.Name.Namespace;
            XElement   htmlNode       = navDocument.Element(xhtmlNamespace + "html");

            if (htmlNode == null)
            {
                throw new Exception("EPUB parsing error: navigation file does not contain html element.");
            }
            XElement bodyNode = htmlNode.Element(xhtmlNamespace + "body");

            if (bodyNode == null)
            {
                throw new Exception("EPUB parsing error: navigation file does not contain body element.");
            }

            result.Navs = new List <Epub3Nav>();
            string folder = ZipPathUtils.GetDirectoryPath(navManifestItem.Href);

            foreach (XElement navNode in bodyNode.Elements(xhtmlNamespace + "nav"))
            {
                Epub3Nav epub3Nav = ReadEpub3Nav(navNode);
                AdjustRelativePath(epub3Nav.Ol, folder);
                result.Navs.Add(epub3Nav);
            }
            return(result);
        }
Ejemplo n.º 7
0
        public static EpubByteContentFileRef ReadBookCover(EpubSchema epubSchema, Dictionary <string, EpubByteContentFileRef> imageContentRefs)
        {
            List <EpubMetadataMeta> metaItems = epubSchema.Package.Metadata.MetaItems;

            if (metaItems == null || !metaItems.Any())
            {
                return(null);
            }
            EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => metaItem.Name.CompareOrdinalIgnoreCase("cover"));

            if (coverMetaItem == null)
            {
                return(null);
            }
            if (String.IsNullOrEmpty(coverMetaItem.Content))
            {
                throw new Exception("Incorrect EPUB metadata: cover item content is missing.");
            }
            EpubManifestItem coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Id.CompareOrdinalIgnoreCase(coverMetaItem.Content));

            if (coverManifestItem == null)
            {
                // 2019-08-20 Hotfix: if coverManifestItem is not found by its Id, then try it with its Href - some ebooks refer to the image directly!
                coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Href.CompareOrdinalIgnoreCase(coverMetaItem.Content));
                if (null == coverManifestItem)
                {
                    throw new Exception($"Incorrect EPUB manifest: item with ID = \"{coverMetaItem.Content}\" is missing.");
                }
            }
            if (imageContentRefs.TryGetValue(coverManifestItem.Href, out EpubByteContentFileRef coverImageContentFileRef))
            {
                return(coverImageContentFileRef);
            }

            // 2019-08-21 Fix some ebooks seem to contain more than one item with Id="cover"
            // thus we test if there is a second item....

            coverManifestItem = epubSchema.Package.Manifest.Where(manifestItem => manifestItem.Id.CompareOrdinalIgnoreCase(coverMetaItem.Content)).Skip(1).FirstOrDefault();;
            if (coverManifestItem == null)
            {
                // 2019-08-20 Hotfix: if coverManifestItem is not found by its Id, then try it with its Href - some ebooks refer to the image directly!
                coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Href.CompareOrdinalIgnoreCase(coverMetaItem.Content));

                if (null == coverManifestItem)
                {
                    throw new Exception($"Incorrect EPUB manifest: item with ID = \"{coverMetaItem.Content}\" is missing.");
                }
            }
            if (imageContentRefs.TryGetValue(coverManifestItem.Href, out EpubByteContentFileRef coverImageContentFileRef2))
            {
                return(coverImageContentFileRef2);
            }
            throw new Exception($"Incorrect EPUB manifest: item with href = \"{coverManifestItem.Href}\" is missing.");
        }
        public static async Task <Image> ReadBookCoverAsync(EpubBookRef bookRef)
        {
            List <EpubMetadataMeta> metaItems = bookRef.Schema.Package.Metadata.MetaItems;

            if (metaItems == null || !metaItems.Any())
            {
                return(null);
            }

            EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => string.Compare(metaItem.Name, "cover", StringComparison.OrdinalIgnoreCase) == 0);

            if (coverMetaItem == null)
            {
                return(null);
            }

            if (String.IsNullOrEmpty(coverMetaItem.Content))
            {
                throw new Exception("Incorrect EPUB metadata: cover item content is missing.");
            }

            EpubManifestItem coverManifestItem = bookRef.Schema.Package.Manifest.FirstOrDefault(manifestItem => String.Compare(manifestItem.Id, coverMetaItem.Content, StringComparison.OrdinalIgnoreCase) == 0);

            if (coverManifestItem == null)
            {
                throw new Exception(string.Format(CultureInfo.InvariantCulture, "Incorrect EPUB manifest: item with ID = \"{0}\" is missing.", coverMetaItem.Content));
            }

            EpubByteContentFileRef coverImageContentFileRef;

            if (!bookRef.Content.Images.TryGetValue(coverManifestItem.Href, out coverImageContentFileRef))
            {
                throw new Exception(string.Format(CultureInfo.InvariantCulture, "Incorrect EPUB manifest: item with href = \"{0}\" is missing.", coverManifestItem.Href));
            }

            byte[] coverImageContent = await coverImageContentFileRef.ReadContentAsBytesAsync().ConfigureAwait(false);

            using (MemoryStream coverImageStream = new MemoryStream(coverImageContent))
            {
                Image image = new Image();
                //return await Task.Run(() => Image.FromStream(coverImageStream)).ConfigureAwait(false);
                Func <Stream> stream = () => coverImageStream;
                image.Source = ImageSource.FromStream(stream);
                return(await Task.Run(() => image).ConfigureAwait(false));
            }
        }
Ejemplo n.º 9
0
        public static List <EpubTextContentFileRef> GetReadingOrder(EpubBookRef bookRef)
        {
            List <EpubTextContentFileRef> result = new List <EpubTextContentFileRef>();

            foreach (EpubSpineItemRef spineItemRef in bookRef.Schema.Package.Spine)
            {
                EpubManifestItem manifestItem = bookRef.Schema.Package.Manifest.FirstOrDefault(item => item.Id == spineItemRef.IdRef);
                if (manifestItem == null)
                {
                    throw new Exception($"Incorrect EPUB spine: item with IdRef = \"{spineItemRef.IdRef}\" is missing in the manifest.");
                }
                if (!bookRef.Content.Html.TryGetValue(manifestItem.Href, out EpubTextContentFileRef htmlContentFileRef))
                {
                    throw new Exception($"Incorrect EPUB manifest: item with href = \"{spineItemRef.IdRef}\" is missing in the book.");
                }
                result.Add(htmlContentFileRef);
            }
            return(result);
        }
Ejemplo n.º 10
0
        private static async Task <BitmapImage> LoadCoverImageAsync(EpubBook book)
        {
            //TO-DO Currently this function only accepts covers as a image file. If cover is wrapped in.xhtml file - nothing happen.
            List <EpubMetadataMeta> metaItems = book.Schema.Package.Metadata.MetaItems;
            BitmapImage             result    = new BitmapImage();

            if (metaItems == null || !metaItems.Any())
            {
                return(null);
            }
            EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => String.Compare(metaItem.Name, "cover", StringComparison.OrdinalIgnoreCase) == 0);

            if (coverMetaItem == null)
            {
                return(null);
            }
            if (String.IsNullOrEmpty(coverMetaItem.Content))
            {
                throw new Exception("Incorrect EPUB metadata: cover item content is missing");
            }
            EpubManifestItem coverManifestItem = book.Schema.Package.Manifest.FirstOrDefault(manifestItem => String.Compare(manifestItem.Id, coverMetaItem.Content, StringComparison.OrdinalIgnoreCase) == 0);

            if (coverManifestItem == null)
            {
                throw new Exception(String.Format("Incorrect EPUB manifest: item with ID = \"{0}\" is missing", coverMetaItem.Content));
            }
            EpubByteContentFile coverImageContentFile;

            // ---------------------------------------------------------------------------------------------------------------------
            //TO-DO: Currently this function only accepts covers as a image file. If cover is wrapped in.xhtml file - nothing happen.
            // Have to check how people using wrapped cover - do they point <meta content> directly to xhtml or just placing it in the manifest
            // ---------------------------------------------------------------------------------------------------------------------
            if (!book.Content.Images.TryGetValue(coverManifestItem.Href, out coverImageContentFile))
            {
                throw new Exception(String.Format("Incorrect EPUB manifest: item with href = \"{0}\" is missing", coverManifestItem.Href));
            }
            // Old code is not working as SystemDrawings is deprecated
            //using (MemoryStream coverImageStream = new MemoryStream(coverImageContentFile.Content))
            result = await ConvertToBitmapImageAsync(coverImageContentFile.Content);

            return(result);
        }
Ejemplo n.º 11
0
        public static async Task <EpubNavigation> ReadNavigationAsync(ZipArchive 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("EPUB parsing error: TOC item {0} not found in EPUB manifest.", tocId));
            }
            string          tocFileEntryPath = ZipPathUtils.Combine(contentDirectoryPath, tocManifestItem.Href);
            ZipArchiveEntry tocFileEntry     = epubArchive.GetEntry(tocFileEntryPath);

            if (tocFileEntry == null)
            {
                throw new Exception(String.Format("EPUB parsing error: TOC file {0} not found in archive.", tocFileEntryPath));
            }
            if (tocFileEntry.Length > Int32.MaxValue)
            {
                throw new Exception(String.Format("EPUB parsing error: TOC file {0} is larger 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);
        }
Ejemplo n.º 12
0
        public static EpubByteContentFileRef ReadBookCover(EpubSchema epubSchema, Dictionary <string, EpubByteContentFileRef> imageContentRefs)
        {
            List <EpubMetadataMeta> metaItems = epubSchema.Package.Metadata.MetaItems;

            if (metaItems == null || !metaItems.Any())
            {
                return(null);
            }
            EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => metaItem.Name.CompareOrdinalIgnoreCase("cover"));

            if (coverMetaItem == null)
            {
                return(null);
            }
            if (String.IsNullOrEmpty(coverMetaItem.Content))
            {
                throw new Exception("Incorrect EPUB metadata: cover item content is missing.");
            }

            EpubByteContentFileRef coverImageContentFileRef;
            EpubManifestItem       coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Id.CompareOrdinalIgnoreCase(coverMetaItem.Content));

            if (null != coverManifestItem?.Href && imageContentRefs.TryGetValue(coverManifestItem.Href, out coverImageContentFileRef))
            {
                return(coverImageContentFileRef);
            }

            // For non-standard ebooks, we try several other ways...
            if (null != coverManifestItem) // we have found the item but there was no corresponding image ...
            {
                // some ebooks seem to contain more than one item with Id="cover"
                // thus we test if there is a second item, and whether that is an image....
                coverManifestItem = epubSchema.Package.Manifest.Where(manifestItem => manifestItem.Id.CompareOrdinalIgnoreCase(coverMetaItem.Content)).Skip(1).FirstOrDefault();;
                if (null != coverManifestItem?.Href && imageContentRefs.TryGetValue(coverManifestItem.Href, out coverImageContentFileRef))
                {
                    return(coverImageContentFileRef);
                }
            }

            // we have still not found the item
            // 2019-08-20 Hotfix: if coverManifestItem is not found by its Id, then try it with its Href - some ebooks refer to the image directly!
            coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Href.CompareOrdinalIgnoreCase(coverMetaItem.Content));
            if (null != coverManifestItem?.Href && imageContentRefs.TryGetValue(coverManifestItem.Href, out coverImageContentFileRef))
            {
                return(coverImageContentFileRef);
            }
            // 2019-08-24 if it is still not found, then try to find an Id named cover
            coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Id.CompareOrdinalIgnoreCase(coverMetaItem.Name));
            if (null != coverManifestItem?.Href && imageContentRefs.TryGetValue(coverManifestItem.Href, out coverImageContentFileRef))
            {
                return(coverImageContentFileRef);
            }
            // 2019-08-24 if it is still not found, then try to find it in the guide
            var guideItem = epubSchema.Package.Guide.FirstOrDefault(reference => reference.Title.CompareOrdinalIgnoreCase(coverMetaItem.Name));

            if (null != guideItem?.Href && imageContentRefs.TryGetValue(guideItem.Href, out coverImageContentFileRef))
            {
                return(coverImageContentFileRef);
            }


            throw new Exception($"Incorrect EPUB manifest: item with ID = \"{coverMetaItem.Content}\" is missing or no corresponding image was found.");
        }
Ejemplo n.º 13
0
        public static async Task <EpubNavigation> ReadNavigationAsync(ZipArchive epubArchive, string contentDirectoryPath, EpubPackage package)
        {
            EpubNavigation    result            = new EpubNavigation();
            string            tocId             = package.Spine.Toc;
            XmlReaderSettings xmlReaderSettings = new XmlReaderSettings
            {
                // XmlResolver = null,
                Async         = true,
                DtdProcessing = DtdProcessing.Ignore
            };

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

            //Cheking if toc id referenced in spine exist in manifest
            EpubManifestItem tocManifestItem = package.Manifest.FirstOrDefault(item => String.Compare(item.Id, tocId, StringComparison.OrdinalIgnoreCase) == 0);

            if (tocManifestItem == null)
            {
                throw new Exception(String.Format("EPUB parsing error: TOC item {0} not found in EPUB manifest.", tocId));
            }
            //Opening .toc file in archive using href-reference from manifest
            string          tocFileEntryPath = ZipPathUtils.Combine(contentDirectoryPath, tocManifestItem.Href);
            ZipArchiveEntry tocFileEntry     = epubArchive.GetEntry(tocFileEntryPath);

            if (tocFileEntry == null)
            {
                throw new Exception(String.Format("EPUB parsing error: TOC file {0} not found in archive.", tocFileEntryPath));
            }
            if (tocFileEntry.Length > Int32.MaxValue)
            {
                throw new Exception(String.Format("EPUB parsing error: TOC file {0} is bigger than 2 Gb.", tocFileEntryPath));
            }
            // ------------------ Actual Parsing starts here: -------------------------
            using (Stream containerStream = tocFileEntry.Open())
            {
                using (XmlReader xmlReader = XmlReader.Create(containerStream, xmlReaderSettings))
                {
                    result.Head = await ReadNavigationHeadAsync(xmlReader);

                    result.DocTitle = await ReadNavigationDocTitleAsync(xmlReader);

                    result.DocAuthors = await ReadNavigationAuthorsAsync(xmlReader);

                    result.NavMap = await ReadNavigationMapAsync(xmlReader);

                    result.NavLists = new List <EpubNavigationList>(); //Empty, because not implemented
                    result.PageList = new EpubNavigationPageList();    //Empty, because not implemented
                }
            }

            return(result);
            //-------------------------------------------Boring old style Silverlight code...-----------------------------------------------------------------
            //------------------------------------------------------------------------------------------------------------------------------------------------
            //XmlDocument containerDocument;
            //containerDocument = XmlDocument.Load(containerStream);
            //XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(containerDocument.NameTable);
            //xmlNamespaceManager.AddNamespace("ncx", "http://www.daisy.org/z3986/2005/ncx/");
            ////Parsing head section
            //XmlNode headNode = containerDocument.DocumentElement.SelectSingleNode("ncx:head", xmlNamespaceManager);
            //if (headNode == null)
            //    throw new Exception("EPUB parsing error: TOC file does not contain head element");
            //EpubNavigationHead navigationHead = ReadNavigationHead(headNode);
            //result.Head = navigationHead;
            ////Parsing title
            //XmlNode docTitleNode = containerDocument.DocumentElement.SelectSingleNode("ncx:docTitle", xmlNamespaceManager);
            //if (docTitleNode == null)
            //    throw new Exception("EPUB parsing error: TOC file does not contain docTitle element");
            //EpubNavigationDocTitle navigationDocTitle = ReadNavigationDocTitle(docTitleNode);
            //result.DocTitle = navigationDocTitle;
            ////Parsing authors section...
            //result.DocAuthors = new List<EpubNavigationDocAuthor>();
            //foreach (XmlNode docAuthorNode in containerDocument.DocumentElement.SelectNodes("ncx:docAuthor", xmlNamespaceManager))
            //{
            //    EpubNavigationDocAuthor navigationDocAuthor = ReadNavigationDocAuthor(docAuthorNode);
            //    result.DocAuthors.Add(navigationDocAuthor);
            //}
            //Parsing navMap section
            //XmlNode navMapNode = containerDocument.DocumentElement.SelectSingleNode("ncx:navMap", xmlNamespaceManager);
            //if (navMapNode == null)
            //    throw new Exception("EPUB parsing error: TOC file does not contain navMap element");
            //EpubNavigationMap navMap = ReadNavigationMap(navMapNode);
            //result.NavMap = navMap;

            //-----------------------------------TO-DO: Implement -----------------------------------------------------------
            //TO-DO:  Implement  pageList parsing. Needed to tide-up  position inside epub to actual pages of the printed book
            //--------------------------------------------------------------------------------------------------------------
            //Parsing pageList node
            //XmlNode pageListNode = containerDocument.DocumentElement.SelectSingleNode("ncx:pageList", xmlNamespaceManager);
            //if (pageListNode != null)
            //{
            //    EpubNavigationPageList pageList = ReadNavigationPageList(pageListNode);
            //    result.PageList = pageList;
            //}
            ////TO-DO:  Implement  navList parsing. It is a secondary navigation system for supplied book info - schemes, fugures, diagrams, illustrations etc
            ////Parsing navList nodes
            //result.NavLists = new List<EpubNavigationList>();
            //foreach (XmlNode navigationListNode in containerDocument.DocumentElement.SelectNodes("ncx:navList", xmlNamespaceManager))
            //{
            //    EpubNavigationList navigationList = ReadNavigationList(navigationListNode);
            //    result.NavLists.Add(navigationList);
            //}
            //--------------------------------------------------------------------------------------------------------------
        }
Ejemplo n.º 14
0
        private static EpubManifest ReadManifest(XElement manifestNode)
        {
            EpubManifest result = new EpubManifest();

            foreach (XElement manifestItemNode in manifestNode.Elements())
            {
                if (manifestItemNode.CompareNameTo("item"))
                {
                    EpubManifestItem manifestItem = new EpubManifestItem();
                    foreach (XAttribute manifestItemNodeAttribute in manifestItemNode.Attributes())
                    {
                        string attributeValue = manifestItemNodeAttribute.Value;
                        switch (manifestItemNodeAttribute.GetLowerCaseLocalName())
                        {
                        case "id":
                            manifestItem.Id = attributeValue;
                            break;

                        case "href":
                            manifestItem.Href = Uri.UnescapeDataString(attributeValue);
                            break;

                        case "media-type":
                            manifestItem.MediaType = attributeValue;
                            break;

                        case "required-namespace":
                            manifestItem.RequiredNamespace = attributeValue;
                            break;

                        case "required-modules":
                            manifestItem.RequiredModules = attributeValue;
                            break;

                        case "fallback":
                            manifestItem.Fallback = attributeValue;
                            break;

                        case "fallback-style":
                            manifestItem.FallbackStyle = attributeValue;
                            break;

                        case "properties":
                            manifestItem.Properties = ReadManifestProperties(attributeValue);
                            break;
                        }
                    }
                    if (String.IsNullOrWhiteSpace(manifestItem.Id))
                    {
                        throw new Exception("Incorrect EPUB manifest: item ID is missing");
                    }
                    if (String.IsNullOrWhiteSpace(manifestItem.Href))
                    {
                        throw new Exception("Incorrect EPUB manifest: item href is missing");
                    }
                    if (String.IsNullOrWhiteSpace(manifestItem.MediaType))
                    {
                        throw new Exception("Incorrect EPUB manifest: item media type is missing");
                    }
                    result.Add(manifestItem);
                }
            }
            return(result);
        }
Ejemplo n.º 15
0
        private static async System.Threading.Tasks.Task <EpubManifest> ReadManifestAsync(XmlReader reader)
        {
            EpubManifest result = new EpubManifest();

            bool isManifestFound = await reader.ReadToFollowingAsync("manifest", "http://www.idpf.org/2007/opf");

            if (!isManifestFound)
            {
                throw new Exception("EPUB parsing error: manifest declarations not found in the package.");
            }

            while (await reader.ReadAsync() && !(reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "manifest"))
            {
                if (!String.IsNullOrWhiteSpace(reader.LocalName))
                {
                    EpubManifestItem manifestItem = new EpubManifestItem();
                    switch (reader.LocalName.ToLowerInvariant())
                    {
                    case "item":
                        while (reader.MoveToNextAttribute())
                        {
                            switch (reader.LocalName.ToLowerInvariant())
                            {
                            case "id":
                                manifestItem.Id = reader.Value;
                                break;

                            case "href":
                                manifestItem.Href = reader.Value;
                                break;

                            case "media-type":
                                manifestItem.MediaType = reader.Value;
                                break;

                            case "required-namespace":
                                manifestItem.RequiredNamespace = reader.Value;
                                break;

                            case "required-modules":
                                manifestItem.RequiredModules = reader.Value;
                                break;

                            case "fallback":
                                manifestItem.Fallback = reader.Value;
                                break;

                            case "fallback-style":
                                manifestItem.FallbackStyle = reader.Value;
                                break;
                            }
                        }
                        break;
                    }
                    if (String.IsNullOrWhiteSpace(manifestItem.Id))
                    {
                        throw new Exception("Incorrect EPUB manifest: item ID is missing");
                    }
                    if (String.IsNullOrWhiteSpace(manifestItem.Href))
                    {
                        throw new Exception("Incorrect EPUB manifest: item href is missing");
                    }
                    if (String.IsNullOrWhiteSpace(manifestItem.MediaType))
                    {
                        throw new Exception("Incorrect EPUB manifest: item media type is missing");
                    }
                    result.Add(manifestItem);
                }
            }
            return(result);
        }
Ejemplo n.º 16
0
        public static EpubNavigation ReadNavigation(ZipArchive 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("EPUB parsing error: TOC item {0} not found in EPUB manifest.", tocId));
            }
            string          tocFileEntryPath = ZipPathUtils.Combine(contentDirectoryPath, tocManifestItem.Href);
            ZipArchiveEntry tocFileEntry     = epubArchive.GetEntry(tocFileEntryPath);

            if (tocFileEntry == null)
            {
                throw new Exception(String.Format("EPUB parsing error: TOC file {0} not found in archive.", tocFileEntryPath));
            }
            if (tocFileEntry.Length > Int32.MaxValue)
            {
                throw new Exception(String.Format("EPUB parsing error: TOC file {0} is bigger than 2 Gb.", tocFileEntryPath));
            }
            XmlDocument containerDocument;

            using (Stream containerStream = tocFileEntry.Open())
                containerDocument = XmlUtils.LoadDocument(containerStream);
            XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(containerDocument.NameTable);

            xmlNamespaceManager.AddNamespace("ncx", "http://www.daisy.org/z3986/2005/ncx/");
            XmlNode headNode = containerDocument.DocumentElement.SelectSingleNode("ncx:head", xmlNamespaceManager);

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

            result.Head = navigationHead;
            XmlNode docTitleNode = containerDocument.DocumentElement.SelectSingleNode("ncx:docTitle", xmlNamespaceManager);

            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 (XmlNode docAuthorNode in containerDocument.DocumentElement.SelectNodes("ncx:docAuthor", xmlNamespaceManager))
            {
                EpubNavigationDocAuthor navigationDocAuthor = ReadNavigationDocAuthor(docAuthorNode);
                result.DocAuthors.Add(navigationDocAuthor);
            }
            XmlNode navMapNode = containerDocument.DocumentElement.SelectSingleNode("ncx:navMap", xmlNamespaceManager);

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

            result.NavMap = navMap;
            XmlNode pageListNode = containerDocument.DocumentElement.SelectSingleNode("ncx:pageList", xmlNamespaceManager);

            if (pageListNode != null)
            {
                EpubNavigationPageList pageList = ReadNavigationPageList(pageListNode);
                result.PageList = pageList;
            }
            result.NavLists = new List <EpubNavigationList>();
            foreach (XmlNode navigationListNode in containerDocument.DocumentElement.SelectNodes("ncx:navList", xmlNamespaceManager))
            {
                EpubNavigationList navigationList = ReadNavigationList(navigationListNode);
                result.NavLists.Add(navigationList);
            }
            return(result);
        }