Merge pull request #1252 from jellyfin/release-10.3.z
Backmerge release 10.3.0
This commit is contained in:
commit
a8da122fb3
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 6.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 13 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.2 KiB |
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
return true;
|
||||
if(authenticationResult.Username != username)
|
||||
{
|
||||
_logger.LogDebug("Authentication provider provided updated username {1}", authenticationResult.Username);
|
||||
username = authenticationResult.Username;
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -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}"
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "Σύστημα",
|
||||
|
|
|
@ -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}"
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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}"
|
||||
}
|
||||
|
|
93
Emby.Server.Implementations/Localization/Core/zh-TW.json
Normal file
93
Emby.Server.Implementations/Localization/Core/zh-TW.json
Normal file
|
@ -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}"
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit ec5a3b6e5efb6041153b92818aee562f20ee994d
|
||||
Subproject commit 874b51234ee4e1f01e2e7410980a1003f316d6a2
|
|
@ -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")]
|
||||
|
|
|
@ -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
|
||||
|
|
17
bump_version
17
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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user