Skip to content

Commit

Permalink
Merge pull request #45 from MinecraftPlaye/opf-cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
crobibero authored Jan 18, 2022
2 parents 20c78b2 + 8233ac6 commit 731421f
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 184 deletions.
24 changes: 14 additions & 10 deletions Jellyfin.Plugin.Bookshelf/Providers/BookProviderFromOpf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,24 @@ public bool HasChanged(BaseItem item, IDirectoryService directoryService)
public Task<MetadataResult<Book>> GetMetadata(ItemInfo info, IDirectoryService directoryService, CancellationToken cancellationToken)
{
var path = GetXmlFile(info.Path).FullName;
var result = new MetadataResult<Book>();

try
{
var item = new Book();
result.HasMetadata = true;
result.Item = item;
ReadOpfData(result, path, cancellationToken);
var result = ReadOpfData(path, cancellationToken);

if (result is null)
{
return Task.FromResult(new MetadataResult<Book> { HasMetadata = false });
}
else
{
return Task.FromResult(result);
}
}
catch (FileNotFoundException)
{
result.HasMetadata = false;
return Task.FromResult(new MetadataResult<Book> { HasMetadata = false });
}

return Task.FromResult(result);
}

private FileSystemMetadata GetXmlFile(string path)
Expand All @@ -85,14 +88,15 @@ private FileSystemMetadata GetXmlFile(string path)
return file.Exists ? file : _fileSystem.GetFileInfo(Path.Combine(directoryPath, CalibreOpfFile));
}

private void ReadOpfData(MetadataResult<Book> bookResult, string metaFile, CancellationToken cancellationToken)
private MetadataResult<Book> ReadOpfData(string metaFile, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();

var doc = new XmlDocument();
doc.Load(metaFile);

OpfReader.ReadOpfData(bookResult, doc, _logger, cancellationToken);
var utilities = new OpfReader<BookProviderFromOpf>(doc, _logger);
return utilities.ReadOpfData(cancellationToken);
}
}
}
111 changes: 13 additions & 98 deletions Jellyfin.Plugin.Bookshelf/Providers/Epub/EpubMetadataImageProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Net;
using Microsoft.Extensions.Logging;

namespace Jellyfin.Plugin.Bookshelf.Providers.Epub
{
Expand All @@ -17,8 +18,16 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.Epub
/// </summary>
public class EpubMetadataImageProvider : IDynamicImageProvider
{
private const string DcNamespace = @"http://purl.org/dc/elements/1.1/";
private const string OpfNamespace = @"http://www.idpf.org/2007/opf";
private readonly ILogger<EpubMetadataImageProvider> _logger;

/// <summary>
/// Initializes a new instance of the <see cref="EpubMetadataImageProvider"/> class.
/// </summary>
/// <param name="logger">Instance of the <see cref="ILogger{EpubMetadataImageProvider}"/> interface.</param>
public EpubMetadataImageProvider(ILogger<EpubMetadataImageProvider> logger)
{
_logger = logger;
}

/// <inheritdoc />
public string Name => "Epub Metadata";
Expand Down Expand Up @@ -46,92 +55,10 @@ public Task<DynamicImageResponse> GetImage(BaseItem item, ImageType type, Cancel
return Task.FromResult(new DynamicImageResponse { HasImage = false });
}

private bool IsValidImage(string? mimeType)
{
return !string.IsNullOrEmpty(mimeType)
&& !string.IsNullOrWhiteSpace(MimeTypes.ToExtension(mimeType));
}

private EpubCover? ReadManifestItem(XmlNode manifestNode, string opfRootDirectory)
{
var href = manifestNode.Attributes?["href"]?.Value;
var mediaType = manifestNode.Attributes?["media-type"]?.Value;

if (string.IsNullOrEmpty(href)
|| string.IsNullOrEmpty(mediaType)
|| !IsValidImage(mediaType))
{
return null;
}

var coverPath = Path.Combine(opfRootDirectory, href);
return new EpubCover(mediaType, coverPath);
}

private EpubCover? ReadCoverPath(XmlDocument opf, string opfRootDirectory)
{
var namespaceManager = new XmlNamespaceManager(opf.NameTable);
namespaceManager.AddNamespace("dc", DcNamespace);
namespaceManager.AddNamespace("opf", OpfNamespace);

var coverImagePropertyNode = opf.SelectSingleNode("//opf:item[@properties='cover-image']", namespaceManager);
if (coverImagePropertyNode is not null)
{
var coverImageProperty = ReadManifestItem(coverImagePropertyNode, opfRootDirectory);
if (coverImageProperty != null)
{
return coverImageProperty;
}
}

var coverIdNode = opf.SelectSingleNode("//opf:item[@id='cover']", namespaceManager);
if (coverIdNode is not null)
{
var coverId = ReadManifestItem(coverIdNode, opfRootDirectory);
if (coverId != null)
{
return coverId;
}
}

var coverImageIdNode = opf.SelectSingleNode("//opf:item[@id='cover-image']", namespaceManager);
if (coverImageIdNode is not null)
{
var coverImageId = ReadManifestItem(coverImageIdNode, opfRootDirectory);
if (coverImageId != null)
{
return coverImageId;
}
}

var metaCoverImage = opf.SelectSingleNode("//opf:meta[@name='cover']", namespaceManager);
var content = metaCoverImage?.Attributes?["content"]?.Value;
if (string.IsNullOrEmpty(content) || metaCoverImage is null)
{
return null;
}

var coverPath = Path.Combine("Images", content);
var coverFileManifest = opf.SelectSingleNode($"//opf:item[@href='{coverPath}']", namespaceManager);
var mediaType = coverFileManifest?.Attributes?["media-type"]?.Value;
if (coverFileManifest?.Attributes is not null
&& !string.IsNullOrEmpty(mediaType) && IsValidImage(mediaType))
{
return new EpubCover(mediaType, Path.Combine(opfRootDirectory, coverPath));
}

var coverFileIdManifest = opf.SelectSingleNode($"//opf:item[@id='{content}']", namespaceManager);
if (coverFileIdManifest is not null)
{
return ReadManifestItem(coverFileIdManifest, opfRootDirectory);
}

return null;
}

private async Task<DynamicImageResponse> LoadCover(ZipArchive epub, XmlDocument opf, string opfRootDirectory)
{
var coverRef = ReadCoverPath(opf, opfRootDirectory);
var utilities = new OpfReader<EpubMetadataImageProvider>(opf, _logger);
var coverRef = utilities.ReadCoverPath(opfRootDirectory);
if (coverRef == null)
{
return new DynamicImageResponse { HasImage = false };
Expand Down Expand Up @@ -193,17 +120,5 @@ private Task<DynamicImageResponse> GetFromZip(BaseItem item)

return LoadCover(epub, opfDocument, opfRootDirectory);
}

private readonly struct EpubCover
{
public EpubCover(string coverMimeType, string coverPath)
{
(MimeType, Path) = (coverMimeType, coverPath);
}

public string MimeType { get; }

public string Path { get; }
}
}
}
28 changes: 15 additions & 13 deletions Jellyfin.Plugin.Bookshelf/Providers/Epub/EpubMetadataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,22 @@ public Task<MetadataResult<Book>> GetMetadata(
CancellationToken cancellationToken)
{
var path = GetEpubFile(info.Path)?.FullName;
var result = new MetadataResult<Book>();

if (path == null)
if (path is null)
{
result.HasMetadata = false;
return Task.FromResult(new MetadataResult<Book> { HasMetadata = false });
}

var result = ReadEpubAsZip(path, cancellationToken);

if (result is null)
{
return Task.FromResult(new MetadataResult<Book> { HasMetadata = false });
}
else
{
var item = new Book();
result.HasMetadata = true;
result.Item = item;
ReadEpubAsZip(result, path, cancellationToken);
return Task.FromResult(result);
}

return Task.FromResult(result);
}

private FileSystemMetadata? GetEpubFile(string path)
Expand All @@ -74,28 +75,29 @@ public Task<MetadataResult<Book>> GetMetadata(
return fileInfo;
}

private void ReadEpubAsZip(MetadataResult<Book> result, string path, CancellationToken cancellationToken)
private MetadataResult<Book>? ReadEpubAsZip(string path, CancellationToken cancellationToken)
{
using var epub = ZipFile.OpenRead(path);

var opfFilePath = EpubUtils.ReadContentFilePath(epub);
if (opfFilePath == null)
{
return;
return null;
}

var opf = epub.GetEntry(opfFilePath);
if (opf == null)
{
return;
return null;
}

using var opfStream = opf.Open();

var opfDocument = new XmlDocument();
opfDocument.Load(opfStream);

OpfReader.ReadOpfData(result, opfDocument, _logger, cancellationToken);
var utilities = new OpfReader<EpubMetadataProvider>(opfDocument, _logger);
return utilities.ReadOpfData(cancellationToken);
}
}
}
Loading

0 comments on commit 731421f

Please sign in to comment.