aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations')
-rw-r--r--Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs149
-rw-r--r--Emby.Server.Implementations/Activity/ActivityRepository.cs2
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs18
-rw-r--r--Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs8
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs16
-rw-r--r--Emby.Server.Implementations/Dto/DtoService.cs113
-rw-r--r--Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs17
-rw-r--r--Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs3
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs5
-rw-r--r--Emby.Server.Implementations/Library/UserViewManager.cs30
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs75
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvManager.cs18
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs15
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs48
-rw-r--r--Emby.Server.Implementations/Localization/Core/el.json10
-rw-r--r--Emby.Server.Implementations/Localization/Core/es.json4
-rw-r--r--Emby.Server.Implementations/Localization/Core/fr.json4
-rw-r--r--Emby.Server.Implementations/Localization/Core/nb.json4
-rw-r--r--Emby.Server.Implementations/MediaEncoder/EncodingManager.cs2
-rw-r--r--Emby.Server.Implementations/Net/SocketFactory.cs3
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteTranscodeFileTask.cs (renamed from Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteTranscodingTempTask.cs)9
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs13
-rw-r--r--Emby.Server.Implementations/Services/ResponseHelper.cs2
-rw-r--r--Emby.Server.Implementations/Services/ServiceExec.cs39
-rw-r--r--Emby.Server.Implementations/Services/UrlExtensions.cs14
-rw-r--r--Emby.Server.Implementations/Sorting/ArtistComparer.cs24
26 files changed, 355 insertions, 290 deletions
diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
index fb4ffd74b..1514402d6 100644
--- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
+++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
@@ -96,7 +96,10 @@ namespace Emby.Server.Implementations.Activity
{
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("CameraImageUploadedFrom"), e.Argument.Device.Name),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("CameraImageUploadedFrom"),
+ e.Argument.Device.Name),
Type = NotificationType.CameraImageUploaded.ToString()
});
}
@@ -105,7 +108,10 @@ namespace Emby.Server.Implementations.Activity
{
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("UserLockedOutWithName"), e.Argument.Name),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("UserLockedOutWithName"),
+ e.Argument.Name),
Type = NotificationType.UserLockedOut.ToString(),
UserId = e.Argument.Id
});
@@ -115,7 +121,11 @@ namespace Emby.Server.Implementations.Activity
{
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"), e.Provider, Notifications.Notifications.GetItemName(e.Item)),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"),
+ e.Provider,
+ Notifications.Notifications.GetItemName(e.Item)),
Type = "SubtitleDownloadFailure",
ItemId = e.Item.Id.ToString("N", CultureInfo.InvariantCulture),
ShortOverview = e.Exception.Message
@@ -178,7 +188,12 @@ namespace Emby.Server.Implementations.Activity
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("UserStartedPlayingItemWithValues"), user.Name, GetItemName(item), e.DeviceName),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("UserStartedPlayingItemWithValues"),
+ user.Name,
+ GetItemName(item),
+ e.DeviceName),
Type = GetPlaybackNotificationType(item.MediaType),
UserId = user.Id
});
@@ -193,7 +208,7 @@ namespace Emby.Server.Implementations.Activity
name = item.SeriesName + " - " + name;
}
- if (item.Artists != null && item.Artists.Length > 0)
+ if (item.Artists != null && item.Artists.Count > 0)
{
name = item.Artists[0] + " - " + name;
}
@@ -238,21 +253,31 @@ namespace Emby.Server.Implementations.Activity
if (string.IsNullOrEmpty(session.UserName))
{
- name = string.Format(_localization.GetLocalizedString("DeviceOfflineWithName"), session.DeviceName);
+ name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("DeviceOfflineWithName"),
+ session.DeviceName);
// Causing too much spam for now
return;
}
else
{
- name = string.Format(_localization.GetLocalizedString("UserOfflineFromDevice"), session.UserName, session.DeviceName);
+ name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("UserOfflineFromDevice"),
+ session.UserName,
+ session.DeviceName);
}
CreateLogEntry(new ActivityLogEntry
{
Name = name,
Type = "SessionEnded",
- ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), session.RemoteEndPoint),
+ ShortOverview = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("LabelIpAddressValue"),
+ session.RemoteEndPoint),
UserId = session.UserId
});
}
@@ -263,9 +288,15 @@ namespace Emby.Server.Implementations.Activity
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("AuthenticationSucceededWithUserName"), user.Name),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("AuthenticationSucceededWithUserName"),
+ user.Name),
Type = "AuthenticationSucceeded",
- ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), e.Argument.SessionInfo.RemoteEndPoint),
+ ShortOverview = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("LabelIpAddressValue"),
+ e.Argument.SessionInfo.RemoteEndPoint),
UserId = user.Id
});
}
@@ -274,9 +305,15 @@ namespace Emby.Server.Implementations.Activity
{
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("FailedLoginAttemptWithUserName"), e.Argument.Username),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("FailedLoginAttemptWithUserName"),
+ e.Argument.Username),
Type = "AuthenticationFailed",
- ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), e.Argument.RemoteEndPoint),
+ ShortOverview = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("LabelIpAddressValue"),
+ e.Argument.RemoteEndPoint),
Severity = LogLevel.Error
});
}
@@ -285,7 +322,10 @@ namespace Emby.Server.Implementations.Activity
{
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("UserPolicyUpdatedWithName"), e.Argument.Name),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("UserPolicyUpdatedWithName"),
+ e.Argument.Name),
Type = "UserPolicyUpdated",
UserId = e.Argument.Id
});
@@ -295,7 +335,10 @@ namespace Emby.Server.Implementations.Activity
{
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("UserDeletedWithName"), e.Argument.Name),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("UserDeletedWithName"),
+ e.Argument.Name),
Type = "UserDeleted"
});
}
@@ -304,7 +347,10 @@ namespace Emby.Server.Implementations.Activity
{
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("UserPasswordChangedWithName"), e.Argument.Name),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("UserPasswordChangedWithName"),
+ e.Argument.Name),
Type = "UserPasswordChanged",
UserId = e.Argument.Id
});
@@ -314,7 +360,10 @@ namespace Emby.Server.Implementations.Activity
{
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("UserCreatedWithName"), e.Argument.Name),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("UserCreatedWithName"),
+ e.Argument.Name),
Type = "UserCreated",
UserId = e.Argument.Id
});
@@ -327,21 +376,31 @@ namespace Emby.Server.Implementations.Activity
if (string.IsNullOrEmpty(session.UserName))
{
- name = string.Format(_localization.GetLocalizedString("DeviceOnlineWithName"), session.DeviceName);
+ name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("DeviceOnlineWithName"),
+ session.DeviceName);
// Causing too much spam for now
return;
}
else
{
- name = string.Format(_localization.GetLocalizedString("UserOnlineFromDevice"), session.UserName, session.DeviceName);
+ name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("UserOnlineFromDevice"),
+ session.UserName,
+ session.DeviceName);
}
CreateLogEntry(new ActivityLogEntry
{
Name = name,
Type = "SessionStarted",
- ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), session.RemoteEndPoint),
+ ShortOverview = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("LabelIpAddressValue"),
+ session.RemoteEndPoint),
UserId = session.UserId
});
}
@@ -350,9 +409,15 @@ namespace Emby.Server.Implementations.Activity
{
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("PluginUpdatedWithName"), e.Argument.Item1.Name),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("PluginUpdatedWithName"),
+ e.Argument.Item1.Name),
Type = NotificationType.PluginUpdateInstalled.ToString(),
- ShortOverview = string.Format(_localization.GetLocalizedString("VersionNumber"), e.Argument.Item2.versionStr),
+ ShortOverview = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("VersionNumber"),
+ e.Argument.Item2.versionStr),
Overview = e.Argument.Item2.description
});
}
@@ -361,7 +426,10 @@ namespace Emby.Server.Implementations.Activity
{
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("PluginUninstalledWithName"), e.Argument.Name),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("PluginUninstalledWithName"),
+ e.Argument.Name),
Type = NotificationType.PluginUninstalled.ToString()
});
}
@@ -370,9 +438,15 @@ namespace Emby.Server.Implementations.Activity
{
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("PluginInstalledWithName"), e.Argument.name),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("PluginInstalledWithName"),
+ e.Argument.name),
Type = NotificationType.PluginInstalled.ToString(),
- ShortOverview = string.Format(_localization.GetLocalizedString("VersionNumber"), e.Argument.versionStr)
+ ShortOverview = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("VersionNumber"),
+ e.Argument.versionStr)
});
}
@@ -382,9 +456,15 @@ namespace Emby.Server.Implementations.Activity
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("NameInstallFailed"), installationInfo.Name),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("NameInstallFailed"),
+ installationInfo.Name),
Type = NotificationType.InstallationFailed.ToString(),
- ShortOverview = string.Format(_localization.GetLocalizedString("VersionNumber"), installationInfo.Version),
+ ShortOverview = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("VersionNumber"),
+ installationInfo.Version),
Overview = e.Exception.Message
});
}
@@ -401,7 +481,10 @@ namespace Emby.Server.Implementations.Activity
}
var time = result.EndTimeUtc - result.StartTimeUtc;
- var runningTime = string.Format(_localization.GetLocalizedString("LabelRunningTimeValue"), ToUserFriendlyString(time));
+ var runningTime = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("LabelRunningTimeValue"),
+ ToUserFriendlyString(time));
if (result.Status == TaskCompletionStatus.Failed)
{
@@ -419,7 +502,10 @@ namespace Emby.Server.Implementations.Activity
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name),
+ Name = string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("ScheduledTaskFailedWithName"),
+ task.Name),
Type = NotificationType.TaskFailed.ToString(),
Overview = string.Join(Environment.NewLine, vals),
ShortOverview = runningTime,
@@ -534,8 +620,11 @@ namespace Emby.Server.Implementations.Activity
/// <param name="description">The name of this item (singular form)</param>
private static string CreateValueString(int value, string description)
{
- return string.Format("{0:#,##0} {1}",
- value, value == 1 ? description : string.Format("{0}s", description));
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0:#,##0} {1}",
+ value,
+ value == 1 ? description : string.Format(CultureInfo.InvariantCulture, "{0}s", description));
}
}
}
diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs
index 541b23afd..ffaeaa541 100644
--- a/Emby.Server.Implementations/Activity/ActivityRepository.cs
+++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs
@@ -247,7 +247,7 @@ namespace Emby.Server.Implementations.Activity
ReadTransactionMode);
}
- result.Items = list.ToArray();
+ result.Items = list;
return result;
}
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 6ab3d1bb1..24f59478c 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -202,10 +202,10 @@ namespace Emby.Server.Implementations
/// Gets or sets all concrete types.
/// </summary>
/// <value>All concrete types.</value>
- public Type[] AllConcreteTypes { get; protected set; }
+ private Type[] _allConcreteTypes;
/// <summary>
- /// The disposable parts
+ /// The disposable parts.
/// </summary>
private readonly List<IDisposable> _disposableParts = new List<IDisposable>();
@@ -499,7 +499,7 @@ namespace Emby.Server.Implementations
{
var currentType = typeof(T);
- return AllConcreteTypes.Where(i => currentType.IsAssignableFrom(i));
+ return _allConcreteTypes.Where(i => currentType.IsAssignableFrom(i));
}
/// <inheritdoc />
@@ -1010,9 +1010,11 @@ namespace Emby.Server.Implementations
.Select(x => Assembly.LoadFrom(x))
.SelectMany(x => x.ExportedTypes)
.Where(x => x.IsClass && !x.IsAbstract && !x.IsInterface && !x.IsGenericType)
- .ToList();
+ .ToArray();
- types.AddRange(types);
+ int oldLen = _allConcreteTypes.Length;
+ Array.Resize(ref _allConcreteTypes, oldLen + types.Length);
+ types.CopyTo(_allConcreteTypes, oldLen);
var plugins = types.Where(x => x.IsAssignableFrom(typeof(IPlugin)))
.Select(CreateInstanceSafe)
@@ -1022,8 +1024,8 @@ namespace Emby.Server.Implementations
.Where(x => x != null)
.ToArray();
- int oldLen = _plugins.Length;
- Array.Resize<IPlugin>(ref _plugins, _plugins.Length + plugins.Length);
+ oldLen = _plugins.Length;
+ Array.Resize(ref _plugins, oldLen + plugins.Length);
plugins.CopyTo(_plugins, oldLen);
var entries = types.Where(x => x.IsAssignableFrom(typeof(IServerEntryPoint)))
@@ -1140,7 +1142,7 @@ namespace Emby.Server.Implementations
{
Logger.LogInformation("Loading assemblies");
- AllConcreteTypes = GetTypes(GetComposablePartAssemblies()).ToArray();
+ _allConcreteTypes = GetTypes(GetComposablePartAssemblies()).ToArray();
}
private IEnumerable<Type> GetTypes(IEnumerable<Assembly> assemblies)
diff --git a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
index c4fa68cac..c7f92b80b 100644
--- a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
+++ b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
@@ -66,7 +66,7 @@ namespace Emby.Server.Implementations.Configuration
{
base.AddParts(factories);
- UpdateTranscodingTempPath();
+ UpdateTranscodePath();
}
/// <summary>
@@ -87,13 +87,13 @@ namespace Emby.Server.Implementations.Configuration
/// <summary>
/// Updates the transcoding temporary path.
/// </summary>
- private void UpdateTranscodingTempPath()
+ private void UpdateTranscodePath()
{
var encodingConfig = this.GetConfiguration<EncodingOptions>("encoding");
((ServerApplicationPaths)ApplicationPaths).TranscodingTempPath = string.IsNullOrEmpty(encodingConfig.TranscodingTempPath) ?
null :
- Path.Combine(encodingConfig.TranscodingTempPath, "transcoding-temp");
+ Path.Combine(encodingConfig.TranscodingTempPath, "transcodes");
}
protected override void OnNamedConfigurationUpdated(string key, object configuration)
@@ -102,7 +102,7 @@ namespace Emby.Server.Implementations.Configuration
if (string.Equals(key, "encoding", StringComparison.OrdinalIgnoreCase))
{
- UpdateTranscodingTempPath();
+ UpdateTranscodePath();
}
}
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 9d983307f..2f083dda4 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -979,7 +979,7 @@ namespace Emby.Server.Implementations.Data
}
string artists = null;
- if (item is IHasArtist hasArtists && hasArtists.Artists.Length > 0)
+ if (item is IHasArtist hasArtists && hasArtists.Artists.Count > 0)
{
artists = string.Join("|", hasArtists.Artists);
}
@@ -987,7 +987,7 @@ namespace Emby.Server.Implementations.Data
string albumArtists = null;
if (item is IHasAlbumArtist hasAlbumArtists
- && hasAlbumArtists.AlbumArtists.Length > 0)
+ && hasAlbumArtists.AlbumArtists.Count > 0)
{
albumArtists = string.Join("|", hasAlbumArtists.AlbumArtists);
}
@@ -2746,7 +2746,7 @@ namespace Emby.Server.Implementations.Data
var returnList = GetItemList(query);
return new QueryResult<BaseItem>
{
- Items = returnList.ToArray(),
+ Items = returnList,
TotalRecordCount = returnList.Count
};
}
@@ -2883,7 +2883,7 @@ namespace Emby.Server.Implementations.Data
}
LogQueryTime("GetItems", commandText, now);
- result.Items = list.ToArray();
+ result.Items = list;
return result;
}
@@ -3161,7 +3161,7 @@ namespace Emby.Server.Implementations.Data
var returnList = GetItemIdsList(query);
return new QueryResult<Guid>
{
- Items = returnList.ToArray(),
+ Items = returnList,
TotalRecordCount = returnList.Count
};
}
@@ -3281,7 +3281,7 @@ namespace Emby.Server.Implementations.Data
LogQueryTime("GetItemIds", commandText, now);
- result.Items = list.ToArray();
+ result.Items = list;
return result;
}
@@ -5520,7 +5520,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
result.TotalRecordCount = list.Count;
}
- result.Items = list.ToArray();
+ result.Items = list;
return result;
}
@@ -5731,7 +5731,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
if (isSubsequentRow)
{
- insertText.Append(",");
+ insertText.Append(',');
}
insertText.AppendFormat("(@ItemId, @Name{0}, @Role{0}, @PersonType{0}, @SortOrder{0}, @ListOrder{0})", i.ToString(CultureInfo.InvariantCulture));
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index 1a7f10634..75192a8f1 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/Emby.Server.Implementations/Dto/DtoService.cs
@@ -80,27 +80,25 @@ namespace Emby.Server.Implementations.Dto
return GetBaseItemDto(item, options, user, owner);
}
- public BaseItemDto[] GetBaseItemDtos(IReadOnlyList<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null)
- => GetBaseItemDtos(items, items.Count, options, user, owner);
-
- public BaseItemDto[] GetBaseItemDtos(IEnumerable<BaseItem> items, int itemCount, DtoOptions options, User user = null, BaseItem owner = null)
+ /// <inheritdoc />
+ public IReadOnlyList<BaseItemDto> GetBaseItemDtos(IReadOnlyList<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null)
{
- var returnItems = new BaseItemDto[itemCount];
- var programTuples = new List<Tuple<BaseItem, BaseItemDto>>();
- var channelTuples = new List<Tuple<BaseItemDto, LiveTvChannel>>();
+ var returnItems = new BaseItemDto[items.Count];
+ var programTuples = new List<(BaseItem, BaseItemDto)>();
+ var channelTuples = new List<(BaseItemDto, LiveTvChannel)>();
- var index = 0;
- foreach (var item in items)
+ for (int index = 0; index < items.Count; index++)
{
+ var item = items[index];
var dto = GetBaseItemDtoInternal(item, options, user, owner);
if (item is LiveTvChannel tvChannel)
{
- channelTuples.Add(new Tuple<BaseItemDto, LiveTvChannel>(dto, tvChannel));
+ channelTuples.Add((dto, tvChannel));
}
else if (item is LiveTvProgram)
{
- programTuples.Add(new Tuple<BaseItem, BaseItemDto>(item, dto));
+ programTuples.Add((item, dto));
}
if (item is IItemByName byName)
@@ -121,7 +119,6 @@ namespace Emby.Server.Implementations.Dto
}
returnItems[index] = dto;
- index++;
}
if (programTuples.Count > 0)
@@ -140,33 +137,32 @@ namespace Emby.Server.Implementations.Dto
public BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null)
{
var dto = GetBaseItemDtoInternal(item, options, user, owner);
- var tvChannel = item as LiveTvChannel;
- if (tvChannel != null)
+ if (item is LiveTvChannel tvChannel)
{
- var list = new List<Tuple<BaseItemDto, LiveTvChannel>> { new Tuple<BaseItemDto, LiveTvChannel>(dto, tvChannel) };
+ var list = new List<(BaseItemDto, LiveTvChannel)>(1) { (dto, tvChannel) };
_livetvManager().AddChannelInfo(list, options, user);
}
else if (item is LiveTvProgram)
{
- var list = new List<Tuple<BaseItem, BaseItemDto>> { new Tuple<BaseItem, BaseItemDto>(item, dto) };
+ var list = new List<(BaseItem, BaseItemDto)>(1) { (item, dto) };
var task = _livetvManager().AddInfoToProgramDto(list, options.Fields, user);
Task.WaitAll(task);
}
- var byName = item as IItemByName;
-
- if (byName != null)
+ if (item is IItemByName itemByName
+ && options.ContainsField(ItemFields.ItemCounts))
{
- if (options.ContainsField(ItemFields.ItemCounts))
- {
- SetItemByNameInfo(item, dto, GetTaggedItems(byName, user, new DtoOptions(false)
- {
- EnableImages = false
-
- }), user);
- }
-
- return dto;
+ SetItemByNameInfo(
+ item,
+ dto,
+ GetTaggedItems(
+ itemByName,
+ user,
+ new DtoOptions(false)
+ {
+ EnableImages = false
+ }),
+ user);
}
return dto;
@@ -174,12 +170,12 @@ namespace Emby.Server.Implementations.Dto
private static IList<BaseItem> GetTaggedItems(IItemByName byName, User user, DtoOptions options)
{
- return byName.GetTaggedItems(new InternalItemsQuery(user)
- {
- Recursive = true,
- DtoOptions = options
-
- });
+ return byName.GetTaggedItems(
+ new InternalItemsQuery(user)
+ {
+ Recursive = true,
+ DtoOptions = options
+ });
}
private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null)
@@ -222,8 +218,7 @@ namespace Emby.Server.Implementations.Dto
AttachUserSpecificInfo(dto, item, user, options);
}
- var hasMediaSources = item as IHasMediaSources;
- if (hasMediaSources != null)
+ if (item is IHasMediaSources hasMediaSources)
{
if (options.ContainsField(ItemFields.MediaSources))
{
@@ -769,14 +764,12 @@ namespace Emby.Server.Implementations.Dto
dto.CriticRating = item.CriticRating;
- var hasDisplayOrder = item as IHasDisplayOrder;
- if (hasDisplayOrder != null)
+ if (item is IHasDisplayOrder hasDisplayOrder)
{
dto.DisplayOrder = hasDisplayOrder.DisplayOrder;
}
- var hasCollectionType = item as IHasCollectionType;
- if (hasCollectionType != null)
+ if (item is IHasCollectionType hasCollectionType)
{
dto.CollectionType = hasCollectionType.CollectionType;
}
@@ -886,8 +879,7 @@ namespace Emby.Server.Implementations.Dto
//}
}
- var hasArtist = item as IHasArtist;
- if (hasArtist != null)
+ if (item is IHasArtist hasArtist)
{
dto.Artists = hasArtist.Artists;
@@ -1074,17 +1066,24 @@ namespace Emby.Server.Implementations.Dto
if (options.ContainsField(ItemFields.LocalTrailerCount))
{
+ int trailerCount = 0;
if (allExtras == null)
{
allExtras = item.GetExtras().ToArray();
}
- dto.LocalTrailerCount = allExtras.Count(i => i.ExtraType.HasValue && i.ExtraType.Value == ExtraType.Trailer);
+ trailerCount += allExtras.Count(i => i.ExtraType.HasValue && i.ExtraType.Value == ExtraType.Trailer);
+
+ if (item is IHasTrailers hasTrailers)
+ {
+ trailerCount += hasTrailers.GetTrailerCount();
+ }
+
+ dto.LocalTrailerCount = trailerCount;
}
// Add EpisodeInfo
- var episode = item as Episode;
- if (episode != null)
+ if (item is Episode episode)
{
dto.IndexNumberEnd = episode.IndexNumberEnd;
dto.SeriesName = episode.SeriesName;
@@ -1102,7 +1101,7 @@ namespace Emby.Server.Implementations.Dto
Series episodeSeries = null;
- //if (options.ContainsField(ItemFields.SeriesPrimaryImage))
+ if (options.ContainsField(ItemFields.SeriesPrimaryImage))
{
episodeSeries = episodeSeries ?? episode.Series;
if (episodeSeries != null)
@@ -1122,8 +1121,7 @@ namespace Emby.Server.Implementations.Dto
}
// Add SeriesInfo
- var series = item as Series;
- if (series != null)
+ if (item is Series series)
{
dto.AirDays = series.AirDays;
dto.AirTime = series.AirTime;
@@ -1131,8 +1129,7 @@ namespace Emby.Server.Implementations.Dto
}
// Add SeasonInfo
- var season = item as Season;
- if (season != null)
+ if (item is Season season)
{
dto.SeriesName = season.SeriesName;
dto.SeriesId = season.SeriesId;
@@ -1148,7 +1145,7 @@ namespace Emby.Server.Implementations.Dto
}
}
- //if (options.ContainsField(ItemFields.SeriesPrimaryImage))
+ if (options.ContainsField(ItemFields.SeriesPrimaryImage))
{
series = series ?? season.Series;
if (series != null)
@@ -1158,14 +1155,12 @@ namespace Emby.Server.Implementations.Dto
}
}
- var musicVideo = item as MusicVideo;
- if (musicVideo != null)
+ if (item is MusicVideo musicVideo)
{
SetMusicVideoProperties(dto, musicVideo);
}
- var book = item as Book;
- if (book != null)
+ if (item is Book book)
{
SetBookProperties(dto, book);
}
@@ -1205,8 +1200,7 @@ namespace Emby.Server.Implementations.Dto
}
}
- var photo = item as Photo;
- if (photo != null)
+ if (item is Photo photo)
{
SetPhotoProperties(dto, photo);
}
@@ -1225,8 +1219,7 @@ namespace Emby.Server.Implementations.Dto
private BaseItem GetImageDisplayParent(BaseItem currentItem, BaseItem originalItem)
{
- var musicAlbum = currentItem as MusicAlbum;
- if (musicAlbum != null)
+ if (currentItem is MusicAlbum musicAlbum)
{
var artist = musicAlbum.GetMusicArtist(new DtoOptions(false));
if (artist != null)
diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
index 276312a30..457448604 100644
--- a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Security;
@@ -89,7 +90,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
AccessToken = token
});
- var tokenInfo = result.Items.Length > 0 ? result.Items[0] : null;
+ var tokenInfo = result.Items.Count > 0 ? result.Items[0] : null;
if (tokenInfo != null)
{
@@ -190,17 +191,23 @@ namespace Emby.Server.Implementations.HttpServer.Security
/// <returns>Dictionary{System.StringSystem.String}.</returns>
private Dictionary<string, string> GetAuthorization(string authorizationHeader)
{
- if (authorizationHeader == null) return null;
+ if (authorizationHeader == null)
+ {
+ return null;
+ }
var parts = authorizationHeader.Split(new[] { ' ' }, 2);
// There should be at least to parts
- if (parts.Length != 2) return null;
+ if (parts.Length != 2)
+ {
+ return null;
+ }
var acceptedNames = new[] { "MediaBrowser", "Emby" };
// It has to be a digest request
- if (!acceptedNames.Contains(parts[0] ?? string.Empty, StringComparer.OrdinalIgnoreCase))
+ if (!acceptedNames.Contains(parts[0], StringComparer.OrdinalIgnoreCase))
{
return null;
}
@@ -232,7 +239,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
return value;
}
- return System.Net.WebUtility.HtmlEncode(value);
+ return WebUtility.HtmlEncode(value);
}
}
}
diff --git a/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs b/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs
index b07244fda..2282b8efb 100644
--- a/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs
+++ b/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs
@@ -37,7 +37,7 @@ namespace Emby.Server.Implementations.Library
throw new ArgumentNullException(nameof(resolvedUser));
}
- // As long as jellyfin supports passwordless users, we need this little block here to accomodate
+ // As long as jellyfin supports passwordless users, we need this little block here to accommodate
if (!HasPassword(resolvedUser) && string.IsNullOrEmpty(password))
{
return Task.FromResult(new ProviderAuthenticationResult
@@ -105,6 +105,7 @@ namespace Emby.Server.Implementations.Library
public Task ChangePassword(User user, string newPassword)
{
ConvertPasswordFormat(user);
+
// This is needed to support changing a no password user to a password user
if (string.IsNullOrEmpty(user.Password))
{
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 30ff855cc..36934f65f 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -1441,7 +1441,7 @@ namespace Emby.Server.Implementations.Library
return new QueryResult<BaseItem>
{
- Items = list.ToArray()
+ Items = list
};
}
@@ -1977,8 +1977,7 @@ namespace Emby.Server.Implementations.Library
public LibraryOptions GetLibraryOptions(BaseItem item)
{
- var collectionFolder = item as CollectionFolder;
- if (collectionFolder == null)
+ if (!(item is CollectionFolder collectionFolder))
{
collectionFolder = GetCollectionFolders(item)
.OfType<CollectionFolder>()
diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs
index 71f16ac3e..4d79cae13 100644
--- a/Emby.Server.Implementations/Library/UserViewManager.cs
+++ b/Emby.Server.Implementations/Library/UserViewManager.cs
@@ -224,7 +224,7 @@ namespace Emby.Server.Implementations.Library
return list;
}
- private List<BaseItem> GetItemsForLatestItems(User user, LatestItemsQuery request, DtoOptions options)
+ private IReadOnlyList<BaseItem> GetItemsForLatestItems(User user, LatestItemsQuery request, DtoOptions options)
{
var parentId = request.ParentId;
@@ -236,24 +236,22 @@ namespace Emby.Server.Implementations.Library
if (!parentId.Equals(Guid.Empty))
{
var parentItem = _libraryManager.GetItemById(parentId);
- var parentItemChannel = parentItem as Channel;
- if (parentItemChannel != null)
+ if (parentItem is Channel parentItemChannel)
{
- return _channelManager.GetLatestChannelItemsInternal(new InternalItemsQuery(user)
- {
- ChannelIds = new[] { parentId },
- IsPlayed = request.IsPlayed,
- StartIndex = request.StartIndex,
- Limit = request.Limit,
- IncludeItemTypes = request.IncludeItemTypes,
- EnableTotalRecordCount = false
-
-
- }, CancellationToken.None).Result.Items.ToList();
+ return _channelManager.GetLatestChannelItemsInternal(
+ new InternalItemsQuery(user)
+ {
+ ChannelIds = new[] { parentId },
+ IsPlayed = request.IsPlayed,
+ StartIndex = request.StartIndex,
+ Limit = request.Limit,
+ IncludeItemTypes = request.IncludeItemTypes,
+ EnableTotalRecordCount = false
+ },
+ CancellationToken.None).Result.Items;
}
- var parent = parentItem as Folder;
- if (parent != null)
+ if (parentItem is Folder parent)
{
parents.Add(parent);
}
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
index 9a9bae215..3cc0541e7 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
@@ -87,8 +87,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
CreateNoWindow = true,
UseShellExecute = false,
- // Must consume both stdout and stderr or deadlocks may occur
- //RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
@@ -120,9 +118,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
cancellationToken.Register(Stop);
- // MUST read both stdout and stderr asynchronously or a deadlock may occurr
- //process.BeginOutputReadLine();
-
onStarted();
// Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
@@ -138,11 +133,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
string videoArgs;
if (EncodeVideo(mediaSource))
{
- var maxBitrate = 25000000;
+ const int MaxBitrate = 25000000;
videoArgs = string.Format(
- "-codec:v:0 libx264 -force_key_frames \"expr:gte(t,n_forced*5)\" {0} -pix_fmt yuv420p -preset superfast -crf 23 -b:v {1} -maxrate {1} -bufsize ({1}*2) -vsync -1 -profile:v high -level 41",
- GetOutputSizeParam(),
- maxBitrate.ToString(CultureInfo.InvariantCulture));
+ CultureInfo.InvariantCulture,
+ "-codec:v:0 libx264 -force_key_frames \"expr:gte(t,n_forced*5)\" {0} -pix_fmt yuv420p -preset superfast -crf 23 -b:v {1} -maxrate {1} -bufsize ({1}*2) -vsync -1 -profile:v high -level 41",
+ GetOutputSizeParam(),
+ MaxBitrate);
}
else
{
@@ -151,18 +147,17 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
videoArgs += " -fflags +genpts";
- var durationParam = " -t " + _mediaEncoder.GetTimeParameter(duration.Ticks);
- durationParam = string.Empty;
-
var flags = new List<string>();
if (mediaSource.IgnoreDts)
{
flags.Add("+igndts");
}
+
if (mediaSource.IgnoreIndex)
{
flags.Add("+ignidx");
}
+
if (mediaSource.GenPtsInput)
{
flags.Add("+genpts");
@@ -172,11 +167,9 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
if (flags.Count > 0)
{
- inputModifier += " -fflags " + string.Join("", flags.ToArray());
+ inputModifier += " -fflags " + string.Join(string.Empty, flags);
}
- var videoStream = mediaSource.VideoStream;
-
if (mediaSource.ReadAtNativeFramerate)
{
inputModifier += " -re";
@@ -200,13 +193,14 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
var outputParam = string.Empty;
- var commandLineArgs = string.Format("-i \"{0}\"{5} {2} -map_metadata -1 -threads 0 {3}{4}{6} -y \"{1}\"",
+ var commandLineArgs = string.Format(
+ CultureInfo.InvariantCulture,
+ "-i \"{0}\" {2} -map_metadata -1 -threads 0 {3}{4}{5} -y \"{1}\"",
inputTempFile,
targetFile,
videoArgs,
GetAudioArgs(mediaSource),
subtitleArgs,
- durationParam,
outputParam);
return inputModifier + " " + commandLineArgs;
@@ -257,7 +251,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
_logger.LogInformation("Stopping ffmpeg recording process for {path}", _targetPath);
- //process.Kill();
_process.StandardInput.WriteLine("q");
}
catch (Exception ex)
@@ -309,44 +302,26 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
_hasExited = true;
- DisposeLogStream();
+ _logFileStream?.Dispose();
+ _logFileStream = null;
- try
- {
- var exitCode = process.ExitCode;
+ var exitCode = process.ExitCode;
- _logger.LogInformation("FFMpeg recording exited with code {ExitCode} for {path}", exitCode, _targetPath);
+ _logger.LogInformation("FFMpeg recording exited with code {ExitCode} for {Path}", exitCode, _targetPath);
- if (exitCode == 0)
- {
- _taskCompletionSource.TrySetResult(true);
- }
- else
- {
- _taskCompletionSource.TrySetException(new Exception(string.Format("Recording for {path} failed. Exit code {ExitCode}", _targetPath, exitCode)));
- }
- }
- catch
+ if (exitCode == 0)
{
- _logger.LogError("FFMpeg recording exited with an error for {path}.", _targetPath);
- _taskCompletionSource.TrySetException(new Exception(string.Format("Recording for {path} failed", _targetPath)));
+ _taskCompletionSource.TrySetResult(true);
}
- }
-
- private void DisposeLogStream()
- {
- if (_logFileStream != null)
+ else
{
- try
- {
- _logFileStream.Dispose();
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Error disposing recording log stream");
- }
-
- _logFileStream = null;
+ _taskCompletionSource.TrySetException(
+ new Exception(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Recording for {0} failed. Exit code {1}",
+ _targetPath,
+ exitCode)));
}
}
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index 1e5198dd6..ee975e19a 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -881,7 +881,7 @@ namespace Emby.Server.Implementations.LiveTv
}
var programList = _libraryManager.QueryItems(internalQuery).Items;
- var totalCount = programList.Length;
+ var totalCount = programList.Count;
var orderedPrograms = programList.Cast<LiveTvProgram>().OrderBy(i => i.StartDate.Date);
@@ -969,8 +969,8 @@ namespace Emby.Server.Implementations.LiveTv
var timers = new Dictionary<string, List<TimerInfo>>();
var seriesTimers = new Dictionary<string, List<SeriesTimerInfo>>();
- TimerInfo[] timerList = null;
- SeriesTimerInfo[] seriesTimerList = null;
+ IReadOnlyList<TimerInfo> timerList = null;
+ IReadOnlyList<SeriesTimerInfo> seriesTimerList = null;
foreach (var programTuple in programs)
{
@@ -1296,6 +1296,7 @@ namespace Emby.Server.Implementations.LiveTv
}
private const int MaxGuideDays = 14;
+
private double GetGuideDays()
{
var config = GetConfiguration();
@@ -1340,6 +1341,7 @@ namespace Emby.Server.Implementations.LiveTv
excludeItemTypes.Add(typeof(Movie).Name);
}
}
+
if (query.IsSeries.HasValue)
{
if (query.IsSeries.Value)
@@ -1351,10 +1353,12 @@ namespace Emby.Server.Implementations.LiveTv
excludeItemTypes.Add(typeof(Episode).Name);
}
}
+
if (query.IsSports ?? false)
{
genres.Add("Sports");
}
+
if (query.IsKids ?? false)
{
genres.Add("Kids");
@@ -1400,20 +1404,20 @@ namespace Emby.Server.Implementations.LiveTv
if (query.IsInProgress ?? false)
{
- //TODO Fix The co-variant conversion between Video[] and BaseItem[], this can generate runtime issues.
+ // TODO: Fix The co-variant conversion between Video[] and BaseItem[], this can generate runtime issues.
result.Items = result
.Items
.OfType<Video>()
.Where(i => !i.IsCompleteMedia)
.ToArray();
- result.TotalRecordCount = result.Items.Length;
+ result.TotalRecordCount = result.Items.Count;
}
return result;
}
- public Task AddInfoToProgramDto(List<Tuple<BaseItem, BaseItemDto>> tuples, ItemFields[] fields, User user = null)
+ public Task AddInfoToProgramDto(IReadOnlyCollection<(BaseItem, BaseItemDto)> tuples, ItemFields[] fields, User user = null)
{
var programTuples = new List<Tuple<BaseItemDto, string, string>>();
var hasChannelImage = fields.Contains(ItemFields.ChannelImage);
@@ -1877,7 +1881,7 @@ namespace Emby.Server.Implementations.LiveTv
return _libraryManager.GetItemById(internalChannelId);
}
- public void AddChannelInfo(List<Tuple<BaseItemDto, LiveTvChannel>> tuples, DtoOptions options, User user)
+ public void AddChannelInfo(IReadOnlyCollection<(BaseItemDto, LiveTvChannel)> tuples, DtoOptions options, User user)
{
var now = DateTime.UtcNow;
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index 85754ca8b..da98f3e58 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
@@ -584,9 +584,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
Logger,
Config.ApplicationPaths,
_appHost,
- _socketFactory,
_networkManager,
_streamHelper);
+
}
var enableHttpStream = true;
@@ -601,9 +601,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
httpUrl += "?transcode=" + profile;
}
+
mediaSource.Path = httpUrl;
- return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _streamHelper);
+ return new SharedHttpStream(
+ mediaSource,
+ info,
+ streamId,
+ FileSystem,
+ _httpClient,
+ Logger,
+ Config.ApplicationPaths,
+ _appHost,
+ _streamHelper);
}
return new HdHomerunUdpStream(
@@ -616,7 +626,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
Logger,
Config.ApplicationPaths,
_appHost,
- _socketFactory,
_networkManager,
_streamHelper);
}
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
index fbbab07f8..eafa86d54 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
@@ -1,5 +1,4 @@
using System;
-using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Net;
@@ -22,8 +21,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private const int RtpHeaderBytes = 12;
private readonly IServerApplicationHost _appHost;
- private readonly MediaBrowser.Model.Net.ISocketFactory _socketFactory;
-
private readonly IHdHomerunChannelCommands _channelCommands;
private readonly int _numTuners;
private readonly INetworkManager _networkManager;
@@ -38,13 +35,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
ILogger logger,
IServerApplicationPaths appPaths,
IServerApplicationHost appHost,
- MediaBrowser.Model.Net.ISocketFactory socketFactory,
INetworkManager networkManager,
IStreamHelper streamHelper)
: base(mediaSource, tunerHostInfo, fileSystem, logger, appPaths, streamHelper)
{
_appHost = appHost;
- _socketFactory = socketFactory;
_networkManager = networkManager;
OriginalStreamId = originalStreamId;
_channelCommands = channelCommands;
@@ -82,7 +77,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}
}
- var udpClient = _socketFactory.CreateUdpSocket(localPort);
+ var udpClient = new UdpClient(localPort, AddressFamily.InterNetwork);
var hdHomerunManager = new HdHomerunManager();
try
@@ -133,7 +128,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
await taskCompletionSource.Task.ConfigureAwait(false);
}
- private Task StartStreaming(MediaBrowser.Model.Net.ISocket udpClient, HdHomerunManager hdHomerunManager, IPAddress remoteAddress, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
+ private Task StartStreaming(UdpClient udpClient, HdHomerunManager hdHomerunManager, IPAddress remoteAddress, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
{
return Task.Run(async () =>
{
@@ -162,28 +157,37 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
});
}
- private async Task CopyTo(MediaBrowser.Model.Net.ISocket udpClient, string file, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
+ private async Task CopyTo(UdpClient udpClient, string file, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
{
- byte[] buffer = ArrayPool<byte>.Shared.Rent(StreamDefaults.DefaultCopyToBufferSize);
- try
+ var resolved = false;
+
+ using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read))
{
- using (var source = _socketFactory.CreateNetworkStream(udpClient, false))
- using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read))
+ while (true)
{
- var currentCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, new CancellationTokenSource(TimeSpan.FromSeconds(30)).Token).Token;
- int read;
- var resolved = false;
- while ((read = await source.ReadAsync(buffer, 0, buffer.Length, currentCancellationToken).ConfigureAwait(false)) != 0)
+ cancellationToken.ThrowIfCancellationRequested();
+ using (var timeOutSource = new CancellationTokenSource())
+ using (var linkedSource = CancellationTokenSource.CreateLinkedTokenSource(
+ cancellationToken,
+ timeOutSource.Token))
{
- cancellationToken.ThrowIfCancellationRequested();
+ var resTask = udpClient.ReceiveAsync();
+ if (await Task.WhenAny(resTask, Task.Delay(30000, linkedSource.Token)).ConfigureAwait(false) != resTask)
+ {
+ resTask.Dispose();
+ break;
+ }
- currentCancellationToken = cancellationToken;
+ // We don't want all these delay tasks to keep running
+ timeOutSource.Cancel();
+ var res = await resTask.ConfigureAwait(false);
+ var buffer = res.Buffer;
- read -= RtpHeaderBytes;
+ var read = buffer.Length - RtpHeaderBytes;
if (read > 0)
{
- await fileStream.WriteAsync(buffer, RtpHeaderBytes, read).ConfigureAwait(false);
+ fileStream.Write(buffer, RtpHeaderBytes, read);
}
if (!resolved)
@@ -195,10 +199,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}
}
}
- finally
- {
- ArrayPool<byte>.Shared.Return(buffer);
- }
}
}
}
diff --git a/Emby.Server.Implementations/Localization/Core/el.json b/Emby.Server.Implementations/Localization/Core/el.json
index db7ebb0c0..3589a4893 100644
--- a/Emby.Server.Implementations/Localization/Core/el.json
+++ b/Emby.Server.Implementations/Localization/Core/el.json
@@ -3,7 +3,7 @@
"AppDeviceValues": "Εφαρμογή: {0}, Συσκευή: {1}",
"Application": "Εφαρμογή",
"Artists": "Καλλιτέχνες",
- "AuthenticationSucceededWithUserName": "{0} επιτυχείς σύνδεση",
+ "AuthenticationSucceededWithUserName": "Ο χρήστης {0} επαληθεύτηκε με επιτυχία",
"Books": "Βιβλία",
"CameraImageUploadedFrom": "Μια νέα εικόνα κάμερας έχει αποσταλεί από {0}",
"Channels": "Κανάλια",
@@ -15,9 +15,9 @@
"Favorites": "Αγαπημένα",
"Folders": "Φάκελοι",
"Genres": "Είδη",
- "HeaderAlbumArtists": "Άλμπουμ Καλλιτεχνών",
+ "HeaderAlbumArtists": "Καλλιτέχνες του Άλμπουμ",
"HeaderCameraUploads": "Μεταφορτώσεις Κάμερας",
- "HeaderContinueWatching": "Συνεχίστε να παρακολουθείτε",
+ "HeaderContinueWatching": "Συνεχίστε την παρακολούθηση",
"HeaderFavoriteAlbums": "Αγαπημένα Άλμπουμ",
"HeaderFavoriteArtists": "Αγαπημένοι Καλλιτέχνες",
"HeaderFavoriteEpisodes": "Αγαπημένα Επεισόδια",
@@ -27,7 +27,7 @@
"HeaderNextUp": "Επόμενο",
"HeaderRecordingGroups": "Γκρουπ Εγγραφών",
"HomeVideos": "Προσωπικά βίντεο",
- "Inherit": "Inherit",
+ "Inherit": "Κληρονόμηση",
"ItemAddedWithName": "{0} προστέθηκε στη βιβλιοθήκη",
"ItemRemovedWithName": "{0} διαγράφηκε από τη βιβλιοθήκη",
"LabelIpAddressValue": "Διεύθυνση IP: {0}",
@@ -92,6 +92,6 @@
"UserStartedPlayingItemWithValues": "{0} παίζει {1} σε {2}",
"UserStoppedPlayingItemWithValues": "{0} τελείωσε να παίζει {1} σε {2}",
"ValueHasBeenAddedToLibrary": "{0} προστέθηκαν στη βιβλιοθήκη πολυμέσων σας",
- "ValueSpecialEpisodeName": "Special - {0}",
+ "ValueSpecialEpisodeName": "Σπέσιαλ - {0}",
"VersionNumber": "Έκδοση {0}"
}
diff --git a/Emby.Server.Implementations/Localization/Core/es.json b/Emby.Server.Implementations/Localization/Core/es.json
index f03184d5b..c78794967 100644
--- a/Emby.Server.Implementations/Localization/Core/es.json
+++ b/Emby.Server.Implementations/Localization/Core/es.json
@@ -23,7 +23,7 @@
"HeaderFavoriteEpisodes": "Episodios favoritos",
"HeaderFavoriteShows": "Series favoritas",
"HeaderFavoriteSongs": "Canciones favoritas",
- "HeaderLiveTV": "TV en directo",
+ "HeaderLiveTV": "Televisión en directo",
"HeaderNextUp": "Siguiendo",
"HeaderRecordingGroups": "Grupos de grabación",
"HomeVideos": "Vídeos caseros",
@@ -79,7 +79,7 @@
"SubtitlesDownloadedForItem": "Descargar subtítulos para {0}",
"Sync": "Sincronizar",
"System": "Sistema",
- "TvShows": "Series de TV",
+ "TvShows": "Programas de televisión",
"User": "Usuario",
"UserCreatedWithName": "El usuario {0} ha sido creado",
"UserDeletedWithName": "El usuario {0} ha sido borrado",
diff --git a/Emby.Server.Implementations/Localization/Core/fr.json b/Emby.Server.Implementations/Localization/Core/fr.json
index e434b7605..6bfedb712 100644
--- a/Emby.Server.Implementations/Localization/Core/fr.json
+++ b/Emby.Server.Implementations/Localization/Core/fr.json
@@ -17,14 +17,14 @@
"Genres": "Genres",
"HeaderAlbumArtists": "Artistes de l'album",
"HeaderCameraUploads": "Photos transférées",
- "HeaderContinueWatching": "Continuer à regarder",
+ "HeaderContinueWatching": "Reprendre",
"HeaderFavoriteAlbums": "Albums favoris",
"HeaderFavoriteArtists": "Artistes favoris",
"HeaderFavoriteEpisodes": "Épisodes favoris",
"HeaderFavoriteShows": "Séries favorites",
"HeaderFavoriteSongs": "Chansons favorites",
"HeaderLiveTV": "TV en direct",
- "HeaderNextUp": "En Cours",
+ "HeaderNextUp": "À suivre",
"HeaderRecordingGroups": "Groupes d'enregistrements",
"HomeVideos": "Vidéos personnelles",
"Inherit": "Hériter",
diff --git a/Emby.Server.Implementations/Localization/Core/nb.json b/Emby.Server.Implementations/Localization/Core/nb.json
index dbda794ad..daa3f5880 100644
--- a/Emby.Server.Implementations/Localization/Core/nb.json
+++ b/Emby.Server.Implementations/Localization/Core/nb.json
@@ -1,11 +1,11 @@
{
"Albums": "Album",
- "AppDeviceValues": "App:{0}, Enhet {1}",
+ "AppDeviceValues": "App:{0}, Enhet: {1}",
"Application": "Applikasjon",
"Artists": "Artister",
"AuthenticationSucceededWithUserName": "{0} vellykkede autentisert",
"Books": "Bøker",
- "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}",
+ "CameraImageUploadedFrom": "Et nytt kamerabilde er lastet opp fra {0}",
"Channels": "Kanaler",
"ChapterNameValue": "Kapittel {0}",
"Collections": "Samlinger",
diff --git a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs
index 52d07d784..840aca7a6 100644
--- a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs
+++ b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs
@@ -139,7 +139,7 @@ namespace Emby.Server.Implementations.MediaEncoder
var protocol = MediaProtocol.File;
- var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, Array.Empty<string>());
+ var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, null, Array.Empty<string>());
Directory.CreateDirectory(Path.GetDirectoryName(path));
diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs
index cb53ce50c..0870db003 100644
--- a/Emby.Server.Implementations/Net/SocketFactory.cs
+++ b/Emby.Server.Implementations/Net/SocketFactory.cs
@@ -19,7 +19,8 @@ namespace Emby.Server.Implementations.Net
throw new ArgumentException("localPort cannot be less than zero.", nameof(localPort));
}
- var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp);
+ var retVal = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
+
try
{
retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteTranscodingTempTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteTranscodeFileTask.cs
index ad9b56535..c343a7d48 100644
--- a/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteTranscodingTempTask.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteTranscodeFileTask.cs
@@ -13,23 +13,22 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
/// <summary>
/// Deletes all transcoding temp files
/// </summary>
- public class DeleteTranscodingTempTask : IScheduledTask, IConfigurableScheduledTask
+ public class DeleteTranscodeFileTask : IScheduledTask, IConfigurableScheduledTask
{
/// <summary>
/// Gets or sets the application paths.
/// </summary>
/// <value>The application paths.</value>
- protected ServerApplicationPaths ApplicationPaths { get; set; }
-
+ private ServerApplicationPaths ApplicationPaths { get; set; }
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
/// <summary>
- /// Initializes a new instance of the <see cref="DeleteTranscodingTempTask" /> class.
+ /// Initializes a new instance of the <see cref="DeleteTranscodeFileTask" /> class.
/// </summary>
- public DeleteTranscodingTempTask(ServerApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem)
+ public DeleteTranscodeFileTask(ServerApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem)
{
ApplicationPaths = appPaths;
_logger = logger;
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs
index 1a3d85ad7..3e6d251c9 100644
--- a/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs
@@ -10,7 +10,7 @@ using MediaBrowser.Model.Tasks;
namespace Emby.Server.Implementations.ScheduledTasks
{
/// <summary>
- /// Class RefreshMediaLibraryTask
+ /// Class RefreshMediaLibraryTask.
/// </summary>
public class RefreshMediaLibraryTask : IScheduledTask
{
@@ -31,15 +31,14 @@ namespace Emby.Server.Implementations.ScheduledTasks
}
/// <summary>
- /// Creates the triggers that define when the task will run
+ /// Creates the triggers that define when the task will run.
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
- return new[] {
-
- // Every so often
- new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(12).Ticks}
+ yield return new TaskTriggerInfo
+ {
+ Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(12).Ticks
};
}
@@ -60,7 +59,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
public string Name => "Scan media library";
- public string Description => "Scans your media library and refreshes metatata based on configuration.";
+ public string Description => "Scans your media library for new files and refreshes metadata.";
public string Category => "Library";
diff --git a/Emby.Server.Implementations/Services/ResponseHelper.cs b/Emby.Server.Implementations/Services/ResponseHelper.cs
index ca2b22fe0..a566b18dd 100644
--- a/Emby.Server.Implementations/Services/ResponseHelper.cs
+++ b/Emby.Server.Implementations/Services/ResponseHelper.cs
@@ -6,8 +6,8 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Emby.Server.Implementations.HttpServer;
-using Microsoft.AspNetCore.Http;
using MediaBrowser.Model.Services;
+using Microsoft.AspNetCore.Http;
namespace Emby.Server.Implementations.Services
{
diff --git a/Emby.Server.Implementations/Services/ServiceExec.cs b/Emby.Server.Implementations/Services/ServiceExec.cs
index 9124b9c14..9f5f97028 100644
--- a/Emby.Server.Implementations/Services/ServiceExec.cs
+++ b/Emby.Server.Implementations/Services/ServiceExec.cs
@@ -87,8 +87,7 @@ namespace Emby.Server.Implementations.Services
var response = actionContext.ServiceAction(instance, requestDto);
- var taskResponse = response as Task;
- if (taskResponse != null)
+ if (response is Task taskResponse)
{
return GetTaskResult(taskResponse);
}
@@ -104,8 +103,7 @@ namespace Emby.Server.Implementations.Services
{
try
{
- var taskObject = task as Task<object>;
- if (taskObject != null)
+ if (task is Task<object> taskObject)
{
return await taskObject.ConfigureAwait(false);
}
@@ -136,7 +134,7 @@ namespace Emby.Server.Implementations.Services
}
catch (TypeAccessException)
{
- return null; //return null for void Task's
+ return null; // return null for void Task's
}
}
@@ -155,29 +153,22 @@ namespace Emby.Server.Implementations.Services
Id = ServiceMethod.Key(serviceType, actionName, requestType.GetMethodName())
};
- try
- {
- actionCtx.ServiceAction = CreateExecFn(serviceType, requestType, mi);
- }
- catch
- {
- //Potential problems with MONO, using reflection for fallback
- actionCtx.ServiceAction = (service, request) =>
- mi.Invoke(service, new[] { request });
- }
+ actionCtx.ServiceAction = CreateExecFn(serviceType, requestType, mi);
var reqFilters = new List<IHasRequestFilter>();
foreach (var attr in mi.GetCustomAttributes(true))
{
- var hasReqFilter = attr as IHasRequestFilter;
-
- if (hasReqFilter != null)
+ if (attr is IHasRequestFilter hasReqFilter)
+ {
reqFilters.Add(hasReqFilter);
+ }
}
if (reqFilters.Count > 0)
+ {
actionCtx.RequestFilters = reqFilters.OrderBy(i => i.Priority).ToArray();
+ }
actions.Add(actionCtx);
}
@@ -198,15 +189,19 @@ namespace Emby.Server.Implementations.Services
if (mi.ReturnType != typeof(void))
{
- var executeFunc = Expression.Lambda<ActionInvokerFn>
- (callExecute, serviceParam, requestDtoParam).Compile();
+ var executeFunc = Expression.Lambda<ActionInvokerFn>(
+ callExecute,
+ serviceParam,
+ requestDtoParam).Compile();
return executeFunc;
}
else
{
- var executeFunc = Expression.Lambda<VoidActionInvokerFn>
- (callExecute, serviceParam, requestDtoParam).Compile();
+ var executeFunc = Expression.Lambda<VoidActionInvokerFn>(
+ callExecute,
+ serviceParam,
+ requestDtoParam).Compile();
return (service, request) =>
{
diff --git a/Emby.Server.Implementations/Services/UrlExtensions.cs b/Emby.Server.Implementations/Services/UrlExtensions.cs
index 8899fbfa3..5d4407f3b 100644
--- a/Emby.Server.Implementations/Services/UrlExtensions.cs
+++ b/Emby.Server.Implementations/Services/UrlExtensions.cs
@@ -12,10 +12,10 @@ namespace Emby.Server.Implementations.Services
{
public static string GetMethodName(this Type type)
{
- var typeName = type.FullName != null //can be null, e.g. generic types
- ? LeftPart(type.FullName, "[[") //Generic Fullname
- .Replace(type.Namespace + ".", "") //Trim Namespaces
- .Replace("+", ".") //Convert nested into normal type
+ var typeName = type.FullName != null // can be null, e.g. generic types
+ ? LeftPart(type.FullName, "[[") // Generic Fullname
+ .Replace(type.Namespace + ".", string.Empty) // Trim Namespaces
+ .Replace("+", ".") // Convert nested into normal type
: type.Name;
return type.IsGenericParameter ? "'" + typeName : typeName;
@@ -23,7 +23,11 @@ namespace Emby.Server.Implementations.Services
private static string LeftPart(string strVal, string needle)
{
- if (strVal == null) return null;
+ if (strVal == null)
+ {
+ return null;
+ }
+
var pos = strVal.IndexOf(needle, StringComparison.OrdinalIgnoreCase);
return pos == -1
? strVal
diff --git a/Emby.Server.Implementations/Sorting/ArtistComparer.cs b/Emby.Server.Implementations/Sorting/ArtistComparer.cs
index 9d5befc9a..756d3c5b6 100644
--- a/Emby.Server.Implementations/Sorting/ArtistComparer.cs
+++ b/Emby.Server.Implementations/Sorting/ArtistComparer.cs
@@ -7,16 +7,14 @@ using MediaBrowser.Model.Querying;
namespace Emby.Server.Implementations.Sorting
{
/// <summary>
- /// Class ArtistComparer
+ /// Class ArtistComparer.
/// </summary>
public class ArtistComparer : IBaseItemComparer
{
- /// <summary>
- /// Compares the specified x.
- /// </summary>
- /// <param name="x">The x.</param>
- /// <param name="y">The y.</param>
- /// <returns>System.Int32.</returns>
+ /// <inheritdoc />
+ public string Name => ItemSortBy.Artist;
+
+ /// <inheritdoc />
public int Compare(BaseItem x, BaseItem y)
{
return string.Compare(GetValue(x), GetValue(y), StringComparison.CurrentCultureIgnoreCase);
@@ -29,20 +27,12 @@ namespace Emby.Server.Implementations.Sorting
/// <returns>System.String.</returns>
private static string GetValue(BaseItem x)
{
- var audio = x as Audio;
-
- if (audio == null)
+ if (!(x is Audio audio))
{
return string.Empty;
}
- return audio.Artists.Length == 0 ? null : audio.Artists[0];
+ return audio.Artists.Count == 0 ? null : audio.Artists[0];
}
-
- /// <summary>
- /// Gets the name.
- /// </summary>
- /// <value>The name.</value>
- public string Name => ItemSortBy.Artist;
}
}