using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using Jellyfin.Data.Entities; using MediaBrowser.Controller.Chapters; using MediaBrowser.Controller.Drawing; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using Microsoft.EntityFrameworkCore; namespace Jellyfin.Server.Implementations.Item; /// /// The Chapter manager. /// public class ChapterRepository : IChapterRepository { private readonly IDbContextFactory _dbProvider; private readonly IImageProcessor _imageProcessor; /// /// Initializes a new instance of the class. /// /// The EFCore provider. /// The Image Processor. public ChapterRepository(IDbContextFactory dbProvider, IImageProcessor imageProcessor) { _dbProvider = dbProvider; _imageProcessor = imageProcessor; } /// public ChapterInfo? GetChapter(BaseItemDto baseItem, int index) { return GetChapter(baseItem.Id, index); } /// public IReadOnlyList GetChapters(BaseItemDto baseItem) { return GetChapters(baseItem.Id); } /// public ChapterInfo? GetChapter(Guid baseItemId, int index) { using var context = _dbProvider.CreateDbContext(); var chapter = context.Chapters .Select(e => new { chapter = e, baseItemPath = e.Item.Path }) .FirstOrDefault(e => e.chapter.ItemId.Equals(baseItemId) && e.chapter.ChapterIndex == index); if (chapter is not null) { return Map(chapter.chapter, chapter.baseItemPath!); } return null; } /// public IReadOnlyList GetChapters(Guid baseItemId) { using var context = _dbProvider.CreateDbContext(); return context.Chapters.Where(e => e.ItemId.Equals(baseItemId)) .Select(e => new { chapter = e, baseItemPath = e.Item.Path }) .ToList() .Select(e => Map(e.chapter, e.baseItemPath!)) .ToImmutableArray(); } /// public void SaveChapters(Guid itemId, IReadOnlyList chapters) { using var context = _dbProvider.CreateDbContext(); using (var transaction = context.Database.BeginTransaction()) { context.Chapters.Where(e => e.ItemId.Equals(itemId)).ExecuteDelete(); for (var i = 0; i < chapters.Count; i++) { var chapter = chapters[i]; context.Chapters.Add(Map(chapter, i, itemId)); } context.SaveChanges(); transaction.Commit(); } } private Chapter Map(ChapterInfo chapterInfo, int index, Guid itemId) { return new Chapter() { ChapterIndex = index, StartPositionTicks = chapterInfo.StartPositionTicks, ImageDateModified = chapterInfo.ImageDateModified, ImagePath = chapterInfo.ImagePath, ItemId = itemId, Name = chapterInfo.Name, Item = null! }; } private ChapterInfo Map(Chapter chapterInfo, string baseItemPath) { var chapterEntity = new ChapterInfo() { StartPositionTicks = chapterInfo.StartPositionTicks, ImageDateModified = chapterInfo.ImageDateModified.GetValueOrDefault(), ImagePath = chapterInfo.ImagePath, Name = chapterInfo.Name, }; chapterEntity.ImageTag = _imageProcessor.GetImageCacheTag(baseItemPath, chapterEntity.ImageDateModified); return chapterEntity; } }