diff options
Diffstat (limited to 'Emby.Server.Implementations')
15 files changed, 168 insertions, 171 deletions
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index aed0c14a2..67bc0cd2b 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -764,9 +764,8 @@ namespace Emby.Server.Implementations LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager); serviceCollection.AddSingleton(LibraryManager); - // TODO wtaylor: investigate use of second music manager var musicManager = new MusicManager(LibraryManager); - serviceCollection.AddSingleton<IMusicManager>(new MusicManager(LibraryManager)); + serviceCollection.AddSingleton<IMusicManager>(musicManager); LibraryMonitor = new LibraryMonitor(LoggerFactory, LibraryManager, ServerConfigurationManager, FileSystemManager); serviceCollection.AddSingleton(LibraryMonitor); diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs index 2b8a5bdc5..1d7c11989 100644 --- a/Emby.Server.Implementations/Collections/CollectionManager.cs +++ b/Emby.Server.Implementations/Collections/CollectionManager.cs @@ -31,11 +31,7 @@ namespace Emby.Server.Implementations.Collections private readonly ILogger _logger; private readonly IProviderManager _providerManager; private readonly ILocalizationManager _localizationManager; - private IApplicationPaths _appPaths; - - public event EventHandler<CollectionCreatedEventArgs> CollectionCreated; - public event EventHandler<CollectionModifiedEventArgs> ItemsAddedToCollection; - public event EventHandler<CollectionModifiedEventArgs> ItemsRemovedFromCollection; + private readonly IApplicationPaths _appPaths; public CollectionManager( ILibraryManager libraryManager, @@ -55,6 +51,10 @@ namespace Emby.Server.Implementations.Collections _appPaths = appPaths; } + public event EventHandler<CollectionCreatedEventArgs> CollectionCreated; + public event EventHandler<CollectionModifiedEventArgs> ItemsAddedToCollection; + public event EventHandler<CollectionModifiedEventArgs> ItemsRemovedFromCollection; + private IEnumerable<Folder> FindFolders(string path) { return _libraryManager @@ -341,11 +341,11 @@ namespace Emby.Server.Implementations.Collections } } - public class CollectionManagerEntryPoint : IServerEntryPoint + public sealed class CollectionManagerEntryPoint : IServerEntryPoint { private readonly CollectionManager _collectionManager; private readonly IServerConfigurationManager _config; - private ILogger _logger; + private readonly ILogger _logger; public CollectionManagerEntryPoint(ICollectionManager collectionManager, IServerConfigurationManager config, ILogger logger) { @@ -354,6 +354,7 @@ namespace Emby.Server.Implementations.Collections _logger = logger; } + /// <inheritdoc /> public async Task RunAsync() { if (!_config.Configuration.CollectionsUpgraded && _config.Configuration.IsStartupWizardCompleted) @@ -377,39 +378,10 @@ namespace Emby.Server.Implementations.Collections } } - #region IDisposable Support - private bool disposedValue = false; // To detect redundant calls - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - // TODO: dispose managed state (managed objects). - } - - // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. - // TODO: set large fields to null. - - disposedValue = true; - } - } - - // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources. - // ~CollectionManagerEntryPoint() { - // // Do not change this code. Put cleanup code in Dispose(bool disposing) above. - // Dispose(false); - // } - - // This code added to correctly implement the disposable pattern. + /// <inheritdoc /> public void Dispose() { - // Do not change this code. Put cleanup code in Dispose(bool disposing) above. - Dispose(true); - // TODO: uncomment the following line if the finalizer is overridden above. - // GC.SuppressFinalize(this); + // Nothing to dispose } - #endregion } } diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 69cfcb67b..ef1fe07c1 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -4593,10 +4593,20 @@ namespace Emby.Server.Implementations.Data if (query.ExcludeInheritedTags.Length > 0) { - var tagValues = query.ExcludeInheritedTags.Select(i => "'" + GetCleanValue(i) + "'"); - var tagValuesList = string.Join(",", tagValues); - - whereClauses.Add("((select CleanValue from itemvalues where ItemId=Guid and Type=6 and cleanvalue in (" + tagValuesList + ")) is null)"); + var paramName = "@ExcludeInheritedTags"; + if (statement == null) + { + int index = 0; + string excludedTags = string.Join(",", query.ExcludeInheritedTags.Select(t => paramName + index++)); + whereClauses.Add("((select CleanValue from itemvalues where ItemId=Guid and Type=6 and cleanvalue in (" + excludedTags + ")) is null)"); + } + else + { + for (int index = 0; index < query.ExcludeInheritedTags.Length; index++) + { + statement.TryBind(paramName + index, GetCleanValue(query.ExcludeInheritedTags[index])); + } + } } if (query.SeriesStatuses.Length > 0) diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 115e07d57..7ae6f38a1 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -49,7 +49,7 @@ <GenerateDocumentationFile>true</GenerateDocumentationFile> </PropertyGroup> - <!-- Code analysers--> + <!-- Code Analyzers--> <ItemGroup Condition=" '$(Configuration)' == 'Debug' "> <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.7" /> <PackageReference Include="SerilogAnalyzer" Version="0.15.0" /> diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 6942088fe..cee51479e 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -392,9 +392,9 @@ namespace Emby.Server.Implementations.Library // Add this flag to GetDeletePaths if required in the future var isRequiredForDelete = true; - foreach (var fileSystemInfo in item.GetDeletePaths().ToList()) + foreach (var fileSystemInfo in item.GetDeletePaths()) { - if (File.Exists(fileSystemInfo.FullName)) + if (Directory.Exists(fileSystemInfo.FullName) || File.Exists(fileSystemInfo.FullName)) { try { diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index bfb3ddae2..1b9c317d8 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -397,7 +397,7 @@ namespace Emby.Server.Implementations.Library if (providers.Length == 0) { // Assign the user to the InvalidAuthProvider since no configured auth provider was valid/found - _logger.LogWarning("User {UserName} was found with invalid/missing Authentication Provider {AuthenticationProviderId}. Assigning user to InvalidAuthProvider until this is corrected", user.Name, user.Policy.AuthenticationProviderId); + _logger.LogWarning("User {UserName} was found with invalid/missing Authentication Provider {AuthenticationProviderId}. Assigning user to InvalidAuthProvider until this is corrected", user?.Name, user?.Policy.AuthenticationProviderId); providers = new IAuthenticationProvider[] { _invalidAuthProvider }; } @@ -477,7 +477,7 @@ namespace Emby.Server.Implementations.Library if (!success && _networkManager.IsInLocalNetwork(remoteEndPoint) - && user.Configuration.EnableLocalPassword + && user?.Configuration.EnableLocalPassword == true && !string.IsNullOrEmpty(user.EasyPassword)) { // Check easy password diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs index 8dee7046e..84e8c31f9 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Net.Http; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Net; @@ -74,7 +75,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV DecompressionMethod = CompressionMethod.None }; - using (var response = await _httpClient.SendAsync(httpRequestOptions, "GET").ConfigureAwait(false)) + using (var response = await _httpClient.SendAsync(httpRequestOptions, HttpMethod.Get).ConfigureAwait(false)) { _logger.LogInformation("Opened recording stream from tuner provider"); diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 838ac97d7..1dd794da0 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -5,6 +5,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Net; +using System.Net.Http; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common; @@ -12,7 +13,6 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Extensions; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Net; using MediaBrowser.Model.Serialization; @@ -663,7 +663,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings try { - return await _httpClient.SendAsync(options, "GET").ConfigureAwait(false); + return await _httpClient.SendAsync(options, HttpMethod.Get).ConfigureAwait(false); } catch (HttpException ex) { @@ -738,7 +738,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings httpOptions.RequestHeaders["token"] = token; - using (await _httpClient.SendAsync(httpOptions, "PUT").ConfigureAwait(false)) + using (await _httpClient.SendAsync(httpOptions, HttpMethod.Put).ConfigureAwait(false)) { } } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs index 758495362..0d94f4b32 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Net.Http; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; @@ -64,7 +65,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts httpRequestOptions.RequestHeaders[header.Key] = header.Value; } - var response = await _httpClient.SendAsync(httpRequestOptions, "GET").ConfigureAwait(false); + var response = await _httpClient.SendAsync(httpRequestOptions, HttpMethod.Get).ConfigureAwait(false); var extension = "ts"; var requiresRemux = false; diff --git a/Emby.Server.Implementations/Localization/Core/lt-LT.json b/Emby.Server.Implementations/Localization/Core/lt-LT.json index e2f3ba3dc..e8e1b7740 100644 --- a/Emby.Server.Implementations/Localization/Core/lt-LT.json +++ b/Emby.Server.Implementations/Localization/Core/lt-LT.json @@ -1,97 +1,97 @@ { "Albums": "Albumai", - "AppDeviceValues": "App: {0}, Device: {1}", - "Application": "Application", + "AppDeviceValues": "Programa: {0}, Įrenginys: {1}", + "Application": "Programa", "Artists": "Atlikėjai", - "AuthenticationSucceededWithUserName": "{0} successfully authenticated", + "AuthenticationSucceededWithUserName": "{0} sėkmingai autentifikuota", "Books": "Knygos", - "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}", + "CameraImageUploadedFrom": "Nauja nuotrauka įkelta iš kameros {0}", "Channels": "Kanalai", - "ChapterNameValue": "Chapter {0}", + "ChapterNameValue": "Scena{0}", "Collections": "Kolekcijos", - "DeviceOfflineWithName": "{0} has disconnected", - "DeviceOnlineWithName": "{0} is connected", - "FailedLoginAttemptWithUserName": "Failed login attempt from {0}", + "DeviceOfflineWithName": "{0} buvo atjungtas", + "DeviceOnlineWithName": "{0} prisijungęs", + "FailedLoginAttemptWithUserName": "{0} - nesėkmingas bandymas prisijungti", "Favorites": "Mėgstami", "Folders": "Katalogai", "Genres": "Žanrai", "HeaderAlbumArtists": "Albumo atlikėjai", - "HeaderCameraUploads": "Camera Uploads", + "HeaderCameraUploads": "Kameros", "HeaderContinueWatching": "Žiūrėti toliau", - "HeaderFavoriteAlbums": "Favorite Albums", - "HeaderFavoriteArtists": "Favorite Artists", - "HeaderFavoriteEpisodes": "Favorite Episodes", - "HeaderFavoriteShows": "Favorite Shows", - "HeaderFavoriteSongs": "Favorite Songs", - "HeaderLiveTV": "Live TV", - "HeaderNextUp": "Next Up", - "HeaderRecordingGroups": "Recording Groups", - "HomeVideos": "Home videos", - "Inherit": "Inherit", - "ItemAddedWithName": "{0} was added to the library", - "ItemRemovedWithName": "{0} was removed from the library", - "LabelIpAddressValue": "Ip address: {0}", - "LabelRunningTimeValue": "Running time: {0}", - "Latest": "Latest", - "MessageApplicationUpdated": "Jellyfin Server has been updated", - "MessageApplicationUpdatedTo": "Jellyfin Server has been updated to {0}", - "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated", - "MessageServerConfigurationUpdated": "Server configuration has been updated", + "HeaderFavoriteAlbums": "Mėgstami Albumai", + "HeaderFavoriteArtists": "Mėgstami Atlikėjai", + "HeaderFavoriteEpisodes": "Mėgstamiausios serijos", + "HeaderFavoriteShows": "Mėgstamiausi serialai", + "HeaderFavoriteSongs": "Mėgstamos dainos", + "HeaderLiveTV": "TV gyvai", + "HeaderNextUp": "Toliau eilėje", + "HeaderRecordingGroups": "Įrašų grupės", + "HomeVideos": "Namų vaizdo įrašai", + "Inherit": "Paveldėti", + "ItemAddedWithName": "{0} - buvo įkeltas į mediateką", + "ItemRemovedWithName": "{0} - buvo pašalinta iš mediatekos", + "LabelIpAddressValue": "IP adresas: {0}", + "LabelRunningTimeValue": "Trukmė: {0}", + "Latest": "Naujausi", + "MessageApplicationUpdated": "\"Jellyfin Server\" atnaujintas", + "MessageApplicationUpdatedTo": "\"Jellyfin Server\" buvo atnaujinta iki {0}", + "MessageNamedServerConfigurationUpdatedWithValue": "Serverio nustatymai (skyrius {0}) buvo atnaujinti", + "MessageServerConfigurationUpdated": "Serverio nustatymai buvo atnaujinti", "MixedContent": "Mixed content", "Movies": "Filmai", - "Music": "Music", - "MusicVideos": "Music videos", - "NameInstallFailed": "{0} installation failed", - "NameSeasonNumber": "Season {0}", - "NameSeasonUnknown": "Season Unknown", - "NewVersionIsAvailable": "A new version of Jellyfin Server is available for download.", - "NotificationOptionApplicationUpdateAvailable": "Application update available", - "NotificationOptionApplicationUpdateInstalled": "Application update installed", - "NotificationOptionAudioPlayback": "Audio playback started", - "NotificationOptionAudioPlaybackStopped": "Audio playback stopped", - "NotificationOptionCameraImageUploaded": "Camera image uploaded", - "NotificationOptionInstallationFailed": "Installation failure", - "NotificationOptionNewLibraryContent": "New content added", - "NotificationOptionPluginError": "Plugin failure", - "NotificationOptionPluginInstalled": "Plugin installed", - "NotificationOptionPluginUninstalled": "Plugin uninstalled", - "NotificationOptionPluginUpdateInstalled": "Plugin update installed", - "NotificationOptionServerRestartRequired": "Server restart required", - "NotificationOptionTaskFailed": "Scheduled task failure", - "NotificationOptionUserLockedOut": "User locked out", - "NotificationOptionVideoPlayback": "Video playback started", - "NotificationOptionVideoPlaybackStopped": "Video playback stopped", - "Photos": "Photos", - "Playlists": "Playlists", + "Music": "Muzika", + "MusicVideos": "Muzikiniai klipai", + "NameInstallFailed": "{0} diegimo klaida", + "NameSeasonNumber": "Sezonas {0}", + "NameSeasonUnknown": "Sezonas neatpažintas", + "NewVersionIsAvailable": "Nauja \"Jellyfin Server\" versija yra prieinama atsisiuntimui.", + "NotificationOptionApplicationUpdateAvailable": "Galimi programos atnaujinimai", + "NotificationOptionApplicationUpdateInstalled": "Programos atnaujinimai įdiegti", + "NotificationOptionAudioPlayback": "Garso atkūrimas pradėtas", + "NotificationOptionAudioPlaybackStopped": "Garso atkūrimas sustabdytas", + "NotificationOptionCameraImageUploaded": "Kameros vaizdai įkelti", + "NotificationOptionInstallationFailed": "Diegimo klaida", + "NotificationOptionNewLibraryContent": "Naujas turinys įkeltas", + "NotificationOptionPluginError": "Įskiepio klaida", + "NotificationOptionPluginInstalled": "Įskiepis įdiegtas", + "NotificationOptionPluginUninstalled": "Įskiepis pašalintas", + "NotificationOptionPluginUpdateInstalled": "Įskiepio atnaujinimas įdiegtas", + "NotificationOptionServerRestartRequired": "Reikalingas serverio perleidimas", + "NotificationOptionTaskFailed": "Suplanuotos užduoties klaida", + "NotificationOptionUserLockedOut": "Vartotojas užblokuotas", + "NotificationOptionVideoPlayback": "Vaizdo įrašo atkūrimas pradėtas", + "NotificationOptionVideoPlaybackStopped": "Vaizdo įrašo atkūrimas sustabdytas", + "Photos": "Nuotraukos", + "Playlists": "Grojaraštis", "Plugin": "Plugin", - "PluginInstalledWithName": "{0} was installed", - "PluginUninstalledWithName": "{0} was uninstalled", - "PluginUpdatedWithName": "{0} was updated", + "PluginInstalledWithName": "{0} buvo įdiegtas", + "PluginUninstalledWithName": "{0} buvo pašalintas", + "PluginUpdatedWithName": "{0} buvo atnaujintas", "ProviderValue": "Provider: {0}", - "ScheduledTaskFailedWithName": "{0} failed", - "ScheduledTaskStartedWithName": "{0} started", - "ServerNameNeedsToBeRestarted": "{0} needs to be restarted", - "Shows": "Shows", - "Songs": "Songs", - "StartupEmbyServerIsLoading": "Jellyfin Server is loading. Please try again shortly.", + "ScheduledTaskFailedWithName": "{0} klaida", + "ScheduledTaskStartedWithName": "{0} paleista", + "ServerNameNeedsToBeRestarted": "{0} reikia iš naujo paleisti", + "Shows": "Laidos", + "Songs": "Kūriniai", + "StartupEmbyServerIsLoading": "Jellyfin Server kraunasi. Netrukus pabandykite dar kartą.", "SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}", - "SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}", - "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}", + "SubtitleDownloadFailureFromForItem": "{1} subtitrai buvo nesėkmingai parsiųsti iš {0}", + "SubtitlesDownloadedForItem": "{0} subtitrai parsiųsti", "Sync": "Sinchronizuoti", "System": "System", - "TvShows": "TV Shows", + "TvShows": "TV Serialai", "User": "User", - "UserCreatedWithName": "User {0} has been created", - "UserDeletedWithName": "User {0} has been deleted", - "UserDownloadingItemWithValues": "{0} is downloading {1}", - "UserLockedOutWithName": "User {0} has been locked out", - "UserOfflineFromDevice": "{0} has disconnected from {1}", - "UserOnlineFromDevice": "{0} is online from {1}", - "UserPasswordChangedWithName": "Password has been changed for user {0}", - "UserPolicyUpdatedWithName": "User policy has been updated for {0}", - "UserStartedPlayingItemWithValues": "{0} is playing {1} on {2}", - "UserStoppedPlayingItemWithValues": "{0} has finished playing {1} on {2}", - "ValueHasBeenAddedToLibrary": "{0} has been added to your media library", + "UserCreatedWithName": "Vartotojas {0} buvo sukurtas", + "UserDeletedWithName": "Vartotojas {0} ištrintas", + "UserDownloadingItemWithValues": "{0} siunčiasi {1}", + "UserLockedOutWithName": "Vartotojas {0} užblokuotas", + "UserOfflineFromDevice": "{0} buvo atjungtas nuo {1}", + "UserOnlineFromDevice": "{0} prisijungęs iš {1}", + "UserPasswordChangedWithName": "Slaptažodis pakeistas vartotojui {0}", + "UserPolicyUpdatedWithName": "Vartotojo {0} teisės buvo pakeistos", + "UserStartedPlayingItemWithValues": "{0} leidžia {1} į {2}", + "UserStoppedPlayingItemWithValues": "{0} baigė leisti {1} į {2}", + "ValueHasBeenAddedToLibrary": "{0} pridėtas į mediateką", "ValueSpecialEpisodeName": "Ypatinga - {0}", "VersionNumber": "Version {0}" } diff --git a/Emby.Server.Implementations/Localization/Core/nb.json b/Emby.Server.Implementations/Localization/Core/nb.json index 48216f71c..7d4b2bdac 100644 --- a/Emby.Server.Implementations/Localization/Core/nb.json +++ b/Emby.Server.Implementations/Localization/Core/nb.json @@ -17,7 +17,7 @@ "Genres": "Sjangre", "HeaderAlbumArtists": "Albumartister", "HeaderCameraUploads": "Kameraopplastinger", - "HeaderContinueWatching": "Forsett å se på", + "HeaderContinueWatching": "Fortsett å se", "HeaderFavoriteAlbums": "Favorittalbum", "HeaderFavoriteArtists": "Favorittartister", "HeaderFavoriteEpisodes": "Favorittepisoder", @@ -25,18 +25,18 @@ "HeaderFavoriteSongs": "Favorittsanger", "HeaderLiveTV": "Direkte-TV", "HeaderNextUp": "Neste", - "HeaderRecordingGroups": "Opptak Grupper", - "HomeVideos": "Hjemmelaget filmer", + "HeaderRecordingGroups": "Opptaksgrupper", + "HomeVideos": "Hjemmelagde filmer", "Inherit": "Arve", "ItemAddedWithName": "{0} ble lagt til i biblioteket", "ItemRemovedWithName": "{0} ble fjernet fra biblioteket", - "LabelIpAddressValue": "IP adresse: {0}", - "LabelRunningTimeValue": "Løpetid {0}", + "LabelIpAddressValue": "IP-adresse: {0}", + "LabelRunningTimeValue": "Kjøretid {0}", "Latest": "Siste", - "MessageApplicationUpdated": "Jellyfin server har blitt oppdatert", - "MessageApplicationUpdatedTo": "Jellyfin-serveren ble oppdatert til {0}", - "MessageNamedServerConfigurationUpdatedWithValue": "Server konfigurasjon seksjon {0} har blitt oppdatert", - "MessageServerConfigurationUpdated": "Server konfigurasjon er oppdatert", + "MessageApplicationUpdated": "Jellyfin Server har blitt oppdatert", + "MessageApplicationUpdatedTo": "Jellyfin Server ble oppdatert til {0}", + "MessageNamedServerConfigurationUpdatedWithValue": "Serverkonfigurasjon seksjon {0} har blitt oppdatert", + "MessageServerConfigurationUpdated": "Serverkonfigurasjon er oppdatert", "MixedContent": "Blandet innhold", "Movies": "Filmer", "Music": "Musikk", @@ -44,38 +44,38 @@ "NameInstallFailed": "{0}-installasjonen mislyktes", "NameSeasonNumber": "Sesong {0}", "NameSeasonUnknown": "Sesong ukjent", - "NewVersionIsAvailable": "En ny versjon av Jellyfin-serveren er tilgjengelig for nedlastning.", + "NewVersionIsAvailable": "En ny versjon av Jellyfin Server er tilgjengelig for nedlasting.", "NotificationOptionApplicationUpdateAvailable": "Programvareoppdatering er tilgjengelig", "NotificationOptionApplicationUpdateInstalled": "Applikasjonsoppdatering installert", - "NotificationOptionAudioPlayback": "Lyd tilbakespilling startet", - "NotificationOptionAudioPlaybackStopped": "Lyd avspilling stoppet", - "NotificationOptionCameraImageUploaded": "Kamera bilde lastet opp", + "NotificationOptionAudioPlayback": "Lydavspilling startet", + "NotificationOptionAudioPlaybackStopped": "Lydavspilling stoppet", + "NotificationOptionCameraImageUploaded": "Kamerabilde lastet opp", "NotificationOptionInstallationFailed": "Installasjonsfeil", - "NotificationOptionNewLibraryContent": "Ny innhold er lagt til", - "NotificationOptionPluginError": "Plugin feil", + "NotificationOptionNewLibraryContent": "Nytt innhold lagt til", + "NotificationOptionPluginError": "Pluginfeil", "NotificationOptionPluginInstalled": "Plugin installert", "NotificationOptionPluginUninstalled": "Plugin avinstallert", - "NotificationOptionPluginUpdateInstalled": "Plugin oppdatering installert", - "NotificationOptionServerRestartRequired": "Server omstart er nødvendig", - "NotificationOptionTaskFailed": "Feil under utføring av planlagt oppgaver", + "NotificationOptionPluginUpdateInstalled": "Pluginoppdatering installert", + "NotificationOptionServerRestartRequired": "Serveromstart er nødvendig", + "NotificationOptionTaskFailed": "Feil under utføring av planlagt oppgave", "NotificationOptionUserLockedOut": "Bruker er utestengt", - "NotificationOptionVideoPlayback": "Video tilbakespilling startet", - "NotificationOptionVideoPlaybackStopped": "Video avspilling stoppet", + "NotificationOptionVideoPlayback": "Videoavspilling startet", + "NotificationOptionVideoPlaybackStopped": "Videoavspilling stoppet", "Photos": "Bilder", - "Playlists": "Spillelister", + "Playlists": "Spliielister", "Plugin": "Plugin", "PluginInstalledWithName": "{0} ble installert", "PluginUninstalledWithName": "{0} ble avinstallert", "PluginUpdatedWithName": "{0} ble oppdatert", - "ProviderValue": "Leverandører: {0}", - "ScheduledTaskFailedWithName": "{0} Mislykkes", - "ScheduledTaskStartedWithName": "{0} Startet", + "ProviderValue": "Leverandør: {0}", + "ScheduledTaskFailedWithName": "{0} mislykkes", + "ScheduledTaskStartedWithName": "{0} startet", "ServerNameNeedsToBeRestarted": "{0} må startes på nytt", "Shows": "Programmer", "Songs": "Sanger", - "StartupEmbyServerIsLoading": "Jellyfin server laster. Prøv igjen snart.", + "StartupEmbyServerIsLoading": "Jellyfin Server laster. Prøv igjen snart.", "SubtitleDownloadFailureForItem": "En feil oppstå under nedlasting av undertekster for {0}", - "SubtitleDownloadFailureFromForItem": "Kunne ikke laste ned teksting fra {0} for {1}", + "SubtitleDownloadFailureFromForItem": "Kunne ikke laste ned undertekster fra {0} for {1}", "SubtitlesDownloadedForItem": "Undertekster lastet ned for {0}", "Sync": "Synkroniser", "System": "System", diff --git a/Emby.Server.Implementations/Localization/Core/ro.json b/Emby.Server.Implementations/Localization/Core/ro.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/Emby.Server.Implementations/Localization/Core/ro.json @@ -0,0 +1 @@ +{} diff --git a/Emby.Server.Implementations/Localization/Core/zh-CN.json b/Emby.Server.Implementations/Localization/Core/zh-CN.json index 87f8553ae..a4d53c57e 100644 --- a/Emby.Server.Implementations/Localization/Core/zh-CN.json +++ b/Emby.Server.Implementations/Localization/Core/zh-CN.json @@ -24,7 +24,7 @@ "HeaderFavoriteShows": "最爱的节目", "HeaderFavoriteSongs": "最爱的歌曲", "HeaderLiveTV": "电视直播", - "HeaderNextUp": "接下来", + "HeaderNextUp": "下一步", "HeaderRecordingGroups": "录制组", "HomeVideos": "家庭视频", "Inherit": "继承", @@ -34,7 +34,7 @@ "LabelRunningTimeValue": "运行时间:{0}", "Latest": "最新", "MessageApplicationUpdated": "Jellyfin 服务器已更新", - "MessageApplicationUpdatedTo": "Jellyfin Server 的版本已更新为 {0}", + "MessageApplicationUpdatedTo": "Jellyfin Server 版本已更新为 {0}", "MessageNamedServerConfigurationUpdatedWithValue": "服务器配置 {0} 部分已更新", "MessageServerConfigurationUpdated": "服务器配置已更新", "MixedContent": "混合内容", @@ -42,7 +42,7 @@ "Music": "音乐", "MusicVideos": "音乐视频", "NameInstallFailed": "{0} 安装失败", - "NameSeasonNumber": "季 {0}", + "NameSeasonNumber": "第 {0} 季", "NameSeasonUnknown": "未知季", "NewVersionIsAvailable": "Jellyfin Server 有新版本可以下载。", "NotificationOptionApplicationUpdateAvailable": "有可用的应用程序更新", diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs index 0f58e43ed..b26f4026c 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistManager.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs @@ -56,10 +56,8 @@ namespace Emby.Server.Implementations.Playlists { var name = options.Name; - var folderName = _fileSystem.GetValidFilename(name) + " [playlist]"; - + var folderName = _fileSystem.GetValidFilename(name); var parentFolder = GetPlaylistsFolder(Guid.Empty); - if (parentFolder == null) { throw new ArgumentException(); @@ -253,11 +251,13 @@ namespace Emby.Server.Implementations.Playlists SavePlaylistFile(playlist); } - _providerManager.QueueRefresh(playlist.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)) - { - ForceSave = true - - }, RefreshPriority.High); + _providerManager.QueueRefresh( + playlist.Id, + new MetadataRefreshOptions(new DirectoryService(_fileSystem)) + { + ForceSave = true + }, + RefreshPriority.High); } public void MoveItem(string playlistId, string entryId, int newIndex) @@ -303,7 +303,8 @@ namespace Emby.Server.Implementations.Playlists private void SavePlaylistFile(Playlist item) { - // This is probably best done as a metatata provider, but saving a file over itself will first require some core work to prevent this from happening when not needed + // this is probably best done as a metadata provider + // saving a file over itself will require some work to prevent this from happening when not needed var playlistPath = item.Path; var extension = Path.GetExtension(playlistPath); @@ -335,12 +336,14 @@ namespace Emby.Server.Implementations.Playlists { entry.Duration = TimeSpan.FromTicks(child.RunTimeTicks.Value); } + playlist.PlaylistEntries.Add(entry); } string text = new WplContent().ToText(playlist); File.WriteAllText(playlistPath, text); } + if (string.Equals(".zpl", extension, StringComparison.OrdinalIgnoreCase)) { var playlist = new ZplPlaylist(); @@ -375,6 +378,7 @@ namespace Emby.Server.Implementations.Playlists string text = new ZplContent().ToText(playlist); File.WriteAllText(playlistPath, text); } + if (string.Equals(".m3u", extension, StringComparison.OrdinalIgnoreCase)) { var playlist = new M3uPlaylist(); @@ -398,12 +402,14 @@ namespace Emby.Server.Implementations.Playlists { entry.Duration = TimeSpan.FromTicks(child.RunTimeTicks.Value); } + playlist.PlaylistEntries.Add(entry); } string text = new M3uContent().ToText(playlist); File.WriteAllText(playlistPath, text); } + if (string.Equals(".m3u8", extension, StringComparison.OrdinalIgnoreCase)) { var playlist = new M3uPlaylist(); @@ -427,12 +433,14 @@ namespace Emby.Server.Implementations.Playlists { entry.Duration = TimeSpan.FromTicks(child.RunTimeTicks.Value); } + playlist.PlaylistEntries.Add(entry); } string text = new M3u8Content().ToText(playlist); File.WriteAllText(playlistPath, text); } + if (string.Equals(".pls", extension, StringComparison.OrdinalIgnoreCase)) { var playlist = new PlsPlaylist(); @@ -448,6 +456,7 @@ namespace Emby.Server.Implementations.Playlists { entry.Length = TimeSpan.FromTicks(child.RunTimeTicks.Value); } + playlist.PlaylistEntries.Add(entry); } @@ -473,7 +482,7 @@ namespace Emby.Server.Implementations.Playlists throw new ArgumentException("File absolute path was null or empty.", nameof(fileAbsolutePath)); } - if (!folderPath.EndsWith(Path.DirectorySeparatorChar.ToString())) + if (!folderPath.EndsWith(Path.DirectorySeparatorChar)) { folderPath = folderPath + Path.DirectorySeparatorChar; } @@ -481,7 +490,11 @@ namespace Emby.Server.Implementations.Playlists var folderUri = new Uri(folderPath); var fileAbsoluteUri = new Uri(fileAbsolutePath); - if (folderUri.Scheme != fileAbsoluteUri.Scheme) { return fileAbsolutePath; } // path can't be made relative. + // path can't be made relative + if (folderUri.Scheme != fileAbsoluteUri.Scheme) + { + return fileAbsolutePath; + } var relativeUri = folderUri.MakeRelativeUri(fileAbsoluteUri); string relativePath = Uri.UnescapeDataString(relativeUri.ToString()); diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 2705e0628..c897036eb 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Linq; using System.Net.Http; +using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; @@ -189,7 +189,7 @@ namespace Emby.Server.Implementations.Updates } /// <inheritdoc /> - public async IAsyncEnumerable<PackageVersionInfo> GetAvailablePluginUpdates(CancellationToken cancellationToken = default) + public async IAsyncEnumerable<PackageVersionInfo> GetAvailablePluginUpdates([EnumeratorCancellation] CancellationToken cancellationToken = default) { var catalog = await GetAvailablePackages(cancellationToken).ConfigureAwait(false); |
