diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 5ed77356b8..e6ec38846b 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -734,7 +734,9 @@ namespace MediaBrowser.Api.Playback { if (audioStream != null) { - if (audioStream.Channels > 2 && string.Equals(request.AudioCodec, "wma", StringComparison.OrdinalIgnoreCase)) + var codec = request.AudioCodec ?? string.Empty; + + if (audioStream.Channels > 2 && codec.IndexOf("wma", StringComparison.OrdinalIgnoreCase) != -1) { // wmav2 currently only supports two channel output return 2; diff --git a/MediaBrowser.Api/SessionsService.cs b/MediaBrowser.Api/SessionsService.cs index a509c876ce..1f3bcf75be 100644 --- a/MediaBrowser.Api/SessionsService.cs +++ b/MediaBrowser.Api/SessionsService.cs @@ -146,7 +146,36 @@ namespace MediaBrowser.Api /// /// The play command. [ApiMember(Name = "Command", Description = "The command to send.", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public SystemCommand Command { get; set; } + public string Command { get; set; } + } + + [Route("/Sessions/{Id}/Command/{Command}", "POST", Summary = "Issues a system command to a client")] + public class SendGeneralCommand : IReturnVoid + { + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public Guid Id { get; set; } + + /// + /// Gets or sets the command. + /// + /// The play command. + [ApiMember(Name = "Command", Description = "The command to send.", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public string Command { get; set; } + } + + [Route("/Sessions/{Id}/Command", "POST", Summary = "Issues a system command to a client")] + public class SendFullGeneralCommand : GeneralCommand, IReturnVoid + { + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public Guid Id { get; set; } } [Route("/Sessions/{Id}/Message", "POST", Summary = "Issues a command to a client to display a message to the user")] @@ -301,9 +330,22 @@ namespace MediaBrowser.Api /// The request. public void Post(SendSystemCommand request) { - var task = _sessionManager.SendSystemCommand(GetSession().Id, request.Id, request.Command, CancellationToken.None); + GeneralCommandType commandType; - Task.WaitAll(task); + if (Enum.TryParse(request.Command, true, out commandType)) + { + var currentSession = GetSession(); + + var command = new GeneralCommand + { + Name = commandType.ToString(), + ControllingUserId = currentSession.UserId.HasValue ? currentSession.UserId.Value.ToString("N") : null + }; + + var task = _sessionManager.SendGeneralCommand(currentSession.Id, request.Id, command, CancellationToken.None); + + Task.WaitAll(task); + } } /// @@ -343,6 +385,32 @@ namespace MediaBrowser.Api Task.WaitAll(task); } + public void Post(SendGeneralCommand request) + { + var currentSession = GetSession(); + + var command = new GeneralCommand + { + Name = request.Command, + ControllingUserId = currentSession.UserId.HasValue ? currentSession.UserId.Value.ToString("N") : null + }; + + var task = _sessionManager.SendGeneralCommand(currentSession.Id, request.Id, command, CancellationToken.None); + + Task.WaitAll(task); + } + + public void Post(SendFullGeneralCommand request) + { + var currentSession = GetSession(); + + request.ControllingUserId = currentSession.UserId.HasValue ? currentSession.UserId.Value.ToString("N") : null; + + var task = _sessionManager.SendGeneralCommand(currentSession.Id, request.Id, request, CancellationToken.None); + + Task.WaitAll(task); + } + public void Post(AddUserToSession request) { _sessionManager.AddAdditionalUser(request.Id, request.UserId); diff --git a/MediaBrowser.Controller/Session/ISessionController.cs b/MediaBrowser.Controller/Session/ISessionController.cs index 02cc875bd0..cf57f6621e 100644 --- a/MediaBrowser.Controller/Session/ISessionController.cs +++ b/MediaBrowser.Controller/Session/ISessionController.cs @@ -19,14 +19,6 @@ namespace MediaBrowser.Controller.Session /// true if this instance is session active; otherwise, false. bool IsSessionActive { get; } - /// - /// Sends the system command. - /// - /// The command. - /// The cancellation token. - /// Task. - Task SendSystemCommand(SystemCommand command, CancellationToken cancellationToken); - /// /// Sends the message command. /// @@ -65,7 +57,7 @@ namespace MediaBrowser.Controller.Session /// The command. /// The cancellation token. /// Task. - Task SendGenericCommand(GenericCommand command, CancellationToken cancellationToken); + Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken); /// /// Sends the library update info. diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index 459e43d081..434c513360 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -84,15 +84,15 @@ namespace MediaBrowser.Controller.Session Task ReportSessionEnded(Guid sessionId); /// - /// Sends the system command. + /// Sends the general command. /// /// The controlling session identifier. - /// The session id. + /// The session identifier. /// The command. /// The cancellation token. /// Task. - Task SendSystemCommand(Guid controllingSessionId, Guid sessionId, SystemCommand command, CancellationToken cancellationToken); - + Task SendGeneralCommand(Guid controllingSessionId, Guid sessionId, GeneralCommand command, CancellationToken cancellationToken); + /// /// Sends the message command. /// diff --git a/MediaBrowser.Dlna/PlayTo/DlnaController.cs b/MediaBrowser.Dlna/PlayTo/DlnaController.cs index 0c9f292ad8..96df8c8622 100644 --- a/MediaBrowser.Dlna/PlayTo/DlnaController.cs +++ b/MediaBrowser.Dlna/PlayTo/DlnaController.cs @@ -308,25 +308,6 @@ namespace MediaBrowser.Dlna.PlayTo return Task.FromResult(true); } - public Task SendSystemCommand(SystemCommand command, CancellationToken cancellationToken) - { - switch (command) - { - case SystemCommand.VolumeDown: - return _device.VolumeDown(); - case SystemCommand.VolumeUp: - return _device.VolumeUp(); - case SystemCommand.Mute: - return _device.VolumeDown(true); - case SystemCommand.Unmute: - return _device.VolumeUp(true); - case SystemCommand.ToggleMute: - return _device.ToggleMute(); - default: - return Task.FromResult(true); - } - } - public Task SendUserDataChangeInfo(UserDataChangeInfo info, CancellationToken cancellationToken) { return Task.FromResult(true); @@ -620,9 +601,30 @@ namespace MediaBrowser.Dlna.PlayTo } } - public Task SendGenericCommand(GenericCommand command, CancellationToken cancellationToken) + public Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken) { - throw new NotImplementedException(); + GeneralCommandType commandType; + + if (!Enum.TryParse(command.Name, true, out commandType)) + { + switch (commandType) + { + case GeneralCommandType.VolumeDown: + return _device.VolumeDown(); + case GeneralCommandType.VolumeUp: + return _device.VolumeUp(); + case GeneralCommandType.Mute: + return _device.VolumeDown(true); + case GeneralCommandType.Unmute: + return _device.VolumeUp(true); + case GeneralCommandType.ToggleMute: + return _device.ToggleMute(); + default: + return Task.FromResult(true); + } + } + + return Task.FromResult(true); } } } diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs index 79d512dc1d..4a9023c7f3 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs @@ -180,7 +180,9 @@ namespace MediaBrowser.MediaEncoding.Encoder { if (audioStream != null) { - if (audioStream.Channels > 2 && string.Equals(request.AudioCodec, "wma", StringComparison.OrdinalIgnoreCase)) + var codec = request.AudioCodec ?? string.Empty; + + if (audioStream.Channels > 2 && codec.IndexOf("wma", StringComparison.OrdinalIgnoreCase) != -1) { // wmav2 currently only supports two channel output return 2; diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 93df0c8b91..675d43be74 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -768,7 +768,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } // Use ffmpeg to sample 100 (we can drop this if required using thumbnail=50 for 50 frames) frames and pick the best thumbnail. Have a fall back just in case. - var args = useIFrame ? string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2},thumbnail=80\" -f image2 \"{1}\"", inputPath, "-", vf) : + var args = useIFrame ? string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2},thumbnail=50\" -f image2 \"{1}\"", inputPath, "-", vf) : string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, "-", vf); var probeSize = GetProbeSizeArgument(type); diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index 6c4d9d9e29..00fb2131c6 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -428,8 +428,8 @@ Session\BrowseRequest.cs - - Session\GenericCommand.cs + + Session\GeneralCommand.cs Session\MessageCommand.cs @@ -449,9 +449,6 @@ Session\SessionInfoDto.cs - - Session\SystemCommand.cs - Session\UserDataChangeInfo.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index b39cecc61d..f8bc2a600f 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -415,8 +415,8 @@ Session\BrowseRequest.cs - - Session\GenericCommand.cs + + Session\GeneralCommand.cs Session\MessageCommand.cs @@ -436,9 +436,6 @@ Session\SessionInfoDto.cs - - Session\SystemCommand.cs - Session\UserDataChangeInfo.cs diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 28c5822e9a..dc5e26be3d 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -593,17 +593,9 @@ namespace MediaBrowser.Model.ApiClient /// Sends the command asynchronous. /// /// The session identifier. - /// The request. - /// Task. - Task SendCommandAsync(string sessionId, GenericCommand request); - - /// - /// Sends a system command to the client - /// - /// The session id. /// The command. /// Task. - Task SendSystemCommandAsync(string sessionId, SystemCommand command); + Task SendCommandAsync(string sessionId, GeneralCommand command); /// /// Instructs the client to display a message to the user diff --git a/MediaBrowser.Model/ApiClient/IServerEvents.cs b/MediaBrowser.Model/ApiClient/IServerEvents.cs index 0a38c63adc..63135baa2c 100644 --- a/MediaBrowser.Model/ApiClient/IServerEvents.cs +++ b/MediaBrowser.Model/ApiClient/IServerEvents.cs @@ -1,4 +1,5 @@ -using System; +using MediaBrowser.Model.Session; +using System; namespace MediaBrowser.Model.ApiClient { @@ -66,7 +67,7 @@ namespace MediaBrowser.Model.ApiClient /// /// Occurs when [system command]. /// - event EventHandler SystemCommand; + event EventHandler GeneralCommand; /// /// Occurs when [notification added]. /// diff --git a/MediaBrowser.Model/ApiClient/ServerEventArgs.cs b/MediaBrowser.Model/ApiClient/ServerEventArgs.cs index d3212caf45..b7f709e957 100644 --- a/MediaBrowser.Model/ApiClient/ServerEventArgs.cs +++ b/MediaBrowser.Model/ApiClient/ServerEventArgs.cs @@ -152,13 +152,13 @@ namespace MediaBrowser.Model.ApiClient /// /// Class SystemCommandEventArgs /// - public class SystemCommandEventArgs : EventArgs + public class GeneralCommandEventArgs : EventArgs { /// /// Gets or sets the command. /// /// The command. - public SystemCommand Command { get; set; } + public GeneralCommand Command { get; set; } } /// diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 207543fe88..0859f69998 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -132,7 +132,7 @@ - + @@ -171,7 +171,6 @@ - diff --git a/MediaBrowser.Model/Session/GenericCommand.cs b/MediaBrowser.Model/Session/GeneralCommand.cs similarity index 91% rename from MediaBrowser.Model/Session/GenericCommand.cs rename to MediaBrowser.Model/Session/GeneralCommand.cs index f7ea0a84a5..0de7d6dd8e 100644 --- a/MediaBrowser.Model/Session/GenericCommand.cs +++ b/MediaBrowser.Model/Session/GeneralCommand.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace MediaBrowser.Model.Session { - public class GenericCommand + public class GeneralCommand { public string Name { get; set; } @@ -11,7 +11,7 @@ namespace MediaBrowser.Model.Session public Dictionary Arguments { get; set; } - public GenericCommand() + public GeneralCommand() { Arguments = new Dictionary(StringComparer.OrdinalIgnoreCase); } @@ -20,7 +20,7 @@ namespace MediaBrowser.Model.Session /// /// This exists simply to identify a set of known commands. /// - public enum CoreGenericCommand + public enum GeneralCommandType { MoveUp = 0, MoveDown = 1, diff --git a/MediaBrowser.Model/Session/SystemCommand.cs b/MediaBrowser.Model/Session/SystemCommand.cs deleted file mode 100644 index 2fcaef6e39..0000000000 --- a/MediaBrowser.Model/Session/SystemCommand.cs +++ /dev/null @@ -1,14 +0,0 @@ - -namespace MediaBrowser.Model.Session -{ - public enum SystemCommand - { - GoHome, - GoToSettings, - VolumeUp, - VolumeDown, - Mute, - Unmute, - ToggleMute - } -} diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index ec31c55295..5b1e7d6bb9 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -116,6 +116,12 @@ namespace MediaBrowser.Model.System /// The log path. public string LogPath { get; set; } + /// + /// Gets or sets the internal metadata path. + /// + /// The internal metadata path. + public string InternalMetadataPath { get; set; } + /// /// Gets or sets the transcoding temporary path. /// diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs index ff8f6a2e63..c33b9d5496 100644 --- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs @@ -174,11 +174,21 @@ namespace MediaBrowser.Providers.TV /// Task. private async Task AddMissingEpisodes(List series, string seriesDataPath, IEnumerable> episodeLookup, CancellationToken cancellationToken) { - var existingEpisodes = series.SelectMany(s => s.RecursiveChildren.OfType()).ToList(); + var existingEpisodes = (from s in series + let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1) + from c in s.RecursiveChildren.OfType() + select new Tuple((c.ParentIndexNumber ?? 0) + seasonOffset, c)) + .ToList(); + + var lookup = episodeLookup as IList> ?? episodeLookup.ToList(); + + var seasonCounts = (from e in lookup + group e by e.Item1 into g select g) + .ToDictionary(g => g.Key, g => g.Count()); var hasChanges = false; - foreach (var tuple in episodeLookup) + foreach (var tuple in lookup) { if (tuple.Item1 <= 0) { @@ -192,7 +202,7 @@ namespace MediaBrowser.Providers.TV continue; } - var existingEpisode = GetExistingEpisode(existingEpisodes, tuple); + var existingEpisode = GetExistingEpisode(existingEpisodes, seasonCounts, tuple); if (existingEpisode != null) { @@ -208,13 +218,13 @@ namespace MediaBrowser.Providers.TV var now = DateTime.UtcNow; var targetSeries = DetermineAppropriateSeries(series, tuple.Item1); + var seasonOffset = TvdbSeriesProvider.GetSeriesOffset(targetSeries.ProviderIds) ?? ((targetSeries.AnimeSeriesIndex ?? 1) - 1); if (airDate.Value < now) { // tvdb has a lot of nearly blank episodes _logger.Info("Creating virtual missing episode {0} {1}x{2}", targetSeries.Name, tuple.Item1, tuple.Item2); - - await AddEpisode(targetSeries, tuple.Item1, tuple.Item2, cancellationToken).ConfigureAwait(false); + await AddEpisode(targetSeries, tuple.Item1 - seasonOffset, tuple.Item2, cancellationToken).ConfigureAwait(false); hasChanges = true; } @@ -222,8 +232,7 @@ namespace MediaBrowser.Providers.TV { // tvdb has a lot of nearly blank episodes _logger.Info("Creating virtual unaired episode {0} {1}x{2}", targetSeries.Name, tuple.Item1, tuple.Item2); - - await AddEpisode(targetSeries, tuple.Item1, tuple.Item2, cancellationToken).ConfigureAwait(false); + await AddEpisode(targetSeries, tuple.Item1 - seasonOffset, tuple.Item2, cancellationToken).ConfigureAwait(false); hasChanges = true; } @@ -232,40 +241,48 @@ namespace MediaBrowser.Providers.TV return hasChanges; } - private Series DetermineAppropriateSeries(List series, int seasonNumber) + private Series DetermineAppropriateSeries(IEnumerable series, int seasonNumber) { - return series.FirstOrDefault(s => s.RecursiveChildren.OfType().Any(season => season.IndexNumber == seasonNumber)) ?? - series.FirstOrDefault(s => s.RecursiveChildren.OfType().Any(season => season.IndexNumber == 1)) ?? - series.OrderBy(s => s.RecursiveChildren.OfType().Select(season => season.IndexNumber).Min()).First(); - } + var seriesAndOffsets = series.Select(s => new { Series = s, SeasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1) }).ToList(); + var bestMatch = seriesAndOffsets.FirstOrDefault(s => s.Series.RecursiveChildren.OfType().Any(season => (season.IndexNumber + s.SeasonOffset) == seasonNumber)) ?? + seriesAndOffsets.FirstOrDefault(s => s.Series.RecursiveChildren.OfType().Any(season => (season.IndexNumber + s.SeasonOffset) == 1)) ?? + seriesAndOffsets.OrderBy(s => s.Series.RecursiveChildren.OfType().Select(season => season.IndexNumber + s.SeasonOffset).Min()).First(); + + return bestMatch.Series; + } + /// /// Removes the virtual entry after a corresponding physical version has been added /// private async Task RemoveObsoleteOrMissingEpisodes(IEnumerable series, IEnumerable> episodeLookup, CancellationToken cancellationToken) { - var existingEpisodes = series.SelectMany(s => s.RecursiveChildren.OfType()).ToList(); + var existingEpisodes = (from s in series + let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1) + from c in s.RecursiveChildren.OfType() + select new { SeasonOffset = seasonOffset, Episode = c }) + .ToList(); var physicalEpisodes = existingEpisodes - .Where(i => i.LocationType != LocationType.Virtual) + .Where(i => i.Episode.LocationType != LocationType.Virtual) .ToList(); var virtualEpisodes = existingEpisodes - .Where(i => i.LocationType == LocationType.Virtual) + .Where(i => i.Episode.LocationType == LocationType.Virtual) .ToList(); var episodesToRemove = virtualEpisodes .Where(i => { - if (i.IndexNumber.HasValue && i.ParentIndexNumber.HasValue) + if (i.Episode.IndexNumber.HasValue && i.Episode.ParentIndexNumber.HasValue) { - var seasonNumber = i.ParentIndexNumber.Value; - var episodeNumber = i.IndexNumber.Value; + var seasonNumber = i.Episode.ParentIndexNumber.Value + i.SeasonOffset; + var episodeNumber = i.Episode.IndexNumber.Value; // If there's a physical episode with the same season and episode number, delete it if (physicalEpisodes.Any(p => - p.ParentIndexNumber.HasValue && p.ParentIndexNumber.Value == seasonNumber && - p.ContainsEpisodeNumber(episodeNumber))) + p.Episode.ParentIndexNumber.HasValue && (p.Episode.ParentIndexNumber.Value + p.SeasonOffset) == seasonNumber && + p.Episode.ContainsEpisodeNumber(episodeNumber))) { return true; } @@ -285,7 +302,7 @@ namespace MediaBrowser.Providers.TV var hasChanges = false; - foreach (var episodeToRemove in episodesToRemove) + foreach (var episodeToRemove in episodesToRemove.Select(e => e.Episode)) { _logger.Info("Removing missing/unaired episode {0} {1}x{2}", episodeToRemove.Series.Name, episodeToRemove.ParentIndexNumber, episodeToRemove.IndexNumber); @@ -306,25 +323,29 @@ namespace MediaBrowser.Providers.TV /// Task{System.Boolean}. private async Task RemoveObsoleteOrMissingSeasons(IEnumerable series, IEnumerable> episodeLookup, CancellationToken cancellationToken) { - var existingSeasons = series.SelectMany(s => s.Children.OfType()).ToList(); + var existingSeasons = (from s in series + let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1) + from c in s.Children.OfType() + select new { SeasonOffset = seasonOffset, Season = c }) + .ToList(); var physicalSeasons = existingSeasons - .Where(i => i.LocationType != LocationType.Virtual) + .Where(i => i.Season.LocationType != LocationType.Virtual) .ToList(); var virtualSeasons = existingSeasons - .Where(i => i.LocationType == LocationType.Virtual) + .Where(i => i.Season.LocationType == LocationType.Virtual) .ToList(); var seasonsToRemove = virtualSeasons .Where(i => { - if (i.IndexNumber.HasValue) + if (i.Season.IndexNumber.HasValue) { - var seasonNumber = i.IndexNumber.Value; + var seasonNumber = i.Season.IndexNumber.Value + i.SeasonOffset; // If there's a physical season with the same number, delete it - if (physicalSeasons.Any(p => p.IndexNumber.HasValue && p.IndexNumber.Value == seasonNumber)) + if (physicalSeasons.Any(p => p.Season.IndexNumber.HasValue && (p.Season.IndexNumber.Value + p.SeasonOffset) == seasonNumber)) { return true; } @@ -344,7 +365,7 @@ namespace MediaBrowser.Providers.TV var hasChanges = false; - foreach (var seasonToRemove in seasonsToRemove) + foreach (var seasonToRemove in seasonsToRemove.Select(s => s.Season)) { _logger.Info("Removing virtual season {0} {1}", seasonToRemove.Series.Name, seasonToRemove.IndexNumber); @@ -417,9 +438,7 @@ namespace MediaBrowser.Providers.TV await series.AddChild(season, cancellationToken).ConfigureAwait(false); - await season.RefreshMetadata(new MetadataRefreshOptions - { - }, cancellationToken).ConfigureAwait(false); + await season.RefreshMetadata(new MetadataRefreshOptions(), cancellationToken).ConfigureAwait(false); return season; } @@ -428,12 +447,37 @@ namespace MediaBrowser.Providers.TV /// Gets the existing episode. /// /// The existing episodes. + /// /// The tuple. /// Episode. - private Episode GetExistingEpisode(IEnumerable existingEpisodes, Tuple tuple) + private Episode GetExistingEpisode(IList> existingEpisodes, Dictionary seasonCounts, Tuple tuple) + { + var s = tuple.Item1; + var e = tuple.Item2; + + while (true) + { + var episode = GetExistingEpisode(existingEpisodes, s, e); + if (episode != null) + return episode; + + s--; + + if (seasonCounts.ContainsKey(s)) + e += seasonCounts[s]; + else + break; + } + + return null; + } + + private static Episode GetExistingEpisode(IEnumerable> existingEpisodes, int season, int episode) { return existingEpisodes - .FirstOrDefault(i => (i.ParentIndexNumber ?? -1) == tuple.Item1 && i.ContainsEpisodeNumber(tuple.Item2)); + .Where(i => i.Item1 == season && i.Item2.ContainsEpisodeNumber(episode)) + .Select(i => i.Item2) + .FirstOrDefault(); } /// diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs index 8c9b8672c7..d350d2fe42 100644 --- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs +++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Configuration; +using System.Collections.Generic; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; @@ -11,6 +12,11 @@ using System.Threading.Tasks; namespace MediaBrowser.Providers.TV { + class SeriesGroup : List, IGrouping + { + public string Key { get; set; } + } + class SeriesPostScanTask : ILibraryPostScanTask, IHasOrder { /// @@ -39,11 +45,7 @@ namespace MediaBrowser.Providers.TV .OfType() .ToList(); - var seriesGroups = from series in seriesList - let tvdbId = series.GetProviderId(MetadataProviders.Tvdb) - where !string.IsNullOrEmpty(tvdbId) - group series by tvdbId into g - select g; + var seriesGroups = FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList(); await new MissingEpisodeProvider(_logger, _config, _libraryManager).Run(seriesGroups, cancellationToken).ConfigureAwait(false); @@ -84,6 +86,51 @@ namespace MediaBrowser.Providers.TV } } + private IEnumerable> FindSeriesGroups(List seriesList) + { + var links = seriesList.ToDictionary(s => s, s => seriesList.Where(c => c != s && ShareProviderId(s, c)).ToList()); + + var visited = new HashSet(); + + foreach (var series in seriesList) + { + if (!visited.Contains(series)) + { + var group = new SeriesGroup(); + FindAllLinked(series, visited, links, group); + + group.Key = group.Select(s => s.GetProviderId(MetadataProviders.Tvdb)).FirstOrDefault(id => !string.IsNullOrEmpty(id)); + + yield return group; + } + } + } + + private void FindAllLinked(Series series, HashSet visited, IDictionary> linksMap, List results) + { + results.Add(series); + visited.Add(series); + + var links = linksMap[series]; + + foreach (var s in links) + { + if (!visited.Contains(s)) + { + FindAllLinked(s, visited, linksMap, results); + } + } + } + + private bool ShareProviderId(Series a, Series b) + { + return a.ProviderIds.Any(id => + { + string value; + return b.ProviderIds.TryGetValue(id.Key, out value) && id.Value == value; + }); + } + public int Order { get diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index a76e101113..f9ebaddf83 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -25,7 +25,8 @@ namespace MediaBrowser.Providers.TV { public class TvdbSeriesProvider : IRemoteMetadataProvider, IHasOrder { - internal const string TvdbSeriesOffset = "TvdbSeriesOffset"; + private const string TvdbSeriesOffset = "TvdbSeriesOffset"; + private const string TvdbSeriesOffsetFormat = "{0}-{1}"; internal readonly SemaphoreSlim TvDbResourcePool = new SemaphoreSlim(2, 2); internal static TvdbSeriesProvider Current { get; private set; } @@ -109,17 +110,22 @@ namespace MediaBrowser.Providers.TV return; var offset = info.AnimeSeriesIndex - index; - series.SetProviderId(TvdbSeriesOffset, offset.ToString()); + var id = string.Format(TvdbSeriesOffsetFormat, series.GetProviderId(MetadataProviders.Tvdb), offset); + series.SetProviderId(TvdbSeriesOffset, id); } internal static int? GetSeriesOffset(Dictionary seriesProviderIds) { - string offsetString; - if (!seriesProviderIds.TryGetValue(TvdbSeriesOffset, out offsetString)) + string idString; + if (!seriesProviderIds.TryGetValue(TvdbSeriesOffset, out idString)) + return null; + + var parts = idString.Split('-'); + if (parts.Length < 2) return null; int offset; - if (int.TryParse(offsetString, out offset)) + if (int.TryParse(parts[1], out offset)) return offset; return null; diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 13a1e8f165..558087a252 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -115,22 +115,19 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies } // Find movies that are mixed in the same folder - if (args.Path.IndexOf("[trailers]", StringComparison.OrdinalIgnoreCase) != -1 || - string.Equals(collectionType, CollectionType.Trailers, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(collectionType, CollectionType.Trailers, StringComparison.OrdinalIgnoreCase)) { return ResolveVideo(args); } Video item = null; - if (args.Path.IndexOf("[musicvideos]", StringComparison.OrdinalIgnoreCase) != -1 || - string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase)) { item = ResolveVideo(args); } - if (args.Path.IndexOf("[adultvideos]", StringComparison.OrdinalIgnoreCase) != -1 || - string.Equals(collectionType, CollectionType.AdultVideos, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(collectionType, CollectionType.AdultVideos, StringComparison.OrdinalIgnoreCase)) { item = ResolveVideo(args); } diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json new file mode 100644 index 0000000000..12cdb7035e --- /dev/null +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json @@ -0,0 +1,31 @@ +{ + "SettingsSaved": "Einstellungen gespeichert", + "AddUser": "Benutzer hinzuf\u00fcgen", + "Users": "Benutzer", + "Delete": "L\u00f6schen", + "Administrator": "Administrator", + "Password": "Passwort", + "CreatePassword": "Passwort erstellen", + "DeleteImage": "Bild l\u00f6schen", + "DeleteImageConfirmation": "M\u00f6chten Sie das Bild wirklich l\u00f6schen?", + "FileReadCancelled": "Das Einlesen der Datei wurde abgebrochen.", + "FileNotFound": "Datei nicht gefunden", + "FileReadError": "Beim Lesen der Datei ist ein Fehler aufgetreten.", + "DeleteUser": "Benutzer l\u00f6schen", + "DeleteUserConfirmation": "M\u00f6chten Sie {0} wirklich l\u00f6schen?", + "PasswordResetHeader": "Passwort zur\u00fccksetzen", + "PasswordResetComplete": "Das Passwort wurde zur\u00fcckgesetzt.", + "PasswordResetConfirmation": "M\u00f6chten Sie das Passwort wirklich zur\u00fccksetzen?", + "PasswordSaved": "Passwort gespeichert", + "PasswordMatchError": "Passwort und Passwortbest\u00e4tigung stimmen nicht \u00fcberein.", + "OptionOff": "Aus", + "OptionOn": "Ein", + "OptionRelease": "Release", + "OptionBeta": "Beta", + "OptionDev": "Dev", + "UninstallPluginHeader": "Deinstalliere Plugin", + "UninstallPluginConfirmation": "M\u00f6chten Sie {0} wirklich deinstallieren?", + "NoPluginConfigurationMessage": "Bei diesem Plugin kann nichts eingestellt werden.", + "NoPluginsInstalledMessage": "Sie haben keine Plugins installiert.", + "BrowsePluginCatalogMessage": "Durchsuchen Sie unsere Bibliothek um alle verf\u00fcgbaren Plugins anzuzeigen." +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json index 45f0d7e133..7184d47247 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json @@ -17,5 +17,15 @@ "PasswordResetComplete": "The password has been reset.", "PasswordResetConfirmation": "Are you sure you wish to reset the password?", "PasswordSaved": "Password saved.", - "PasswordMatchError": "Password and password confirmation must match." + "PasswordMatchError": "Password and password confirmation must match.", + "OptionOff": "Off", + "OptionOn": "On", + "OptionRelease": "Release", + "OptionBeta": "Beta", + "OptionDev": "Dev", + "UninstallPluginHeader": "Uninstall Plugin", + "UninstallPluginConfirmation": "Are you sure you wish to uninstall {0}?", + "NoPluginConfigurationMessage": "This plugin has nothing to configure.", + "NoPluginsInstalledMessage": "You have no plugins installed.", + "BrowsePluginCatalogMessage": "Browse our plugin catalog to view available plugins." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json new file mode 100644 index 0000000000..b0b9fd1a91 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json @@ -0,0 +1,31 @@ +{ + "SettingsSaved": "Configuracion guardada", + "AddUser": "Agregar usuario", + "Users": "Usuarios", + "Delete": "Borrar", + "Administrator": "Administrador", + "Password": "Contrase\u00f1a", + "CreatePassword": "Crear Contrase\u00f1a", + "DeleteImage": "Borrar Imagen", + "DeleteImageConfirmation": "Esta seguro que desea borrar esta imagen?", + "FileReadCancelled": "La lectura del archivo se ha cancelado.", + "FileNotFound": "Archivo no encontrado.", + "FileReadError": "Se encontr\u00f3 un error al leer el archivo.", + "DeleteUser": "Borrar Usuario", + "DeleteUserConfirmation": "Esta seguro que desea eliminar a {0}?", + "PasswordResetHeader": "Restablecer contrase\u00f1a", + "PasswordResetComplete": "La contrase\u00f1a se ha restablecido.", + "PasswordResetConfirmation": "Esta seguro que desea restablecer la contrase\u00f1a?", + "PasswordSaved": "Contrase\u00f1a guardada.", + "PasswordMatchError": "La contrase\u00f1a y la confirmaci\u00f3n de la contrase\u00f1a deben de ser iguales.", + "OptionOff": "Apagado", + "OptionOn": "Prendido", + "OptionRelease": "Liberar", + "OptionBeta": "Beta", + "OptionDev": "Desarrollo", + "UninstallPluginHeader": "Desinstalar Plugin", + "UninstallPluginConfirmation": "Esta seguro que desea desinstalar {0}?", + "NoPluginConfigurationMessage": "El plugin no requiere configuraci\u00f3n", + "NoPluginsInstalledMessage": "No tiene plugins instalados.", + "BrowsePluginCatalogMessage": "Navegar el catalogo de plugins para ver los plugins disponibles." +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json new file mode 100644 index 0000000000..9e1ebbfee6 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json @@ -0,0 +1,31 @@ +{ + "SettingsSaved": "Param\u00e8tres sauvegard\u00e9s.", + "AddUser": "Ajout\u00e9 Usager", + "Users": "Usagers", + "Delete": "Supprimer", + "Administrator": "Administrateur", + "Password": "Mot de passe", + "CreatePassword": "Cr\u00e9er mot de passe", + "DeleteImage": "Supprimer Image", + "DeleteImageConfirmation": "\u00cates-vous s\u00fbr de vouloir supprimer l'image?", + "FileReadCancelled": "La lecture du fichier a \u00e9t\u00e9 annul\u00e9e.", + "FileNotFound": "Fichier non trouv\u00e9", + "FileReadError": "Un erreur est survenue pendant la lecture du fichier.", + "DeleteUser": "Supprimer Usager", + "DeleteUserConfirmation": "\u00cates-vous s\u00fbr de vouloir supprimer {0}?", + "PasswordResetHeader": "Red\u00e9marrage du mot de passe", + "PasswordResetComplete": "Le mot de passe a \u00e9t\u00e9 red\u00e9marr\u00e9.", + "PasswordResetConfirmation": "\u00cates-vous s\u00fbr de vouloir red\u00e9marrer le mot de passe?", + "PasswordSaved": "Mot de passe sauvegard\u00e9.", + "PasswordMatchError": "Mot de passe et confirmation de mot de passe doivent correspondre.", + "OptionOff": "Off", + "OptionOn": "On", + "OptionRelease": "Lancement", + "OptionBeta": "Beta", + "OptionDev": "Dev", + "UninstallPluginHeader": "D\u00e9sinstaller module d'extention", + "UninstallPluginConfirmation": "\u00cates-vous s\u00fbr de vouloir d\u00e9sinstaller {0}?", + "NoPluginConfigurationMessage": "Ce module d'extension n'a rien \u00e0 configurer.", + "NoPluginsInstalledMessage": "Vous n'avez aucun module d'extension install\u00e9.", + "BrowsePluginCatalogMessage": "Explorer notre catalogue de modules d'extension pour voir ce qui est disponible." +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 41f8508a5f..6b014bf34f 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -17,5 +17,15 @@ "PasswordResetComplete": "The password has been reset.", "PasswordResetConfirmation": "Are you sure you wish to reset the password?", "PasswordSaved": "Password saved.", - "PasswordMatchError": "Password and password confirmation must match." + "PasswordMatchError": "Password and password confirmation must match.", + "OptionOff": "Off", + "OptionOn": "On", + "OptionRelease": "Release", + "OptionBeta": "Beta", + "OptionDev": "Dev", + "UninstallPluginHeader": "Uninstall Plugin", + "UninstallPluginConfirmation": "Are you sure you wish to uninstall {0}?", + "NoPluginConfigurationMessage": "This plugin has nothing to configure.", + "NoPluginsInstalledMessage": "You have no plugins installed.", + "BrowsePluginCatalogMessage": "Browse our plugin catalog to view available plugins." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json new file mode 100644 index 0000000000..17a343283c --- /dev/null +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json @@ -0,0 +1,31 @@ +{ + "SettingsSaved": "Instellingen opgeslagen.", + "AddUser": "Gebruiker toevoegen", + "Users": "Gebruikers", + "Delete": "Verwijderen", + "Administrator": "Beheerder", + "Password": "Wachtwoord", + "CreatePassword": "Maak wachtwoord", + "DeleteImage": "Verwijder afbeelding", + "DeleteImageConfirmation": "Weet je zeker dat je deze afbeelding wilt verwijderen?", + "FileReadCancelled": "Het lezen van het bestand is geannuleerd", + "FileNotFound": "Bestand niet gevonden.", + "FileReadError": "Er is een fout opgetreden bij het lezen van het bestand.", + "DeleteUser": "Verwijder gebruiker", + "DeleteUserConfirmation": "Weet je zeker dat je {0} wilt verwijderen?", + "PasswordResetHeader": "Wachtwoord opnieuw instellen", + "PasswordResetComplete": "Het wachtwoord is opnieuw ingesteld.", + "PasswordResetConfirmation": "Weet je zeker dat je het wachtwoord opnieuw in wilt stellen?", + "PasswordSaved": "Wachtwoord opgeslagen.", + "PasswordMatchError": "Wachtwoord en wachtwoord bevestiging moeten hetzelfde zijn.", + "OptionOff": "Uit", + "OptionOn": "Aan", + "OptionRelease": "Release", + "OptionBeta": "Beta", + "OptionDev": "Dev", + "UninstallPluginHeader": "Deinstalleer Plugin", + "UninstallPluginConfirmation": "Weet u zeker dat u {0} wilt deinstalleren?", + "NoPluginConfigurationMessage": "Deze plugin heeft niets in te stellen", + "NoPluginsInstalledMessage": "U heeft geen plugins geinstalleerd", + "BrowsePluginCatalogMessage": "Blader door de Plugincatalogus voor beschikbare plugins." +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json index 25d3ff9442..e81a18e798 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json @@ -8,14 +8,24 @@ "CreatePassword": "Criar Senha", "DeleteImage": "Apagar Imagem", "DeleteImageConfirmation": "Tem a certeza que pretende apagar a imagem?", - "FileReadCancelled": "The file read has been cancelled.", + "FileReadCancelled": "A leitura do ficheiro foi cancelada.", "FileNotFound": "Ficheiro n\u00e3o encontrado", "FileReadError": "Ocorreu um erro ao ler o ficheiro.", "DeleteUser": "Apagar Utilizador", "DeleteUserConfirmation": "Tem a certeza que pretende apagar {0}?", - "PasswordResetHeader": "Password Reset", - "PasswordResetComplete": "The password has been reset.", - "PasswordResetConfirmation": "Are you sure you wish to reset the password?", + "PasswordResetHeader": "Redefinir Senha", + "PasswordResetComplete": "A senha foi redefinida.", + "PasswordResetConfirmation": "Tem a certeza que pretende redefinir a senha?", "PasswordSaved": "Senha guardada.", - "PasswordMatchError": "Password and password confirmation must match." + "PasswordMatchError": "A senha e a confirma\u00e7\u00e3o da senha devem coincidir.", + "OptionOff": "Desligado", + "OptionOn": "Ligado", + "OptionRelease": "Final", + "OptionBeta": "Beta", + "OptionDev": "Dev", + "UninstallPluginHeader": "Desinstalar extens\u00e3o", + "UninstallPluginConfirmation": "Tem a certeza que pretende desinstalar {0}?", + "NoPluginConfigurationMessage": "Esta extens\u00e3o n\u00e3o \u00e9 configur\u00e1vel.", + "NoPluginsInstalledMessage": "N\u00e3o tem extens\u00f5es instaladas.", + "BrowsePluginCatalogMessage": "Navegue o nosso cat\u00e1logo de extens\u00f5es para ser as extens\u00f5es dispon\u00edveis." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json new file mode 100644 index 0000000000..b54e3f1296 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json @@ -0,0 +1,31 @@ +{ + "SettingsSaved": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b", + "AddUser": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f", + "Users": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438", + "Delete": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c", + "Administrator": "\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440", + "Password": "\u041f\u0430\u0440\u043e\u043b\u044c", + "CreatePassword": "\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c", + "DeleteImage": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435", + "DeleteImageConfirmation": "\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0436\u0435\u043b\u0430\u0435\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435?", + "FileReadCancelled": "\u0427\u0442\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u0431\u044b\u043b\u043e \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u043e", + "FileNotFound": "\u0424\u0430\u0439\u043b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d", + "FileReadError": "\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430", + "DeleteUser": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f", + "DeleteUserConfirmation": "\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0436\u0435\u043b\u0430\u0435\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c {0}?", + "PasswordResetHeader": "\u0421\u0431\u0440\u043e\u0441 \u043f\u0430\u0440\u043e\u043b\u044f", + "PasswordResetComplete": "\u041f\u0430\u0440\u043e\u043b\u044c \u0431\u044b\u043b \u0441\u0431\u0440\u043e\u0448\u0435\u043d", + "PasswordResetConfirmation": "\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0436\u0435\u043b\u0430\u0435\u0442\u0435 \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c?", + "PasswordSaved": "\u041f\u0430\u0440\u043e\u043b\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d", + "PasswordMatchError": "\u041f\u043e\u043b\u044f \u041f\u0430\u0440\u043e\u043b\u044c \u0438 \u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u043e\u043b\u044f \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c", + "OptionOff": "\u0412\u044b\u043a\u043b.", + "OptionOn": "\u0412\u043a\u043b.", + "OptionRelease": "\u0412\u044b\u043f\u0443\u0441\u043a", + "OptionBeta": "\u0411\u0435\u0442\u0430", + "OptionDev": "\u0420\u0430\u0437\u0440\u0430\u0431.", + "UninstallPluginHeader": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d", + "UninstallPluginConfirmation": "\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0436\u0435\u043b\u0430\u0435\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c {0}?", + "NoPluginConfigurationMessage": "\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u043d\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a", + "NoPluginsInstalledMessage": "\u0423 \u0412\u0430\u0441 \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043b\u0430\u0433\u0438\u043d\u0430.", + "BrowsePluginCatalogMessage": "\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043d\u0430\u0448 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0434\u043b\u044f \u043e\u0431\u0437\u043e\u0440\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432." +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json new file mode 100644 index 0000000000..ca7b3a7c75 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json @@ -0,0 +1,31 @@ +{ + "SettingsSaved": "\u8a2d\u7f6e\u5df2\u4fdd\u5b58", + "AddUser": "Add User", + "Users": "\u7528\u6236", + "Delete": "\u522a\u9664", + "Administrator": "\u7ba1\u7406\u54e1", + "Password": "\u5bc6\u78bc", + "CreatePassword": "\u5275\u5efa\u5bc6\u78bc", + "DeleteImage": "\u522a\u9664\u5716\u50cf", + "DeleteImageConfirmation": "\u4f60\u78ba\u5b9a\u8981\u522a\u9664\u9019\u5f35\u5716\u7247\uff1f", + "FileReadCancelled": "The file read has been cancelled.", + "FileNotFound": "File not found.", + "FileReadError": "An error occurred while reading the file.", + "DeleteUser": "\u522a\u9664\u7528\u6236", + "DeleteUserConfirmation": "Are you sure you wish to delete {0}?", + "PasswordResetHeader": "\u91cd\u8a2d\u5bc6\u78bc", + "PasswordResetComplete": "\u5bc6\u78bc\u5df2\u91cd\u8a2d", + "PasswordResetConfirmation": "\u4f60\u78ba\u5b9a\u8981\u91cd\u8a2d\u5bc6\u78bc\uff1f", + "PasswordSaved": "\u5bc6\u78bc\u5df2\u4fdd\u5b58\u3002", + "PasswordMatchError": "\u5bc6\u78bc\u548c\u78ba\u8a8d\u5bc6\u78bc\u5fc5\u9808\u4e00\u81f4\u3002", + "OptionOff": "Off", + "OptionOn": "On", + "OptionRelease": "Release", + "OptionBeta": "Beta", + "OptionDev": "Dev", + "UninstallPluginHeader": "Uninstall Plugin", + "UninstallPluginConfirmation": "Are you sure you wish to uninstall {0}?", + "NoPluginConfigurationMessage": "This plugin has nothing to configure.", + "NoPluginsInstalledMessage": "You have no plugins installed.", + "BrowsePluginCatalogMessage": "Browse our plugin catalog to view available plugins." +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs b/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs index 6f39c67597..9b907ef747 100644 --- a/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs +++ b/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.IO; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Localization; using MediaBrowser.Model.Entities; @@ -12,7 +13,6 @@ using System.Globalization; using System.IO; using System.Linq; using System.Reflection; -using MediaBrowser.Common.Extensions; namespace MediaBrowser.Server.Implementations.Localization { @@ -334,9 +334,14 @@ namespace MediaBrowser.Server.Implementations.Localization return new List { new LocalizatonOption{ Name="English (United States)", Value="en-us"}, + new LocalizatonOption{ Name="Chinese Traditional", Value="zh-TW"}, + new LocalizatonOption{ Name="Dutch", Value="nl"}, + new LocalizatonOption{ Name="French", Value="fr"}, new LocalizatonOption{ Name="German", Value="de"}, + new LocalizatonOption{ Name="Portuguese (Brazil)", Value="pt-BR"}, new LocalizatonOption{ Name="Portuguese (Portugal)", Value="pt-PT"}, - new LocalizatonOption{ Name="Russian", Value="ru"} + new LocalizatonOption{ Name="Russian", Value="ru"}, + new LocalizatonOption{ Name="Spanish", Value="es"} }.OrderBy(i => i.Name); } diff --git a/MediaBrowser.Server.Implementations/Localization/Server/de.json b/MediaBrowser.Server.Implementations/Localization/Server/de.json index ab3271b50f..0aeaf3c502 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/de.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/de.json @@ -4,7 +4,7 @@ "LabelGithubWiki": "Github Wiki", "LabelSwagger": "Swagger", "LabelStandard": "Standard", - "LabelViewApiDocumentation": "Zeige Api Dokumentation", + "LabelViewApiDocumentation": "Zeige API Dokumentation", "LabelBrowseLibrary": "Durchsuche Bibliothek", "LabelConfigureMediaBrowser": "Konfiguriere Media Browser", "LabelOpenLibraryViewer": "\u00d6ffne Bibliothekenansicht", @@ -13,5 +13,38 @@ "LabelPrevious": "Vorheriges", "LabelFinish": "Ende", "LabelNext": "N\u00e4chstes", - "LabelYoureDone": "Du bist fertig!" + "LabelYoureDone": "Du bist fertig!", + "WelcomeToMediaBrowser": "Welcome to Media Browser!", + "LabelMediaBrowser": "Media Browser", + "ThisWizardWillGuideYou": "This wizard will help guide you through the setup process.", + "TellUsAboutYourself": "Tell us about yourself", + "LabelYourFirstName": "Your first name:", + "MoreUsersCanBeAddedLater": "More users can be added later within the Dashboard.", + "UserProfilesIntro": "Media Browser includes built-in support for user profiles, enabling each user to have their own display settings, playstate and parental controls.", + "LabelWindowsService": "Windows Service", + "AWindowsServiceHasBeenInstalled": "A Windows Service has been installed.", + "WindowsServiceIntro1": "Media Browser Server normally runs as a desktop application with a tray icon, but if you prefer to run it as a background service, it can be started from the windows services control panel instead.", + "WindowsServiceIntro2": "If using the windows service, please note that it cannot be run at the same time as the tray icon, so you'll need to exit the tray in order to run the service. The service will also need to be configured with administrative privileges via the control panel. Please note that at this time the service is unable to self-update, so new versions will require manual interaction.", + "WizardCompleted": "That's all we need for now. Media Browser has begun collecting information about your media library. Check out some of our apps, and then click Finish<\/b> to view the Dashboard<\/b>.", + "LabelConfigureSettings": "Configure settings", + "LabelEnableVideoImageExtraction": "Enable video image extraction", + "VideoImageExtractionHelp": "For videos that don't already have images, and that we're unable to find internet images for. This will add some additional time to the initial library scan but will result in a more pleasing presentation.", + "LabelEnableChapterImageExtractionForMovies": "Extract chapter image extraction for Movies", + "LabelChapterImageExtractionForMoviesHelp": "Extracting chapter images will allow clients to display graphical scene selection menus. The process can be slow, cpu-intensive and may require several gigabytes of space. It runs as a nightly scheduled task at 4am, although this is configurable in the scheduled tasks area. It is not recommended to run this task during peak usage hours.", + "LabelEnableAutomaticPortMapping": "Enable automatic port mapping", + "LabelEnableAutomaticPortMappingHelp": "UPnP allows automated router configuration for easy remote access. This may not work with some router models.", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "HeaderSetupLibrary": "Setup your media library", + "ButtonAddMediaFolder": "Add media folder", + "LabelFolderType": "Folder type:", + "MediaFolderHelpPluginRequired": "* Requires the use of a plugin, e.g. GameBrowser or MB Bookshelf.", + "ReferToMediaLibraryWiki": "Refer to the media library wiki.", + "LabelCountry": "Country:", + "LabelLanguage": "Language:", + "HeaderPreferredMetadataLanguage": "Preferred metadata language:", + "LabelSaveLocalMetadata": "Save artwork and metadata into media folders", + "LabelSaveLocalMetadataHelp": "Saving artwork and metadata directly into media folders will put them in a place where they can be easily edited.", + "LabelDownloadInternetMetadata": "Download artwork and metadata from the internet", + "LabelDownloadInternetMetadataHelp": "Media Browser can download information about your media to enable rich presentations." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/en_US.json b/MediaBrowser.Server.Implementations/Localization/Server/en_US.json index f74cca1eb1..40269bde39 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/en_US.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/en_US.json @@ -13,5 +13,38 @@ "LabelPrevious": "Previous", "LabelFinish": "Finish", "LabelNext": "Next", - "LabelYoureDone": "You're Done!" + "LabelYoureDone": "You're Done!", + "WelcomeToMediaBrowser": "Welcome to Media Browser!", + "LabelMediaBrowser": "Media Browser", + "ThisWizardWillGuideYou": "This wizard will help guide you through the setup process.", + "TellUsAboutYourself": "Tell us about yourself", + "LabelYourFirstName": "Your first name:", + "MoreUsersCanBeAddedLater": "More users can be added later within the Dashboard.", + "UserProfilesIntro": "Media Browser includes built-in support for user profiles, enabling each user to have their own display settings, playstate and parental controls.", + "LabelWindowsService": "Windows Service", + "AWindowsServiceHasBeenInstalled": "A Windows Service has been installed.", + "WindowsServiceIntro1": "Media Browser Server normally runs as a desktop application with a tray icon, but if you prefer to run it as a background service, it can be started from the windows services control panel instead.", + "WindowsServiceIntro2": "If using the windows service, please note that it cannot be run at the same time as the tray icon, so you'll need to exit the tray in order to run the service. The service will also need to be configured with administrative privileges via the control panel. Please note that at this time the service is unable to self-update, so new versions will require manual interaction.", + "WizardCompleted": "That's all we need for now. Media Browser has begun collecting information about your media library. Check out some of our apps, and then click Finish<\/b> to view the Dashboard<\/b>.", + "LabelConfigureSettings": "Configure settings", + "LabelEnableVideoImageExtraction": "Enable video image extraction", + "VideoImageExtractionHelp": "For videos that don't already have images, and that we're unable to find internet images for. This will add some additional time to the initial library scan but will result in a more pleasing presentation.", + "LabelEnableChapterImageExtractionForMovies": "Extract chapter image extraction for Movies", + "LabelChapterImageExtractionForMoviesHelp": "Extracting chapter images will allow clients to display graphical scene selection menus. The process can be slow, cpu-intensive and may require several gigabytes of space. It runs as a nightly scheduled task at 4am, although this is configurable in the scheduled tasks area. It is not recommended to run this task during peak usage hours.", + "LabelEnableAutomaticPortMapping": "Enable automatic port mapping", + "LabelEnableAutomaticPortMappingHelp": "UPnP allows automated router configuration for easy remote access. This may not work with some router models.", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "HeaderSetupLibrary": "Setup your media library", + "ButtonAddMediaFolder": "Add media folder", + "LabelFolderType": "Folder type:", + "MediaFolderHelpPluginRequired": "* Requires the use of a plugin, e.g. GameBrowser or MB Bookshelf.", + "ReferToMediaLibraryWiki": "Refer to the media library wiki.", + "LabelCountry": "Country:", + "LabelLanguage": "Language:", + "HeaderPreferredMetadataLanguage": "Preferred metadata language:", + "LabelSaveLocalMetadata": "Save artwork and metadata into media folders", + "LabelSaveLocalMetadataHelp": "Saving artwork and metadata directly into media folders will put them in a place where they can be easily edited.", + "LabelDownloadInternetMetadata": "Download artwork and metadata from the internet", + "LabelDownloadInternetMetadataHelp": "Media Browser can download information about your media to enable rich presentations." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/es.json b/MediaBrowser.Server.Implementations/Localization/Server/es.json new file mode 100644 index 0000000000..f475e1db4d --- /dev/null +++ b/MediaBrowser.Server.Implementations/Localization/Server/es.json @@ -0,0 +1,50 @@ +{ + "LabelExit": "Salir", + "LabelVisitCommunity": "Visitar la comunidad", + "LabelGithubWiki": "Wiki de Github", + "LabelSwagger": "Swagger", + "LabelStandard": "Estandar", + "LabelViewApiDocumentation": "Ver documentacion de Api", + "LabelBrowseLibrary": "Navegar biblioteca", + "LabelConfigureMediaBrowser": "Configurar Media Browser", + "LabelOpenLibraryViewer": "Abrir el visor de la biblioteca", + "LabelRestartServer": "reiniciar el servidor", + "LabelShowLogWindow": "Mostrar la ventana del log", + "LabelPrevious": "Anterior", + "LabelFinish": "Terminar", + "LabelNext": "Siguiente", + "LabelYoureDone": "Ha Terminado!", + "WelcomeToMediaBrowser": "Welcome to Media Browser!", + "LabelMediaBrowser": "Media Browser", + "ThisWizardWillGuideYou": "This wizard will help guide you through the setup process.", + "TellUsAboutYourself": "Tell us about yourself", + "LabelYourFirstName": "Your first name:", + "MoreUsersCanBeAddedLater": "More users can be added later within the Dashboard.", + "UserProfilesIntro": "Media Browser includes built-in support for user profiles, enabling each user to have their own display settings, playstate and parental controls.", + "LabelWindowsService": "Windows Service", + "AWindowsServiceHasBeenInstalled": "A Windows Service has been installed.", + "WindowsServiceIntro1": "Media Browser Server normally runs as a desktop application with a tray icon, but if you prefer to run it as a background service, it can be started from the windows services control panel instead.", + "WindowsServiceIntro2": "If using the windows service, please note that it cannot be run at the same time as the tray icon, so you'll need to exit the tray in order to run the service. The service will also need to be configured with administrative privileges via the control panel. Please note that at this time the service is unable to self-update, so new versions will require manual interaction.", + "WizardCompleted": "That's all we need for now. Media Browser has begun collecting information about your media library. Check out some of our apps, and then click Finish<\/b> to view the Dashboard<\/b>.", + "LabelConfigureSettings": "Configure settings", + "LabelEnableVideoImageExtraction": "Enable video image extraction", + "VideoImageExtractionHelp": "For videos that don't already have images, and that we're unable to find internet images for. This will add some additional time to the initial library scan but will result in a more pleasing presentation.", + "LabelEnableChapterImageExtractionForMovies": "Extract chapter image extraction for Movies", + "LabelChapterImageExtractionForMoviesHelp": "Extracting chapter images will allow clients to display graphical scene selection menus. The process can be slow, cpu-intensive and may require several gigabytes of space. It runs as a nightly scheduled task at 4am, although this is configurable in the scheduled tasks area. It is not recommended to run this task during peak usage hours.", + "LabelEnableAutomaticPortMapping": "Enable automatic port mapping", + "LabelEnableAutomaticPortMappingHelp": "UPnP allows automated router configuration for easy remote access. This may not work with some router models.", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "HeaderSetupLibrary": "Setup your media library", + "ButtonAddMediaFolder": "Add media folder", + "LabelFolderType": "Folder type:", + "MediaFolderHelpPluginRequired": "* Requires the use of a plugin, e.g. GameBrowser or MB Bookshelf.", + "ReferToMediaLibraryWiki": "Refer to the media library wiki.", + "LabelCountry": "Country:", + "LabelLanguage": "Language:", + "HeaderPreferredMetadataLanguage": "Preferred metadata language:", + "LabelSaveLocalMetadata": "Save artwork and metadata into media folders", + "LabelSaveLocalMetadataHelp": "Saving artwork and metadata directly into media folders will put them in a place where they can be easily edited.", + "LabelDownloadInternetMetadata": "Download artwork and metadata from the internet", + "LabelDownloadInternetMetadataHelp": "Media Browser can download information about your media to enable rich presentations." +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/fr.json b/MediaBrowser.Server.Implementations/Localization/Server/fr.json new file mode 100644 index 0000000000..038fb56077 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Localization/Server/fr.json @@ -0,0 +1,50 @@ +{ + "LabelExit": "Quitter", + "LabelVisitCommunity": "Visiter Communaut\u00e9", + "LabelGithubWiki": "GitHub Wiki", + "LabelSwagger": "Swagger", + "LabelStandard": "Standard", + "LabelViewApiDocumentation": "Consulter la documentation API", + "LabelBrowseLibrary": "Naviguer la biblioth\u00e8que", + "LabelConfigureMediaBrowser": "Configurer Media Browser", + "LabelOpenLibraryViewer": "Ouvrir le navigateur de biblioth\u00e8que", + "LabelRestartServer": "Red\u00e9marrer Serveur", + "LabelShowLogWindow": "Afficher la fen\u00eatre du journal d'\u00e9v\u00e8nements", + "LabelPrevious": "Pr\u00e9c\u00e9dant", + "LabelFinish": "Termin\u00e9", + "LabelNext": "Suivant", + "LabelYoureDone": "Vous avez Termin\u00e9!", + "WelcomeToMediaBrowser": "Welcome to Media Browser!", + "LabelMediaBrowser": "Media Browser", + "ThisWizardWillGuideYou": "This wizard will help guide you through the setup process.", + "TellUsAboutYourself": "Tell us about yourself", + "LabelYourFirstName": "Your first name:", + "MoreUsersCanBeAddedLater": "More users can be added later within the Dashboard.", + "UserProfilesIntro": "Media Browser includes built-in support for user profiles, enabling each user to have their own display settings, playstate and parental controls.", + "LabelWindowsService": "Windows Service", + "AWindowsServiceHasBeenInstalled": "A Windows Service has been installed.", + "WindowsServiceIntro1": "Media Browser Server normally runs as a desktop application with a tray icon, but if you prefer to run it as a background service, it can be started from the windows services control panel instead.", + "WindowsServiceIntro2": "If using the windows service, please note that it cannot be run at the same time as the tray icon, so you'll need to exit the tray in order to run the service. The service will also need to be configured with administrative privileges via the control panel. Please note that at this time the service is unable to self-update, so new versions will require manual interaction.", + "WizardCompleted": "That's all we need for now. Media Browser has begun collecting information about your media library. Check out some of our apps, and then click Finish<\/b> to view the Dashboard<\/b>.", + "LabelConfigureSettings": "Configure settings", + "LabelEnableVideoImageExtraction": "Enable video image extraction", + "VideoImageExtractionHelp": "For videos that don't already have images, and that we're unable to find internet images for. This will add some additional time to the initial library scan but will result in a more pleasing presentation.", + "LabelEnableChapterImageExtractionForMovies": "Extract chapter image extraction for Movies", + "LabelChapterImageExtractionForMoviesHelp": "Extracting chapter images will allow clients to display graphical scene selection menus. The process can be slow, cpu-intensive and may require several gigabytes of space. It runs as a nightly scheduled task at 4am, although this is configurable in the scheduled tasks area. It is not recommended to run this task during peak usage hours.", + "LabelEnableAutomaticPortMapping": "Enable automatic port mapping", + "LabelEnableAutomaticPortMappingHelp": "UPnP allows automated router configuration for easy remote access. This may not work with some router models.", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "HeaderSetupLibrary": "Setup your media library", + "ButtonAddMediaFolder": "Add media folder", + "LabelFolderType": "Folder type:", + "MediaFolderHelpPluginRequired": "* Requires the use of a plugin, e.g. GameBrowser or MB Bookshelf.", + "ReferToMediaLibraryWiki": "Refer to the media library wiki.", + "LabelCountry": "Country:", + "LabelLanguage": "Language:", + "HeaderPreferredMetadataLanguage": "Preferred metadata language:", + "LabelSaveLocalMetadata": "Save artwork and metadata into media folders", + "LabelSaveLocalMetadataHelp": "Saving artwork and metadata directly into media folders will put them in a place where they can be easily edited.", + "LabelDownloadInternetMetadata": "Download artwork and metadata from the internet", + "LabelDownloadInternetMetadataHelp": "Media Browser can download information about your media to enable rich presentations." +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/nl.json b/MediaBrowser.Server.Implementations/Localization/Server/nl.json new file mode 100644 index 0000000000..0fcf20a537 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Localization/Server/nl.json @@ -0,0 +1,50 @@ +{ + "LabelExit": "Afsluiten", + "LabelVisitCommunity": "Bezoek de community", + "LabelGithubWiki": "Github Wiki", + "LabelSwagger": "Swagger", + "LabelStandard": "Standaard", + "LabelViewApiDocumentation": "Bekijk Api documentatie", + "LabelBrowseLibrary": "Bekijk bibliotheek", + "LabelConfigureMediaBrowser": "Configureer Media Browser", + "LabelOpenLibraryViewer": "Open bibliotheek verkenner", + "LabelRestartServer": "Herstart server", + "LabelShowLogWindow": "Toon log venster", + "LabelPrevious": "Vorige", + "LabelFinish": "Finish", + "LabelNext": "Volgende", + "LabelYoureDone": "Gereed!", + "WelcomeToMediaBrowser": "Welcome to Media Browser!", + "LabelMediaBrowser": "Media Browser", + "ThisWizardWillGuideYou": "This wizard will help guide you through the setup process.", + "TellUsAboutYourself": "Tell us about yourself", + "LabelYourFirstName": "Your first name:", + "MoreUsersCanBeAddedLater": "More users can be added later within the Dashboard.", + "UserProfilesIntro": "Media Browser includes built-in support for user profiles, enabling each user to have their own display settings, playstate and parental controls.", + "LabelWindowsService": "Windows Service", + "AWindowsServiceHasBeenInstalled": "A Windows Service has been installed.", + "WindowsServiceIntro1": "Media Browser Server normally runs as a desktop application with a tray icon, but if you prefer to run it as a background service, it can be started from the windows services control panel instead.", + "WindowsServiceIntro2": "If using the windows service, please note that it cannot be run at the same time as the tray icon, so you'll need to exit the tray in order to run the service. The service will also need to be configured with administrative privileges via the control panel. Please note that at this time the service is unable to self-update, so new versions will require manual interaction.", + "WizardCompleted": "That's all we need for now. Media Browser has begun collecting information about your media library. Check out some of our apps, and then click Finish<\/b> to view the Dashboard<\/b>.", + "LabelConfigureSettings": "Configure settings", + "LabelEnableVideoImageExtraction": "Enable video image extraction", + "VideoImageExtractionHelp": "For videos that don't already have images, and that we're unable to find internet images for. This will add some additional time to the initial library scan but will result in a more pleasing presentation.", + "LabelEnableChapterImageExtractionForMovies": "Extract chapter image extraction for Movies", + "LabelChapterImageExtractionForMoviesHelp": "Extracting chapter images will allow clients to display graphical scene selection menus. The process can be slow, cpu-intensive and may require several gigabytes of space. It runs as a nightly scheduled task at 4am, although this is configurable in the scheduled tasks area. It is not recommended to run this task during peak usage hours.", + "LabelEnableAutomaticPortMapping": "Enable automatic port mapping", + "LabelEnableAutomaticPortMappingHelp": "UPnP allows automated router configuration for easy remote access. This may not work with some router models.", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "HeaderSetupLibrary": "Setup your media library", + "ButtonAddMediaFolder": "Add media folder", + "LabelFolderType": "Folder type:", + "MediaFolderHelpPluginRequired": "* Requires the use of a plugin, e.g. GameBrowser or MB Bookshelf.", + "ReferToMediaLibraryWiki": "Refer to the media library wiki.", + "LabelCountry": "Country:", + "LabelLanguage": "Language:", + "HeaderPreferredMetadataLanguage": "Preferred metadata language:", + "LabelSaveLocalMetadata": "Save artwork and metadata into media folders", + "LabelSaveLocalMetadataHelp": "Saving artwork and metadata directly into media folders will put them in a place where they can be easily edited.", + "LabelDownloadInternetMetadata": "Download artwork and metadata from the internet", + "LabelDownloadInternetMetadataHelp": "Media Browser can download information about your media to enable rich presentations." +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json b/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json new file mode 100644 index 0000000000..a7997e5a2b --- /dev/null +++ b/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json @@ -0,0 +1,50 @@ +{ + "LabelExit": "Sair", + "LabelVisitCommunity": "Visite o Community", + "LabelGithubWiki": "Wiki do Github", + "LabelSwagger": "Swagger", + "LabelStandard": "Standard", + "LabelViewApiDocumentation": "View Api Documentation", + "LabelBrowseLibrary": "Browse Library", + "LabelConfigureMediaBrowser": "Configure Media Browser", + "LabelOpenLibraryViewer": "Open Library Viewer", + "LabelRestartServer": "Restart Server", + "LabelShowLogWindow": "Show Log Window", + "LabelPrevious": "Previous", + "LabelFinish": "Finish", + "LabelNext": "Next", + "LabelYoureDone": "You're Done!", + "WelcomeToMediaBrowser": "Welcome to Media Browser!", + "LabelMediaBrowser": "Media Browser", + "ThisWizardWillGuideYou": "This wizard will help guide you through the setup process.", + "TellUsAboutYourself": "Tell us about yourself", + "LabelYourFirstName": "Your first name:", + "MoreUsersCanBeAddedLater": "More users can be added later within the Dashboard.", + "UserProfilesIntro": "Media Browser includes built-in support for user profiles, enabling each user to have their own display settings, playstate and parental controls.", + "LabelWindowsService": "Windows Service", + "AWindowsServiceHasBeenInstalled": "A Windows Service has been installed.", + "WindowsServiceIntro1": "Media Browser Server normally runs as a desktop application with a tray icon, but if you prefer to run it as a background service, it can be started from the windows services control panel instead.", + "WindowsServiceIntro2": "If using the windows service, please note that it cannot be run at the same time as the tray icon, so you'll need to exit the tray in order to run the service. The service will also need to be configured with administrative privileges via the control panel. Please note that at this time the service is unable to self-update, so new versions will require manual interaction.", + "WizardCompleted": "That's all we need for now. Media Browser has begun collecting information about your media library. Check out some of our apps, and then click Finish<\/b> to view the Dashboard<\/b>.", + "LabelConfigureSettings": "Configure settings", + "LabelEnableVideoImageExtraction": "Enable video image extraction", + "VideoImageExtractionHelp": "For videos that don't already have images, and that we're unable to find internet images for. This will add some additional time to the initial library scan but will result in a more pleasing presentation.", + "LabelEnableChapterImageExtractionForMovies": "Extract chapter image extraction for Movies", + "LabelChapterImageExtractionForMoviesHelp": "Extracting chapter images will allow clients to display graphical scene selection menus. The process can be slow, cpu-intensive and may require several gigabytes of space. It runs as a nightly scheduled task at 4am, although this is configurable in the scheduled tasks area. It is not recommended to run this task during peak usage hours.", + "LabelEnableAutomaticPortMapping": "Enable automatic port mapping", + "LabelEnableAutomaticPortMappingHelp": "UPnP allows automated router configuration for easy remote access. This may not work with some router models.", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "HeaderSetupLibrary": "Setup your media library", + "ButtonAddMediaFolder": "Add media folder", + "LabelFolderType": "Folder type:", + "MediaFolderHelpPluginRequired": "* Requires the use of a plugin, e.g. GameBrowser or MB Bookshelf.", + "ReferToMediaLibraryWiki": "Refer to the media library wiki.", + "LabelCountry": "Country:", + "LabelLanguage": "Language:", + "HeaderPreferredMetadataLanguage": "Preferred metadata language:", + "LabelSaveLocalMetadata": "Save artwork and metadata into media folders", + "LabelSaveLocalMetadataHelp": "Saving artwork and metadata directly into media folders will put them in a place where they can be easily edited.", + "LabelDownloadInternetMetadata": "Download artwork and metadata from the internet", + "LabelDownloadInternetMetadataHelp": "Media Browser can download information about your media to enable rich presentations." +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json b/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json index 7003147086..9fddc4f98c 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json @@ -13,5 +13,38 @@ "LabelPrevious": "Anterior", "LabelFinish": "Terminar", "LabelNext": "Seguinte", - "LabelYoureDone": "Concluiu!" + "LabelYoureDone": "Concluiu!", + "WelcomeToMediaBrowser": "Welcome to Media Browser!", + "LabelMediaBrowser": "Media Browser", + "ThisWizardWillGuideYou": "This wizard will help guide you through the setup process.", + "TellUsAboutYourself": "Tell us about yourself", + "LabelYourFirstName": "Your first name:", + "MoreUsersCanBeAddedLater": "More users can be added later within the Dashboard.", + "UserProfilesIntro": "Media Browser includes built-in support for user profiles, enabling each user to have their own display settings, playstate and parental controls.", + "LabelWindowsService": "Windows Service", + "AWindowsServiceHasBeenInstalled": "A Windows Service has been installed.", + "WindowsServiceIntro1": "Media Browser Server normally runs as a desktop application with a tray icon, but if you prefer to run it as a background service, it can be started from the windows services control panel instead.", + "WindowsServiceIntro2": "If using the windows service, please note that it cannot be run at the same time as the tray icon, so you'll need to exit the tray in order to run the service. The service will also need to be configured with administrative privileges via the control panel. Please note that at this time the service is unable to self-update, so new versions will require manual interaction.", + "WizardCompleted": "That's all we need for now. Media Browser has begun collecting information about your media library. Check out some of our apps, and then click Finish<\/b> to view the Dashboard<\/b>.", + "LabelConfigureSettings": "Configure settings", + "LabelEnableVideoImageExtraction": "Enable video image extraction", + "VideoImageExtractionHelp": "For videos that don't already have images, and that we're unable to find internet images for. This will add some additional time to the initial library scan but will result in a more pleasing presentation.", + "LabelEnableChapterImageExtractionForMovies": "Extract chapter image extraction for Movies", + "LabelChapterImageExtractionForMoviesHelp": "Extracting chapter images will allow clients to display graphical scene selection menus. The process can be slow, cpu-intensive and may require several gigabytes of space. It runs as a nightly scheduled task at 4am, although this is configurable in the scheduled tasks area. It is not recommended to run this task during peak usage hours.", + "LabelEnableAutomaticPortMapping": "Enable automatic port mapping", + "LabelEnableAutomaticPortMappingHelp": "UPnP allows automated router configuration for easy remote access. This may not work with some router models.", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "HeaderSetupLibrary": "Setup your media library", + "ButtonAddMediaFolder": "Add media folder", + "LabelFolderType": "Folder type:", + "MediaFolderHelpPluginRequired": "* Requires the use of a plugin, e.g. GameBrowser or MB Bookshelf.", + "ReferToMediaLibraryWiki": "Refer to the media library wiki.", + "LabelCountry": "Country:", + "LabelLanguage": "Language:", + "HeaderPreferredMetadataLanguage": "Preferred metadata language:", + "LabelSaveLocalMetadata": "Save artwork and metadata into media folders", + "LabelSaveLocalMetadataHelp": "Saving artwork and metadata directly into media folders will put them in a place where they can be easily edited.", + "LabelDownloadInternetMetadata": "Download artwork and metadata from the internet", + "LabelDownloadInternetMetadataHelp": "Media Browser can download information about your media to enable rich presentations." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ru.json b/MediaBrowser.Server.Implementations/Localization/Server/ru.json index 4cc6b90f7f..5b673132ee 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/ru.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/ru.json @@ -2,16 +2,49 @@ "LabelExit": "\u0412\u044b\u0445\u043e\u0434", "LabelVisitCommunity": "\u041f\u043e\u0441\u0435\u0442\u0438\u0442\u044c \u0421\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e", "LabelGithubWiki": "\u0412\u0438\u043a\u0438 \u043d\u0430 Github", - "LabelSwagger": "\u041e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u0435", - "LabelStandard": "\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439", + "LabelSwagger": "\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Swagger", + "LabelStandard": "\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f", "LabelViewApiDocumentation": "\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e API", "LabelBrowseLibrary": "\u041e\u0431\u043e\u0437\u0440\u0435\u0432\u0430\u0442\u0435\u043b\u044c \u041c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438", - "LabelConfigureMediaBrowser": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Media Browser", - "LabelOpenLibraryViewer": "\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u041c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438", - "LabelRestartServer": "\u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440", - "LabelShowLogWindow": "\u041e\u043a\u043d\u043e \u0416\u0443\u0440\u043d\u0430\u043b\u0430", + "LabelConfigureMediaBrowser": "\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c Media Browser", + "LabelOpenLibraryViewer": "\u0418\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u041c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0443", + "LabelRestartServer": "\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440", + "LabelShowLogWindow": "\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0416\u0443\u0440\u043d\u0430\u043b \u0432 \u043e\u043a\u043d\u0435", "LabelPrevious": "\u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0435", - "LabelFinish": "\u0417\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c", + "LabelFinish": "\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c", "LabelNext": "\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435", - "LabelYoureDone": "\u0412\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0438!" + "LabelYoureDone": "\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e!", + "WelcomeToMediaBrowser": "Welcome to Media Browser!", + "LabelMediaBrowser": "Media Browser", + "ThisWizardWillGuideYou": "This wizard will help guide you through the setup process.", + "TellUsAboutYourself": "Tell us about yourself", + "LabelYourFirstName": "Your first name:", + "MoreUsersCanBeAddedLater": "More users can be added later within the Dashboard.", + "UserProfilesIntro": "Media Browser includes built-in support for user profiles, enabling each user to have their own display settings, playstate and parental controls.", + "LabelWindowsService": "Windows Service", + "AWindowsServiceHasBeenInstalled": "A Windows Service has been installed.", + "WindowsServiceIntro1": "Media Browser Server normally runs as a desktop application with a tray icon, but if you prefer to run it as a background service, it can be started from the windows services control panel instead.", + "WindowsServiceIntro2": "If using the windows service, please note that it cannot be run at the same time as the tray icon, so you'll need to exit the tray in order to run the service. The service will also need to be configured with administrative privileges via the control panel. Please note that at this time the service is unable to self-update, so new versions will require manual interaction.", + "WizardCompleted": "That's all we need for now. Media Browser has begun collecting information about your media library. Check out some of our apps, and then click Finish<\/b> to view the Dashboard<\/b>.", + "LabelConfigureSettings": "Configure settings", + "LabelEnableVideoImageExtraction": "Enable video image extraction", + "VideoImageExtractionHelp": "For videos that don't already have images, and that we're unable to find internet images for. This will add some additional time to the initial library scan but will result in a more pleasing presentation.", + "LabelEnableChapterImageExtractionForMovies": "Extract chapter image extraction for Movies", + "LabelChapterImageExtractionForMoviesHelp": "Extracting chapter images will allow clients to display graphical scene selection menus. The process can be slow, cpu-intensive and may require several gigabytes of space. It runs as a nightly scheduled task at 4am, although this is configurable in the scheduled tasks area. It is not recommended to run this task during peak usage hours.", + "LabelEnableAutomaticPortMapping": "Enable automatic port mapping", + "LabelEnableAutomaticPortMappingHelp": "UPnP allows automated router configuration for easy remote access. This may not work with some router models.", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "HeaderSetupLibrary": "Setup your media library", + "ButtonAddMediaFolder": "Add media folder", + "LabelFolderType": "Folder type:", + "MediaFolderHelpPluginRequired": "* Requires the use of a plugin, e.g. GameBrowser or MB Bookshelf.", + "ReferToMediaLibraryWiki": "Refer to the media library wiki.", + "LabelCountry": "Country:", + "LabelLanguage": "Language:", + "HeaderPreferredMetadataLanguage": "Preferred metadata language:", + "LabelSaveLocalMetadata": "Save artwork and metadata into media folders", + "LabelSaveLocalMetadataHelp": "Saving artwork and metadata directly into media folders will put them in a place where they can be easily edited.", + "LabelDownloadInternetMetadata": "Download artwork and metadata from the internet", + "LabelDownloadInternetMetadataHelp": "Media Browser can download information about your media to enable rich presentations." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 62a4183911..9630509d3b 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -13,5 +13,38 @@ "LabelPrevious": "Previous", "LabelFinish": "Finish", "LabelNext": "Next", - "LabelYoureDone": "You're Done!" + "LabelYoureDone": "You're Done!", + "WelcomeToMediaBrowser": "Welcome to Media Browser!", + "LabelMediaBrowser": "Media Browser", + "ThisWizardWillGuideYou": "This wizard will help guide you through the setup process.", + "TellUsAboutYourself": "Tell us about yourself", + "LabelYourFirstName": "Your first name:", + "MoreUsersCanBeAddedLater": "More users can be added later within the Dashboard.", + "UserProfilesIntro": "Media Browser includes built-in support for user profiles, enabling each user to have their own display settings, playstate and parental controls.", + "LabelWindowsService": "Windows Service", + "AWindowsServiceHasBeenInstalled": "A Windows Service has been installed.", + "WindowsServiceIntro1": "Media Browser Server normally runs as a desktop application with a tray icon, but if you prefer to run it as a background service, it can be started from the windows services control panel instead.", + "WindowsServiceIntro2": "If using the windows service, please note that it cannot be run at the same time as the tray icon, so you'll need to exit the tray in order to run the service. The service will also need to be configured with administrative privileges via the control panel. Please note that at this time the service is unable to self-update, so new versions will require manual interaction.", + "WizardCompleted": "That's all we need for now. Media Browser has begun collecting information about your media library. Check out some of our apps, and then click Finish to view the Dashboard.", + "LabelConfigureSettings": "Configure settings", + "LabelEnableVideoImageExtraction": "Enable video image extraction", + "VideoImageExtractionHelp": "For videos that don't already have images, and that we're unable to find internet images for. This will add some additional time to the initial library scan but will result in a more pleasing presentation.", + "LabelEnableChapterImageExtractionForMovies": "Extract chapter image extraction for Movies", + "LabelChapterImageExtractionForMoviesHelp": "Extracting chapter images will allow clients to display graphical scene selection menus. The process can be slow, cpu-intensive and may require several gigabytes of space. It runs as a nightly scheduled task at 4am, although this is configurable in the scheduled tasks area. It is not recommended to run this task during peak usage hours.", + "LabelEnableAutomaticPortMapping": "Enable automatic port mapping", + "LabelEnableAutomaticPortMappingHelp": "UPnP allows automated router configuration for easy remote access. This may not work with some router models.", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "HeaderSetupLibrary": "Setup your media library", + "ButtonAddMediaFolder": "Add media folder", + "LabelFolderType": "Folder type:", + "MediaFolderHelpPluginRequired": "* Requires the use of a plugin, e.g. GameBrowser or MB Bookshelf.", + "ReferToMediaLibraryWiki": "Refer to the media library wiki.", + "LabelCountry": "Country:", + "LabelLanguage": "Language:", + "HeaderPreferredMetadataLanguage": "Preferred metadata language:", + "LabelSaveLocalMetadata": "Save artwork and metadata into media folders", + "LabelSaveLocalMetadataHelp": "Saving artwork and metadata directly into media folders will put them in a place where they can be easily edited.", + "LabelDownloadInternetMetadata": "Download artwork and metadata from the internet", + "LabelDownloadInternetMetadataHelp": "Media Browser can download information about your media to enable rich presentations." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json b/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json new file mode 100644 index 0000000000..6084c1511f --- /dev/null +++ b/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json @@ -0,0 +1,50 @@ +{ + "LabelExit": "\u96e2\u958b", + "LabelVisitCommunity": "\u8a2a\u554f\u793e\u5340", + "LabelGithubWiki": "Github Wiki", + "LabelSwagger": "Swagger", + "LabelStandard": "\u6a19\u6dee", + "LabelViewApiDocumentation": "View Api Documentation", + "LabelBrowseLibrary": "Browse Library", + "LabelConfigureMediaBrowser": "Configure Media Browser", + "LabelOpenLibraryViewer": "Open Library Viewer", + "LabelRestartServer": "\u91cd\u65b0\u555f\u52d5\u670d\u52d9\u5668", + "LabelShowLogWindow": "\u986f\u793a\u65e5\u8a8c\u8996\u7a97", + "LabelPrevious": "\u4e0a\u4e00\u500b", + "LabelFinish": "\u5b8c\u7d50", + "LabelNext": "\u4e0b\u4e00\u500b", + "LabelYoureDone": "You're Done!", + "WelcomeToMediaBrowser": "Welcome to Media Browser!", + "LabelMediaBrowser": "Media Browser", + "ThisWizardWillGuideYou": "This wizard will help guide you through the setup process.", + "TellUsAboutYourself": "Tell us about yourself", + "LabelYourFirstName": "Your first name:", + "MoreUsersCanBeAddedLater": "More users can be added later within the Dashboard.", + "UserProfilesIntro": "Media Browser includes built-in support for user profiles, enabling each user to have their own display settings, playstate and parental controls.", + "LabelWindowsService": "Windows Service", + "AWindowsServiceHasBeenInstalled": "A Windows Service has been installed.", + "WindowsServiceIntro1": "Media Browser Server normally runs as a desktop application with a tray icon, but if you prefer to run it as a background service, it can be started from the windows services control panel instead.", + "WindowsServiceIntro2": "If using the windows service, please note that it cannot be run at the same time as the tray icon, so you'll need to exit the tray in order to run the service. The service will also need to be configured with administrative privileges via the control panel. Please note that at this time the service is unable to self-update, so new versions will require manual interaction.", + "WizardCompleted": "That's all we need for now. Media Browser has begun collecting information about your media library. Check out some of our apps, and then click Finish<\/b> to view the Dashboard<\/b>.", + "LabelConfigureSettings": "Configure settings", + "LabelEnableVideoImageExtraction": "Enable video image extraction", + "VideoImageExtractionHelp": "For videos that don't already have images, and that we're unable to find internet images for. This will add some additional time to the initial library scan but will result in a more pleasing presentation.", + "LabelEnableChapterImageExtractionForMovies": "Extract chapter image extraction for Movies", + "LabelChapterImageExtractionForMoviesHelp": "Extracting chapter images will allow clients to display graphical scene selection menus. The process can be slow, cpu-intensive and may require several gigabytes of space. It runs as a nightly scheduled task at 4am, although this is configurable in the scheduled tasks area. It is not recommended to run this task during peak usage hours.", + "LabelEnableAutomaticPortMapping": "Enable automatic port mapping", + "LabelEnableAutomaticPortMappingHelp": "UPnP allows automated router configuration for easy remote access. This may not work with some router models.", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "HeaderSetupLibrary": "Setup your media library", + "ButtonAddMediaFolder": "Add media folder", + "LabelFolderType": "Folder type:", + "MediaFolderHelpPluginRequired": "* Requires the use of a plugin, e.g. GameBrowser or MB Bookshelf.", + "ReferToMediaLibraryWiki": "Refer to the media library wiki.", + "LabelCountry": "Country:", + "LabelLanguage": "Language:", + "HeaderPreferredMetadataLanguage": "Preferred metadata language:", + "LabelSaveLocalMetadata": "Save artwork and metadata into media folders", + "LabelSaveLocalMetadataHelp": "Saving artwork and metadata directly into media folders will put them in a place where they can be easily edited.", + "LabelDownloadInternetMetadata": "Download artwork and metadata from the internet", + "LabelDownloadInternetMetadataHelp": "Media Browser can download information about your media to enable rich presentations." +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 539b968c72..d06cf01812 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -290,6 +290,17 @@ + + + + + + + + + + + diff --git a/MediaBrowser.Server.Implementations/Roku/RokuSessionController.cs b/MediaBrowser.Server.Implementations/Roku/RokuSessionController.cs index 7c8d71b4f0..608e92b24c 100644 --- a/MediaBrowser.Server.Implementations/Roku/RokuSessionController.cs +++ b/MediaBrowser.Server.Implementations/Roku/RokuSessionController.cs @@ -41,16 +41,6 @@ namespace MediaBrowser.Server.Implementations.Roku } } - public Task SendSystemCommand(SystemCommand command, CancellationToken cancellationToken) - { - return SendCommand(new WebSocketMessage - { - MessageType = "SystemCommand", - Data = command.ToString() - - }, cancellationToken); - } - public Task SendMessageCommand(MessageCommand command, CancellationToken cancellationToken) { return SendCommand(new WebSocketMessage @@ -148,9 +138,9 @@ namespace MediaBrowser.Server.Implementations.Roku } - public Task SendGenericCommand(GenericCommand command, CancellationToken cancellationToken) + public Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken) { - return SendCommand(new WebSocketMessage + return SendCommand(new WebSocketMessage { MessageType = "Command", Data = command diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 00d2aa992d..3b6e9fefbc 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -661,24 +661,24 @@ namespace MediaBrowser.Server.Implementations.Session return session; } - public Task SendSystemCommand(Guid controllingSessionId, Guid sessionId, SystemCommand command, CancellationToken cancellationToken) + public Task SendMessageCommand(Guid controllingSessionId, Guid sessionId, MessageCommand command, CancellationToken cancellationToken) { var session = GetSessionForRemoteControl(sessionId); var controllingSession = GetSession(controllingSessionId); AssertCanControl(session, controllingSession); - return session.SessionController.SendSystemCommand(command, cancellationToken); + return session.SessionController.SendMessageCommand(command, cancellationToken); } - public Task SendMessageCommand(Guid controllingSessionId, Guid sessionId, MessageCommand command, CancellationToken cancellationToken) + public Task SendGeneralCommand(Guid controllingSessionId, Guid sessionId, GeneralCommand command, CancellationToken cancellationToken) { var session = GetSessionForRemoteControl(sessionId); var controllingSession = GetSession(controllingSessionId); AssertCanControl(session, controllingSession); - return session.SessionController.SendMessageCommand(command, cancellationToken); + return session.SessionController.SendGeneralCommand(command, cancellationToken); } public Task SendPlayCommand(Guid controllingSessionId, Guid sessionId, PlayRequest command, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Session/WebSocketController.cs b/MediaBrowser.Server.Implementations/Session/WebSocketController.cs index ddf4ec2ca7..3bb84fa0ee 100644 --- a/MediaBrowser.Server.Implementations/Session/WebSocketController.cs +++ b/MediaBrowser.Server.Implementations/Session/WebSocketController.cs @@ -57,18 +57,6 @@ namespace MediaBrowser.Server.Implementations.Session return socket; } - public Task SendSystemCommand(SystemCommand command, CancellationToken cancellationToken) - { - var socket = GetActiveSocket(); - - return socket.SendAsync(new WebSocketMessage - { - MessageType = "SystemCommand", - Data = command.ToString() - - }, cancellationToken); - } - public Task SendMessageCommand(MessageCommand command, CancellationToken cancellationToken) { var socket = GetActiveSocket(); @@ -199,13 +187,13 @@ namespace MediaBrowser.Server.Implementations.Session }, cancellationToken); } - public Task SendGenericCommand(GenericCommand command, CancellationToken cancellationToken) + public Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken) { var socket = GetActiveSocket(); - return socket.SendAsync(new WebSocketMessage + return socket.SendAsync(new WebSocketMessage { - MessageType = "Command", + MessageType = "GeneralCommand", Data = command }, cancellationToken); diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index 2575434f41..b545156ec0 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -879,6 +879,7 @@ namespace MediaBrowser.ServerApplication ProgramDataPath = ApplicationPaths.ProgramDataPath, LogPath = ApplicationPaths.LogDirectoryPath, ItemsByNamePath = ApplicationPaths.ItemsByNamePath, + InternalMetadataPath = ApplicationPaths.InternalMetadataPath, CachePath = ApplicationPaths.CachePath, MacAddress = GetMacAddress(), HttpServerPortNumber = HttpServerPort, diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 75b1c0f707..de113297e7 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -219,7 +219,7 @@ namespace MediaBrowser.WebDashboard.Api var contentType = MimeTypes.GetMimeType(path); var isHtml = IsHtml(path); - var localizationCulture = isHtml ? GetLocalizationCulture() : null; + var localizationCulture = GetLocalizationCulture(); // Don't cache if not configured to do so // But always cache images to simulate production