diff options
Diffstat (limited to 'Emby.Server.Implementations')
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; } } |
