aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBond-009 <bond.009@outlook.com>2019-04-20 12:25:29 +0200
committerGitHub <noreply@github.com>2019-04-20 12:25:29 +0200
commita8da122fb3c9c1f66f43da01099fb6aa86d554c6 (patch)
tree12fbf29535844df988492d06420beadab0ac190c
parent7bea62adbfc7350c01a222cb92c86c13c0b43412 (diff)
parent46c37c0ae8d5b5de02ff6f8208a7b91436f54237 (diff)
Merge pull request #1252 from jellyfin/release-10.3.z
Backmerge release 10.3.0
-rw-r--r--Dockerfile8
-rw-r--r--Dockerfile.arm6
-rw-r--r--Dockerfile.arm646
-rw-r--r--Emby.Dlna/Images/logo120.pngbin7522 -> 6201 bytes
-rw-r--r--Emby.Dlna/Images/logo240.pngbin18287 -> 13339 bytes
-rw-r--r--Emby.Dlna/Images/logo48.pngbin2554 -> 2263 bytes
-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
-rw-r--r--MediaBrowser.Api/UserService.cs7
-rw-r--r--MediaBrowser.Common/Extensions/ResourceNotFoundException.cs24
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs5
-rw-r--r--MediaBrowser.Model/System/PublicSystemInfo.cs5
-rw-r--r--MediaBrowser.Model/System/SystemInfo.cs4
m---------MediaBrowser.WebDashboard/jellyfin-web0
-rw-r--r--SharedVersion.cs4
-rw-r--r--build.yaml2
-rwxr-xr-xbump_version17
-rw-r--r--deployment/debian-package-x64/pkg-src/changelog6
-rw-r--r--deployment/fedora-package-x64/pkg-src/jellyfin.spec4
-rw-r--r--deployment/windows/build-jellyfin.ps16
-rw-r--r--deployment/windows/install-jellyfin.ps110
32 files changed, 390 insertions, 199 deletions
diff --git a/Dockerfile b/Dockerfile
index 5794bdde1..050f8fc49 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,6 @@
-ARG DOTNET_VERSION=2
+ARG DOTNET_VERSION=2.2
-FROM microsoft/dotnet:${DOTNET_VERSION}-sdk as builder
+FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION} as builder
WORKDIR /repo
COPY . .
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
@@ -8,7 +8,7 @@ RUN bash -c "source deployment/common.build.sh && \
build_jellyfin Jellyfin.Server Release linux-x64 /jellyfin"
FROM jellyfin/ffmpeg as ffmpeg
-FROM microsoft/dotnet:${DOTNET_VERSION}-runtime
+FROM mcr.microsoft.com/dotnet/core/runtime:${DOTNET_VERSION}
# libfontconfig1 is required for Skia
RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y \
@@ -21,7 +21,7 @@ RUN apt-get update \
COPY --from=ffmpeg / /
COPY --from=builder /jellyfin /jellyfin
-ARG JELLYFIN_WEB_VERSION=10.2.2
+ARG JELLYFIN_WEB_VERSION=10.3.0
RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \
&& mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web
diff --git a/Dockerfile.arm b/Dockerfile.arm
index 1497da0ef..81089b519 100644
--- a/Dockerfile.arm
+++ b/Dockerfile.arm
@@ -8,7 +8,7 @@ FROM alpine as qemu_extract
COPY --from=qemu /usr/bin qemu-arm-static.tar.gz
RUN tar -xzvf qemu-arm-static.tar.gz
-FROM microsoft/dotnet:${DOTNET_VERSION}-sdk-stretch as builder
+FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION} as builder
WORKDIR /repo
COPY . .
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
@@ -21,7 +21,7 @@ RUN bash -c "source deployment/common.build.sh && \
build_jellyfin Jellyfin.Server Release linux-arm /jellyfin"
-FROM microsoft/dotnet:${DOTNET_VERSION}-runtime-stretch-slim-arm32v7
+FROM mcr.microsoft.com/dotnet/core/runtime:${DOTNET_VERSION}-stretch-slim-arm32v7
COPY --from=qemu_extract qemu-arm-static /usr/bin
RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
@@ -30,7 +30,7 @@ RUN apt-get update \
&& chmod 777 /cache /config /media
COPY --from=builder /jellyfin /jellyfin
-ARG JELLYFIN_WEB_VERSION=10.2.2
+ARG JELLYFIN_WEB_VERSION=10.3.0
RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \
&& mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web
diff --git a/Dockerfile.arm64 b/Dockerfile.arm64
index f4658a055..1ad4dc5a2 100644
--- a/Dockerfile.arm64
+++ b/Dockerfile.arm64
@@ -9,7 +9,7 @@ COPY --from=qemu /usr/bin qemu-aarch64-static.tar.gz
RUN tar -xzvf qemu-aarch64-static.tar.gz
-FROM microsoft/dotnet:${DOTNET_VERSION}-sdk-stretch as builder
+FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION} as builder
WORKDIR /repo
COPY . .
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
@@ -22,7 +22,7 @@ RUN bash -c "source deployment/common.build.sh && \
build_jellyfin Jellyfin.Server Release linux-arm64 /jellyfin"
-FROM microsoft/dotnet:${DOTNET_VERSION}-runtime-stretch-slim-arm64v8
+FROM mcr.microsoft.com/dotnet/core/runtime:${DOTNET_VERSION}-stretch-slim-arm64v8
COPY --from=qemu_extract qemu-aarch64-static /usr/bin
RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
@@ -31,7 +31,7 @@ RUN apt-get update \
&& chmod 777 /cache /config /media
COPY --from=builder /jellyfin /jellyfin
-ARG JELLYFIN_WEB_VERSION=10.2.2
+ARG JELLYFIN_WEB_VERSION=10.3.0
RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \
&& mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web
diff --git a/Emby.Dlna/Images/logo120.png b/Emby.Dlna/Images/logo120.png
index 321c47729..14f6c8d5f 100644
--- a/Emby.Dlna/Images/logo120.png
+++ b/Emby.Dlna/Images/logo120.png
Binary files differ
diff --git a/Emby.Dlna/Images/logo240.png b/Emby.Dlna/Images/logo240.png
index 64c828129..ff50314d4 100644
--- a/Emby.Dlna/Images/logo240.png
+++ b/Emby.Dlna/Images/logo240.png
Binary files differ
diff --git a/Emby.Dlna/Images/logo48.png b/Emby.Dlna/Images/logo48.png
index b8fc14564..d6b5fd1df 100644
--- a/Emby.Dlna/Images/logo48.png
+++ b/Emby.Dlna/Images/logo48.png
Binary files differ
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);
diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs
index a6849f75f..497800d26 100644
--- a/MediaBrowser.Api/UserService.cs
+++ b/MediaBrowser.Api/UserService.cs
@@ -379,10 +379,15 @@ namespace MediaBrowser.Api
throw new ResourceNotFoundException("User not found");
}
+ if (!string.IsNullOrEmpty(request.Password) && string.IsNullOrEmpty(request.Pw))
+ {
+ throw new MethodNotAllowedException("Hashed-only passwords are not valid for this API.");
+ }
+
return Post(new AuthenticateUserByName
{
Username = user.Name,
- Password = request.Password,
+ Password = null, // This should always be null
Pw = request.Pw
});
}
diff --git a/MediaBrowser.Common/Extensions/ResourceNotFoundException.cs b/MediaBrowser.Common/Extensions/ResourceNotFoundException.cs
index f62c65fd7..9f70ae7d8 100644
--- a/MediaBrowser.Common/Extensions/ResourceNotFoundException.cs
+++ b/MediaBrowser.Common/Extensions/ResourceNotFoundException.cs
@@ -26,6 +26,30 @@ namespace MediaBrowser.Common.Extensions
}
}
+ /// <summary>
+ /// Class MethodNotAllowedException
+ /// </summary>
+ public class MethodNotAllowedException : Exception
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MethodNotAllowedException" /> class.
+ /// </summary>
+ public MethodNotAllowedException()
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MethodNotAllowedException" /> class.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ public MethodNotAllowedException(string message)
+ : base(message)
+ {
+
+ }
+ }
+
public class RemoteServiceUnavailableException : Exception
{
public RemoteServiceUnavailableException()
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index 4867c0f85..b626600fa 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -230,6 +230,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <returns></returns>
private string ExistsOnSystemPath(string filename)
{
+ string inJellyfinPath = GetEncoderPathFromDirectory(System.AppContext.BaseDirectory, filename);
+ if (!string.IsNullOrEmpty(inJellyfinPath))
+ {
+ return inJellyfinPath;
+ }
var values = Environment.GetEnvironmentVariable("PATH");
foreach (var path in values.Split(Path.PathSeparator))
diff --git a/MediaBrowser.Model/System/PublicSystemInfo.cs b/MediaBrowser.Model/System/PublicSystemInfo.cs
index d97eda352..d6e031e42 100644
--- a/MediaBrowser.Model/System/PublicSystemInfo.cs
+++ b/MediaBrowser.Model/System/PublicSystemInfo.cs
@@ -25,6 +25,11 @@ namespace MediaBrowser.Model.System
/// </summary>
/// <value>The version.</value>
public string Version { get; set; }
+
+ /// <summary>
+ /// The product name. This is the AssemblyProduct name.
+ /// </summary>
+ public string ProductName { get; set; }
/// <summary>
/// Gets or sets the operating system.
diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs
index 222c10798..3f73cc4e0 100644
--- a/MediaBrowser.Model/System/SystemInfo.cs
+++ b/MediaBrowser.Model/System/SystemInfo.cs
@@ -32,10 +32,6 @@ namespace MediaBrowser.Model.System
/// <value>The display name of the operating system.</value>
public string OperatingSystemDisplayName { get; set; }
- /// <summary>
- /// The product name. This is the AssemblyProduct name.
- /// </summary>
- public string ProductName { get; set; }
/// <summary>
/// Get or sets the package name.
diff --git a/MediaBrowser.WebDashboard/jellyfin-web b/MediaBrowser.WebDashboard/jellyfin-web
-Subproject ec5a3b6e5efb6041153b92818aee562f20ee994
+Subproject 874b51234ee4e1f01e2e7410980a1003f316d6a
diff --git a/SharedVersion.cs b/SharedVersion.cs
index 785ba9301..3a0263bd6 100644
--- a/SharedVersion.cs
+++ b/SharedVersion.cs
@@ -1,4 +1,4 @@
using System.Reflection;
-[assembly: AssemblyVersion("10.2.2")]
-[assembly: AssemblyFileVersion("10.2.2")]
+[assembly: AssemblyVersion("10.3.0")]
+[assembly: AssemblyFileVersion("10.3.0")]
diff --git a/build.yaml b/build.yaml
index 289c1cadd..47ca589f8 100644
--- a/build.yaml
+++ b/build.yaml
@@ -1,7 +1,7 @@
---
# We just wrap `build` so this is really it
name: "jellyfin"
-version: "10.2.2"
+version: "10.3.0"
packages:
- debian-package-x64
- debian-package-armhf
diff --git a/bump_version b/bump_version
index b118af54b..398caee15 100755
--- a/bump_version
+++ b/bump_version
@@ -54,6 +54,7 @@ old_version="$(
grep "AssemblyVersion" ${shared_version_file} \
| sed -E 's/\[assembly: ?AssemblyVersion\("([0-9\.]+)"\)\]/\1/'
)"
+echo $old_version
# Set the shared version to the specified new_version
old_version_sed="$( sed 's/\./\\./g' <<<"${old_version}" )" # Escape the '.' chars
@@ -62,9 +63,11 @@ sed -i "s/${old_version_sed}/${new_version_sed}/g" ${shared_version_file}
old_version="$(
grep "version:" ${build_file} \
- | sed -E 's/version: "([0-9\.]+)"/\1/'
+ | sed -E 's/version: "([0-9\.]+[-a-z0-9]*)"/\1/'
)"
+echo $old_version
+# Set the build.yaml version to the specified new_version
old_version_sed="$( sed 's/\./\\./g' <<<"${old_version}" )" # Escape the '.' chars
sed -i "s/${old_version_sed}/${new_version}/g" ${build_file}
@@ -74,6 +77,16 @@ else
new_version_deb="${new_version}-1"
fi
+# Set the Dockerfile web version to the specified new_version
+old_version="$(
+ grep "JELLYFIN_WEB_VERSION=" Dockerfile \
+ | sed -E 's/ARG JELLYFIN_WEB_VERSION=([0-9\.]+[-a-z0-9]*)/\1/'
+)"
+echo $old_version
+
+old_version_sed="$( sed 's/\./\\./g' <<<"${old_version}" )" # Escape the '.' chars
+sed -i "s/${old_version_sed}/${new_version}/g" Dockerfile*
+
# Write out a temporary Debian changelog with our new stuff appended and some templated formatting
debian_changelog_file="deployment/debian-package-x64/pkg-src/changelog"
debian_changelog_temp="$( mktemp )"
@@ -124,5 +137,5 @@ mv ${fedora_spec_temp} ${fedora_spec_file}
rm -rf ${fedora_changelog_temp} ${fedora_spec_temp_dir}
# Stage the changed files for commit
-git add ${shared_version_file} ${build_file} ${debian_changelog_file} ${fedora_spec_file}
+git add ${shared_version_file} ${build_file} ${debian_changelog_file} ${fedora_spec_file} Dockerfile*
git status
diff --git a/deployment/debian-package-x64/pkg-src/changelog b/deployment/debian-package-x64/pkg-src/changelog
index 349e8787f..3908c277b 100644
--- a/deployment/debian-package-x64/pkg-src/changelog
+++ b/deployment/debian-package-x64/pkg-src/changelog
@@ -1,3 +1,9 @@
+jellyfin (10.3.0-1) unstable; urgency=medium
+
+ * New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0
+
+ -- Jellyfin Packaging Team <packaging@jellyfin.org> Fri, 19 Apr 2019 14:24:29 -0400
+
jellyfin (10.2.2-1) unstable; urgency=medium
* jellyfin:
diff --git a/deployment/fedora-package-x64/pkg-src/jellyfin.spec b/deployment/fedora-package-x64/pkg-src/jellyfin.spec
index e24bd2fcb..36fe78c62 100644
--- a/deployment/fedora-package-x64/pkg-src/jellyfin.spec
+++ b/deployment/fedora-package-x64/pkg-src/jellyfin.spec
@@ -7,7 +7,7 @@
%endif
Name: jellyfin
-Version: 10.2.2
+Version: 10.3.0
Release: 1%{?dist}
Summary: The Free Software Media Browser
License: GPLv2
@@ -140,6 +140,8 @@ fi
%systemd_postun_with_restart jellyfin.service
%changelog
+* Fri Apr 19 2019 Jellyfin Packaging Team <packaging@jellyfin.org>
+- New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0
* Thu Feb 28 2019 Jellyfin Packaging Team <packaging@jellyfin.org>
- jellyfin:
- PR968 Release 10.2.z copr autobuild
diff --git a/deployment/windows/build-jellyfin.ps1 b/deployment/windows/build-jellyfin.ps1
index 2c83f264c..2999912b3 100644
--- a/deployment/windows/build-jellyfin.ps1
+++ b/deployment/windows/build-jellyfin.ps1
@@ -26,7 +26,10 @@ function Build-JellyFin {
Write-Error "arm only supported with Windows 8 or higher"
exit
}
- dotnet publish -c $BuildType -r "$windowsversion-$Architecture" MediaBrowser.sln -o $InstallLocation -v $DotNetVerbosity
+ Write-Verbose "windowsversion-Architecture: $windowsversion-$Architecture"
+ Write-Verbose "InstallLocation: $InstallLocation"
+ Write-Verbose "DotNetVerbosity: $DotNetVerbosity"
+ dotnet publish -c $BuildType -r `"$windowsversion-$Architecture`" MediaBrowser.sln -o $InstallLocation -v $DotNetVerbosity
}
function Install-FFMPEG {
@@ -73,6 +76,7 @@ function Install-NSSM {
Write-Warning "NSSM will not be installed"
}else{
Write-Verbose "Downloading NSSM"
+ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri https://nssm.cc/ci/nssm-2.24-101-g897c7ad.zip -UseBasicParsing -OutFile "$tempdir/nssm.zip" | Write-Verbose
}
diff --git a/deployment/windows/install-jellyfin.ps1 b/deployment/windows/install-jellyfin.ps1
index b6e00e056..0cd7f5236 100644
--- a/deployment/windows/install-jellyfin.ps1
+++ b/deployment/windows/install-jellyfin.ps1
@@ -58,7 +58,7 @@ function Elevate-Window {
if($Quiet.IsPresent -or $Quiet -eq $true){
if([string]::IsNullOrEmpty($JellyfinLibraryLocation)){
- $Script:JellyfinDataDir = "$env:AppData\jellyfin\"
+ $Script:JellyfinDataDir = "$env:LOCALAPPDATA\jellyfin\"
}else{
$Script:JellyfinDataDir = $JellyfinLibraryLocation
}
@@ -82,7 +82,7 @@ if($Quiet.IsPresent -or $Quiet -eq $true){
}else{
$Script:InstallServiceAsUser = $true
$Script:UserCredentials = $ServiceUser
- $Script:JellyfinDataDir = "C:\Users\$($Script:UserCredentials.UserName)\Appdata\Roaming\jellyfin\"}
+ $Script:JellyfinDataDir = "$env:HOMEDRIVE\Users\$($Script:UserCredentials.UserName)\Appdata\Local\jellyfin\"}
if($CreateDesktopShorcut.IsPresent -or $CreateDesktopShorcut -eq $true) {$Script:CreateShortcut = $true}else{$Script:CreateShortcut = $false}
if($MigrateEmbyLibrary.IsPresent -or $MigrateEmbyLibrary -eq $true){$Script:MigrateLibrary = $true}else{$Script:MigrateLibrary = $false}
if($LaunchJellyfin.IsPresent -or $LaunchJellyfin -eq $true){$Script:StartJellyfin = $true}else{$Script:StartJellyfin = $false}
@@ -131,7 +131,7 @@ if($Quiet.IsPresent -or $Quiet -eq $true){
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
-$Script:JellyFinDataDir = "$env:AppData\jellyfin\"
+$Script:JellyFinDataDir = "$env:LOCALAPPDATA\jellyfin\"
$Script:DefaultJellyfinInstallDirectory = "$env:Appdata\jellyfin\"
$Script:defaultEmbyDataDir = "$env:Appdata\Emby-Server\"
$Script:InstallAsService = $False
@@ -392,7 +392,7 @@ $ServiceUserBox.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDow
$GUIElementsCollection += $ServiceUserBox
$MigrateLibraryCheck = New-Object system.Windows.Forms.CheckBox
-$MigrateLibraryCheck.text = "Import Emby Library"
+$MigrateLibraryCheck.text = "Import Emby/Old JF Library"
$MigrateLibraryCheck.AutoSize = $false
$MigrateLibraryCheck.width = 160
$MigrateLibraryCheck.height = 20
@@ -401,7 +401,7 @@ $MigrateLibraryCheck.Font = 'Microsoft Sans Serif,10'
$GUIElementsCollection += $MigrateLibraryCheck
$LibraryMigrationLabel = New-Object system.Windows.Forms.Label
-$LibraryMigrationLabel.text = "Emby Library Path"
+$LibraryMigrationLabel.text = "Emby/Old JF Library Path"
$LibraryMigrationLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleLeft
$LibraryMigrationLabel.AutoSize = $false
$LibraryMigrationLabel.width = 120