using System; using System.IO; using System.IO.Compression; using System.Threading; using System.Threading.Tasks; using System.Xml; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.IO; using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.Books.OpenPackagingFormat { /// /// Provides book metadata from OPF content in an EPUB item. /// public class EpubProvider : ILocalMetadataProvider { private readonly IFileSystem _fileSystem; private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// Instance of the interface. /// Instance of the interface. public EpubProvider(IFileSystem fileSystem, ILogger logger) { _fileSystem = fileSystem; _logger = logger; } /// public string Name => "EPUB Metadata"; /// public Task> GetMetadata(ItemInfo info, IDirectoryService directoryService, CancellationToken cancellationToken) { var path = GetEpubFile(info.Path)?.FullName; if (path is null) { return Task.FromResult(new MetadataResult { HasMetadata = false }); } var result = ReadEpubAsZip(path, cancellationToken); if (result is null) { return Task.FromResult(new MetadataResult { HasMetadata = false }); } else { return Task.FromResult(result); } } private FileSystemMetadata? GetEpubFile(string path) { var fileInfo = _fileSystem.GetFileSystemInfo(path); if (fileInfo.IsDirectory) { return null; } if (!string.Equals(Path.GetExtension(fileInfo.FullName), ".epub", StringComparison.OrdinalIgnoreCase)) { return null; } return fileInfo; } private MetadataResult? ReadEpubAsZip(string path, CancellationToken cancellationToken) { using var epub = ZipFile.OpenRead(path); var opfFilePath = EpubUtils.ReadContentFilePath(epub); if (opfFilePath == null) { return null; } var opf = epub.GetEntry(opfFilePath); if (opf == null) { return null; } using var opfStream = opf.Open(); var opfDocument = new XmlDocument(); opfDocument.Load(opfStream); var utilities = new OpfReader(opfDocument, _logger); return utilities.ReadOpfData(cancellationToken); } } }