diff options
Diffstat (limited to 'MediaBrowser.Server.Implementations/Channels/ChannelManager.cs')
| -rw-r--r-- | MediaBrowser.Server.Implementations/Channels/ChannelManager.cs | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs new file mode 100644 index 000000000..630c7373e --- /dev/null +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -0,0 +1,257 @@ +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Channels; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Channels; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Querying; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.Channels +{ + public class ChannelManager : IChannelManager + { + private IChannel[] _channels; + private List<Channel> _channelEntities = new List<Channel>(); + + private readonly IUserManager _userManager; + private readonly IDtoService _dtoService; + private readonly ILibraryManager _libraryManager; + private readonly ILogger _logger; + private readonly IServerConfigurationManager _config; + private readonly IFileSystem _fileSystem; + + public ChannelManager(IUserManager userManager, IDtoService dtoService, ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem) + { + _userManager = userManager; + _dtoService = dtoService; + _libraryManager = libraryManager; + _logger = logger; + _config = config; + _fileSystem = fileSystem; + } + + public void AddParts(IEnumerable<IChannel> channels) + { + _channels = channels.ToArray(); + } + + public Task<QueryResult<BaseItemDto>> GetChannels(ChannelQuery query, CancellationToken cancellationToken) + { + var user = string.IsNullOrWhiteSpace(query.UserId) + ? null + : _userManager.GetUserById(new Guid(query.UserId)); + + var channels = _channelEntities.OrderBy(i => i.SortName).ToList(); + + if (user != null) + { + channels = channels.Where(i => GetChannelProvider(i).IsEnabledFor(user) && i.IsVisible(user)) + .ToList(); + } + + // Get everything + var fields = Enum.GetNames(typeof(ItemFields)) + .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) + .ToList(); + + var returnItems = channels.Select(i => _dtoService.GetBaseItemDto(i, fields, user)) + .ToArray(); + + var result = new QueryResult<BaseItemDto> + { + Items = returnItems, + TotalRecordCount = returnItems.Length + }; + + return Task.FromResult(result); + } + + public async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken) + { + var allChannelsList = _channels.ToList(); + + var list = new List<Channel>(); + + var numComplete = 0; + + foreach (var channelInfo in allChannelsList) + { + cancellationToken.ThrowIfCancellationRequested(); + + try + { + var item = await GetChannel(channelInfo, cancellationToken).ConfigureAwait(false); + + list.Add(item); + + _libraryManager.RegisterItem(item); + } + catch (OperationCanceledException) + { + throw; + } + catch (Exception ex) + { + _logger.ErrorException("Error getting channel information for {0}", ex, channelInfo.Name); + } + + numComplete++; + double percent = numComplete; + percent /= allChannelsList.Count; + + progress.Report(100 * percent); + } + + _channelEntities = list.ToList(); + progress.Report(100); + } + + private async Task<Channel> GetChannel(IChannel channelInfo, CancellationToken cancellationToken) + { + var path = Path.Combine(_config.ApplicationPaths.ItemsByNamePath, "channels", _fileSystem.GetValidFilename(channelInfo.Name)); + + var fileInfo = new DirectoryInfo(path); + + var isNew = false; + + if (!fileInfo.Exists) + { + _logger.Debug("Creating directory {0}", path); + + Directory.CreateDirectory(path); + fileInfo = new DirectoryInfo(path); + + if (!fileInfo.Exists) + { + throw new IOException("Path not created: " + path); + } + + isNew = true; + } + + var id = GetInternalChannelId(channelInfo.Name); + + var item = _libraryManager.GetItemById(id) as Channel; + + if (item == null) + { + item = new Channel + { + Name = channelInfo.Name, + Id = id, + DateCreated = _fileSystem.GetCreationTimeUtc(fileInfo), + DateModified = _fileSystem.GetLastWriteTimeUtc(fileInfo), + Path = path + }; + + isNew = true; + } + + item.HomePageUrl = channelInfo.HomePageUrl; + item.OriginalChannelName = channelInfo.Name; + + if (string.IsNullOrEmpty(item.Name)) + { + item.Name = channelInfo.Name; + } + + await item.RefreshMetadata(new MetadataRefreshOptions + { + ForceSave = isNew + + }, cancellationToken); + + return item; + } + + private Guid GetInternalChannelId(string name) + { + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentNullException("name"); + } + + return ("Channel " + name).GetMBId(typeof(Channel)); + } + + public async Task<QueryResult<BaseItemDto>> GetChannelItems(ChannelItemQuery query, CancellationToken cancellationToken) + { + var user = string.IsNullOrWhiteSpace(query.UserId) + ? null + : _userManager.GetUserById(new Guid(query.UserId)); + + var id = new Guid(query.ChannelId); + var channel = _channelEntities.First(i => i.Id == id); + var channelProvider = GetChannelProvider(channel); + + var items = await GetChannelItems(channelProvider, user, query.CategoryId, cancellationToken) + .ConfigureAwait(false); + + + return await GetReturnItems(items, user, query.StartIndex, query.Limit, cancellationToken).ConfigureAwait(false); + } + + private Task<IEnumerable<ChannelItemInfo>> GetChannelItems(IChannel channel, User user, string categoryId, CancellationToken cancellationToken) + { + // TODO: Put some caching in here + + if (string.IsNullOrWhiteSpace(categoryId)) + { + return channel.GetChannelItems(user, cancellationToken); + } + + return channel.GetChannelItems(categoryId, user, cancellationToken); + } + + private async Task<QueryResult<BaseItemDto>> GetReturnItems(IEnumerable<ChannelItemInfo> items, User user, int? startIndex, int? limit, CancellationToken cancellationToken) + { + if (startIndex.HasValue) + { + items = items.Skip(startIndex.Value); + } + if (limit.HasValue) + { + items = items.Take(limit.Value); + } + + // Get everything + var fields = Enum.GetNames(typeof(ItemFields)) + .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) + .ToList(); + + var tasks = items.Select(GetChannelItemEntity); + + var returnItems = await Task.WhenAll(tasks).ConfigureAwait(false); + + var returnItemArray = returnItems.Select(i => _dtoService.GetBaseItemDto(i, fields, user)) + .ToArray(); + + return new QueryResult<BaseItemDto> + { + Items = returnItemArray, + TotalRecordCount = returnItems.Length + }; + } + + private async Task<BaseItem> GetChannelItemEntity(ChannelItemInfo info) + { + return null; + } + + private IChannel GetChannelProvider(Channel channel) + { + return _channels.First(i => string.Equals(i.Name, channel.OriginalChannelName, StringComparison.OrdinalIgnoreCase)); + } + } +} |
