< Summary - Jellyfin

Information
Class: MediaBrowser.Providers.Books.OpenPackagingFormat.OpfProvider
Assembly: MediaBrowser.Providers
File(s): /srv/git/jellyfin/MediaBrowser.Providers/Books/OpenPackagingFormat/OpfProvider.cs
Line coverage
12%
Covered lines: 3
Uncovered lines: 21
Coverable lines: 24
Total lines: 94
Line coverage: 12.5%
Branch coverage
0%
Covered branches: 0
Total branches: 8
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 1/29/2026 - 12:13:32 AM Line coverage: 12.5% (3/24) Branch coverage: 0% (0/8) Total lines: 94 1/29/2026 - 12:13:32 AM Line coverage: 12.5% (3/24) Branch coverage: 0% (0/8) Total lines: 94

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_Name()100%210%
HasChanged(...)0%620%
GetMetadata(...)100%210%
GetXmlFile(...)0%4260%
ReadOpfData(...)100%210%

File(s)

/srv/git/jellyfin/MediaBrowser.Providers/Books/OpenPackagingFormat/OpfProvider.cs

#LineLine coverage
 1using System.IO;
 2using System.Threading;
 3using System.Threading.Tasks;
 4using System.Xml;
 5using MediaBrowser.Controller.Entities;
 6using MediaBrowser.Controller.Providers;
 7using MediaBrowser.Model.IO;
 8using Microsoft.Extensions.Logging;
 9
 10namespace MediaBrowser.Providers.Books.OpenPackagingFormat
 11{
 12    /// <summary>
 13    /// Provides metadata for book items that have an OPF file in the same directory. Supports the standard
 14    /// content.opf filename, bespoke metadata.opf name from Calibre libraries, and OPF files that have the
 15    /// same name as their respective books for directories with several books.
 16    /// </summary>
 17    public class OpfProvider : ILocalMetadataProvider<Book>, IHasItemChangeMonitor
 18    {
 19        private const string StandardOpfFile = "content.opf";
 20        private const string CalibreOpfFile = "metadata.opf";
 21
 22        private readonly IFileSystem _fileSystem;
 23
 24        private readonly ILogger<OpfProvider> _logger;
 25
 26        /// <summary>
 27        /// Initializes a new instance of the <see cref="OpfProvider"/> class.
 28        /// </summary>
 29        /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 30        /// <param name="logger">Instance of the <see cref="ILogger{OpfProvider}"/> interface.</param>
 31        public OpfProvider(IFileSystem fileSystem, ILogger<OpfProvider> logger)
 32        {
 2133            _fileSystem = fileSystem;
 2134            _logger = logger;
 2135        }
 36
 37        /// <inheritdoc />
 038        public string Name => "Open Packaging Format";
 39
 40        /// <inheritdoc />
 41        public bool HasChanged(BaseItem item, IDirectoryService directoryService)
 42        {
 043            var file = GetXmlFile(item.Path);
 44
 045            return file.Exists && _fileSystem.GetLastWriteTimeUtc(file) > item.DateLastSaved;
 46        }
 47
 48        /// <inheritdoc />
 49        public Task<MetadataResult<Book>> GetMetadata(ItemInfo info, IDirectoryService directoryService, CancellationTok
 50        {
 051            var path = GetXmlFile(info.Path).FullName;
 52
 53            try
 54            {
 055                return Task.FromResult(ReadOpfData(path, cancellationToken));
 56            }
 057            catch (FileNotFoundException)
 58            {
 059                return Task.FromResult(new MetadataResult<Book> { HasMetadata = false });
 60            }
 061        }
 62
 63        private FileSystemMetadata GetXmlFile(string path)
 64        {
 065            var fileInfo = _fileSystem.GetFileSystemInfo(path);
 066            var directoryInfo = fileInfo.IsDirectory ? fileInfo : _fileSystem.GetDirectoryInfo(Path.GetDirectoryName(pat
 67
 68            // check for OPF with matching name first since it's the most specific filename
 069            var specificFile = Path.Combine(directoryInfo.FullName, Path.GetFileNameWithoutExtension(path) + ".opf");
 070            var file = _fileSystem.GetFileInfo(specificFile);
 71
 072            if (file.Exists)
 73            {
 074                return file;
 75            }
 76
 077            file = _fileSystem.GetFileInfo(Path.Combine(directoryInfo.FullName, StandardOpfFile));
 78
 79            // check metadata.opf last since it's really only used by Calibre
 080            return file.Exists ? file : _fileSystem.GetFileInfo(Path.Combine(directoryInfo.FullName, CalibreOpfFile));
 81        }
 82
 83        private MetadataResult<Book> ReadOpfData(string file, CancellationToken cancellationToken)
 84        {
 085            cancellationToken.ThrowIfCancellationRequested();
 86
 087            var doc = new XmlDocument();
 088            doc.Load(file);
 89
 090            var utilities = new OpfReader<OpfProvider>(doc, _logger);
 091            return utilities.ReadOpfData(cancellationToken);
 92        }
 93    }
 94}