Fix some warnings

This commit is contained in:
Bond_009 2020-04-11 12:03:10 +02:00
parent 29539174a3
commit 49fe5e0a21
15 changed files with 233 additions and 210 deletions

View file

@ -1,5 +1,3 @@
#pragma warning disable CS1591
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
@ -27,6 +25,9 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Activity namespace Emby.Server.Implementations.Activity
{ {
/// <summary>
/// Entry point for the activity logger.
/// </summary>
public sealed class ActivityLogEntryPoint : IServerEntryPoint public sealed class ActivityLogEntryPoint : IServerEntryPoint
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
@ -42,16 +43,15 @@ namespace Emby.Server.Implementations.Activity
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ActivityLogEntryPoint"/> class. /// Initializes a new instance of the <see cref="ActivityLogEntryPoint"/> class.
/// </summary> /// </summary>
/// <param name="logger"></param> /// <param name="logger">The logger.</param>
/// <param name="sessionManager"></param> /// <param name="sessionManager">The session manager.</param>
/// <param name="deviceManager"></param> /// <param name="deviceManager">The device manager.</param>
/// <param name="taskManager"></param> /// <param name="taskManager">The task manager.</param>
/// <param name="activityManager"></param> /// <param name="activityManager">The activity manager.</param>
/// <param name="localization"></param> /// <param name="localization">The localization manager.</param>
/// <param name="installationManager"></param> /// <param name="installationManager">The installation manager.</param>
/// <param name="subManager"></param> /// <param name="subManager">The subtitle manager.</param>
/// <param name="userManager"></param> /// <param name="userManager">The user manager.</param>
/// <param name="appHost"></param>
public ActivityLogEntryPoint( public ActivityLogEntryPoint(
ILogger<ActivityLogEntryPoint> logger, ILogger<ActivityLogEntryPoint> logger,
ISessionManager sessionManager, ISessionManager sessionManager,
@ -74,6 +74,7 @@ namespace Emby.Server.Implementations.Activity
_userManager = userManager; _userManager = userManager;
} }
/// <inheritdoc />
public Task RunAsync() public Task RunAsync()
{ {
_taskManager.TaskCompleted += OnTaskCompleted; _taskManager.TaskCompleted += OnTaskCompleted;
@ -168,7 +169,12 @@ namespace Emby.Server.Implementations.Activity
CreateLogEntry(new ActivityLogEntry CreateLogEntry(new ActivityLogEntry
{ {
Name = string.Format(_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"), user.Name, GetItemName(item), e.DeviceName), Name = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"),
user.Name,
GetItemName(item),
e.DeviceName),
Type = GetPlaybackStoppedNotificationType(item.MediaType), Type = GetPlaybackStoppedNotificationType(item.MediaType),
UserId = user.Id UserId = user.Id
}); });
@ -485,8 +491,8 @@ namespace Emby.Server.Implementations.Activity
var result = e.Result; var result = e.Result;
var task = e.Task; var task = e.Task;
var activityTask = task.ScheduledTask as IConfigurableScheduledTask; if (task.ScheduledTask is IConfigurableScheduledTask activityTask
if (activityTask != null && !activityTask.IsLogged) && !activityTask.IsLogged)
{ {
return; return;
} }
@ -560,7 +566,7 @@ namespace Emby.Server.Implementations.Activity
/// <summary> /// <summary>
/// Constructs a user-friendly string for this TimeSpan instance. /// Constructs a user-friendly string for this TimeSpan instance.
/// </summary> /// </summary>
public static string ToUserFriendlyString(TimeSpan span) private static string ToUserFriendlyString(TimeSpan span)
{ {
const int DaysInYear = 365; const int DaysInYear = 365;
const int DaysInMonth = 30; const int DaysInMonth = 30;

View file

@ -11,22 +11,17 @@ namespace Emby.Server.Implementations.Activity
{ {
public class ActivityManager : IActivityManager public class ActivityManager : IActivityManager
{ {
public event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
private readonly IActivityRepository _repo; private readonly IActivityRepository _repo;
private readonly ILogger _logger;
private readonly IUserManager _userManager; private readonly IUserManager _userManager;
public ActivityManager( public ActivityManager(IActivityRepository repo, IUserManager userManager)
ILoggerFactory loggerFactory,
IActivityRepository repo,
IUserManager userManager)
{ {
_logger = loggerFactory.CreateLogger(nameof(ActivityManager));
_repo = repo; _repo = repo;
_userManager = userManager; _userManager = userManager;
} }
public event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
public void Create(ActivityLogEntry entry) public void Create(ActivityLogEntry entry)
{ {
entry.Date = DateTime.UtcNow; entry.Date = DateTime.UtcNow;

View file

@ -17,11 +17,12 @@ namespace Emby.Server.Implementations.Activity
{ {
public class ActivityRepository : BaseSqliteRepository, IActivityRepository public class ActivityRepository : BaseSqliteRepository, IActivityRepository
{ {
private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US")); private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLog";
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
public ActivityRepository(ILoggerFactory loggerFactory, IServerApplicationPaths appPaths, IFileSystem fileSystem) public ActivityRepository(ILogger<ActivityRepository> logger, IServerApplicationPaths appPaths, IFileSystem fileSystem)
: base(loggerFactory.CreateLogger(nameof(ActivityRepository))) : base(logger)
{ {
DbFilePath = Path.Combine(appPaths.DataPath, "activitylog.db"); DbFilePath = Path.Combine(appPaths.DataPath, "activitylog.db");
_fileSystem = fileSystem; _fileSystem = fileSystem;
@ -76,8 +77,6 @@ namespace Emby.Server.Implementations.Activity
} }
} }
private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLog";
public void Create(ActivityLogEntry entry) public void Create(ActivityLogEntry entry)
{ {
if (entry == null) if (entry == null)
@ -87,32 +86,34 @@ namespace Emby.Server.Implementations.Activity
using (var connection = GetConnection()) using (var connection = GetConnection())
{ {
connection.RunInTransaction(db => connection.RunInTransaction(
{ db =>
using (var statement = db.PrepareStatement("insert into ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)"))
{ {
statement.TryBind("@Name", entry.Name); using (var statement = db.PrepareStatement("insert into ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)"))
statement.TryBind("@Overview", entry.Overview);
statement.TryBind("@ShortOverview", entry.ShortOverview);
statement.TryBind("@Type", entry.Type);
statement.TryBind("@ItemId", entry.ItemId);
if (entry.UserId.Equals(Guid.Empty))
{ {
statement.TryBindNull("@UserId"); statement.TryBind("@Name", entry.Name);
}
else
{
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
}
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue()); statement.TryBind("@Overview", entry.Overview);
statement.TryBind("@LogSeverity", entry.Severity.ToString()); statement.TryBind("@ShortOverview", entry.ShortOverview);
statement.TryBind("@Type", entry.Type);
statement.TryBind("@ItemId", entry.ItemId);
statement.MoveNext(); if (entry.UserId.Equals(Guid.Empty))
} {
}, TransactionMode); statement.TryBindNull("@UserId");
}
else
{
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
}
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
statement.TryBind("@LogSeverity", entry.Severity.ToString());
statement.MoveNext();
}
},
TransactionMode);
} }
} }
@ -125,33 +126,35 @@ namespace Emby.Server.Implementations.Activity
using (var connection = GetConnection()) using (var connection = GetConnection())
{ {
connection.RunInTransaction(db => connection.RunInTransaction(
{ db =>
using (var statement = db.PrepareStatement("Update ActivityLog set Name=@Name,Overview=@Overview,ShortOverview=@ShortOverview,Type=@Type,ItemId=@ItemId,UserId=@UserId,DateCreated=@DateCreated,LogSeverity=@LogSeverity where Id=@Id"))
{ {
statement.TryBind("@Id", entry.Id); using (var statement = db.PrepareStatement("Update ActivityLog set Name=@Name,Overview=@Overview,ShortOverview=@ShortOverview,Type=@Type,ItemId=@ItemId,UserId=@UserId,DateCreated=@DateCreated,LogSeverity=@LogSeverity where Id=@Id"))
statement.TryBind("@Name", entry.Name);
statement.TryBind("@Overview", entry.Overview);
statement.TryBind("@ShortOverview", entry.ShortOverview);
statement.TryBind("@Type", entry.Type);
statement.TryBind("@ItemId", entry.ItemId);
if (entry.UserId.Equals(Guid.Empty))
{ {
statement.TryBindNull("@UserId"); statement.TryBind("@Id", entry.Id);
}
else
{
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
}
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue()); statement.TryBind("@Name", entry.Name);
statement.TryBind("@LogSeverity", entry.Severity.ToString()); statement.TryBind("@Overview", entry.Overview);
statement.TryBind("@ShortOverview", entry.ShortOverview);
statement.TryBind("@Type", entry.Type);
statement.TryBind("@ItemId", entry.ItemId);
statement.MoveNext(); if (entry.UserId.Equals(Guid.Empty))
} {
}, TransactionMode); statement.TryBindNull("@UserId");
}
else
{
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
}
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
statement.TryBind("@LogSeverity", entry.Severity.ToString());
statement.MoveNext();
}
},
TransactionMode);
} }
} }
@ -164,6 +167,7 @@ namespace Emby.Server.Implementations.Activity
{ {
whereClauses.Add("DateCreated>=@DateCreated"); whereClauses.Add("DateCreated>=@DateCreated");
} }
if (hasUserId.HasValue) if (hasUserId.HasValue)
{ {
if (hasUserId.Value) if (hasUserId.Value)
@ -204,7 +208,7 @@ namespace Emby.Server.Implementations.Activity
if (limit.HasValue) if (limit.HasValue)
{ {
commandText += " LIMIT " + limit.Value.ToString(_usCulture); commandText += " LIMIT " + limit.Value.ToString(CultureInfo.InvariantCulture);
} }
var statementTexts = new[] var statementTexts = new[]
@ -304,7 +308,7 @@ namespace Emby.Server.Implementations.Activity
index++; index++;
if (reader[index].SQLiteType != SQLiteType.Null) if (reader[index].SQLiteType != SQLiteType.Null)
{ {
info.Severity = (LogLevel)Enum.Parse(typeof(LogLevel), reader[index].ToString(), true); info.Severity = Enum.Parse<LogLevel>(reader[index].ToString(), true);
} }
return info; return info;

View file

@ -841,7 +841,7 @@ namespace Emby.Server.Implementations
var activityLogRepo = GetActivityLogRepository(); var activityLogRepo = GetActivityLogRepository();
serviceCollection.AddSingleton(activityLogRepo); serviceCollection.AddSingleton(activityLogRepo);
serviceCollection.AddSingleton<IActivityManager>(new ActivityManager(LoggerFactory, activityLogRepo, UserManager)); serviceCollection.AddSingleton<IActivityManager>(new ActivityManager(activityLogRepo, UserManager));
var authContext = new AuthorizationContext(AuthenticationRepository, UserManager); var authContext = new AuthorizationContext(AuthenticationRepository, UserManager);
serviceCollection.AddSingleton<IAuthorizationContext>(authContext); serviceCollection.AddSingleton<IAuthorizationContext>(authContext);

View file

@ -50,6 +50,7 @@ namespace Emby.Server.Implementations.Archiving
} }
} }
/// <inheritdoc />
public void ExtractAllFromZip(Stream source, string targetPath, bool overwriteExistingFiles) public void ExtractAllFromZip(Stream source, string targetPath, bool overwriteExistingFiles)
{ {
using (var reader = ZipReader.Open(source)) using (var reader = ZipReader.Open(source))
@ -66,6 +67,7 @@ namespace Emby.Server.Implementations.Archiving
} }
} }
/// <inheritdoc />
public void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles) public void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles)
{ {
using (var reader = GZipReader.Open(source)) using (var reader = GZipReader.Open(source))
@ -82,6 +84,7 @@ namespace Emby.Server.Implementations.Archiving
} }
} }
/// <inheritdoc />
public void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName) public void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName)
{ {
using (var reader = GZipReader.Open(source)) using (var reader = GZipReader.Open(source))

View file

@ -20,6 +20,8 @@ namespace Emby.Server.Implementations.Channels
_channelManager = channelManager; _channelManager = channelManager;
} }
public string Name => "Channel Image Provider";
public IEnumerable<ImageType> GetSupportedImages(BaseItem item) public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{ {
return GetChannel(item).GetSupportedChannelImages(); return GetChannel(item).GetSupportedChannelImages();
@ -32,8 +34,6 @@ namespace Emby.Server.Implementations.Channels
return channel.GetChannelImage(type, cancellationToken); return channel.GetChannelImage(type, cancellationToken);
} }
public string Name => "Channel Image Provider";
public bool Supports(BaseItem item) public bool Supports(BaseItem item)
{ {
return item is Channel; return item is Channel;

View file

@ -31,8 +31,6 @@ namespace Emby.Server.Implementations.Channels
{ {
public class ChannelManager : IChannelManager public class ChannelManager : IChannelManager
{ {
internal IChannel[] Channels { get; private set; }
private readonly IUserManager _userManager; private readonly IUserManager _userManager;
private readonly IUserDataManager _userDataManager; private readonly IUserDataManager _userDataManager;
private readonly IDtoService _dtoService; private readonly IDtoService _dtoService;
@ -43,11 +41,16 @@ namespace Emby.Server.Implementations.Channels
private readonly IJsonSerializer _jsonSerializer; private readonly IJsonSerializer _jsonSerializer;
private readonly IProviderManager _providerManager; private readonly IProviderManager _providerManager;
private readonly ConcurrentDictionary<string, Tuple<DateTime, List<MediaSourceInfo>>> _channelItemMediaInfo =
new ConcurrentDictionary<string, Tuple<DateTime, List<MediaSourceInfo>>>();
private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
public ChannelManager( public ChannelManager(
IUserManager userManager, IUserManager userManager,
IDtoService dtoService, IDtoService dtoService,
ILibraryManager libraryManager, ILibraryManager libraryManager,
ILoggerFactory loggerFactory, ILogger<ChannelManager> logger,
IServerConfigurationManager config, IServerConfigurationManager config,
IFileSystem fileSystem, IFileSystem fileSystem,
IUserDataManager userDataManager, IUserDataManager userDataManager,
@ -57,7 +60,7 @@ namespace Emby.Server.Implementations.Channels
_userManager = userManager; _userManager = userManager;
_dtoService = dtoService; _dtoService = dtoService;
_libraryManager = libraryManager; _libraryManager = libraryManager;
_logger = loggerFactory.CreateLogger(nameof(ChannelManager)); _logger = logger;
_config = config; _config = config;
_fileSystem = fileSystem; _fileSystem = fileSystem;
_userDataManager = userDataManager; _userDataManager = userDataManager;
@ -65,6 +68,8 @@ namespace Emby.Server.Implementations.Channels
_providerManager = providerManager; _providerManager = providerManager;
} }
internal IChannel[] Channels { get; private set; }
private static TimeSpan CacheLength => TimeSpan.FromHours(3); private static TimeSpan CacheLength => TimeSpan.FromHours(3);
public void AddParts(IEnumerable<IChannel> channels) public void AddParts(IEnumerable<IChannel> channels)
@ -85,8 +90,7 @@ namespace Emby.Server.Implementations.Channels
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);
} }
public bool EnableMediaProbe(BaseItem item) public bool EnableMediaProbe(BaseItem item)
@ -146,15 +150,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 +173,6 @@ namespace Emby.Server.Implementations.Channels
{ {
return false; return false;
} }
}).ToList(); }).ToList();
} }
@ -188,9 +189,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 +216,6 @@ namespace Emby.Server.Implementations.Channels
{ {
return false; return false;
} }
}).ToList(); }).ToList();
} }
@ -226,6 +226,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();
@ -256,11 +257,9 @@ namespace Emby.Server.Implementations.Channels
var internalResult = GetChannelsInternal(query); var internalResult = GetChannelsInternal(query);
var dtoOptions = new DtoOptions() var dtoOptions = new DtoOptions();
{
};
//TODO Fix The co-variant conversion (internalResult.Items) between Folder[] and BaseItem[], this can generate runtime issues. // TODO Fix The co-variant conversion (internalResult.Items) between Folder[] and BaseItem[], this can generate runtime issues.
var returnItems = _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user); var returnItems = _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user);
var result = new QueryResult<BaseItemDto> var result = new QueryResult<BaseItemDto>
@ -341,8 +340,8 @@ namespace Emby.Server.Implementations.Channels
} }
catch catch
{ {
} }
return; return;
} }
@ -365,11 +364,9 @@ namespace Emby.Server.Implementations.Channels
var channel = GetChannel(item.ChannelId); var channel = GetChannel(item.ChannelId);
var channelPlugin = GetChannelProvider(channel); var channelPlugin = GetChannelProvider(channel);
var requiresCallback = channelPlugin as IRequiresMediaInfoCallback;
IEnumerable<MediaSourceInfo> results; IEnumerable<MediaSourceInfo> results;
if (requiresCallback != null) if (channelPlugin is IRequiresMediaInfoCallback requiresCallback)
{ {
results = await GetChannelItemMediaSourcesInternal(requiresCallback, item.ExternalId, cancellationToken) results = await GetChannelItemMediaSourcesInternal(requiresCallback, item.ExternalId, cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
@ -384,9 +381,6 @@ namespace Emby.Server.Implementations.Channels
.ToList(); .ToList();
} }
private readonly ConcurrentDictionary<string, Tuple<DateTime, List<MediaSourceInfo>>> _channelItemMediaInfo =
new ConcurrentDictionary<string, Tuple<DateTime, List<MediaSourceInfo>>>();
private async Task<IEnumerable<MediaSourceInfo>> GetChannelItemMediaSourcesInternal(IRequiresMediaInfoCallback channel, string id, CancellationToken cancellationToken) private async Task<IEnumerable<MediaSourceInfo>> GetChannelItemMediaSourcesInternal(IRequiresMediaInfoCallback channel, string id, CancellationToken cancellationToken)
{ {
if (_channelItemMediaInfo.TryGetValue(id, out Tuple<DateTime, List<MediaSourceInfo>> cachedInfo)) if (_channelItemMediaInfo.TryGetValue(id, out Tuple<DateTime, List<MediaSourceInfo>> cachedInfo))
@ -444,18 +438,21 @@ namespace Emby.Server.Implementations.Channels
{ {
isNew = true; isNew = true;
} }
item.Path = path; item.Path = path;
if (!item.ChannelId.Equals(id)) if (!item.ChannelId.Equals(id))
{ {
forceUpdate = true; forceUpdate = true;
} }
item.ChannelId = id; item.ChannelId = id;
if (item.ParentId != parentFolderId) if (item.ParentId != parentFolderId)
{ {
forceUpdate = true; forceUpdate = true;
} }
item.ParentId = parentFolderId; item.ParentId = parentFolderId;
item.OfficialRating = GetOfficialRating(channelInfo.ParentalRating); item.OfficialRating = GetOfficialRating(channelInfo.ParentalRating);
@ -472,10 +469,12 @@ namespace Emby.Server.Implementations.Channels
_libraryManager.CreateItem(item, null); _libraryManager.CreateItem(item, null);
} }
await item.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem)) await item.RefreshMetadata(
{ new MetadataRefreshOptions(new DirectoryService(_fileSystem))
ForceSave = !isNew && forceUpdate {
}, cancellationToken).ConfigureAwait(false); ForceSave = !isNew && forceUpdate
},
cancellationToken).ConfigureAwait(false);
return item; return item;
} }
@ -509,12 +508,12 @@ namespace Emby.Server.Implementations.Channels
public ChannelFeatures[] GetAllChannelFeatures() public ChannelFeatures[] GetAllChannelFeatures()
{ {
return _libraryManager.GetItemIds(new InternalItemsQuery return _libraryManager.GetItemIds(
{ new InternalItemsQuery
IncludeItemTypes = new[] { typeof(Channel).Name }, {
OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) } IncludeItemTypes = new[] { typeof(Channel).Name },
OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) }
}).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray(); }).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray();
} }
public ChannelFeatures GetChannelFeatures(string id) public ChannelFeatures GetChannelFeatures(string id)
@ -532,13 +531,13 @@ namespace Emby.Server.Implementations.Channels
public bool SupportsExternalTransfer(Guid channelId) public bool SupportsExternalTransfer(Guid channelId)
{ {
//var channel = GetChannel(channelId);
var channelProvider = GetChannelProvider(channelId); var channelProvider = GetChannelProvider(channelId);
return channelProvider.GetChannelFeatures().SupportsContentDownloading; return channelProvider.GetChannelFeatures().SupportsContentDownloading;
} }
public ChannelFeatures GetChannelFeaturesDto(Channel channel, public ChannelFeatures GetChannelFeaturesDto(
Channel channel,
IChannel provider, IChannel provider,
InternalChannelFeatures features) InternalChannelFeatures features)
{ {
@ -567,6 +566,7 @@ namespace Emby.Server.Implementations.Channels
{ {
throw new ArgumentNullException(nameof(name)); throw new ArgumentNullException(nameof(name));
} }
return _libraryManager.GetNewItemId("Channel " + name, typeof(Channel)); return _libraryManager.GetNewItemId("Channel " + name, typeof(Channel));
} }
@ -614,7 +614,7 @@ namespace Emby.Server.Implementations.Channels
query.IsFolder = false; query.IsFolder = false;
// hack for trailers, figure out a better way later // hack for trailers, figure out a better way later
var sortByPremiereDate = channels.Length == 1 && channels[0].GetType().Name.IndexOf("Trailer") != -1; var sortByPremiereDate = channels.Length == 1 && channels[0].GetType().Name.Contains("Trailer", StringComparison.Ordinal);
if (sortByPremiereDate) if (sortByPremiereDate)
{ {
@ -640,10 +640,12 @@ namespace Emby.Server.Implementations.Channels
{ {
var internalChannel = await GetChannel(channel, cancellationToken).ConfigureAwait(false); var internalChannel = await GetChannel(channel, cancellationToken).ConfigureAwait(false);
var query = new InternalItemsQuery(); var query = new InternalItemsQuery
query.Parent = internalChannel; {
query.EnableTotalRecordCount = false; Parent = internalChannel,
query.ChannelIds = new Guid[] { internalChannel.Id }; EnableTotalRecordCount = false,
ChannelIds = new Guid[] { internalChannel.Id }
};
var result = await GetChannelItemsInternal(query, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false); var result = await GetChannelItemsInternal(query, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
@ -651,13 +653,15 @@ namespace Emby.Server.Implementations.Channels
{ {
if (item is Folder folder) if (item is Folder folder)
{ {
await GetChannelItemsInternal(new InternalItemsQuery await GetChannelItemsInternal(
{ new InternalItemsQuery
Parent = folder, {
EnableTotalRecordCount = false, Parent = folder,
ChannelIds = new Guid[] { internalChannel.Id } EnableTotalRecordCount = false,
ChannelIds = new Guid[] { internalChannel.Id }
}, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false); },
new SimpleProgress<double>(),
cancellationToken).ConfigureAwait(false);
} }
} }
} }
@ -672,7 +676,8 @@ namespace Emby.Server.Implementations.Channels
var parentItem = query.ParentId == Guid.Empty ? channel : _libraryManager.GetItemById(query.ParentId); var parentItem = query.ParentId == Guid.Empty ? channel : _libraryManager.GetItemById(query.ParentId);
var itemsResult = await GetChannelItems(channelProvider, var itemsResult = await GetChannelItems(
channelProvider,
query.User, query.User,
parentItem is Channel ? null : parentItem.ExternalId, parentItem is Channel ? null : parentItem.ExternalId,
null, null,
@ -684,13 +689,12 @@ namespace Emby.Server.Implementations.Channels
{ {
query.Parent = channel; query.Parent = channel;
} }
query.ChannelIds = Array.Empty<Guid>(); query.ChannelIds = Array.Empty<Guid>();
// Not yet sure why this is causing a problem // Not yet sure why this is causing a problem
query.GroupByPresentationUniqueKey = false; query.GroupByPresentationUniqueKey = false;
//_logger.LogDebug("GetChannelItemsInternal");
// null if came from cache // null if came from cache
if (itemsResult != null) if (itemsResult != null)
{ {
@ -707,12 +711,15 @@ namespace Emby.Server.Implementations.Channels
var deadItem = _libraryManager.GetItemById(deadId); var deadItem = _libraryManager.GetItemById(deadId);
if (deadItem != null) if (deadItem != null)
{ {
_libraryManager.DeleteItem(deadItem, new DeleteOptions _libraryManager.DeleteItem(
{ deadItem,
DeleteFileLocation = false, new DeleteOptions
DeleteFromExternalProvider = false {
DeleteFileLocation = false,
}, parentItem, false); DeleteFromExternalProvider = false
},
parentItem,
false);
} }
} }
} }
@ -735,7 +742,6 @@ namespace Emby.Server.Implementations.Channels
return result; return result;
} }
private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
private async Task<ChannelItemResult> GetChannelItems(IChannel channel, private async Task<ChannelItemResult> GetChannelItems(IChannel channel,
User user, User user,
string externalFolderId, string externalFolderId,
@ -743,7 +749,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);
@ -761,11 +767,9 @@ namespace Emby.Server.Implementations.Channels
} }
catch (FileNotFoundException) catch (FileNotFoundException)
{ {
} }
catch (IOException) catch (IOException)
{ {
} }
await _resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); await _resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
@ -785,11 +789,9 @@ namespace Emby.Server.Implementations.Channels
} }
catch (FileNotFoundException) catch (FileNotFoundException)
{ {
} }
catch (IOException) catch (IOException)
{ {
} }
var query = new InternalChannelItemQuery var query = new InternalChannelItemQuery
@ -833,7 +835,8 @@ namespace Emby.Server.Implementations.Channels
} }
} }
private string GetChannelDataCachePath(IChannel channel, private string GetChannelDataCachePath(
IChannel channel,
string userId, string userId,
string externalFolderId, string externalFolderId,
ChannelItemSortField? sortField, ChannelItemSortField? sortField,
@ -843,8 +846,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;
} }
@ -858,6 +860,7 @@ namespace Emby.Server.Implementations.Channels
{ {
filename += "-sortField-" + sortField.Value; filename += "-sortField-" + sortField.Value;
} }
if (sortDescending) if (sortDescending)
{ {
filename += "-sortDescending"; filename += "-sortDescending";
@ -865,7 +868,8 @@ namespace Emby.Server.Implementations.Channels
filename = filename.GetMD5().ToString("N", CultureInfo.InvariantCulture); filename = filename.GetMD5().ToString("N", CultureInfo.InvariantCulture);
return Path.Combine(_config.ApplicationPaths.CachePath, return Path.Combine(
_config.ApplicationPaths.CachePath,
"channels", "channels",
channelId, channelId,
version, version,
@ -981,7 +985,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,26 +1017,24 @@ 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))
{ {
_logger.LogDebug("Forcing update due to TrailerTypes {0}", item.Name); _logger.LogDebug("Forcing update due to TrailerTypes {0}", item.Name);
forceUpdate = true; forceUpdate = true;
} }
trailer.TrailerTypes = info.TrailerTypes.ToArray(); trailer.TrailerTypes = info.TrailerTypes.ToArray();
} }
@ -1057,6 +1058,7 @@ namespace Emby.Server.Implementations.Channels
forceUpdate = true; forceUpdate = true;
_logger.LogDebug("Forcing update due to ChannelId {0}", item.Name); _logger.LogDebug("Forcing update due to ChannelId {0}", item.Name);
} }
item.ChannelId = internalChannelId; item.ChannelId = internalChannelId;
if (!item.ParentId.Equals(parentFolderId)) if (!item.ParentId.Equals(parentFolderId))
@ -1064,16 +1066,17 @@ namespace Emby.Server.Implementations.Channels
forceUpdate = true; forceUpdate = true;
_logger.LogDebug("Forcing update due to parent folder Id {0}", item.Name); _logger.LogDebug("Forcing update due to parent folder Id {0}", item.Name);
} }
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))
{ {
forceUpdate = true; forceUpdate = true;
_logger.LogDebug("Forcing update due to SeriesName {0}", item.Name); _logger.LogDebug("Forcing update due to SeriesName {0}", item.Name);
} }
hasSeries.SeriesName = info.SeriesName; hasSeries.SeriesName = info.SeriesName;
} }
@ -1082,24 +1085,23 @@ namespace Emby.Server.Implementations.Channels
forceUpdate = true; forceUpdate = true;
_logger.LogDebug("Forcing update due to ExternalId {0}", item.Name); _logger.LogDebug("Forcing update due to ExternalId {0}", item.Name);
} }
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))
@ -1156,7 +1158,7 @@ namespace Emby.Server.Implementations.Channels
} }
} }
if (isNew || forceUpdate || item.DateLastRefreshed == default(DateTime)) if (isNew || forceUpdate || item.DateLastRefreshed == default)
{ {
_providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.Normal); _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.Normal);
} }

View file

@ -14,14 +14,12 @@ namespace Emby.Server.Implementations.Channels
public class ChannelPostScanTask public class ChannelPostScanTask
{ {
private readonly IChannelManager _channelManager; private readonly IChannelManager _channelManager;
private readonly IUserManager _userManager;
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly ILibraryManager _libraryManager; private readonly ILibraryManager _libraryManager;
public ChannelPostScanTask(IChannelManager channelManager, IUserManager userManager, ILogger logger, ILibraryManager libraryManager) public ChannelPostScanTask(IChannelManager channelManager, ILogger logger, ILibraryManager libraryManager)
{ {
_channelManager = channelManager; _channelManager = channelManager;
_userManager = userManager;
_logger = logger; _logger = logger;
_libraryManager = libraryManager; _libraryManager = libraryManager;
} }

View file

@ -7,29 +7,26 @@ using System.Threading.Tasks;
using MediaBrowser.Common.Progress; using MediaBrowser.Common.Progress;
using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Tasks; using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using MediaBrowser.Model.Globalization;
namespace Emby.Server.Implementations.Channels namespace Emby.Server.Implementations.Channels
{ {
public class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask public class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask
{ {
private readonly IChannelManager _channelManager; private readonly IChannelManager _channelManager;
private readonly IUserManager _userManager;
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly ILibraryManager _libraryManager; private readonly ILibraryManager _libraryManager;
private readonly ILocalizationManager _localization; private readonly ILocalizationManager _localization;
public RefreshChannelsScheduledTask( public RefreshChannelsScheduledTask(
IChannelManager channelManager, IChannelManager channelManager,
IUserManager userManager,
ILogger<RefreshChannelsScheduledTask> logger, ILogger<RefreshChannelsScheduledTask> logger,
ILibraryManager libraryManager, ILibraryManager libraryManager,
ILocalizationManager localization) ILocalizationManager localization)
{ {
_channelManager = channelManager; _channelManager = channelManager;
_userManager = userManager;
_logger = logger; _logger = logger;
_libraryManager = libraryManager; _libraryManager = libraryManager;
_localization = localization; _localization = localization;
@ -63,7 +60,7 @@ namespace Emby.Server.Implementations.Channels
await manager.RefreshChannels(new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false); await manager.RefreshChannels(new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
await new ChannelPostScanTask(_channelManager, _userManager, _logger, _libraryManager).Run(progress, cancellationToken) await new ChannelPostScanTask(_channelManager, _logger, _libraryManager).Run(progress, cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
} }
@ -72,7 +69,6 @@ namespace Emby.Server.Implementations.Channels
{ {
return new[] return new[]
{ {
// Every so often // Every so often
new TaskTriggerInfo new TaskTriggerInfo
{ {

View file

@ -46,9 +46,7 @@ namespace Emby.Server.Implementations.Collections
{ {
var subItem = i; var subItem = i;
var episode = subItem as Episode; if (subItem is Episode episode)
if (episode != null)
{ {
var series = episode.Series; var series = episode.Series;
if (series != null && series.HasImage(ImageType.Primary)) if (series != null && series.HasImage(ImageType.Primary))

View file

@ -52,7 +52,9 @@ namespace Emby.Server.Implementations.Collections
} }
public event EventHandler<CollectionCreatedEventArgs> CollectionCreated; public event EventHandler<CollectionCreatedEventArgs> CollectionCreated;
public event EventHandler<CollectionModifiedEventArgs> ItemsAddedToCollection; public event EventHandler<CollectionModifiedEventArgs> ItemsAddedToCollection;
public event EventHandler<CollectionModifiedEventArgs> ItemsRemovedFromCollection; public event EventHandler<CollectionModifiedEventArgs> ItemsRemovedFromCollection;
private IEnumerable<Folder> FindFolders(string path) private IEnumerable<Folder> FindFolders(string path)
@ -109,9 +111,9 @@ namespace Emby.Server.Implementations.Collections
{ {
var folder = GetCollectionsFolder(false).Result; var folder = GetCollectionsFolder(false).Result;
return folder == null ? return folder == null
new List<BoxSet>() : ? Enumerable.Empty<BoxSet>()
folder.GetChildren(user, true).OfType<BoxSet>(); : folder.GetChildren(user, true).OfType<BoxSet>();
} }
public BoxSet CreateCollection(CollectionCreationOptions options) public BoxSet CreateCollection(CollectionCreationOptions options)
@ -191,7 +193,6 @@ namespace Emby.Server.Implementations.Collections
private void AddToCollection(Guid collectionId, IEnumerable<string> ids, bool fireEvent, MetadataRefreshOptions refreshOptions) private void AddToCollection(Guid collectionId, IEnumerable<string> ids, bool fireEvent, MetadataRefreshOptions refreshOptions)
{ {
var collection = _libraryManager.GetItemById(collectionId) as BoxSet; var collection = _libraryManager.GetItemById(collectionId) as BoxSet;
if (collection == null) if (collection == null)
{ {
throw new ArgumentException("No collection exists with the supplied Id"); throw new ArgumentException("No collection exists with the supplied Id");
@ -289,10 +290,13 @@ namespace Emby.Server.Implementations.Collections
} }
collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None); collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
_providerManager.QueueRefresh(collection.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)) _providerManager.QueueRefresh(
{ collection.Id,
ForceSave = true new MetadataRefreshOptions(new DirectoryService(_fileSystem))
}, RefreshPriority.High); {
ForceSave = true
},
RefreshPriority.High);
ItemsRemovedFromCollection?.Invoke(this, new CollectionModifiedEventArgs ItemsRemovedFromCollection?.Invoke(this, new CollectionModifiedEventArgs
{ {

View file

@ -22,6 +22,10 @@ namespace Emby.Server.Implementations.LiveTv
{ {
public class LiveTvDtoService public class LiveTvDtoService
{ {
private const string InternalVersionNumber = "4";
private const string ServiceName = "Emby";
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IImageProcessor _imageProcessor; private readonly IImageProcessor _imageProcessor;
@ -32,13 +36,13 @@ namespace Emby.Server.Implementations.LiveTv
public LiveTvDtoService( public LiveTvDtoService(
IDtoService dtoService, IDtoService dtoService,
IImageProcessor imageProcessor, IImageProcessor imageProcessor,
ILoggerFactory loggerFactory, ILogger<LiveTvDtoService> logger,
IApplicationHost appHost, IApplicationHost appHost,
ILibraryManager libraryManager) ILibraryManager libraryManager)
{ {
_dtoService = dtoService; _dtoService = dtoService;
_imageProcessor = imageProcessor; _imageProcessor = imageProcessor;
_logger = loggerFactory.CreateLogger(nameof(LiveTvDtoService)); _logger = logger;
_appHost = appHost; _appHost = appHost;
_libraryManager = libraryManager; _libraryManager = libraryManager;
} }
@ -161,7 +165,6 @@ namespace Emby.Server.Implementations.LiveTv
Limit = 1, Limit = 1,
ImageTypes = new ImageType[] { ImageType.Thumb }, ImageTypes = new ImageType[] { ImageType.Thumb },
DtoOptions = new DtoOptions(false) DtoOptions = new DtoOptions(false)
}).FirstOrDefault(); }).FirstOrDefault();
if (librarySeries != null) if (librarySeries != null)
@ -179,6 +182,7 @@ namespace Emby.Server.Implementations.LiveTv
_logger.LogError(ex, "Error"); _logger.LogError(ex, "Error");
} }
} }
image = librarySeries.GetImageInfo(ImageType.Backdrop, 0); image = librarySeries.GetImageInfo(ImageType.Backdrop, 0);
if (image != null) if (image != null)
{ {
@ -199,13 +203,12 @@ namespace Emby.Server.Implementations.LiveTv
var program = _libraryManager.GetItemList(new InternalItemsQuery var program = _libraryManager.GetItemList(new InternalItemsQuery
{ {
IncludeItemTypes = new string[] { typeof(LiveTvProgram).Name }, IncludeItemTypes = new string[] { nameof(LiveTvProgram) },
ExternalSeriesId = programSeriesId, ExternalSeriesId = programSeriesId,
Limit = 1, Limit = 1,
ImageTypes = new ImageType[] { ImageType.Primary }, ImageTypes = new ImageType[] { ImageType.Primary },
DtoOptions = new DtoOptions(false), DtoOptions = new DtoOptions(false),
Name = string.IsNullOrEmpty(programSeriesId) ? seriesName : null Name = string.IsNullOrEmpty(programSeriesId) ? seriesName : null
}).FirstOrDefault(); }).FirstOrDefault();
if (program != null) if (program != null)
@ -232,9 +235,10 @@ namespace Emby.Server.Implementations.LiveTv
try try
{ {
dto.ParentBackdropImageTags = new string[] dto.ParentBackdropImageTags = new string[]
{ {
_imageProcessor.GetImageCacheTag(program, image) _imageProcessor.GetImageCacheTag(program, image)
}; };
dto.ParentBackdropItemId = program.Id.ToString("N", CultureInfo.InvariantCulture); dto.ParentBackdropItemId = program.Id.ToString("N", CultureInfo.InvariantCulture);
} }
catch (Exception ex) catch (Exception ex)
@ -255,7 +259,6 @@ namespace Emby.Server.Implementations.LiveTv
Limit = 1, Limit = 1,
ImageTypes = new ImageType[] { ImageType.Thumb }, ImageTypes = new ImageType[] { ImageType.Thumb },
DtoOptions = new DtoOptions(false) DtoOptions = new DtoOptions(false)
}).FirstOrDefault(); }).FirstOrDefault();
if (librarySeries != null) if (librarySeries != null)
@ -273,6 +276,7 @@ namespace Emby.Server.Implementations.LiveTv
_logger.LogError(ex, "Error"); _logger.LogError(ex, "Error");
} }
} }
image = librarySeries.GetImageInfo(ImageType.Backdrop, 0); image = librarySeries.GetImageInfo(ImageType.Backdrop, 0);
if (image != null) if (image != null)
{ {
@ -298,7 +302,6 @@ namespace Emby.Server.Implementations.LiveTv
Limit = 1, Limit = 1,
ImageTypes = new ImageType[] { ImageType.Primary }, ImageTypes = new ImageType[] { ImageType.Primary },
DtoOptions = new DtoOptions(false) DtoOptions = new DtoOptions(false)
}).FirstOrDefault(); }).FirstOrDefault();
if (program == null) if (program == null)
@ -311,7 +314,6 @@ namespace Emby.Server.Implementations.LiveTv
ImageTypes = new ImageType[] { ImageType.Primary }, ImageTypes = new ImageType[] { ImageType.Primary },
DtoOptions = new DtoOptions(false), DtoOptions = new DtoOptions(false),
Name = string.IsNullOrEmpty(programSeriesId) ? seriesName : null Name = string.IsNullOrEmpty(programSeriesId) ? seriesName : null
}).FirstOrDefault(); }).FirstOrDefault();
} }
@ -396,8 +398,6 @@ namespace Emby.Server.Implementations.LiveTv
return null; return null;
} }
private const string InternalVersionNumber = "4";
public Guid GetInternalChannelId(string serviceName, string externalId) public Guid GetInternalChannelId(string serviceName, string externalId)
{ {
var name = serviceName + externalId + InternalVersionNumber; var name = serviceName + externalId + InternalVersionNumber;
@ -405,7 +405,6 @@ namespace Emby.Server.Implementations.LiveTv
return _libraryManager.GetNewItemId(name.ToLowerInvariant(), typeof(LiveTvChannel)); return _libraryManager.GetNewItemId(name.ToLowerInvariant(), typeof(LiveTvChannel));
} }
private const string ServiceName = "Emby";
public string GetInternalTimerId(string externalId) public string GetInternalTimerId(string externalId)
{ {
var name = ServiceName + externalId + InternalVersionNumber; var name = ServiceName + externalId + InternalVersionNumber;

View file

@ -41,6 +41,10 @@ namespace Emby.Server.Implementations.LiveTv
/// </summary> /// </summary>
public class LiveTvManager : ILiveTvManager, IDisposable public class LiveTvManager : ILiveTvManager, IDisposable
{ {
private const string ExternalServiceTag = "ExternalServiceId";
private const string EtagKey = "ProgramEtag";
private readonly IServerConfigurationManager _config; private readonly IServerConfigurationManager _config;
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IItemRepository _itemRepo; private readonly IItemRepository _itemRepo;
@ -91,7 +95,7 @@ namespace Emby.Server.Implementations.LiveTv
_userDataManager = userDataManager; _userDataManager = userDataManager;
_channelManager = channelManager; _channelManager = channelManager;
_tvDtoService = new LiveTvDtoService(dtoService, imageProcessor, loggerFactory, appHost, _libraryManager); _tvDtoService = new LiveTvDtoService(dtoService, imageProcessor, loggerFactory.CreateLogger<LiveTvDtoService>(), appHost, _libraryManager);
} }
public event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled; public event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled;
@ -178,7 +182,6 @@ namespace Emby.Server.Implementations.LiveTv
{ {
Name = i.Name, Name = i.Name,
Id = i.Type Id = i.Type
}).ToList(); }).ToList();
} }
@ -261,6 +264,7 @@ namespace Emby.Server.Implementations.LiveTv
var endTime = DateTime.UtcNow; var endTime = DateTime.UtcNow;
_logger.LogInformation("Live stream opened after {0}ms", (endTime - startTime).TotalMilliseconds); _logger.LogInformation("Live stream opened after {0}ms", (endTime - startTime).TotalMilliseconds);
} }
info.RequiresClosing = true; info.RequiresClosing = true;
var idPrefix = service.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture) + "_"; var idPrefix = service.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture) + "_";
@ -362,30 +366,37 @@ namespace Emby.Server.Implementations.LiveTv
{ {
stream.BitRate = null; stream.BitRate = null;
} }
if (stream.Channels.HasValue && stream.Channels <= 0) if (stream.Channels.HasValue && stream.Channels <= 0)
{ {
stream.Channels = null; stream.Channels = null;
} }
if (stream.AverageFrameRate.HasValue && stream.AverageFrameRate <= 0) if (stream.AverageFrameRate.HasValue && stream.AverageFrameRate <= 0)
{ {
stream.AverageFrameRate = null; stream.AverageFrameRate = null;
} }
if (stream.RealFrameRate.HasValue && stream.RealFrameRate <= 0) if (stream.RealFrameRate.HasValue && stream.RealFrameRate <= 0)
{ {
stream.RealFrameRate = null; stream.RealFrameRate = null;
} }
if (stream.Width.HasValue && stream.Width <= 0) if (stream.Width.HasValue && stream.Width <= 0)
{ {
stream.Width = null; stream.Width = null;
} }
if (stream.Height.HasValue && stream.Height <= 0) if (stream.Height.HasValue && stream.Height <= 0)
{ {
stream.Height = null; stream.Height = null;
} }
if (stream.SampleRate.HasValue && stream.SampleRate <= 0) if (stream.SampleRate.HasValue && stream.SampleRate <= 0)
{ {
stream.SampleRate = null; stream.SampleRate = null;
} }
if (stream.Level.HasValue && stream.Level <= 0) if (stream.Level.HasValue && stream.Level <= 0)
{ {
stream.Level = null; stream.Level = null;
@ -427,7 +438,6 @@ namespace Emby.Server.Implementations.LiveTv
} }
} }
private const string ExternalServiceTag = "ExternalServiceId";
private LiveTvChannel GetChannel(ChannelInfo channelInfo, string serviceName, BaseItem parentFolder, CancellationToken cancellationToken) private LiveTvChannel GetChannel(ChannelInfo channelInfo, string serviceName, BaseItem parentFolder, CancellationToken cancellationToken)
{ {
var parentFolderId = parentFolder.Id; var parentFolderId = parentFolder.Id;
@ -456,6 +466,7 @@ namespace Emby.Server.Implementations.LiveTv
{ {
isNew = true; isNew = true;
} }
item.Tags = channelInfo.Tags; item.Tags = channelInfo.Tags;
} }
@ -463,6 +474,7 @@ namespace Emby.Server.Implementations.LiveTv
{ {
isNew = true; isNew = true;
} }
item.ParentId = parentFolderId; item.ParentId = parentFolderId;
item.ChannelType = channelInfo.ChannelType; item.ChannelType = channelInfo.ChannelType;
@ -472,24 +484,28 @@ namespace Emby.Server.Implementations.LiveTv
{ {
forceUpdate = true; forceUpdate = true;
} }
item.SetProviderId(ExternalServiceTag, serviceName); item.SetProviderId(ExternalServiceTag, serviceName);
if (!string.Equals(channelInfo.Id, item.ExternalId, StringComparison.Ordinal)) if (!string.Equals(channelInfo.Id, item.ExternalId, StringComparison.Ordinal))
{ {
forceUpdate = true; forceUpdate = true;
} }
item.ExternalId = channelInfo.Id; item.ExternalId = channelInfo.Id;
if (!string.Equals(channelInfo.Number, item.Number, StringComparison.Ordinal)) if (!string.Equals(channelInfo.Number, item.Number, StringComparison.Ordinal))
{ {
forceUpdate = true; forceUpdate = true;
} }
item.Number = channelInfo.Number; item.Number = channelInfo.Number;
if (!string.Equals(channelInfo.Name, item.Name, StringComparison.Ordinal)) if (!string.Equals(channelInfo.Name, item.Name, StringComparison.Ordinal))
{ {
forceUpdate = true; forceUpdate = true;
} }
item.Name = channelInfo.Name; item.Name = channelInfo.Name;
if (!item.HasImage(ImageType.Primary)) if (!item.HasImage(ImageType.Primary))
@ -518,8 +534,6 @@ namespace Emby.Server.Implementations.LiveTv
return item; return item;
} }
private const string EtagKey = "ProgramEtag";
private Tuple<LiveTvProgram, bool, bool> GetProgram(ProgramInfo info, Dictionary<Guid, LiveTvProgram> allExistingPrograms, LiveTvChannel channel, ChannelType channelType, string serviceName, CancellationToken cancellationToken) private Tuple<LiveTvProgram, bool, bool> GetProgram(ProgramInfo info, Dictionary<Guid, LiveTvProgram> allExistingPrograms, LiveTvChannel channel, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
{ {
var id = _tvDtoService.GetInternalProgramId(info.Id); var id = _tvDtoService.GetInternalProgramId(info.Id);

View file

@ -6,30 +6,34 @@ using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Persistence namespace MediaBrowser.Controller.Persistence
{ {
/// <summary> /// <summary>
/// Interface IDisplayPreferencesRepository /// Interface IDisplayPreferencesRepository.
/// </summary> /// </summary>
public interface IDisplayPreferencesRepository : IRepository public interface IDisplayPreferencesRepository : IRepository
{ {
/// <summary> /// <summary>
/// Saves display preferences for an item /// Saves display preferences for an item.
/// </summary> /// </summary>
/// <param name="displayPreferences">The display preferences.</param> /// <param name="displayPreferences">The display preferences.</param>
/// <param name="userId">The user id.</param> /// <param name="userId">The user id.</param>
/// <param name="client">The client.</param> /// <param name="client">The client.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns> void SaveDisplayPreferences(
void SaveDisplayPreferences(DisplayPreferences displayPreferences, string userId, string client, DisplayPreferences displayPreferences,
CancellationToken cancellationToken); string userId,
string client,
CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Saves all display preferences for a user /// Saves all display preferences for a user.
/// </summary> /// </summary>
/// <param name="displayPreferences">The display preferences.</param> /// <param name="displayPreferences">The display preferences.</param>
/// <param name="userId">The user id.</param> /// <param name="userId">The user id.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns> void SaveAllDisplayPreferences(
void SaveAllDisplayPreferences(IEnumerable<DisplayPreferences> displayPreferences, Guid userId, IEnumerable<DisplayPreferences> displayPreferences,
CancellationToken cancellationToken); Guid userId,
CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Gets the display preferences. /// Gets the display preferences.
/// </summary> /// </summary>

View file

@ -14,7 +14,7 @@ namespace MediaBrowser.Model.LiveTv
public SeriesTimerInfoDto() public SeriesTimerInfoDto()
{ {
ImageTags = new Dictionary<ImageType, string>(); ImageTags = new Dictionary<ImageType, string>();
Days = new DayOfWeek[] { }; Days = Array.Empty<DayOfWeek>();
Type = "SeriesTimer"; Type = "SeriesTimer";
} }