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> /// <summary>
/// The activity log entry point. /// The activity log entry point.
/// <see cref="IServerEntryPoint"/>.
/// </summary> /// </summary>
public sealed class ActivityLogEntryPoint : IServerEntryPoint public sealed class ActivityLogEntryPoint : IServerEntryPoint
{ {

View File

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

View File

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

View File

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

View File

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

View File

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