aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations')
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs8
-rw-r--r--Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs13
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpListenerHost.cs1
-rw-r--r--Emby.Server.Implementations/Library/UserManager.cs44
-rw-r--r--Emby.Server.Implementations/Localization/Core/cs.json24
-rw-r--r--Emby.Server.Implementations/Localization/Core/da.json4
-rw-r--r--Emby.Server.Implementations/Localization/Core/el.json8
-rw-r--r--Emby.Server.Implementations/Localization/Core/gsw.json166
-rw-r--r--Emby.Server.Implementations/Localization/Core/kk.json8
-rw-r--r--Emby.Server.Implementations/Localization/Core/sl-SI.json66
-rw-r--r--Emby.Server.Implementations/Localization/Core/zh-TW.json93
-rw-r--r--Emby.Server.Implementations/Udp/UdpServer.cs2
-rw-r--r--Emby.Server.Implementations/Updates/InstallationManager.cs38
13 files changed, 303 insertions, 172 deletions
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 0ebbeea57..aa0fdde2d 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -1025,8 +1025,8 @@ namespace Emby.Server.Implementations
private async void PluginInstalled(object sender, GenericEventArgs<PackageVersionInfo> args)
{
- string dir = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(args.Argument.targetFilename));
- var types = Directory.EnumerateFiles(dir, "*.dll", SearchOption.TopDirectoryOnly)
+ string dir = Path.Combine(ApplicationPaths.PluginsPath, args.Argument.name);
+ var types = Directory.EnumerateFiles(dir, "*.dll", SearchOption.AllDirectories)
.Select(x => Assembly.LoadFrom(x))
.SelectMany(x => x.ExportedTypes)
.Where(x => x.IsClass && !x.IsAbstract && !x.IsInterface && !x.IsGenericType)
@@ -1325,7 +1325,7 @@ namespace Emby.Server.Implementations
{
if (Directory.Exists(ApplicationPaths.PluginsPath))
{
- foreach (var file in Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly))
+ foreach (var file in Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.AllDirectories))
{
Logger.LogInformation("Loading assembly {Path}", file);
yield return Assembly.LoadFrom(file);
@@ -1404,7 +1404,6 @@ namespace Emby.Server.Implementations
HasPendingRestart = HasPendingRestart,
IsShuttingDown = IsShuttingDown,
Version = ApplicationVersion,
- ProductName = ApplicationProductName,
WebSocketPortNumber = HttpPort,
CompletedInstallations = InstallationManager.CompletedInstallations.ToArray(),
Id = SystemId,
@@ -1461,6 +1460,7 @@ namespace Emby.Server.Implementations
return new PublicSystemInfo
{
Version = ApplicationVersion,
+ ProductName = ApplicationProductName,
Id = SystemId,
OperatingSystem = OperatingSystem.Id.ToString(),
WanAddress = wanAddress,
diff --git a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
index 18e279c2f..c4fa68cac 100644
--- a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
+++ b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
@@ -74,23 +74,14 @@ namespace Emby.Server.Implementations.Configuration
/// </summary>
private void UpdateMetadataPath()
{
- string metadataPath;
-
if (string.IsNullOrWhiteSpace(Configuration.MetadataPath))
{
- metadataPath = GetInternalMetadataPath();
+ ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = Path.Combine(ApplicationPaths.ProgramDataPath, "metadata");
}
else
{
- metadataPath = Path.Combine(Configuration.MetadataPath, "metadata");
+ ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = Configuration.MetadataPath;
}
-
- ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = metadataPath;
- }
-
- private string GetInternalMetadataPath()
- {
- return Path.Combine(ApplicationPaths.ProgramDataPath, "metadata");
}
/// <summary>
diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
index 79b8f52d7..06d304077 100644
--- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -201,6 +201,7 @@ namespace Emby.Server.Implementations.HttpServer
case DirectoryNotFoundException _:
case FileNotFoundException _:
case ResourceNotFoundException _: return 404;
+ case MethodNotAllowedException _: return 405;
case RemoteServiceUnavailableException _: return 502;
default: return 500;
}
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index 75c82ca71..952cc6896 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -277,24 +277,35 @@ namespace Emby.Server.Implementations.Library
.FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase));
var success = false;
+ string updatedUsername = null;
IAuthenticationProvider authenticationProvider = null;
if (user != null)
{
var authResult = await AuthenticateLocalUser(username, password, hashedPassword, user, remoteEndPoint).ConfigureAwait(false);
authenticationProvider = authResult.Item1;
- success = authResult.Item2;
+ updatedUsername = authResult.Item2;
+ success = authResult.Item3;
}
else
{
// user is null
var authResult = await AuthenticateLocalUser(username, password, hashedPassword, null, remoteEndPoint).ConfigureAwait(false);
authenticationProvider = authResult.Item1;
- success = authResult.Item2;
+ updatedUsername = authResult.Item2;
+ success = authResult.Item3;
if (success && authenticationProvider != null && !(authenticationProvider is DefaultAuthenticationProvider))
{
- user = await CreateUser(username).ConfigureAwait(false);
+ // We should trust the user that the authprovider says, not what was typed
+ if (updatedUsername != username)
+ {
+ username = updatedUsername;
+ }
+
+ // Search the database for the user again; the authprovider might have created it
+ user = Users
+ .FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase));
var hasNewUserPolicy = authenticationProvider as IHasNewUserPolicy;
if (hasNewUserPolicy != null)
@@ -414,32 +425,40 @@ namespace Emby.Server.Implementations.Library
return providers;
}
- private async Task<bool> AuthenticateWithProvider(IAuthenticationProvider provider, string username, string password, User resolvedUser)
+ private async Task<Tuple<string, bool>> AuthenticateWithProvider(IAuthenticationProvider provider, string username, string password, User resolvedUser)
{
try
{
var requiresResolvedUser = provider as IRequiresResolvedUser;
+ ProviderAuthenticationResult authenticationResult = null;
if (requiresResolvedUser != null)
{
- await requiresResolvedUser.Authenticate(username, password, resolvedUser).ConfigureAwait(false);
+ authenticationResult = await requiresResolvedUser.Authenticate(username, password, resolvedUser).ConfigureAwait(false);
}
else
{
- await provider.Authenticate(username, password).ConfigureAwait(false);
+ authenticationResult = await provider.Authenticate(username, password).ConfigureAwait(false);
+ }
+
+ if(authenticationResult.Username != username)
+ {
+ _logger.LogDebug("Authentication provider provided updated username {1}", authenticationResult.Username);
+ username = authenticationResult.Username;
}
- return true;
+ return new Tuple<string, bool>(username, true);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error authenticating with provider {provider}", provider.Name);
- return false;
+ return new Tuple<string, bool>(username, false);
}
}
- private async Task<Tuple<IAuthenticationProvider, bool>> AuthenticateLocalUser(string username, string password, string hashedPassword, User user, string remoteEndPoint)
+ private async Task<Tuple<IAuthenticationProvider, string, bool>> AuthenticateLocalUser(string username, string password, string hashedPassword, User user, string remoteEndPoint)
{
+ string updatedUsername = null;
bool success = false;
IAuthenticationProvider authenticationProvider = null;
@@ -458,11 +477,14 @@ namespace Emby.Server.Implementations.Library
{
foreach (var provider in GetAuthenticationProviders(user))
{
- success = await AuthenticateWithProvider(provider, username, password, user).ConfigureAwait(false);
+ var providerAuthResult = await AuthenticateWithProvider(provider, username, password, user).ConfigureAwait(false);
+ updatedUsername = providerAuthResult.Item1;
+ success = providerAuthResult.Item2;
if (success)
{
authenticationProvider = provider;
+ username = updatedUsername;
break;
}
}
@@ -484,7 +506,7 @@ namespace Emby.Server.Implementations.Library
}
}
- return new Tuple<IAuthenticationProvider, bool>(authenticationProvider, success);
+ return new Tuple<IAuthenticationProvider, string, bool>(authenticationProvider, username, success);
}
private void UpdateInvalidLoginAttemptCount(User user, int newValue)
diff --git a/Emby.Server.Implementations/Localization/Core/cs.json b/Emby.Server.Implementations/Localization/Core/cs.json
index a8b4a4424..c19148921 100644
--- a/Emby.Server.Implementations/Localization/Core/cs.json
+++ b/Emby.Server.Implementations/Localization/Core/cs.json
@@ -5,7 +5,7 @@
"Artists": "Umělci",
"AuthenticationSucceededWithUserName": "{0} úspěšně ověřen",
"Books": "Knihy",
- "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}",
+ "CameraImageUploadedFrom": "Z {0} byla nahrána nová fotografie",
"Channels": "Kanály",
"ChapterNameValue": "Kapitola {0}",
"Collections": "Kolekce",
@@ -16,14 +16,14 @@
"Folders": "Složky",
"Genres": "Žánry",
"HeaderAlbumArtists": "Umělci alba",
- "HeaderCameraUploads": "Camera Uploads",
+ "HeaderCameraUploads": "Nahrané fotografie",
"HeaderContinueWatching": "Pokračovat ve sledování",
"HeaderFavoriteAlbums": "Oblíbená alba",
- "HeaderFavoriteArtists": "Oblíbení umělci",
+ "HeaderFavoriteArtists": "Oblíbení interpreti",
"HeaderFavoriteEpisodes": "Oblíbené epizody",
"HeaderFavoriteShows": "Oblíbené seriály",
- "HeaderFavoriteSongs": "Oblíbené písně",
- "HeaderLiveTV": "Živá TV",
+ "HeaderFavoriteSongs": "Oblíbená hudba",
+ "HeaderLiveTV": "Live TV",
"HeaderNextUp": "Nadcházející",
"HeaderRecordingGroups": "Skupiny nahrávek",
"HomeVideos": "Domáci videa",
@@ -34,17 +34,17 @@
"LabelRunningTimeValue": "Délka média: {0}",
"Latest": "Nejnovější",
"MessageApplicationUpdated": "Jellyfin Server byl aktualizován",
- "MessageApplicationUpdatedTo": "Jellyfin Server has been updated to {0}",
+ "MessageApplicationUpdatedTo": "Jellyfin server byl aktualizován na verzi {0}",
"MessageNamedServerConfigurationUpdatedWithValue": "Konfigurace sekce {0} na serveru byla aktualizována",
"MessageServerConfigurationUpdated": "Konfigurace serveru aktualizována",
"MixedContent": "Smíšený obsah",
"Movies": "Filmy",
"Music": "Hudba",
"MusicVideos": "Hudební klipy",
- "NameInstallFailed": "{0} installation failed",
+ "NameInstallFailed": "Instalace {0} selhala",
"NameSeasonNumber": "Sezóna {0}",
"NameSeasonUnknown": "Neznámá sezóna",
- "NewVersionIsAvailable": "A new version of Jellyfin Server is available for download.",
+ "NewVersionIsAvailable": "Nová verze Jellyfin serveru je k dispozici ke stažení.",
"NotificationOptionApplicationUpdateAvailable": "Dostupná aktualizace aplikace",
"NotificationOptionApplicationUpdateInstalled": "Aktualizace aplikace instalována",
"NotificationOptionAudioPlayback": "Přehrávání audia zahájeno",
@@ -70,12 +70,12 @@
"ProviderValue": "Poskytl: {0}",
"ScheduledTaskFailedWithName": "{0} selhalo",
"ScheduledTaskStartedWithName": "{0} zahájeno",
- "ServerNameNeedsToBeRestarted": "{0} needs to be restarted",
+ "ServerNameNeedsToBeRestarted": "{0} vyžaduje restart",
"Shows": "Seriály",
"Songs": "Skladby",
"StartupEmbyServerIsLoading": "Jellyfin Server je spouštěn. Zkuste to prosím v brzké době znovu.",
"SubtitleDownloadFailureForItem": "Stahování titulků selhalo pro {0}",
- "SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}",
+ "SubtitleDownloadFailureFromForItem": "Stažení titulků pro {1} z {0} selhalo",
"SubtitlesDownloadedForItem": "Staženy titulky pro {0}",
"Sync": "Synchronizace",
"System": "Systém",
@@ -88,10 +88,10 @@
"UserOfflineFromDevice": "{0} se odpojil od {1}",
"UserOnlineFromDevice": "{0} se připojil z {1}",
"UserPasswordChangedWithName": "Provedena změna hesla pro uživatele {0}",
- "UserPolicyUpdatedWithName": "User policy has been updated for {0}",
+ "UserPolicyUpdatedWithName": "Zásady uživatele pro {0} byly aktualizovány",
"UserStartedPlayingItemWithValues": "{0} spustil přehrávání {1}",
"UserStoppedPlayingItemWithValues": "{0} zastavil přehrávání {1}",
- "ValueHasBeenAddedToLibrary": "{0} has been added to your media library",
+ "ValueHasBeenAddedToLibrary": "{0} byl přidán do vaší knihovny médií",
"ValueSpecialEpisodeName": "Speciál - {0}",
"VersionNumber": "Verze {0}"
}
diff --git a/Emby.Server.Implementations/Localization/Core/da.json b/Emby.Server.Implementations/Localization/Core/da.json
index 9d4d74099..cb8f4576a 100644
--- a/Emby.Server.Implementations/Localization/Core/da.json
+++ b/Emby.Server.Implementations/Localization/Core/da.json
@@ -61,8 +61,8 @@
"NotificationOptionUserLockedOut": "Bruger låst ude",
"NotificationOptionVideoPlayback": "Videoafspilning påbegyndt",
"NotificationOptionVideoPlaybackStopped": "Videoafspilning stoppet",
- "Photos": "Fotos",
- "Playlists": "Spillelister",
+ "Photos": "Fotoer",
+ "Playlists": "Afspilningslister",
"Plugin": "Plugin",
"PluginInstalledWithName": "{0} blev installeret",
"PluginUninstalledWithName": "{0} blev afinstalleret",
diff --git a/Emby.Server.Implementations/Localization/Core/el.json b/Emby.Server.Implementations/Localization/Core/el.json
index 91ca34edc..db7ebb0c0 100644
--- a/Emby.Server.Implementations/Localization/Core/el.json
+++ b/Emby.Server.Implementations/Localization/Core/el.json
@@ -16,7 +16,7 @@
"Folders": "Φάκελοι",
"Genres": "Είδη",
"HeaderAlbumArtists": "Άλμπουμ Καλλιτεχνών",
- "HeaderCameraUploads": "Camera Uploads",
+ "HeaderCameraUploads": "Μεταφορτώσεις Κάμερας",
"HeaderContinueWatching": "Συνεχίστε να παρακολουθείτε",
"HeaderFavoriteAlbums": "Αγαπημένα Άλμπουμ",
"HeaderFavoriteArtists": "Αγαπημένοι Καλλιτέχνες",
@@ -34,7 +34,7 @@
"LabelRunningTimeValue": "Διάρκεια: {0}",
"Latest": "Πρόσφατα",
"MessageApplicationUpdated": "Ο Jellyfin Server έχει ενημερωθεί",
- "MessageApplicationUpdatedTo": "Jellyfin Server has been updated to {0}",
+ "MessageApplicationUpdatedTo": "Ο server Jellyfin αναβαθμίστηκε σε έκδοση {0}",
"MessageNamedServerConfigurationUpdatedWithValue": "Η ενότητα {0} ρύθμισης παραμέτρων του server έχει ενημερωθεί",
"MessageServerConfigurationUpdated": "Η ρύθμιση παραμέτρων του server έχει ενημερωθεί",
"MixedContent": "Ανάμεικτο Περιεχόμενο",
@@ -49,7 +49,7 @@
"NotificationOptionApplicationUpdateInstalled": "Η ενημέρωση εφαρμογής εγκαταστάθηκε",
"NotificationOptionAudioPlayback": "Η αναπαραγωγή ήχου ξεκίνησε",
"NotificationOptionAudioPlaybackStopped": "Η αναπαραγωγή ήχου σταμάτησε",
- "NotificationOptionCameraImageUploaded": "Camera image uploaded",
+ "NotificationOptionCameraImageUploaded": "Μεταφορτώθηκε φωτογραφία απο κάμερα",
"NotificationOptionInstallationFailed": "Αποτυχία εγκατάστασης",
"NotificationOptionNewLibraryContent": "Προστέθηκε νέο περιεχόμενο",
"NotificationOptionPluginError": "Αποτυχία του plugin",
@@ -75,7 +75,7 @@
"Songs": "Τραγούδια",
"StartupEmbyServerIsLoading": "Ο Jellyfin Server φορτώνει. Παρακαλώ δοκιμάστε σε λίγο.",
"SubtitleDownloadFailureForItem": "Οι υπότιτλοι απέτυχαν να κατέβουν για {0}",
- "SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}",
+ "SubtitleDownloadFailureFromForItem": "Αποτυχίες μεταφόρτωσης υποτίτλων από {0} για {1}",
"SubtitlesDownloadedForItem": "Οι υπότιτλοι κατέβηκαν για {0}",
"Sync": "Συγχρονισμός",
"System": "Σύστημα",
diff --git a/Emby.Server.Implementations/Localization/Core/gsw.json b/Emby.Server.Implementations/Localization/Core/gsw.json
index 728002a56..69c157401 100644
--- a/Emby.Server.Implementations/Localization/Core/gsw.json
+++ b/Emby.Server.Implementations/Localization/Core/gsw.json
@@ -1,97 +1,97 @@
{
- "Albums": "Albums",
- "AppDeviceValues": "App: {0}, Device: {1}",
- "Application": "Application",
- "Artists": "Artists",
- "AuthenticationSucceededWithUserName": "{0} successfully authenticated",
+ "Albums": "Albom",
+ "AppDeviceValues": "App: {0}, Grät: {1}",
+ "Application": "Aawändig",
+ "Artists": "Könstler",
+ "AuthenticationSucceededWithUserName": "{0} het sech aagmäudet",
"Books": "Büecher",
- "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}",
- "Channels": "Channels",
- "ChapterNameValue": "Chapter {0}",
- "Collections": "Collections",
- "DeviceOfflineWithName": "{0} has disconnected",
- "DeviceOnlineWithName": "{0} is connected",
- "FailedLoginAttemptWithUserName": "Failed login attempt from {0}",
- "Favorites": "Favorites",
- "Folders": "Folders",
+ "CameraImageUploadedFrom": "Es nöis Foti esch ufeglade worde vo {0}",
+ "Channels": "Kanäu",
+ "ChapterNameValue": "Kapitu {0}",
+ "Collections": "Sammlige",
+ "DeviceOfflineWithName": "{0} esch offline gange",
+ "DeviceOnlineWithName": "{0} esch online cho",
+ "FailedLoginAttemptWithUserName": "Fäugschlagne Aamäudeversuech vo {0}",
+ "Favorites": "Favorite",
+ "Folders": "Ordner",
"Genres": "Genres",
- "HeaderAlbumArtists": "Albuminterprete",
- "HeaderCameraUploads": "Camera Uploads",
+ "HeaderAlbumArtists": "Albom-Könstler",
+ "HeaderCameraUploads": "Kamera-Uploads",
"HeaderContinueWatching": "Wiiterluege",
- "HeaderFavoriteAlbums": "Favorite Albums",
- "HeaderFavoriteArtists": "Besti Interpret",
- "HeaderFavoriteEpisodes": "Favorite Episodes",
- "HeaderFavoriteShows": "Favorite Shows",
- "HeaderFavoriteSongs": "Besti Lieder",
- "HeaderLiveTV": "Live TV",
- "HeaderNextUp": "Next Up",
+ "HeaderFavoriteAlbums": "Lieblingsalbe",
+ "HeaderFavoriteArtists": "Lieblings-Interprete",
+ "HeaderFavoriteEpisodes": "Lieblingsepisode",
+ "HeaderFavoriteShows": "Lieblingsserie",
+ "HeaderFavoriteSongs": "Lieblingslieder",
+ "HeaderLiveTV": "Live-Färnseh",
+ "HeaderNextUp": "Als nächts",
"HeaderRecordingGroups": "Ufnahmegruppe",
"HomeVideos": "Heimfilmli",
"Inherit": "Hinzuefüege",
- "ItemAddedWithName": "{0} was added to the library",
- "ItemRemovedWithName": "{0} was removed from the library",
- "LabelIpAddressValue": "Ip address: {0}",
- "LabelRunningTimeValue": "Running time: {0}",
- "Latest": "Letschte",
- "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",
- "MixedContent": "Gmischte Inhalt",
- "Movies": "Movies",
+ "ItemAddedWithName": "{0} esch de Bibliothek dezuegfüegt worde",
+ "ItemRemovedWithName": "{0} esch vo de Bibliothek entfärnt worde",
+ "LabelIpAddressValue": "IP-Adrässe: {0}",
+ "LabelRunningTimeValue": "Loufziit: {0}",
+ "Latest": "Nöischti",
+ "MessageApplicationUpdated": "Jellyfin Server esch aktualisiert worde",
+ "MessageApplicationUpdatedTo": "Jellyfin Server esch of Version {0} aktualisiert worde",
+ "MessageNamedServerConfigurationUpdatedWithValue": "De Serveriistöuigsberiich {0} esch aktualisiert worde",
+ "MessageServerConfigurationUpdated": "Serveriistöuige send aktualisiert worde",
+ "MixedContent": "Gmeschti Inhäut",
+ "Movies": "Film",
"Music": "Musig",
- "MusicVideos": "Musigfilm",
- "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",
+ "MusicVideos": "Musigvideos",
+ "NameInstallFailed": "Installation vo {0} fäugschlage",
+ "NameSeasonNumber": "Staffle {0}",
+ "NameSeasonUnknown": "Staffle unbekannt",
+ "NewVersionIsAvailable": "E nöi Version vo Jellyfin Server esch zom Download parat.",
+ "NotificationOptionApplicationUpdateAvailable": "Aawändigsupdate verfüegbar",
+ "NotificationOptionApplicationUpdateInstalled": "Aawändigsupdate installiert",
+ "NotificationOptionAudioPlayback": "Audiowedergab gstartet",
+ "NotificationOptionAudioPlaybackStopped": "Audiwedergab gstoppt",
+ "NotificationOptionCameraImageUploaded": "Foti ueglade",
+ "NotificationOptionInstallationFailed": "Installationsfäuer",
+ "NotificationOptionNewLibraryContent": "Nöie Inhaut hinzuegfüegt",
+ "NotificationOptionPluginError": "Plugin-Fäuer",
+ "NotificationOptionPluginInstalled": "Plugin installiert",
+ "NotificationOptionPluginUninstalled": "Plugin deinstalliert",
+ "NotificationOptionPluginUpdateInstalled": "Pluginupdate installiert",
+ "NotificationOptionServerRestartRequired": "Serverneustart notwändig",
+ "NotificationOptionTaskFailed": "Planti Uufgab fäugschlage",
+ "NotificationOptionUserLockedOut": "Benotzer usgschlosse",
+ "NotificationOptionVideoPlayback": "Videowedergab gstartet",
+ "NotificationOptionVideoPlaybackStopped": "Videowedergab gstoppt",
"Photos": "Fotis",
- "Playlists": "Abspielliste",
+ "Playlists": "Wedergabeliste",
"Plugin": "Plugin",
- "PluginInstalledWithName": "{0} was installed",
- "PluginUninstalledWithName": "{0} was uninstalled",
- "PluginUpdatedWithName": "{0} was updated",
- "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.",
+ "PluginInstalledWithName": "{0} esch installiert worde",
+ "PluginUninstalledWithName": "{0} esch deinstalliert worde",
+ "PluginUpdatedWithName": "{0} esch updated worde",
+ "ProviderValue": "Aabieter: {0}",
+ "ScheduledTaskFailedWithName": "{0} esch fäugschlage",
+ "ScheduledTaskStartedWithName": "{0} het gstartet",
+ "ServerNameNeedsToBeRestarted": "{0} mues nöi gstartet wärde",
+ "Shows": "Serie",
+ "Songs": "Lieder",
+ "StartupEmbyServerIsLoading": "Jellyfin Server ladt. Bitte grad noeinisch probiere.",
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
- "SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}",
- "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}",
- "Sync": "Sync",
+ "SubtitleDownloadFailureFromForItem": "Ondertetle vo {0} för {1} hend ned chönne abeglade wärde",
+ "SubtitlesDownloadedForItem": "Ondertetle abeglade för {0}",
+ "Sync": "Synchronisation",
"System": "System",
- "TvShows": "TV Shows",
- "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",
- "ValueSpecialEpisodeName": "Spezial - {0}",
+ "TvShows": "Färnsehserie",
+ "User": "Benotzer",
+ "UserCreatedWithName": "Benotzer {0} esch erstöut worde",
+ "UserDeletedWithName": "Benotzer {0} esch glösche worde",
+ "UserDownloadingItemWithValues": "{0} ladt {1} abe",
+ "UserLockedOutWithName": "Benotzer {0} esch usgschlosse worde",
+ "UserOfflineFromDevice": "{0} esch vo {1} trennt worde",
+ "UserOnlineFromDevice": "{0} esch online vo {1}",
+ "UserPasswordChangedWithName": "S'Passwort för Benotzer {0} esch gänderet worde",
+ "UserPolicyUpdatedWithName": "Benotzerrechtlinie för {0} esch aktualisiert worde",
+ "UserStartedPlayingItemWithValues": "{0} hed d'Wedergab vo {1} of {2} gstartet",
+ "UserStoppedPlayingItemWithValues": "{0} het d'Wedergab vo {1} of {2} gstoppt",
+ "ValueHasBeenAddedToLibrary": "{0} esch dinnere Biblithek hinzuegfüegt worde",
+ "ValueSpecialEpisodeName": "Extra - {0}",
"VersionNumber": "Version {0}"
}
diff --git a/Emby.Server.Implementations/Localization/Core/kk.json b/Emby.Server.Implementations/Localization/Core/kk.json
index 23841f37d..cbee71155 100644
--- a/Emby.Server.Implementations/Localization/Core/kk.json
+++ b/Emby.Server.Implementations/Localization/Core/kk.json
@@ -5,7 +5,7 @@
"Artists": "Oryndaýshylar",
"AuthenticationSucceededWithUserName": "{0} túpnusqalyq rastalýy sátti aıaqtaldy",
"Books": "Kitaptar",
- "CameraImageUploadedFrom": "{0} kamerasynan jańa sýret júktep alyndy",
+ "CameraImageUploadedFrom": "{0} kamerasynan jańa sýret júktep salyndy",
"Channels": "Arnalar",
"ChapterNameValue": "{0}-sahna",
"Collections": "Jıyntyqtar",
@@ -35,8 +35,8 @@
"Latest": "Eń keıingi",
"MessageApplicationUpdated": "Jellyfin Serveri jańartyldy",
"MessageApplicationUpdatedTo": "Jellyfin Serveri {0} nusqasyna jańartyldy",
- "MessageNamedServerConfigurationUpdatedWithValue": "Server teńsheliminiń {0} bólimi jańartyldy",
- "MessageServerConfigurationUpdated": "Server teńshelimi jańartyldy",
+ "MessageNamedServerConfigurationUpdatedWithValue": "Server konfıgýrasýasynyń {0} bólimi jańartyldy",
+ "MessageServerConfigurationUpdated": "Server konfıgýrasıasy jańartyldy",
"MixedContent": "Aralas mazmun",
"Movies": "Fılmder",
"Music": "Mýzyka",
@@ -49,7 +49,7 @@
"NotificationOptionApplicationUpdateInstalled": "Qoldanba jańartýy ornatyldy",
"NotificationOptionAudioPlayback": "Dybys oınatýy bastaldy",
"NotificationOptionAudioPlaybackStopped": "Dybys oınatýy toqtatyldy",
- "NotificationOptionCameraImageUploaded": "Kameradan fotosýret keri qotarylǵan",
+ "NotificationOptionCameraImageUploaded": "Kameradan fotosýret júktep salynǵan",
"NotificationOptionInstallationFailed": "Ornatý sátsizdigi",
"NotificationOptionNewLibraryContent": "Jańa mazmun ústelgen",
"NotificationOptionPluginError": "Plagın sátsizdigi",
diff --git a/Emby.Server.Implementations/Localization/Core/sl-SI.json b/Emby.Server.Implementations/Localization/Core/sl-SI.json
index b50ff4706..531dfe51f 100644
--- a/Emby.Server.Implementations/Localization/Core/sl-SI.json
+++ b/Emby.Server.Implementations/Localization/Core/sl-SI.json
@@ -9,7 +9,7 @@
"Channels": "Kanali",
"ChapterNameValue": "Poglavje {0}",
"Collections": "Zbirke",
- "DeviceOfflineWithName": "{0} has disconnected",
+ "DeviceOfflineWithName": "{0} je prekinil povezavo",
"DeviceOnlineWithName": "{0} je povezan",
"FailedLoginAttemptWithUserName": "Neuspešen poskus prijave z {0}",
"Favorites": "Priljubljeni",
@@ -33,9 +33,9 @@
"LabelIpAddressValue": "IP naslov: {0}",
"LabelRunningTimeValue": "Čas trajanja: {0}",
"Latest": "Najnovejše",
- "MessageApplicationUpdated": "Jellyfin strežnik je bil posodobljen",
- "MessageApplicationUpdatedTo": "Jellyfin strežnik je bil posodobljen na {0}",
- "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated",
+ "MessageApplicationUpdated": "Jellyfin Server je bil posodobljen",
+ "MessageApplicationUpdatedTo": "Jellyfin Server je bil posodobljen na {0}",
+ "MessageNamedServerConfigurationUpdatedWithValue": "Oddelek nastavitve strežnika {0} je bil posodobljen",
"MessageServerConfigurationUpdated": "Nastavitve strežnika so bile posodobljene",
"MixedContent": "Razne vsebine",
"Movies": "Filmi",
@@ -57,41 +57,41 @@
"NotificationOptionPluginUninstalled": "Dodatek odstranjen",
"NotificationOptionPluginUpdateInstalled": "Posodobitev dodatka nameščena",
"NotificationOptionServerRestartRequired": "Potreben je ponovni zagon strežnika",
- "NotificationOptionTaskFailed": "Scheduled task failure",
- "NotificationOptionUserLockedOut": "User locked out",
- "NotificationOptionVideoPlayback": "Video playback started",
- "NotificationOptionVideoPlaybackStopped": "Video playback stopped",
- "Photos": "Photos",
- "Playlists": "Playlists",
+ "NotificationOptionTaskFailed": "Razporejena naloga neuspešna",
+ "NotificationOptionUserLockedOut": "Uporabnik zaklenjen",
+ "NotificationOptionVideoPlayback": "Predvajanje videa se je začelo",
+ "NotificationOptionVideoPlaybackStopped": "Predvajanje videa se je ustavilo",
+ "Photos": "Fotografije",
+ "Playlists": "Seznami predvajanja",
"Plugin": "Plugin",
- "PluginInstalledWithName": "{0} was installed",
- "PluginUninstalledWithName": "{0} was uninstalled",
- "PluginUpdatedWithName": "{0} was updated",
+ "PluginInstalledWithName": "{0} je bil nameščen",
+ "PluginUninstalledWithName": "{0} je bil odstranjen",
+ "PluginUpdatedWithName": "{0} je bil posodobljen",
"ProviderValue": "Provider: {0}",
- "ScheduledTaskFailedWithName": "{0} failed",
- "ScheduledTaskStartedWithName": "{0} started",
- "ServerNameNeedsToBeRestarted": "{0} needs to be restarted",
+ "ScheduledTaskFailedWithName": "{0} ni uspelo",
+ "ScheduledTaskStartedWithName": "{0} začeto",
+ "ServerNameNeedsToBeRestarted": "{0} mora biti ponovno zagnan",
"Shows": "Serije",
- "Songs": "Songs",
- "StartupEmbyServerIsLoading": "Jellyfin Server is loading. Please try again shortly.",
+ "Songs": "Pesmi",
+ "StartupEmbyServerIsLoading": "Jellyfin Server se nalaga. Poskusi ponovno kasneje.",
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
- "SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}",
- "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}",
- "Sync": "Sync",
+ "SubtitleDownloadFailureFromForItem": "Neuspešen prenos podnapisov iz {0} za {1}",
+ "SubtitlesDownloadedForItem": "Podnapisi preneseni za {0}",
+ "Sync": "Sinhroniziraj",
"System": "System",
- "TvShows": "TV Shows",
+ "TvShows": "TV serije",
"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": "Uporabnik {0} je bil ustvarjen",
+ "UserDeletedWithName": "Uporabnik {0} je bil izbrisan",
+ "UserDownloadingItemWithValues": "{0} prenaša {1}",
+ "UserLockedOutWithName": "Uporabnik {0} je bil zaklenjen",
+ "UserOfflineFromDevice": "{0} je prekinil povezavo z {1}",
+ "UserOnlineFromDevice": "{0} je aktiven iz {1}",
+ "UserPasswordChangedWithName": "Geslo za uporabnika {0} je bilo spremenjeno",
+ "UserPolicyUpdatedWithName": "Pravilnik uporabe je bil posodobljen za uporabnika {0}",
+ "UserStartedPlayingItemWithValues": "{0} predvaja {1} na {2}",
+ "UserStoppedPlayingItemWithValues": "{0} je nehal predvajati {1} na {2}",
+ "ValueHasBeenAddedToLibrary": "{0} je bil dodan vaši knjižnici",
"ValueSpecialEpisodeName": "Special - {0}",
"VersionNumber": "Version {0}"
}
diff --git a/Emby.Server.Implementations/Localization/Core/zh-TW.json b/Emby.Server.Implementations/Localization/Core/zh-TW.json
new file mode 100644
index 000000000..effff5566
--- /dev/null
+++ b/Emby.Server.Implementations/Localization/Core/zh-TW.json
@@ -0,0 +1,93 @@
+{
+ "Albums": "專輯",
+ "AppDeviceValues": "應用: {0}, 裝置: {1}",
+ "Application": "應用程式",
+ "Artists": "演出者",
+ "AuthenticationSucceededWithUserName": "{0} 成功授權",
+ "Books": "圖書",
+ "CameraImageUploadedFrom": "{0} 已經成功上傳一張相片",
+ "Channels": "頻道",
+ "ChapterNameValue": "章節 {0}",
+ "Collections": "合輯",
+ "DeviceOfflineWithName": "{0} 已經斷線",
+ "DeviceOnlineWithName": "{0} 已經連線",
+ "FailedLoginAttemptWithUserName": "來自 {0} 的失敗登入嘗試",
+ "Favorites": "我的最愛",
+ "Folders": "資料夾",
+ "Genres": "風格",
+ "HeaderAlbumArtists": "專輯演出者",
+ "HeaderCameraUploads": "相機上傳",
+ "HeaderContinueWatching": "繼續觀賞",
+ "HeaderFavoriteAlbums": "最愛專輯",
+ "HeaderFavoriteArtists": "最愛演出者",
+ "HeaderFavoriteEpisodes": "最愛級數",
+ "HeaderFavoriteShows": "最愛節目",
+ "HeaderFavoriteSongs": "最愛歌曲",
+ "HeaderLiveTV": "電視直播",
+ "HeaderNextUp": "接下來",
+ "HomeVideos": "自製影片",
+ "ItemAddedWithName": "{0} 已新增至媒體庫",
+ "ItemRemovedWithName": "{0} 已從媒體庫移除",
+ "LabelIpAddressValue": "IP 位置: {0}",
+ "LabelRunningTimeValue": "運行時間: {0}",
+ "Latest": "最新",
+ "MessageApplicationUpdated": "Jellyfin Server 已經更新",
+ "MessageApplicationUpdatedTo": "Jellyfin Server 已經更新至 {0}",
+ "MessageNamedServerConfigurationUpdatedWithValue": "伺服器設定 {0} 部分已經更新",
+ "MessageServerConfigurationUpdated": "伺服器設定已經更新",
+ "MixedContent": "混合內容",
+ "Movies": "電影",
+ "Music": "音樂",
+ "MusicVideos": "音樂MV",
+ "NameInstallFailed": "{0} 安裝失敗",
+ "NameSeasonNumber": "第 {0} 季",
+ "NameSeasonUnknown": "未知季數",
+ "NewVersionIsAvailable": "新版本的Jellyfin Server 軟體已經推出可供下載。",
+ "NotificationOptionApplicationUpdateAvailable": "有可用的應用程式更新",
+ "NotificationOptionApplicationUpdateInstalled": "應用程式已更新",
+ "NotificationOptionAudioPlayback": "音樂開始播放",
+ "NotificationOptionAudioPlaybackStopped": "音樂停止播放",
+ "NotificationOptionCameraImageUploaded": "相機相片已上傳",
+ "NotificationOptionInstallationFailed": "安裝失敗",
+ "NotificationOptionNewLibraryContent": "已新增新內容",
+ "NotificationOptionPluginError": "外掛失敗",
+ "NotificationOptionPluginInstalled": "外掛已安裝",
+ "NotificationOptionPluginUninstalled": "外掛已移除",
+ "NotificationOptionPluginUpdateInstalled": "已更新外掛",
+ "NotificationOptionServerRestartRequired": "伺服器需要重新啟動",
+ "NotificationOptionTaskFailed": "排程任務失敗",
+ "NotificationOptionUserLockedOut": "使用者已鎖定",
+ "NotificationOptionVideoPlayback": "影片開始播放",
+ "NotificationOptionVideoPlaybackStopped": "影片停止播放",
+ "Photos": "相片",
+ "Playlists": "播放清單",
+ "Plugin": "外掛",
+ "PluginInstalledWithName": "{0} 已安裝",
+ "PluginUninstalledWithName": "{0} 已移除",
+ "PluginUpdatedWithName": "{0} 已更新",
+ "ProviderValue": "提供商: {0}",
+ "ScheduledTaskFailedWithName": "{0} 已失敗",
+ "ScheduledTaskStartedWithName": "{0} 已開始",
+ "ServerNameNeedsToBeRestarted": "{0} 需要重新啟動",
+ "Shows": "節目",
+ "Songs": "歌曲",
+ "StartupEmbyServerIsLoading": "Jellyfin Server正在啟動,請稍後再試一次。",
+ "SubtitlesDownloadedForItem": "已為 {0} 下載字幕",
+ "Sync": "同步",
+ "System": "系統",
+ "TvShows": "電視節目",
+ "User": "使用者",
+ "UserCreatedWithName": "使用者 {0} 已建立",
+ "UserDeletedWithName": "使用者 {0} 已移除",
+ "UserDownloadingItemWithValues": "{0} 正在下載 {1}",
+ "UserLockedOutWithName": "使用者 {0} 已鎖定",
+ "UserOfflineFromDevice": "{0} 已從 {1} 斷線",
+ "UserOnlineFromDevice": "{0} 已連線,來自 {1}",
+ "UserPasswordChangedWithName": "使用者 {0} 的密碼已變更",
+ "UserPolicyUpdatedWithName": "使用者條約已更新為 {0}",
+ "UserStartedPlayingItemWithValues": "{0}正在使用 {2} 播放 {1}",
+ "UserStoppedPlayingItemWithValues": "{0} 已停止在 {2} 播放 {1}",
+ "ValueHasBeenAddedToLibrary": "{0} 已新增至您的媒體庫",
+ "ValueSpecialEpisodeName": "特典 - {0}",
+ "VersionNumber": "版本 {0}"
+}
diff --git a/Emby.Server.Implementations/Udp/UdpServer.cs b/Emby.Server.Implementations/Udp/UdpServer.cs
index bd86c6cdc..e7cda2993 100644
--- a/Emby.Server.Implementations/Udp/UdpServer.cs
+++ b/Emby.Server.Implementations/Udp/UdpServer.cs
@@ -41,8 +41,6 @@ namespace Emby.Server.Implementations.Udp
_socketFactory = socketFactory;
AddMessageResponder("who is JellyfinServer?", true, RespondToV2Message);
- AddMessageResponder("who is EmbyServer?", true, RespondToV2Message);
- AddMessageResponder("who is MediaBrowserServer_v2?", false, RespondToV2Message);
}
private void AddMessageResponder(string message, bool isSubstring, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task> responder)
diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs
index 7310de55d..6833c20c3 100644
--- a/Emby.Server.Implementations/Updates/InstallationManager.cs
+++ b/Emby.Server.Implementations/Updates/InstallationManager.cs
@@ -509,6 +509,8 @@ namespace Emby.Server.Implementations.Updates
private async Task PerformPackageInstallation(IProgress<double> progress, string target, PackageVersionInfo package, CancellationToken cancellationToken)
{
+ // TODO: Remove the `string target` argument as it is not used any longer
+
var extension = Path.GetExtension(package.targetFilename);
var isArchive = string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase);
@@ -518,12 +520,12 @@ namespace Emby.Server.Implementations.Updates
return;
}
- if (target == null)
- {
- target = Path.Combine(_appPaths.PluginsPath, Path.GetFileNameWithoutExtension(package.targetFilename));
- }
+ // Always override the passed-in target (which is a file) and figure it out again
+ target = Path.Combine(_appPaths.PluginsPath, package.name);
+ _logger.LogDebug("Installing plugin to {Filename}.", target);
// Download to temporary file so that, if interrupted, it won't destroy the existing installation
+ _logger.LogDebug("Downloading ZIP.");
var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
{
Url = package.sourceUrl,
@@ -536,9 +538,17 @@ namespace Emby.Server.Implementations.Updates
// TODO: Validate with a checksum, *properly*
+ // Check if the target directory already exists, and remove it if so
+ if (Directory.Exists(target))
+ {
+ _logger.LogDebug("Deleting existing plugin at {Filename}.", target);
+ Directory.Delete(target, true);
+ }
+
// Success - move it to the real target
try
{
+ _logger.LogDebug("Extracting ZIP {TempFile} to {Filename}.", tempFile, target);
using (var stream = File.OpenRead(tempFile))
{
_zipClient.ExtractAllFromZip(stream, target, true);
@@ -552,6 +562,7 @@ namespace Emby.Server.Implementations.Updates
try
{
+ _logger.LogDebug("Deleting temporary file {Filename}.", tempFile);
_fileSystem.DeleteFile(tempFile);
}
catch (IOException ex)
@@ -574,7 +585,13 @@ namespace Emby.Server.Implementations.Updates
_applicationHost.RemovePlugin(plugin);
var path = plugin.AssemblyFilePath;
- _logger.LogInformation("Deleting plugin file {0}", path);
+ bool isDirectory = false;
+ // Check if we have a plugin directory we should remove too
+ if (Path.GetDirectoryName(plugin.AssemblyFilePath) != _appPaths.PluginsPath)
+ {
+ path = Path.GetDirectoryName(plugin.AssemblyFilePath);
+ isDirectory = true;
+ }
// Make this case-insensitive to account for possible incorrect assembly naming
var file = _fileSystem.GetFilePaths(Path.GetDirectoryName(path))
@@ -585,7 +602,16 @@ namespace Emby.Server.Implementations.Updates
path = file;
}
- _fileSystem.DeleteFile(path);
+ if (isDirectory)
+ {
+ _logger.LogInformation("Deleting plugin directory {0}", path);
+ Directory.Delete(path, true);
+ }
+ else
+ {
+ _logger.LogInformation("Deleting plugin file {0}", path);
+ _fileSystem.DeleteFile(path);
+ }
var list = _config.Configuration.UninstalledPlugins.ToList();
var filename = Path.GetFileName(path);