📄
src/Infrastructure/Database/MediaRepository.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System; using System.Linq; using System.Threading; using System.Threading.Tasks; using Jellyfin.Database.Implementations; using Jellyfin.Database.Implementations.Entities; using Microsoft.EntityFrameworkCore; using Slopper.Domain; namespace Slopper.Infrastructure.Database; internal sealed class MediaRepository(JellyfinDbContext jellyfinDbContext, Random random) : IMediaRepository { public async Task<MediaItem> GetRandomMediaItem(CancellationToken cancellationToken) { var query = jellyfinDbContext .MediaStreamInfos.AsNoTracking() .Where(s => s.StreamType == MediaStreamTypeEntity.Subtitle && s.Language == "eng" && s.Codec != "PGSSUB"); var count = await query.CountAsync(cancellationToken); var index = random.Next(count); var mediaStreamInfo = await query .Include(s => s.Item) .OrderBy(s => s.ItemId) .ThenBy(s => s.StreamIndex) .Skip(index) .FirstOrDefaultAsync(cancellationToken) ?? throw new Exception("No media available"); return Map(mediaStreamInfo); } private static MediaItem Map(MediaStreamInfo mediaStreamInfo) => new(MapName(mediaStreamInfo.Item), MapVideoPath(mediaStreamInfo.Item), MapSubtitle(mediaStreamInfo)); private static string MapName(BaseItemEntity item) => item switch { { SeriesName: string seriesName, SeasonName: string seasonName, EpisodeTitle: string episodeTitle } => $"{seriesName} {seasonName} {episodeTitle}", { SeriesName: string seriesName, SeasonName: string seasonName, Name: string name } => $"{seriesName} {seasonName} {name}", { Name: string name } => name, { SortName: string sortName } => sortName, { CleanName: string cleanName } => cleanName, _ => throw new Exception("No name for media item"), }; private static string MapVideoPath(BaseItemEntity item) => item.Path ?? throw new Exception("No video stream for media item"); private static Subtitles MapSubtitle(MediaStreamInfo mediaStreamInfo) => mediaStreamInfo.IsExternal ? new Subtitles.External(mediaStreamInfo.Path ?? throw new Exception("External subtitles without path")) : new Subtitles.Embedded(mediaStreamInfo.StreamIndex); }