| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- using MediaBrowser.Common.Extensions;
- using MediaBrowser.Common.IO;
- using MediaBrowser.Controller;
- using MediaBrowser.Controller.Drawing;
- using MediaBrowser.Controller.LiveTv;
- using MediaBrowser.Controller.Persistence;
- using MediaBrowser.Model.Entities;
- using MediaBrowser.Model.LiveTv;
- using MediaBrowser.Model.Logging;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Threading;
- using System.Threading.Tasks;
- namespace MediaBrowser.Server.Implementations.LiveTv
- {
- /// <summary>
- /// Class LiveTvManager
- /// </summary>
- public class LiveTvManager : ILiveTvManager
- {
- private readonly IServerApplicationPaths _appPaths;
- private readonly IFileSystem _fileSystem;
- private readonly ILogger _logger;
- private readonly IItemRepository _itemRepo;
- private readonly IImageProcessor _imageProcessor;
- private List<Channel> _channels = new List<Channel>();
- private Dictionary<Guid, List<ProgramInfo>> _guide = new Dictionary<Guid, List<ProgramInfo>>();
- private readonly List<ILiveTvService> _services = new List<ILiveTvService>();
- public LiveTvManager(IServerApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor)
- {
- _appPaths = appPaths;
- _fileSystem = fileSystem;
- _logger = logger;
- _itemRepo = itemRepo;
- _imageProcessor = imageProcessor;
- }
- /// <summary>
- /// Gets the services.
- /// </summary>
- /// <value>The services.</value>
- public IReadOnlyList<ILiveTvService> Services
- {
- get { return _services; }
- }
- /// <summary>
- /// Adds the parts.
- /// </summary>
- /// <param name="services">The services.</param>
- public void AddParts(IEnumerable<ILiveTvService> services)
- {
- _services.AddRange(services);
- }
- /// <summary>
- /// Gets the channel info dto.
- /// </summary>
- /// <param name="info">The info.</param>
- /// <returns>ChannelInfoDto.</returns>
- public ChannelInfoDto GetChannelInfoDto(Channel info)
- {
- return new ChannelInfoDto
- {
- Name = info.Name,
- ServiceName = info.ServiceName,
- ChannelType = info.ChannelType,
- ChannelId = info.ChannelId,
- Number = info.ChannelNumber,
- PrimaryImageTag = GetLogoImageTag(info),
- Type = info.GetType().Name,
- Id = info.Id.ToString("N"),
- MediaType = info.MediaType
- };
- }
- private ILiveTvService GetService(ChannelInfo channel)
- {
- return _services.FirstOrDefault(i => string.Equals(channel.ServiceName, i.Name, StringComparison.OrdinalIgnoreCase));
- }
- private Guid? GetLogoImageTag(Channel info)
- {
- var path = info.PrimaryImagePath;
- if (string.IsNullOrEmpty(path))
- {
- return null;
- }
- try
- {
- return _imageProcessor.GetImageCacheTag(info, ImageType.Primary, path);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error getting channel image info for {0}", ex, info.Name);
- }
- return null;
- }
- public IEnumerable<Channel> GetChannels(ChannelQuery query)
- {
- return _channels.OrderBy(i =>
- {
- double number = 0;
- if (!string.IsNullOrEmpty(i.ChannelNumber))
- {
- double.TryParse(i.ChannelNumber, out number);
- }
- return number;
- }).ThenBy(i => i.Name);
- }
- public Channel GetChannel(string id)
- {
- var guid = new Guid(id);
- return _channels.FirstOrDefault(i => i.Id == guid);
- }
- internal async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
- {
- // Avoid implicitly captured closure
- var currentCancellationToken = cancellationToken;
- var tasks = _services.Select(i => i.GetChannelsAsync(currentCancellationToken));
- progress.Report(10);
- var results = await Task.WhenAll(tasks).ConfigureAwait(false);
- var allChannels = results.SelectMany(i => i).ToList();
- var list = new List<Channel>();
- var guide = new Dictionary<Guid, List<ProgramInfo>>();
- var numComplete = 0;
- foreach (var channelInfo in allChannels)
- {
- try
- {
- var item = await GetChannel(channelInfo, cancellationToken).ConfigureAwait(false);
- var service = GetService(channelInfo);
- var programs = await service.GetChannelGuideAsync(channelInfo.Id, cancellationToken).ConfigureAwait(false);
- var programList = programs.ToList();
- foreach (var program in programList)
- {
- program.ExternalChannelId = channelInfo.Id;
- program.ChannelId = item.Id.ToString("N");
- program.ServiceName = service.Name;
- }
- list.Add(item);
- guide[item.Id] = programList;
- }
- catch (OperationCanceledException)
- {
- throw;
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error getting channel information for {0}", ex, channelInfo.Name);
- }
- numComplete++;
- double percent = numComplete;
- percent /= allChannels.Count;
- progress.Report(90 * percent + 10);
- }
- _guide = guide;
- _channels = list;
- }
- private async Task<Channel> GetChannel(ChannelInfo channelInfo, CancellationToken cancellationToken)
- {
- var path = Path.Combine(_appPaths.ItemsByNamePath, "channels", _fileSystem.GetValidFilename(channelInfo.ServiceName), _fileSystem.GetValidFilename(channelInfo.Name));
- var fileInfo = new DirectoryInfo(path);
- var isNew = false;
- if (!fileInfo.Exists)
- {
- Directory.CreateDirectory(path);
- fileInfo = new DirectoryInfo(path);
- if (!fileInfo.Exists)
- {
- throw new IOException("Path not created: " + path);
- }
- isNew = true;
- }
- var type = typeof(Channel);
- var id = (path + channelInfo.Number).GetMBId(type);
- var item = _itemRepo.RetrieveItem(id) as Channel;
- if (item == null)
- {
- item = new Channel
- {
- Name = channelInfo.Name,
- Id = id,
- DateCreated = _fileSystem.GetCreationTimeUtc(fileInfo),
- DateModified = _fileSystem.GetLastWriteTimeUtc(fileInfo),
- Path = path,
- ChannelId = channelInfo.Id,
- ChannelNumber = channelInfo.Number,
- ServiceName = channelInfo.ServiceName
- };
- isNew = true;
- }
- // Set this now so we don't cause additional file system access during provider executions
- item.ResetResolveArgs(fileInfo);
- await item.RefreshMetadata(cancellationToken, forceSave: isNew, resetResolveArgs: false);
- return item;
- }
- public IEnumerable<ProgramInfo> GetPrograms(ProgramQuery query)
- {
- var programs = _guide.Values.SelectMany(i => i);
- if (!string.IsNullOrEmpty(query.ServiceName))
- {
- programs = programs.Where(i => string.Equals(i.ServiceName, query.ServiceName, StringComparison.OrdinalIgnoreCase));
- }
- if (query.ChannelIdList.Length > 0)
- {
- var guids = query.ChannelIdList.Select(i => new Guid(i)).ToList();
- programs = programs.Where(i => guids.Contains(new Guid(i.ChannelId)));
- }
-
- return programs;
- }
- }
- }
|