Clean up and document ChannelManager.cs and implement suggestions

This commit is contained in:
Patrick Barron 2020-04-15 15:00:45 -04:00
parent a54dca09d8
commit c4e6329e58
6 changed files with 139 additions and 102 deletions

View File

@ -27,7 +27,6 @@ namespace Emby.Server.Implementations.Activity
{
/// <summary>
/// The activity log entry point.
/// <see cref="IServerEntryPoint"/>.
/// </summary>
public sealed class ActivityLogEntryPoint : IServerEntryPoint
{

View File

@ -6,7 +6,9 @@ using MediaBrowser.Model.Querying;
namespace Emby.Server.Implementations.Activity
{
/// <inheritdoc />
/// <summary>
/// The activity log manager.
/// </summary>
public class ActivityManager : IActivityManager
{
/// <inheritdoc />

View File

@ -13,7 +13,9 @@ using SQLitePCL.pretty;
namespace Emby.Server.Implementations.Activity
{
/// <inheritdoc cref="IActivityRepository" />
/// <summary>
/// The activity log repository.
/// </summary>
public class ActivityRepository : BaseSqliteRepository, IActivityRepository
{
private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US"));

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Channels;
@ -30,7 +31,7 @@ namespace Emby.Server.Implementations.Channels
{
return item.SourceType == SourceType.Channel
? _channelManager.GetDynamicMediaSources(item, cancellationToken)
: Task.FromResult<IEnumerable<MediaSourceInfo>>(new List<MediaSourceInfo>());
: Task.FromResult(Enumerable.Empty<MediaSourceInfo>());
}
/// <inheritdoc />

View File

@ -1,5 +1,3 @@
#pragma warning disable CS1591
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@ -29,6 +27,9 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Channels
{
/// <summary>
/// The LiveTV channel manager.
/// </summary>
public class ChannelManager : IChannelManager
{
internal IChannel[] Channels { get; private set; }
@ -43,6 +44,18 @@ namespace Emby.Server.Implementations.Channels
private readonly IJsonSerializer _jsonSerializer;
private readonly IProviderManager _providerManager;
/// <summary>
/// Initializes a new instance of the <see cref="ChannelManager"/> class.
/// </summary>
/// <param name="userManager">The user manager.</param>
/// <param name="dtoService">The dto service.</param>
/// <param name="libraryManager">The library manager.</param>
/// <param name="loggerFactory">The logger factory.</param>
/// <param name="config">The server configuration manager.</param>
/// <param name="fileSystem">The filesystem.</param>
/// <param name="userDataManager">The user data manager.</param>
/// <param name="jsonSerializer">The JSON serializer.</param>
/// <param name="providerManager">The provider manager.</param>
public ChannelManager(
IUserManager userManager,
IDtoService dtoService,
@ -67,11 +80,13 @@ namespace Emby.Server.Implementations.Channels
private static TimeSpan CacheLength => TimeSpan.FromHours(3);
/// <inheritdoc />
public void AddParts(IEnumerable<IChannel> channels)
{
Channels = channels.ToArray();
}
/// <inheritdoc />
public bool EnableMediaSourceDisplay(BaseItem item)
{
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
@ -80,15 +95,16 @@ namespace Emby.Server.Implementations.Channels
return !(channel is IDisableMediaSourceDisplay);
}
/// <inheritdoc />
public bool CanDelete(BaseItem item)
{
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
var channel = Channels.FirstOrDefault(i => GetInternalChannelId(i.Name).Equals(internalChannel.Id));
var supportsDelete = channel as ISupportsDelete;
return supportsDelete != null && supportsDelete.CanDelete(item);
return channel is ISupportsDelete supportsDelete && supportsDelete.CanDelete(item);
}
/// <inheritdoc />
public bool EnableMediaProbe(BaseItem item)
{
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
@ -97,6 +113,7 @@ namespace Emby.Server.Implementations.Channels
return channel is ISupportsMediaProbe;
}
/// <inheritdoc />
public Task DeleteItem(BaseItem item)
{
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
@ -123,11 +140,16 @@ namespace Emby.Server.Implementations.Channels
.OrderBy(i => i.Name);
}
/// <summary>
/// Returns an <see cref="IEnumerable{T}"/> containing installed channel ID's.
/// </summary>
/// <returns>An <see cref="IEnumerable{T}"/> containing installed channel ID's.</returns>
public IEnumerable<Guid> GetInstalledChannelIds()
{
return GetAllChannels().Select(i => GetInternalChannelId(i.Name));
}
/// <inheritdoc />
public QueryResult<Channel> GetChannelsInternal(ChannelQuery query)
{
var user = query.UserId.Equals(Guid.Empty)
@ -146,15 +168,13 @@ namespace Emby.Server.Implementations.Channels
{
try
{
var hasAttributes = GetChannelProvider(i) as IHasFolderAttributes;
return (hasAttributes != null && hasAttributes.Attributes.Contains("Recordings", StringComparer.OrdinalIgnoreCase)) == val;
return (GetChannelProvider(i) is IHasFolderAttributes hasAttributes
&& hasAttributes.Attributes.Contains("Recordings", StringComparer.OrdinalIgnoreCase)) == val;
}
catch
{
return false;
}
}).ToList();
}
@ -171,7 +191,6 @@ namespace Emby.Server.Implementations.Channels
{
return false;
}
}).ToList();
}
@ -188,9 +207,9 @@ namespace Emby.Server.Implementations.Channels
{
return false;
}
}).ToList();
}
if (query.IsFavorite.HasValue)
{
var val = query.IsFavorite.Value;
@ -215,7 +234,6 @@ namespace Emby.Server.Implementations.Channels
{
return false;
}
}).ToList();
}
@ -226,6 +244,7 @@ namespace Emby.Server.Implementations.Channels
{
all = all.Skip(query.StartIndex.Value).ToList();
}
if (query.Limit.HasValue)
{
all = all.Take(query.Limit.Value).ToList();
@ -248,6 +267,7 @@ namespace Emby.Server.Implementations.Channels
};
}
/// <inheritdoc />
public QueryResult<BaseItemDto> GetChannels(ChannelQuery query)
{
var user = query.UserId.Equals(Guid.Empty)
@ -272,6 +292,12 @@ namespace Emby.Server.Implementations.Channels
return result;
}
/// <summary>
/// Refreshes the associated channels.
/// </summary>
/// <param name="progress">The progress.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The completed task.</returns>
public async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
{
var allChannelsList = GetAllChannels().ToList();
@ -305,14 +331,7 @@ namespace Emby.Server.Implementations.Channels
private Channel GetChannelEntity(IChannel channel)
{
var item = GetChannel(GetInternalChannelId(channel.Name));
if (item == null)
{
item = GetChannel(channel, CancellationToken.None).Result;
}
return item;
return GetChannel(GetInternalChannelId(channel.Name)) ?? GetChannel(channel, CancellationToken.None).Result;
}
private List<MediaSourceInfo> GetSavedMediaSources(BaseItem item)
@ -351,6 +370,7 @@ namespace Emby.Server.Implementations.Channels
_jsonSerializer.SerializeToFile(mediaSources, path);
}
/// <inheritdoc />
public IEnumerable<MediaSourceInfo> GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken)
{
IEnumerable<MediaSourceInfo> results = GetSavedMediaSources(item);
@ -360,6 +380,12 @@ namespace Emby.Server.Implementations.Channels
.ToList();
}
/// <summary>
/// Gets the dynamic media sources based on the provided item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The completed task.</returns>
public async Task<IEnumerable<MediaSourceInfo>> GetDynamicMediaSources(BaseItem item, CancellationToken cancellationToken)
{
var channel = GetChannel(item.ChannelId);
@ -409,7 +435,7 @@ namespace Emby.Server.Implementations.Channels
private static MediaSourceInfo NormalizeMediaSource(BaseItem item, MediaSourceInfo info)
{
info.RunTimeTicks = info.RunTimeTicks ?? item.RunTimeTicks;
info.RunTimeTicks ??= item.RunTimeTicks;
return info;
}
@ -482,41 +508,43 @@ namespace Emby.Server.Implementations.Channels
private static string GetOfficialRating(ChannelParentalRating rating)
{
switch (rating)
return rating switch
{
case ChannelParentalRating.Adult:
return "XXX";
case ChannelParentalRating.UsR:
return "R";
case ChannelParentalRating.UsPG13:
return "PG-13";
case ChannelParentalRating.UsPG:
return "PG";
default:
return null;
}
ChannelParentalRating.Adult => "XXX",
ChannelParentalRating.UsR => "R",
ChannelParentalRating.UsPG13 => "PG-13",
ChannelParentalRating.UsPG => "PG",
_ => null
};
}
/// <summary>
/// Gets a channel with the provided Guid.
/// </summary>
/// <param name="id">The Guid.</param>
/// <returns>The corresponding channel.</returns>
public Channel GetChannel(Guid id)
{
return _libraryManager.GetItemById(id) as Channel;
}
/// <inheritdoc />
public Channel GetChannel(string id)
{
return _libraryManager.GetItemById(id) as Channel;
}
/// <inheritdoc />
public ChannelFeatures[] GetAllChannelFeatures()
{
return _libraryManager.GetItemIds(new InternalItemsQuery
{
IncludeItemTypes = new[] { typeof(Channel).Name },
OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) }
}).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray();
}
/// <inheritdoc />
public ChannelFeatures GetChannelFeatures(string id)
{
if (string.IsNullOrEmpty(id))
@ -530,6 +558,11 @@ namespace Emby.Server.Implementations.Channels
return GetChannelFeaturesDto(channel, channelProvider, channelProvider.GetChannelFeatures());
}
/// <summary>
/// Checks whether the provided Guid supports external transfer.
/// </summary>
/// <param name="channelId">The Guid.</param>
/// <returns>Whether or not the provided Guid supports external transfer.</returns>
public bool SupportsExternalTransfer(Guid channelId)
{
//var channel = GetChannel(channelId);
@ -538,6 +571,13 @@ namespace Emby.Server.Implementations.Channels
return channelProvider.GetChannelFeatures().SupportsContentDownloading;
}
/// <summary>
/// Gets the provided channel's supported features.
/// </summary>
/// <param name="channel">The channel.</param>
/// <param name="provider">The provider.</param>
/// <param name="features">The features.</param>
/// <returns>The supported features.</returns>
public ChannelFeatures GetChannelFeaturesDto(Channel channel,
IChannel provider,
InternalChannelFeatures features)
@ -570,6 +610,7 @@ namespace Emby.Server.Implementations.Channels
return _libraryManager.GetNewItemId("Channel " + name, typeof(Channel));
}
/// <inheritdoc />
public async Task<QueryResult<BaseItemDto>> GetLatestChannelItems(InternalItemsQuery query, CancellationToken cancellationToken)
{
var internalResult = await GetLatestChannelItemsInternal(query, cancellationToken).ConfigureAwait(false);
@ -588,6 +629,7 @@ namespace Emby.Server.Implementations.Channels
return result;
}
/// <inheritdoc />
public async Task<QueryResult<BaseItem>> GetLatestChannelItemsInternal(InternalItemsQuery query, CancellationToken cancellationToken)
{
var channels = GetAllChannels().Where(i => i is ISupportsLatestMedia).ToArray();
@ -662,6 +704,7 @@ namespace Emby.Server.Implementations.Channels
}
}
/// <inheritdoc />
public async Task<QueryResult<BaseItem>> GetChannelItemsInternal(InternalItemsQuery query, IProgress<double> progress, CancellationToken cancellationToken)
{
// Get the internal channel entity
@ -711,7 +754,6 @@ namespace Emby.Server.Implementations.Channels
{
DeleteFileLocation = false,
DeleteFromExternalProvider = false
}, parentItem, false);
}
}
@ -720,6 +762,7 @@ namespace Emby.Server.Implementations.Channels
return _libraryManager.GetItemsResult(query);
}
/// <inheritdoc />
public async Task<QueryResult<BaseItemDto>> GetChannelItems(InternalItemsQuery query, CancellationToken cancellationToken)
{
var internalResult = await GetChannelItemsInternal(query, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
@ -743,7 +786,7 @@ namespace Emby.Server.Implementations.Channels
bool sortDescending,
CancellationToken cancellationToken)
{
var userId = user == null ? null : user.Id.ToString("N", CultureInfo.InvariantCulture);
var userId = user?.Id.ToString("N", CultureInfo.InvariantCulture);
var cacheLength = CacheLength;
var cachePath = GetChannelDataCachePath(channel, userId, externalFolderId, sortField, sortDescending);
@ -794,7 +837,7 @@ namespace Emby.Server.Implementations.Channels
var query = new InternalChannelItemQuery
{
UserId = user == null ? Guid.Empty : user.Id,
UserId = user?.Id ?? Guid.Empty,
SortBy = sortField,
SortDescending = sortDescending,
FolderId = externalFolderId
@ -843,8 +886,7 @@ namespace Emby.Server.Implementations.Channels
var userCacheKey = string.Empty;
var hasCacheKey = channel as IHasCacheKey;
if (hasCacheKey != null)
if (channel is IHasCacheKey hasCacheKey)
{
userCacheKey = hasCacheKey.GetCacheKey(userId) ?? string.Empty;
}
@ -919,59 +961,55 @@ namespace Emby.Server.Implementations.Channels
if (info.Type == ChannelItemType.Folder)
{
if (info.FolderType == ChannelFolderType.MusicAlbum)
switch (info.FolderType)
{
item = GetItemById<MusicAlbum>(info.Id, channelProvider.Name, out isNew);
}
else if (info.FolderType == ChannelFolderType.MusicArtist)
{
item = GetItemById<MusicArtist>(info.Id, channelProvider.Name, out isNew);
}
else if (info.FolderType == ChannelFolderType.PhotoAlbum)
{
item = GetItemById<PhotoAlbum>(info.Id, channelProvider.Name, out isNew);
}
else if (info.FolderType == ChannelFolderType.Series)
{
item = GetItemById<Series>(info.Id, channelProvider.Name, out isNew);
}
else if (info.FolderType == ChannelFolderType.Season)
{
item = GetItemById<Season>(info.Id, channelProvider.Name, out isNew);
}
else
{
item = GetItemById<Folder>(info.Id, channelProvider.Name, out isNew);
case ChannelFolderType.MusicAlbum:
item = GetItemById<MusicAlbum>(info.Id, channelProvider.Name, out isNew);
break;
case ChannelFolderType.MusicArtist:
item = GetItemById<MusicArtist>(info.Id, channelProvider.Name, out isNew);
break;
case ChannelFolderType.PhotoAlbum:
item = GetItemById<PhotoAlbum>(info.Id, channelProvider.Name, out isNew);
break;
case ChannelFolderType.Series:
item = GetItemById<Series>(info.Id, channelProvider.Name, out isNew);
break;
case ChannelFolderType.Season:
item = GetItemById<Season>(info.Id, channelProvider.Name, out isNew);
break;
default:
item = GetItemById<Folder>(info.Id, channelProvider.Name, out isNew);
break;
}
}
else if (info.MediaType == ChannelMediaType.Audio)
{
if (info.ContentType == ChannelMediaContentType.Podcast)
{
item = GetItemById<AudioBook>(info.Id, channelProvider.Name, out isNew);
}
else
{
item = GetItemById<Audio>(info.Id, channelProvider.Name, out isNew);
}
item = info.ContentType == ChannelMediaContentType.Podcast
? GetItemById<AudioBook>(info.Id, channelProvider.Name, out isNew)
: GetItemById<Audio>(info.Id, channelProvider.Name, out isNew);
}
else
{
if (info.ContentType == ChannelMediaContentType.Episode)
switch (info.ContentType)
{
item = GetItemById<Episode>(info.Id, channelProvider.Name, out isNew);
}
else if (info.ContentType == ChannelMediaContentType.Movie)
{
item = GetItemById<Movie>(info.Id, channelProvider.Name, out isNew);
}
else if (info.ContentType == ChannelMediaContentType.Trailer || info.ExtraType == ExtraType.Trailer)
{
item = GetItemById<Trailer>(info.Id, channelProvider.Name, out isNew);
}
else
{
item = GetItemById<Video>(info.Id, channelProvider.Name, out isNew);
case ChannelMediaContentType.Episode:
item = GetItemById<Episode>(info.Id, channelProvider.Name, out isNew);
break;
case ChannelMediaContentType.Movie:
item = GetItemById<Movie>(info.Id, channelProvider.Name, out isNew);
break;
default:
if (info.ContentType == ChannelMediaContentType.Trailer || info.ExtraType == ExtraType.Trailer)
{
item = GetItemById<Trailer>(info.Id, channelProvider.Name, out isNew);
}
else
{
item = GetItemById<Video>(info.Id, channelProvider.Name, out isNew);
}
break;
}
}
@ -981,7 +1019,6 @@ namespace Emby.Server.Implementations.Channels
{
item.RunTimeTicks = null;
}
else if (isNew || !enableMediaProbe)
{
item.RunTimeTicks = info.RunTimeTicks;
@ -1014,20 +1051,17 @@ namespace Emby.Server.Implementations.Channels
}
}
var hasArtists = item as IHasArtist;
if (hasArtists != null)
if (item is IHasArtist hasArtists)
{
hasArtists.Artists = info.Artists.ToArray();
}
var hasAlbumArtists = item as IHasAlbumArtist;
if (hasAlbumArtists != null)
if (item is IHasAlbumArtist hasAlbumArtists)
{
hasAlbumArtists.AlbumArtists = info.AlbumArtists.ToArray();
}
var trailer = item as Trailer;
if (trailer != null)
if (item is Trailer trailer)
{
if (!info.TrailerTypes.SequenceEqual(trailer.TrailerTypes))
{
@ -1066,8 +1100,7 @@ namespace Emby.Server.Implementations.Channels
}
item.ParentId = parentFolderId;
var hasSeries = item as IHasSeries;
if (hasSeries != null)
if (item is IHasSeries hasSeries)
{
if (!string.Equals(hasSeries.SeriesName, info.SeriesName, StringComparison.OrdinalIgnoreCase))
{
@ -1084,22 +1117,20 @@ namespace Emby.Server.Implementations.Channels
}
item.ExternalId = info.Id;
var channelAudioItem = item as Audio;
if (channelAudioItem != null)
if (item is Audio channelAudioItem)
{
channelAudioItem.ExtraType = info.ExtraType;
var mediaSource = info.MediaSources.FirstOrDefault();
item.Path = mediaSource == null ? null : mediaSource.Path;
item.Path = mediaSource?.Path;
}
var channelVideoItem = item as Video;
if (channelVideoItem != null)
if (item is Video channelVideoItem)
{
channelVideoItem.ExtraType = info.ExtraType;
var mediaSource = info.MediaSources.FirstOrDefault();
item.Path = mediaSource == null ? null : mediaSource.Path;
item.Path = mediaSource?.Path;
}
if (!string.IsNullOrEmpty(info.ImageUrl) && !item.HasImage(ImageType.Primary))

View File

@ -21,7 +21,9 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Collections
{
/// <inheritdoc />
/// <summary>
/// The collection manager.
/// </summary>
public class CollectionManager : ICollectionManager
{
private readonly ILibraryManager _libraryManager;