< Summary - Jellyfin

Information
Class: Jellyfin.Server.Implementations.Item.ChapterRepository
Assembly: Jellyfin.Server.Implementations
File(s): /srv/git/jellyfin/Jellyfin.Server.Implementations/Item/ChapterRepository.cs
Line coverage
5%
Covered lines: 3
Uncovered lines: 56
Coverable lines: 59
Total lines: 118
Line coverage: 5%
Branch coverage
0%
Covered branches: 0
Total branches: 4
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
GetChapter(...)0%620%
GetChapters(...)100%210%
SaveChapters(...)0%620%
DeleteChapters(...)100%210%
Map(...)100%210%
Map(...)100%210%

File(s)

/srv/git/jellyfin/Jellyfin.Server.Implementations/Item/ChapterRepository.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using Jellyfin.Database.Implementations;
 5using Jellyfin.Database.Implementations.Entities;
 6using MediaBrowser.Controller.Drawing;
 7using MediaBrowser.Controller.Persistence;
 8using MediaBrowser.Model.Entities;
 9using Microsoft.EntityFrameworkCore;
 10
 11namespace Jellyfin.Server.Implementations.Item;
 12
 13/// <summary>
 14/// The Chapter manager.
 15/// </summary>
 16public class ChapterRepository : IChapterRepository
 17{
 18    private readonly IDbContextFactory<JellyfinDbContext> _dbProvider;
 19    private readonly IImageProcessor _imageProcessor;
 20
 21    /// <summary>
 22    /// Initializes a new instance of the <see cref="ChapterRepository"/> class.
 23    /// </summary>
 24    /// <param name="dbProvider">The EFCore provider.</param>
 25    /// <param name="imageProcessor">The Image Processor.</param>
 26    public ChapterRepository(IDbContextFactory<JellyfinDbContext> dbProvider, IImageProcessor imageProcessor)
 27    {
 2128        _dbProvider = dbProvider;
 2129        _imageProcessor = imageProcessor;
 2130    }
 31
 32    /// <inheritdoc />
 33    public ChapterInfo? GetChapter(Guid baseItemId, int index)
 34    {
 035        using var context = _dbProvider.CreateDbContext();
 036        var chapter = context.Chapters.AsNoTracking()
 037            .Select(e => new
 038            {
 039                chapter = e,
 040                baseItemPath = e.Item.Path
 041            })
 042            .FirstOrDefault(e => e.chapter.ItemId.Equals(baseItemId) && e.chapter.ChapterIndex == index);
 043        if (chapter is not null)
 44        {
 045            return Map(chapter.chapter, chapter.baseItemPath!);
 46        }
 47
 048        return null;
 049    }
 50
 51    /// <inheritdoc />
 52    public IReadOnlyList<ChapterInfo> GetChapters(Guid baseItemId)
 53    {
 054        using var context = _dbProvider.CreateDbContext();
 055        return context.Chapters.AsNoTracking().Where(e => e.ItemId.Equals(baseItemId))
 056            .Select(e => new
 057            {
 058                chapter = e,
 059                baseItemPath = e.Item.Path
 060            })
 061            .AsEnumerable()
 062            .Select(e => Map(e.chapter, e.baseItemPath!))
 063            .ToArray();
 064    }
 65
 66    /// <inheritdoc />
 67    public void SaveChapters(Guid itemId, IReadOnlyList<ChapterInfo> chapters)
 68    {
 069        using var context = _dbProvider.CreateDbContext();
 070        using (var transaction = context.Database.BeginTransaction())
 71        {
 072            context.Chapters.Where(e => e.ItemId.Equals(itemId)).ExecuteDelete();
 073            for (var i = 0; i < chapters.Count; i++)
 74            {
 075                var chapter = chapters[i];
 076                context.Chapters.Add(Map(chapter, i, itemId));
 77            }
 78
 079            context.SaveChanges();
 080            transaction.Commit();
 081        }
 082    }
 83
 84    /// <inheritdoc />
 85    public void DeleteChapters(Guid itemId)
 86    {
 087        using var context = _dbProvider.CreateDbContext();
 088        context.Chapters.Where(c => c.ItemId.Equals(itemId)).ExecuteDelete();
 089        context.SaveChanges();
 090    }
 91
 92    private Chapter Map(ChapterInfo chapterInfo, int index, Guid itemId)
 93    {
 094        return new Chapter()
 095        {
 096            ChapterIndex = index,
 097            StartPositionTicks = chapterInfo.StartPositionTicks,
 098            ImageDateModified = chapterInfo.ImageDateModified,
 099            ImagePath = chapterInfo.ImagePath,
 0100            ItemId = itemId,
 0101            Name = chapterInfo.Name,
 0102            Item = null!
 0103        };
 104    }
 105
 106    private ChapterInfo Map(Chapter chapterInfo, string baseItemPath)
 107    {
 0108        var chapterEntity = new ChapterInfo()
 0109        {
 0110            StartPositionTicks = chapterInfo.StartPositionTicks,
 0111            ImageDateModified = chapterInfo.ImageDateModified.GetValueOrDefault(),
 0112            ImagePath = chapterInfo.ImagePath,
 0113            Name = chapterInfo.Name,
 0114        };
 0115        chapterEntity.ImageTag = _imageProcessor.GetImageCacheTag(baseItemPath, chapterEntity.ImageDateModified);
 0116        return chapterEntity;
 117    }
 118}