< Summary - Jellyfin

Information
Class: Jellyfin.LiveTv.LiveTvDtoService
Assembly: Jellyfin.LiveTv
File(s): /srv/git/jellyfin/src/Jellyfin.LiveTv/LiveTvDtoService.cs
Line coverage
2%
Covered lines: 6
Uncovered lines: 224
Coverable lines: 230
Total lines: 549
Line coverage: 2.6%
Branch coverage
0%
Covered branches: 0
Total branches: 82
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%
GetTimerInfoDto(...)0%272160%
GetSeriesTimerInfoDto(...)0%4260%
FillImages(...)0%342180%
FillImages(...)0%420200%
GetDayPattern(...)0%506220%
GetImageTag(...)100%210%
GetInternalChannelId(...)100%210%
GetInternalTimerId(...)100%210%
GetInternalSeriesTimerId(...)100%210%
GetInternalProgramId(...)100%210%

File(s)

/srv/git/jellyfin/src/Jellyfin.LiveTv/LiveTvDtoService.cs

#LineLine coverage
 1#nullable disable
 2
 3#pragma warning disable CS1591
 4
 5using System;
 6using System.Globalization;
 7using System.Linq;
 8using System.Threading;
 9using System.Threading.Tasks;
 10using Jellyfin.Data.Enums;
 11using Jellyfin.Extensions;
 12using MediaBrowser.Common;
 13using MediaBrowser.Common.Extensions;
 14using MediaBrowser.Controller.Drawing;
 15using MediaBrowser.Controller.Dto;
 16using MediaBrowser.Controller.Entities;
 17using MediaBrowser.Controller.Library;
 18using MediaBrowser.Controller.LiveTv;
 19using MediaBrowser.Model.Dto;
 20using MediaBrowser.Model.Entities;
 21using MediaBrowser.Model.LiveTv;
 22using Microsoft.Extensions.Logging;
 23
 24namespace Jellyfin.LiveTv
 25{
 26    public class LiveTvDtoService
 27    {
 28        private const string InternalVersionNumber = "4";
 29
 30        private const string ServiceName = "Emby";
 31
 32        private readonly ILogger<LiveTvDtoService> _logger;
 33        private readonly IImageProcessor _imageProcessor;
 34        private readonly IDtoService _dtoService;
 35        private readonly IApplicationHost _appHost;
 36        private readonly ILibraryManager _libraryManager;
 37
 38        public LiveTvDtoService(
 39            IDtoService dtoService,
 40            IImageProcessor imageProcessor,
 41            ILogger<LiveTvDtoService> logger,
 42            IApplicationHost appHost,
 43            ILibraryManager libraryManager)
 44        {
 2245            _dtoService = dtoService;
 2246            _imageProcessor = imageProcessor;
 2247            _logger = logger;
 2248            _appHost = appHost;
 2249            _libraryManager = libraryManager;
 2250        }
 51
 52        public TimerInfoDto GetTimerInfoDto(TimerInfo info, ILiveTvService service, LiveTvProgram program, BaseItem chan
 53        {
 054            var dto = new TimerInfoDto
 055            {
 056                Id = GetInternalTimerId(info.Id),
 057                Overview = info.Overview,
 058                EndDate = info.EndDate,
 059                Name = info.Name,
 060                StartDate = info.StartDate,
 061                ExternalId = info.Id,
 062                ChannelId = GetInternalChannelId(service.Name, info.ChannelId),
 063                Status = info.Status,
 064                SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId) ? null : GetInternalSeriesTimerId(info.SeriesTi
 065                PrePaddingSeconds = info.PrePaddingSeconds,
 066                PostPaddingSeconds = info.PostPaddingSeconds,
 067                IsPostPaddingRequired = info.IsPostPaddingRequired,
 068                IsPrePaddingRequired = info.IsPrePaddingRequired,
 069                KeepUntil = info.KeepUntil,
 070                ExternalChannelId = info.ChannelId,
 071                ExternalSeriesTimerId = info.SeriesTimerId,
 072                ServiceName = service.Name,
 073                ExternalProgramId = info.ProgramId,
 074                Priority = info.Priority,
 075                RunTimeTicks = (info.EndDate - info.StartDate).Ticks,
 076                ServerId = _appHost.SystemId
 077            };
 78
 079            if (!string.IsNullOrEmpty(info.ProgramId))
 80            {
 081                dto.ProgramId = GetInternalProgramId(info.ProgramId).ToString("N", CultureInfo.InvariantCulture);
 82            }
 83
 084            if (program is not null)
 85            {
 086                dto.ProgramInfo = _dtoService.GetBaseItemDto(program, new DtoOptions());
 87
 088                if (info.Status != RecordingStatus.Cancelled && info.Status != RecordingStatus.Error)
 89                {
 090                    dto.ProgramInfo.TimerId = dto.Id;
 091                    dto.ProgramInfo.Status = info.Status.ToString();
 92                }
 93
 094                dto.ProgramInfo.SeriesTimerId = dto.SeriesTimerId;
 95
 096                if (!string.IsNullOrEmpty(info.SeriesTimerId))
 97                {
 098                    FillImages(dto.ProgramInfo, info.Name, info.SeriesId);
 99                }
 100            }
 101
 0102            if (channel is not null)
 103            {
 0104                dto.ChannelName = channel.Name;
 105
 0106                if (channel.HasImage(ImageType.Primary))
 107                {
 0108                    dto.ChannelPrimaryImageTag = GetImageTag(channel);
 109                }
 110            }
 111
 0112            return dto;
 113        }
 114
 115        public SeriesTimerInfoDto GetSeriesTimerInfoDto(SeriesTimerInfo info, ILiveTvService service, string channelName
 116        {
 0117            var dto = new SeriesTimerInfoDto
 0118            {
 0119                Id = GetInternalSeriesTimerId(info.Id).ToString("N", CultureInfo.InvariantCulture),
 0120                Overview = info.Overview,
 0121                EndDate = info.EndDate,
 0122                Name = info.Name,
 0123                StartDate = info.StartDate,
 0124                ExternalId = info.Id,
 0125                PrePaddingSeconds = info.PrePaddingSeconds,
 0126                PostPaddingSeconds = info.PostPaddingSeconds,
 0127                IsPostPaddingRequired = info.IsPostPaddingRequired,
 0128                IsPrePaddingRequired = info.IsPrePaddingRequired,
 0129                Days = info.Days.ToArray(),
 0130                Priority = info.Priority,
 0131                RecordAnyChannel = info.RecordAnyChannel,
 0132                RecordAnyTime = info.RecordAnyTime,
 0133                SkipEpisodesInLibrary = info.SkipEpisodesInLibrary,
 0134                KeepUpTo = info.KeepUpTo,
 0135                KeepUntil = info.KeepUntil,
 0136                RecordNewOnly = info.RecordNewOnly,
 0137                ExternalChannelId = info.ChannelId,
 0138                ExternalProgramId = info.ProgramId,
 0139                ServiceName = service.Name,
 0140                ChannelName = channelName,
 0141                ServerId = _appHost.SystemId
 0142            };
 143
 0144            if (!string.IsNullOrEmpty(info.ChannelId))
 145            {
 0146                dto.ChannelId = GetInternalChannelId(service.Name, info.ChannelId);
 147            }
 148
 0149            if (!string.IsNullOrEmpty(info.ProgramId))
 150            {
 0151                dto.ProgramId = GetInternalProgramId(info.ProgramId).ToString("N", CultureInfo.InvariantCulture);
 152            }
 153
 0154            dto.DayPattern = info.Days is null ? null : GetDayPattern(info.Days.ToArray());
 155
 0156            FillImages(dto, info.Name, info.SeriesId);
 157
 0158            return dto;
 159        }
 160
 161        private void FillImages(BaseItemDto dto, string seriesName, string programSeriesId)
 162        {
 0163            var librarySeries = _libraryManager.GetItemList(new InternalItemsQuery
 0164            {
 0165                IncludeItemTypes = new[] { BaseItemKind.Series },
 0166                Name = seriesName,
 0167                Limit = 1,
 0168                ImageTypes = new ImageType[] { ImageType.Thumb },
 0169                DtoOptions = new DtoOptions(false)
 0170            }).FirstOrDefault();
 171
 0172            if (librarySeries is not null)
 173            {
 0174                var image = librarySeries.GetImageInfo(ImageType.Thumb, 0);
 0175                if (image is not null)
 176                {
 177                    try
 178                    {
 0179                        dto.ParentThumbImageTag = _imageProcessor.GetImageCacheTag(librarySeries, image);
 0180                        dto.ParentThumbItemId = librarySeries.Id;
 0181                    }
 0182                    catch (Exception ex)
 183                    {
 0184                        _logger.LogError(ex, "Error");
 0185                    }
 186                }
 187
 0188                image = librarySeries.GetImageInfo(ImageType.Backdrop, 0);
 0189                if (image is not null)
 190                {
 191                    try
 192                    {
 0193                        dto.ParentBackdropImageTags = new string[]
 0194                            {
 0195                                _imageProcessor.GetImageCacheTag(librarySeries, image)
 0196                            };
 0197                        dto.ParentBackdropItemId = librarySeries.Id;
 0198                    }
 0199                    catch (Exception ex)
 200                    {
 0201                        _logger.LogError(ex, "Error");
 0202                    }
 203                }
 204            }
 205
 0206            var program = _libraryManager.GetItemList(new InternalItemsQuery
 0207            {
 0208                IncludeItemTypes = new[] { BaseItemKind.LiveTvProgram },
 0209                ExternalSeriesId = programSeriesId,
 0210                Limit = 1,
 0211                ImageTypes = new ImageType[] { ImageType.Primary },
 0212                DtoOptions = new DtoOptions(false),
 0213                Name = string.IsNullOrEmpty(programSeriesId) ? seriesName : null
 0214            }).FirstOrDefault();
 215
 0216            if (program is not null)
 217            {
 0218                var image = program.GetImageInfo(ImageType.Primary, 0);
 0219                if (image is not null)
 220                {
 221                    try
 222                    {
 0223                        dto.ParentPrimaryImageTag = _imageProcessor.GetImageCacheTag(program, image);
 0224                        dto.ParentPrimaryImageItemId = program.Id.ToString("N", CultureInfo.InvariantCulture);
 0225                    }
 0226                    catch (Exception ex)
 227                    {
 0228                        _logger.LogError(ex, "Error");
 0229                    }
 230                }
 231
 0232                if (dto.ParentBackdropImageTags is null || dto.ParentBackdropImageTags.Length == 0)
 233                {
 0234                    image = program.GetImageInfo(ImageType.Backdrop, 0);
 0235                    if (image is not null)
 236                    {
 237                        try
 238                        {
 0239                            dto.ParentBackdropImageTags = new string[]
 0240                            {
 0241                                _imageProcessor.GetImageCacheTag(program, image)
 0242                            };
 243
 0244                            dto.ParentBackdropItemId = program.Id;
 0245                        }
 0246                        catch (Exception ex)
 247                        {
 0248                            _logger.LogError(ex, "Error");
 0249                        }
 250                    }
 251                }
 252            }
 0253        }
 254
 255        private void FillImages(SeriesTimerInfoDto dto, string seriesName, string programSeriesId)
 256        {
 0257            var librarySeries = _libraryManager.GetItemList(new InternalItemsQuery
 0258            {
 0259                IncludeItemTypes = new[] { BaseItemKind.Series },
 0260                Name = seriesName,
 0261                Limit = 1,
 0262                ImageTypes = new ImageType[] { ImageType.Thumb },
 0263                DtoOptions = new DtoOptions(false)
 0264            }).FirstOrDefault();
 265
 0266            if (librarySeries is not null)
 267            {
 0268                var image = librarySeries.GetImageInfo(ImageType.Thumb, 0);
 0269                if (image is not null)
 270                {
 271                    try
 272                    {
 0273                        dto.ParentThumbImageTag = _imageProcessor.GetImageCacheTag(librarySeries, image);
 0274                        dto.ParentThumbItemId = librarySeries.Id.ToString("N", CultureInfo.InvariantCulture);
 0275                    }
 0276                    catch (Exception ex)
 277                    {
 0278                        _logger.LogError(ex, "Error");
 0279                    }
 280                }
 281
 0282                image = librarySeries.GetImageInfo(ImageType.Backdrop, 0);
 0283                if (image is not null)
 284                {
 285                    try
 286                    {
 0287                        dto.ParentBackdropImageTags = new string[]
 0288                            {
 0289                                _imageProcessor.GetImageCacheTag(librarySeries, image)
 0290                            };
 0291                        dto.ParentBackdropItemId = librarySeries.Id.ToString("N", CultureInfo.InvariantCulture);
 0292                    }
 0293                    catch (Exception ex)
 294                    {
 0295                        _logger.LogError(ex, "Error");
 0296                    }
 297                }
 298            }
 299
 0300            var program = _libraryManager.GetItemList(new InternalItemsQuery
 0301            {
 0302                IncludeItemTypes = new[] { BaseItemKind.Series },
 0303                Name = seriesName,
 0304                Limit = 1,
 0305                ImageTypes = new ImageType[] { ImageType.Primary },
 0306                DtoOptions = new DtoOptions(false)
 0307            }).FirstOrDefault();
 308
 0309            if (program is null)
 310            {
 0311                program = _libraryManager.GetItemList(new InternalItemsQuery
 0312                {
 0313                    IncludeItemTypes = new[] { BaseItemKind.LiveTvProgram },
 0314                    ExternalSeriesId = programSeriesId,
 0315                    Limit = 1,
 0316                    ImageTypes = new ImageType[] { ImageType.Primary },
 0317                    DtoOptions = new DtoOptions(false),
 0318                    Name = string.IsNullOrEmpty(programSeriesId) ? seriesName : null
 0319                }).FirstOrDefault();
 320            }
 321
 0322            if (program is not null)
 323            {
 0324                var image = program.GetImageInfo(ImageType.Primary, 0);
 0325                if (image is not null)
 326                {
 327                    try
 328                    {
 0329                        dto.ParentPrimaryImageTag = _imageProcessor.GetImageCacheTag(program, image);
 0330                        dto.ParentPrimaryImageItemId = program.Id.ToString("N", CultureInfo.InvariantCulture);
 0331                    }
 0332                    catch (Exception ex)
 333                    {
 0334                        _logger.LogDebug(ex, "GetImageCacheTag raised an exception in LiveTvDtoService.FillImages.");
 0335                    }
 336                }
 337
 0338                if (dto.ParentBackdropImageTags is null || dto.ParentBackdropImageTags.Length == 0)
 339                {
 0340                    image = program.GetImageInfo(ImageType.Backdrop, 0);
 0341                    if (image is not null)
 342                    {
 343                        try
 344                        {
 0345                            dto.ParentBackdropImageTags = new[]
 0346                            {
 0347                                    _imageProcessor.GetImageCacheTag(program, image)
 0348                            };
 0349                            dto.ParentBackdropItemId = program.Id.ToString("N", CultureInfo.InvariantCulture);
 0350                        }
 0351                        catch (Exception ex)
 352                        {
 0353                            _logger.LogError(ex, "Error");
 0354                        }
 355                    }
 356                }
 357            }
 0358        }
 359
 360        public DayPattern? GetDayPattern(DayOfWeek[] days)
 361        {
 0362            DayPattern? pattern = null;
 363
 0364            if (days.Length > 0)
 365            {
 0366                if (days.Length == 7)
 367                {
 0368                    pattern = DayPattern.Daily;
 369                }
 0370                else if (days.Length == 2)
 371                {
 0372                    if (days.Contains(DayOfWeek.Saturday) && days.Contains(DayOfWeek.Sunday))
 373                    {
 0374                        pattern = DayPattern.Weekends;
 375                    }
 376                }
 0377                else if (days.Length == 5)
 378                {
 0379                    if (days.Contains(DayOfWeek.Monday) && days.Contains(DayOfWeek.Tuesday) && days.Contains(DayOfWeek.W
 380                    {
 0381                        pattern = DayPattern.Weekdays;
 382                    }
 383                }
 384            }
 385
 0386            return pattern;
 387        }
 388
 389        internal string GetImageTag(BaseItem info)
 390        {
 391            try
 392            {
 0393                return _imageProcessor.GetImageCacheTag(info, ImageType.Primary);
 394            }
 0395            catch (Exception ex)
 396            {
 0397                _logger.LogError(ex, "Error getting image info for {Name}", info.Name);
 0398            }
 399
 0400            return null;
 0401        }
 402
 403        public Guid GetInternalChannelId(string serviceName, string externalId)
 404        {
 0405            var name = serviceName + externalId + InternalVersionNumber;
 406
 0407            return _libraryManager.GetNewItemId(name.ToLowerInvariant(), typeof(LiveTvChannel));
 408        }
 409
 410        public string GetInternalTimerId(string externalId)
 411        {
 0412            var name = ServiceName + externalId + InternalVersionNumber;
 413
 0414            return name.ToLowerInvariant().GetMD5().ToString("N", CultureInfo.InvariantCulture);
 415        }
 416
 417        public Guid GetInternalSeriesTimerId(string externalId)
 418        {
 0419            var name = ServiceName + externalId + InternalVersionNumber;
 420
 0421            return name.ToLowerInvariant().GetMD5();
 422        }
 423
 424        public Guid GetInternalProgramId(string externalId)
 425        {
 0426            var name = ServiceName + externalId + InternalVersionNumber;
 427
 0428            return _libraryManager.GetNewItemId(name.ToLowerInvariant(), typeof(LiveTvProgram));
 429        }
 430
 431        public async Task<TimerInfo> GetTimerInfo(TimerInfoDto dto, bool isNew, LiveTvManager liveTv, CancellationToken 
 432        {
 433            var info = new TimerInfo
 434            {
 435                Overview = dto.Overview,
 436                EndDate = dto.EndDate,
 437                Name = dto.Name,
 438                StartDate = dto.StartDate,
 439                Status = dto.Status,
 440                PrePaddingSeconds = dto.PrePaddingSeconds,
 441                PostPaddingSeconds = dto.PostPaddingSeconds,
 442                IsPostPaddingRequired = dto.IsPostPaddingRequired,
 443                IsPrePaddingRequired = dto.IsPrePaddingRequired,
 444                KeepUntil = dto.KeepUntil,
 445                Priority = dto.Priority,
 446                SeriesTimerId = dto.ExternalSeriesTimerId,
 447                ProgramId = dto.ExternalProgramId,
 448                ChannelId = dto.ExternalChannelId,
 449                Id = dto.ExternalId
 450            };
 451
 452            // Convert internal server id's to external tv provider id's
 453            if (!isNew && !string.IsNullOrEmpty(dto.Id) && string.IsNullOrEmpty(info.Id))
 454            {
 455                var timer = await liveTv.GetSeriesTimer(dto.Id, cancellationToken).ConfigureAwait(false);
 456
 457                info.Id = timer.ExternalId;
 458            }
 459
 460            if (!dto.ChannelId.IsEmpty() && string.IsNullOrEmpty(info.ChannelId))
 461            {
 462                var channel = _libraryManager.GetItemById(dto.ChannelId);
 463
 464                if (channel is not null)
 465                {
 466                    info.ChannelId = channel.ExternalId;
 467                }
 468            }
 469
 470            if (!string.IsNullOrEmpty(dto.ProgramId) && string.IsNullOrEmpty(info.ProgramId))
 471            {
 472                var program = _libraryManager.GetItemById(dto.ProgramId);
 473
 474                if (program is not null)
 475                {
 476                    info.ProgramId = program.ExternalId;
 477                }
 478            }
 479
 480            if (!string.IsNullOrEmpty(dto.SeriesTimerId) && string.IsNullOrEmpty(info.SeriesTimerId))
 481            {
 482                var timer = await liveTv.GetSeriesTimer(dto.SeriesTimerId, cancellationToken).ConfigureAwait(false);
 483
 484                if (timer is not null)
 485                {
 486                    info.SeriesTimerId = timer.ExternalId;
 487                }
 488            }
 489
 490            return info;
 491        }
 492
 493        public async Task<SeriesTimerInfo> GetSeriesTimerInfo(SeriesTimerInfoDto dto, bool isNew, LiveTvManager liveTv, 
 494        {
 495            var info = new SeriesTimerInfo
 496            {
 497                Overview = dto.Overview,
 498                EndDate = dto.EndDate,
 499                Name = dto.Name,
 500                StartDate = dto.StartDate,
 501                PrePaddingSeconds = dto.PrePaddingSeconds,
 502                PostPaddingSeconds = dto.PostPaddingSeconds,
 503                IsPostPaddingRequired = dto.IsPostPaddingRequired,
 504                IsPrePaddingRequired = dto.IsPrePaddingRequired,
 505                Days = dto.Days.ToList(),
 506                Priority = dto.Priority,
 507                RecordAnyChannel = dto.RecordAnyChannel,
 508                RecordAnyTime = dto.RecordAnyTime,
 509                SkipEpisodesInLibrary = dto.SkipEpisodesInLibrary,
 510                KeepUpTo = dto.KeepUpTo,
 511                KeepUntil = dto.KeepUntil,
 512                RecordNewOnly = dto.RecordNewOnly,
 513                ProgramId = dto.ExternalProgramId,
 514                ChannelId = dto.ExternalChannelId,
 515                Id = dto.ExternalId
 516            };
 517
 518            // Convert internal server id's to external tv provider id's
 519            if (!isNew && !string.IsNullOrEmpty(dto.Id) && string.IsNullOrEmpty(info.Id))
 520            {
 521                var timer = await liveTv.GetSeriesTimer(dto.Id, cancellationToken).ConfigureAwait(false);
 522
 523                info.Id = timer.ExternalId;
 524            }
 525
 526            if (!dto.ChannelId.IsEmpty() && string.IsNullOrEmpty(info.ChannelId))
 527            {
 528                var channel = _libraryManager.GetItemById(dto.ChannelId);
 529
 530                if (channel is not null)
 531                {
 532                    info.ChannelId = channel.ExternalId;
 533                }
 534            }
 535
 536            if (!string.IsNullOrEmpty(dto.ProgramId) && string.IsNullOrEmpty(info.ProgramId))
 537            {
 538                var program = _libraryManager.GetItemById(dto.ProgramId);
 539
 540                if (program is not null)
 541                {
 542                    info.ProgramId = program.ExternalId;
 543                }
 544            }
 545
 546            return info;
 547        }
 548    }
 549}