From d8d5dd487326dd3fccf4e9f30cd8f7e3783fcfda Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 12 Jan 2015 22:46:44 -0500 Subject: make channel access opt-in rather than opt out --- .../Localization/JavaScript/javascript.json | 1 + 1 file changed, 1 insertion(+) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 943daff5e..8acce7b72 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -42,6 +42,7 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Save", + "HeaderDevices": "Devices", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", "HeaderWelcomeToMediaBrowserWebClient": "Welcome to the Media Browser Web Client", -- cgit v1.2.3 From 449f28446b3aae422ff8debcb28429387246542d Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 17 Jan 2015 14:59:06 -0500 Subject: Show ssl port on dashboard. --- .../Localization/JavaScript/javascript.json | 1 + MediaBrowser.Server.Startup.Common/ApplicationHost.cs | 1 + 2 files changed, 2 insertions(+) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 8acce7b72..ad7a0aef0 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -194,6 +194,7 @@ "LabelVideoCodec": "Video: {0}", "LabelRemoteAccessUrl": "Remote access: {0}", "LabelRunningOnPort": "Running on port {0}.", + "LabelRunningOnHttpsPort": "Running on SSL port {0}.", "HeaderLatestFromChannel": "Latest from {0}", "ButtonDownload": "Download", "LabelUnknownLanaguage": "Unknown language", diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 29c530438..3cab5ab2f 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -978,6 +978,7 @@ namespace MediaBrowser.Server.Startup.Common MacAddress = GetMacAddress(), HttpServerPortNumber = HttpServerPort, UseHttps = UseHttps, + HttpsPortNumber = HttpsServerPort, CertificatePath = CertificatePath, OperatingSystem = OperatingSystemDisplayName, CanSelfRestart = CanSelfRestart, -- cgit v1.2.3 From cefd565e67ce3b8225eb2fa8a7338dc4d85b458d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 18 Jan 2015 14:53:34 -0500 Subject: display server name in dashboard --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- .../MediaEncoding/ISubtitleEncoder.cs | 3 +- MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs | 2 +- .../Subtitles/SubtitleEncoder.cs | 65 +++++++++++++--------- .../Configuration/ServerConfiguration.cs | 3 - MediaBrowser.Providers/Movies/MovieDbSearch.cs | 9 +-- .../HttpServer/HttpListenerHost.cs | 11 ---- .../HttpServer/ServerFactory.cs | 6 +- .../Localization/JavaScript/javascript.json | 3 + .../Localization/Server/server.json | 4 +- .../ApplicationHost.cs | 14 +---- 11 files changed, 52 insertions(+), 70 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 56dc38e91..9253bc369 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -629,7 +629,7 @@ namespace MediaBrowser.Api.Playback if (!string.IsNullOrEmpty(state.SubtitleStream.Language)) { - var charenc = SubtitleEncoder.GetSubtitleFileCharacterSet(subtitlePath, state.SubtitleStream.Language); + var charenc = SubtitleEncoder.GetSubtitleFileCharacterSet(subtitlePath); if (!string.IsNullOrEmpty(charenc)) { diff --git a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs index 9e32fc32b..37c2bf4d2 100644 --- a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs @@ -47,9 +47,8 @@ namespace MediaBrowser.Controller.MediaEncoding /// Gets the subtitle language encoding parameter. /// /// The path. - /// The language. /// System.String. - string GetSubtitleFileCharacterSet(string path, string language); + string GetSubtitleFileCharacterSet(string path); } } diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index b357b0417..344eb9fbd 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -1015,7 +1015,7 @@ namespace MediaBrowser.MediaEncoding.Encoder if (!string.IsNullOrEmpty(state.SubtitleStream.Language)) { - var charenc = SubtitleEncoder.GetSubtitleFileCharacterSet(subtitlePath, state.SubtitleStream.Language); + var charenc = SubtitleEncoder.GetSubtitleFileCharacterSet(subtitlePath); if (!string.IsNullOrEmpty(charenc)) { diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 10d8112ff..4723525e3 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -149,22 +149,22 @@ namespace MediaBrowser.MediaEncoding.Subtitles var fileInfo = await GetReadableFile(mediaSource.Path, inputFiles, mediaSource.Protocol, subtitleStream, cancellationToken).ConfigureAwait(false); - var stream = await GetSubtitleStream(fileInfo.Item1, subtitleStream.Language, fileInfo.Item3).ConfigureAwait(false); + var stream = await GetSubtitleStream(fileInfo.Item1, fileInfo.Item3).ConfigureAwait(false); return new Tuple(stream, fileInfo.Item2); } - private async Task GetSubtitleStream(string path, string language, bool requiresCharset) + private async Task GetSubtitleStream(string path, bool requiresCharset) { - if (requiresCharset && !string.IsNullOrEmpty(language)) + if (requiresCharset) { - var charset = GetSubtitleFileCharacterSet(path, language); + var charset = GetSubtitleFileCharacterSet(path); if (!string.IsNullOrEmpty(charset)) { using (var fs = _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true)) { - using (var reader = new StreamReader(fs, Encoding.GetEncoding(charset))) + using (var reader = new StreamReader(fs, GetEncoding(charset))) { var text = await reader.ReadToEndAsync().ConfigureAwait(false); @@ -179,6 +179,23 @@ namespace MediaBrowser.MediaEncoding.Subtitles return File.OpenRead(path); } + private Encoding GetEncoding(string charset) + { + if (string.IsNullOrWhiteSpace(charset)) + { + throw new ArgumentNullException("charset"); + } + + try + { + return Encoding.GetEncoding(charset); + } + catch (ArgumentException) + { + return Encoding.GetEncoding(charset.Replace("-", string.Empty)); + } + } + private async Task> GetReadableFile(string mediaPath, string[] inputFiles, MediaProtocol protocol, @@ -227,8 +244,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles // Convert var outputPath = GetSubtitleCachePath(mediaPath, subtitleStream.Index, ".srt"); - await ConvertTextSubtitleToSrt(subtitleStream.Path, outputPath, subtitleStream.Language, cancellationToken) - .ConfigureAwait(false); + await ConvertTextSubtitleToSrt(subtitleStream.Path, outputPath, cancellationToken).ConfigureAwait(false); return new Tuple(outputPath, "srt", true); } @@ -321,11 +337,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// /// The input path. /// The output path. - /// The language. /// The cancellation token. /// Task. - public async Task ConvertTextSubtitleToSrt(string inputPath, string outputPath, string language, - CancellationToken cancellationToken) + public async Task ConvertTextSubtitleToSrt(string inputPath, string outputPath, CancellationToken cancellationToken) { var semaphore = GetLock(outputPath); @@ -335,7 +349,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { if (!File.Exists(outputPath)) { - await ConvertTextSubtitleToSrtInternal(inputPath, outputPath, language).ConfigureAwait(false); + await ConvertTextSubtitleToSrtInternal(inputPath, outputPath).ConfigureAwait(false); } } finally @@ -349,15 +363,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// /// The input path. /// The output path. - /// The language. /// Task. - /// - /// inputPath + /// inputPath /// or - /// outputPath - /// + /// outputPath /// - private async Task ConvertTextSubtitleToSrtInternal(string inputPath, string outputPath, string language) + private async Task ConvertTextSubtitleToSrtInternal(string inputPath, string outputPath) { if (string.IsNullOrEmpty(inputPath)) { @@ -371,9 +382,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); - var encodingParam = string.IsNullOrEmpty(language) - ? string.Empty - : GetSubtitleFileCharacterSet(inputPath, language); + var encodingParam = GetSubtitleFileCharacterSet(inputPath); if (!string.IsNullOrEmpty(encodingParam)) { @@ -696,10 +705,14 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// Gets the subtitle language encoding param. /// /// The path. - /// The language. /// System.String. - public string GetSubtitleFileCharacterSet(string path, string language) + public string GetSubtitleFileCharacterSet(string path) { + if (GetFileEncoding(path).Equals(Encoding.UTF8)) + { + return string.Empty; + } + var charset = DetectCharset(path); if (!string.IsNullOrWhiteSpace(charset)) @@ -712,11 +725,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles return charset; } - if (GetFileEncoding(path).Equals(Encoding.UTF8)) - { - return string.Empty; - } + return null; + } + public string GetSubtitleFileCharacterSetFromLanguage(string language) + { switch (language.ToLower()) { case "pol": diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index e51cca770..a2a909dcc 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -191,8 +191,6 @@ namespace MediaBrowser.Model.Configuration public bool SaveMetadataHidden { get; set; } - public bool EnableWin8HttpListener { get; set; } - public NameValuePair[] ContentTypes { get; set; } public bool EnableAudioArchiveFiles { get; set; } @@ -214,7 +212,6 @@ namespace MediaBrowser.Model.Configuration EnableDashboardResourceMinification = true; EnableAutomaticRestart = true; - EnableWin8HttpListener = true; EnableUPnP = true; diff --git a/MediaBrowser.Providers/Movies/MovieDbSearch.cs b/MediaBrowser.Providers/Movies/MovieDbSearch.cs index ae176e489..f1ccd1c30 100644 --- a/MediaBrowser.Providers/Movies/MovieDbSearch.cs +++ b/MediaBrowser.Providers/Movies/MovieDbSearch.cs @@ -183,14 +183,7 @@ namespace MediaBrowser.Providers.Movies if (DateTime.TryParseExact(result.release_date, "yyyy-MM-dd", EnUs, DateTimeStyles.None, out r)) { // Allow one year tolernace, preserve order from Tmdb - var variance = Math.Abs(r.Year - year.Value); - - if (variance <= 1) - { - return 0; - } - - return variance; + return Math.Abs(r.Year - year.Value); } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 1d7e89d28..7022dc76d 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -41,8 +41,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer private readonly ReaderWriterLockSlim _localEndpointLock = new ReaderWriterLockSlim(); - private readonly bool _supportsNativeWebSocket; - private string _certificatePath; /// @@ -67,12 +65,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer ILogManager logManager, string serviceName, string defaultRedirectPath, - bool supportsNativeWebSocket, params Assembly[] assembliesWithServices) : base(serviceName, assembliesWithServices) { DefaultRedirectPath = defaultRedirectPath; - _supportsNativeWebSocket = supportsNativeWebSocket; _logger = logManager.GetLogger("HttpServer"); @@ -210,13 +206,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer private IHttpListener GetListener() { - if (_supportsNativeWebSocket && NativeWebSocket.IsSupported) - { - // Certificate location is ignored here. You need to use netsh - // to assign the certificate to the proper port. - return new HttpListenerServer(_logger, OnRequestReceived); - } - return new WebSocketSharpListener(_logger, OnRequestReceived, _certificatePath); } diff --git a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs index 73d761060..d1222ab74 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs @@ -17,17 +17,15 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// The log manager. /// Name of the server. /// The default redirectpath. - /// if set to true [supports native web socket]. /// IHttpServer. public static IHttpServer CreateServer(IApplicationHost applicationHost, ILogManager logManager, string serverName, - string defaultRedirectpath, - bool supportsNativeWebSocket) + string defaultRedirectpath) { LogManager.LogFactory = new ServerLogFactory(logManager); - return new HttpListenerHost(applicationHost, logManager, serverName, defaultRedirectpath, supportsNativeWebSocket); + return new HttpListenerHost(applicationHost, logManager, serverName, defaultRedirectpath); } } } diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index ad7a0aef0..5235f46a9 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -591,6 +591,8 @@ "MediaInfoStreamTypeEmbeddedImage": "Embedded Image", "MediaInfoRefFrames": "Ref frames", "TabPlayback": "Playback", + "TabNotifications": "Notifications", + "TabExpert": "Expert", "HeaderSelectCustomIntrosPath": "Select Custom Intros Path", "HeaderRateAndReview": "Rate and Review", "HeaderThankYou": "Thank You", @@ -625,6 +627,7 @@ "DashboardTourMobile": "The Media Browser dashboard works great on smartphones and tablets. Manage your server from the palm of your hand anytime, anywhere.", "MessageRefreshQueued": "Refresh queued", "TabDevices": "Devices", + "TabExtras": "Extras", "DeviceLastUsedByUserName": "Last used by {0}", "HeaderDeleteDevice": "Delete Device", "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 37948cb3f..dc74c5f86 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -42,7 +42,7 @@ "ButtonTermsOfService": "Terms of Service", "HeaderDeveloperOptions": "Developer Options", "OptionEnableWebClientResponseCache": "Enable web client response caching", - "OptionDisableForDevelopmentHelp": "Disable these for web client development purposes", + "OptionDisableForDevelopmentHelp": "Configure these as needed for web client development purposes.", "OptionEnableWebClientResourceMinification": "Enable web client resource minification", "LabelDashboardSourcePath": "Web client source path:", "LabelDashboardSourcePathHelp": "If running the server from source, specify the path to the dashboard-ui folder. All web client files will be served from this location.", @@ -53,6 +53,7 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", "OptionDetectArchiveFilesAsMediaHelp": "If enabled, files with .rar and .zip extensions will be detected as media files.", @@ -71,6 +72,7 @@ "FolderTypeTvShows": "TV", "FolderTypeInherit": "Inherit", "LabelContentType": "Content type:", + "TitleScheduledTasks": "Scheduled Tasks", "HeaderSetupLibrary": "Setup your media library", "ButtonAddMediaFolder": "Add media folder", "LabelFolderType": "Folder type:", diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index e15b60d47..3867fc243 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -460,19 +460,7 @@ namespace MediaBrowser.Server.Startup.Common RegisterSingleInstance(() => new SearchEngine(LogManager, LibraryManager, UserManager)); - if (IsFirstRun) - { - ServerConfigurationManager.Configuration.EnableWin8HttpListener = false; - ServerConfigurationManager.SaveConfiguration(); - _supportsNativeWebSocket = false; - } - - if (!ServerConfigurationManager.Configuration.EnableWin8HttpListener) - { - _supportsNativeWebSocket = false; - } - - HttpServer = ServerFactory.CreateServer(this, LogManager, "Media Browser", "web/index.html", false); + HttpServer = ServerFactory.CreateServer(this, LogManager, "Media Browser", "web/index.html"); RegisterSingleInstance(HttpServer, false); progress.Report(10); -- cgit v1.2.3 From de76156391655f726b5655f727e06822398827ca Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 18 Jan 2015 23:29:57 -0500 Subject: rework hosting options --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 26 +++++ MediaBrowser.Controller/IServerApplicationHost.cs | 14 ++- MediaBrowser.Controller/Net/IHttpServer.cs | 7 +- MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 2 +- MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 2 +- .../Configuration/ServerConfiguration.cs | 4 +- MediaBrowser.Model/System/SystemInfo.cs | 10 +- .../BoxSets/BoxSetMetadataService.cs | 18 +-- MediaBrowser.Providers/TV/SeriesMetadataService.cs | 13 --- .../Collections/CollectionManager.cs | 6 +- .../Connect/ConnectManager.cs | 31 +++++- .../EntryPoints/ExternalPortForwarding.cs | 80 ++++++++------ .../HttpServer/HttpListenerHost.cs | 7 +- .../SocketSharp/WebSocketSharpListener.cs | 2 +- .../Localization/JavaScript/javascript.json | 5 +- .../Localization/Server/server.json | 15 ++- MediaBrowser.Server.Mono/Program.cs | 2 +- .../ApplicationHost.cs | 122 +++++++++++---------- .../Browser/BrowserLauncher.cs | 4 +- MediaBrowser.ServerApplication/MainStartup.cs | 1 - MediaBrowser.WebDashboard/Api/PackageCreator.cs | 1 + .../MediaBrowser.WebDashboard.csproj | 6 + 23 files changed, 224 insertions(+), 156 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 9253bc369..6d403c898 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -858,7 +858,7 @@ namespace MediaBrowser.Api.Playback if (SupportsThrottleWithStream) { var url = "http://localhost:" + ServerConfigurationManager.Configuration.HttpServerPortNumber.ToString(UsCulture) + "/videos/" + state.Request.Id + "/stream?static=true&Throttle=true&mediaSourceId=" + state.Request.MediaSourceId; - + url += "&transcodingJobId=" + transcodingJobId; return string.Format("\"{0}\"", url); diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 4483c7b0f..e48b8d845 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Progress; +using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; @@ -93,6 +94,31 @@ namespace MediaBrowser.Controller.Entities.Movies return list; } + /// + /// Updates the official rating based on content and returns true or false indicating if it changed. + /// + /// + public bool UpdateRatingToContent() + { + var currentOfficialRating = OfficialRating; + + // Gather all possible ratings + var ratings = RecursiveChildren + .Concat(GetLinkedChildren()) + .Where(i => i is Movie || i is Series) + .Select(i => i.OfficialRating) + .Where(i => !string.IsNullOrEmpty(i)) + .Distinct(StringComparer.OrdinalIgnoreCase) + .Select(i => new Tuple(i, LocalizationManager.GetRatingLevel(i))) + .OrderBy(i => i.Item2 ?? 1000) + .Select(i => i.Item1); + + OfficialRating = ratings.FirstOrDefault() ?? currentOfficialRating; + + return !string.Equals(currentOfficialRating ?? string.Empty, OfficialRating ?? string.Empty, + StringComparison.OrdinalIgnoreCase); + } + public override IEnumerable GetChildren(User user, bool includeLinkedChildren) { var children = base.GetChildren(user, includeLinkedChildren); diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 181c14deb..0b0f6d828 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -28,7 +28,19 @@ namespace MediaBrowser.Controller /// Gets the HTTP server port. /// /// The HTTP server port. - int HttpServerPort { get; } + int HttpPort { get; } + + /// + /// Gets the HTTPS port. + /// + /// The HTTPS port. + int HttpsPort { get; } + + /// + /// Gets a value indicating whether [supports HTTPS]. + /// + /// true if [supports HTTPS]; otherwise, false. + bool EnableHttps { get; } /// /// Gets a value indicating whether this instance has update available. diff --git a/MediaBrowser.Controller/Net/IHttpServer.cs b/MediaBrowser.Controller/Net/IHttpServer.cs index d56bee009..315b48b83 100644 --- a/MediaBrowser.Controller/Net/IHttpServer.cs +++ b/MediaBrowser.Controller/Net/IHttpServer.cs @@ -1,4 +1,3 @@ -using MediaBrowser.Common.Net; using System; using System.Collections.Generic; @@ -15,6 +14,12 @@ namespace MediaBrowser.Controller.Net /// The URL prefix. IEnumerable UrlPrefixes { get; } + /// + /// Gets the certificate path. + /// + /// The certificate path. + string CertificatePath { get; } + /// /// Starts the specified server name. /// diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index bcb539ac8..c75f2e40c 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -167,7 +167,7 @@ namespace MediaBrowser.Dlna.Main var descriptorURI = "/dlna/" + guid.ToString("N") + "/description.xml"; - var uri = new Uri(string.Format("http://{0}:{1}{2}", address, _config.Configuration.HttpServerPortNumber, descriptorURI)); + var uri = new Uri(string.Format("http://{0}:{1}{2}", address, _appHost.HttpPort, descriptorURI)); var services = new List { diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index a60b5efa4..5e37417c6 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -152,7 +152,7 @@ namespace MediaBrowser.Dlna.PlayTo "http", localIp, - _appHost.HttpServerPort + _appHost.HttpPort ); } diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index a2a909dcc..94bd30d0b 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -36,7 +36,7 @@ namespace MediaBrowser.Model.Configuration /// Gets or sets a value indicating whether [use HTTPS]. /// /// true if [use HTTPS]; otherwise, false. - public bool UseHttps { get; set; } + public bool EnableHttps { get; set; } /// /// Gets or sets the value pointing to the file system where the ssl certiifcate is located.. @@ -206,7 +206,7 @@ namespace MediaBrowser.Model.Configuration PublicPort = 8096; HttpServerPortNumber = 8096; HttpsPortNumber = 8920; - UseHttps = false; + EnableHttps = false; CertificatePath = null; EnableDashboardResponseCaching = true; EnableDashboardResourceMinification = true; diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index 0d0c0cddb..ff9d822dd 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -122,11 +122,11 @@ namespace MediaBrowser.Model.System /// The HTTP server port number. public int HttpServerPortNumber { get; set; } - /// - /// Gets or sets the value pointing to the file system where the ssl certiifcate is located. - /// - /// The value pointing to the file system where the ssl certiifcate is located. - public bool UseHttps { get; set; } + /// + /// Gets or sets a value indicating whether [enable HTTPS]. + /// + /// true if [enable HTTPS]; otherwise, false. + public bool EnableHttps { get; set; } /// /// Gets or sets the HTTPS server port number. diff --git a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs index 5e16ed69c..e195df7dd 100644 --- a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs +++ b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs @@ -60,23 +60,7 @@ namespace MediaBrowser.Providers.BoxSets { if (!item.LockedFields.Contains(MetadataFields.OfficialRating)) { - var currentOfficialRating = item.OfficialRating; - - // Gather all possible ratings - var ratings = item.RecursiveChildren - .Concat(item.GetLinkedChildren()) - .Where(i => i is Movie || i is Series) - .Select(i => i.OfficialRating) - .Where(i => !string.IsNullOrEmpty(i)) - .Distinct(StringComparer.OrdinalIgnoreCase) - .Select(i => new Tuple(i, _iLocalizationManager.GetRatingLevel(i))) - .OrderBy(i => i.Item2 ?? 1000) - .Select(i => i.Item1); - - item.OfficialRating = ratings.FirstOrDefault() ?? item.OfficialRating; - - if (!string.Equals(currentOfficialRating ?? string.Empty, item.OfficialRating ?? string.Empty, - StringComparison.OrdinalIgnoreCase)) + if (item.UpdateRatingToContent()) { updateType = updateType | ItemUpdateType.MetadataEdit; } diff --git a/MediaBrowser.Providers/TV/SeriesMetadataService.cs b/MediaBrowser.Providers/TV/SeriesMetadataService.cs index 62e5ff4fc..e03104a23 100644 --- a/MediaBrowser.Providers/TV/SeriesMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeriesMetadataService.cs @@ -8,8 +8,6 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; namespace MediaBrowser.Providers.TV { @@ -61,16 +59,5 @@ namespace MediaBrowser.Providers.TV target.DisplaySpecialsWithSeasons = source.DisplaySpecialsWithSeasons; } } - - protected override async Task BeforeSave(Series item, bool isFullRefresh, ItemUpdateType currentUpdateType) - { - var updateType = await base.BeforeSave(item, isFullRefresh, currentUpdateType).ConfigureAwait(false); - - //var provider = new DummySeasonProvider(ServerConfigurationManager, Logger, _localization, _libraryManager); - - //await provider.Run(item, CancellationToken.None).ConfigureAwait(false); - - return updateType; - } } } diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs index 05efcaa1c..28f3ed89c 100644 --- a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs +++ b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs @@ -184,8 +184,9 @@ namespace MediaBrowser.Server.Implementations.Collections collection.LinkedChildren.AddRange(list); - await collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); + collection.UpdateRatingToContent(); + await collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); await collection.RefreshMetadata(CancellationToken.None).ConfigureAwait(false); if (fireEvent) @@ -274,8 +275,9 @@ namespace MediaBrowser.Server.Implementations.Collections } } - await collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); + collection.UpdateRatingToContent(); + await collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); await collection.RefreshMetadata(CancellationToken.None).ConfigureAwait(false); EventHelper.FireEventIfNotNull(ItemsRemovedFromCollection, this, new CollectionModifiedEventArgs diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index 194a8a4a2..d3a29f420 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -78,7 +78,7 @@ namespace MediaBrowser.Server.Implementations.Connect if (!ip.StartsWith("http://", StringComparison.OrdinalIgnoreCase) && !ip.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { - ip = (_config.Configuration.UseHttps ? "https://" : "http://") + ip; + ip = (_appHost.EnableHttps ? "https://" : "http://") + ip; } return ip + ":" + _config.Configuration.PublicPort.ToString(CultureInfo.InvariantCulture); @@ -90,7 +90,7 @@ namespace MediaBrowser.Server.Implementations.Connect private string XApplicationValue { - get { return "Media Browser Server/" + _appHost.ApplicationVersion; } + get { return _appHost.Name + "/" + _appHost.ApplicationVersion; } } public ConnectManager(ILogger logger, @@ -112,6 +112,7 @@ namespace MediaBrowser.Server.Implementations.Connect _providerManager = providerManager; _userManager.UserConfigurationUpdated += _userManager_UserConfigurationUpdated; + _config.ConfigurationUpdated += _config_ConfigurationUpdated; LoadCachedData(); } @@ -164,8 +165,7 @@ namespace MediaBrowser.Server.Implementations.Connect } catch (HttpException ex) { - if (!ex.StatusCode.HasValue || - !new[] { HttpStatusCode.NotFound, HttpStatusCode.Unauthorized }.Contains(ex.StatusCode.Value)) + if (!ex.StatusCode.HasValue || !new[] { HttpStatusCode.NotFound, HttpStatusCode.Unauthorized }.Contains(ex.StatusCode.Value)) { throw; } @@ -179,6 +179,8 @@ namespace MediaBrowser.Server.Implementations.Connect await CreateServerRegistration(wanApiAddress, localAddress).ConfigureAwait(false); } + _lastReportedIdentifier = GetConnectReportingIdentifier(localAddress, wanApiAddress); + await RefreshAuthorizationsInternal(true, CancellationToken.None).ConfigureAwait(false); } catch (Exception ex) @@ -187,6 +189,27 @@ namespace MediaBrowser.Server.Implementations.Connect } } + private string _lastReportedIdentifier; + private string GetConnectReportingIdentifier() + { + return GetConnectReportingIdentifier(_appHost.GetSystemInfo().LocalAddress, WanApiAddress); + } + private string GetConnectReportingIdentifier(string localAddress, string remoteAddress) + { + return (remoteAddress ?? string.Empty) + (localAddress ?? string.Empty); + } + + void _config_ConfigurationUpdated(object sender, EventArgs e) + { + // If info hasn't changed, don't report anything + if (string.Equals(_lastReportedIdentifier, GetConnectReportingIdentifier(), StringComparison.OrdinalIgnoreCase)) + { + return; + } + + UpdateConnectInfo(); + } + private async Task CreateServerRegistration(string wanApiAddress, string localAddress) { if (string.IsNullOrWhiteSpace(wanApiAddress)) diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index e32068905..4371739b7 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -5,6 +5,7 @@ using MediaBrowser.Model.Logging; using Mono.Nat; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Text; using System.Threading; @@ -17,30 +18,44 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private readonly ILogger _logger; private readonly IServerConfigurationManager _config; - private bool _isStarted; - private Timer _timer; + private bool _isStarted; public ExternalPortForwarding(ILogManager logmanager, IServerApplicationHost appHost, IServerConfigurationManager config) { _logger = logmanager.GetLogger("PortMapper"); _appHost = appHost; _config = config; + } - _config.ConfigurationUpdated += _config_ConfigurationUpdated; + private string _lastConfigIdentifier; + private string GetConfigIdentifier() + { + var values = new List(); + var config = _config.Configuration; + + values.Add(config.EnableUPnP.ToString()); + values.Add(config.PublicPort.ToString(CultureInfo.InvariantCulture)); + values.Add(_appHost.HttpPort.ToString(CultureInfo.InvariantCulture)); + values.Add(_appHost.HttpsPort.ToString(CultureInfo.InvariantCulture)); + values.Add(config.EnableHttps.ToString()); + values.Add(_appHost.EnableHttps.ToString()); + + return string.Join("|", values.ToArray()); } void _config_ConfigurationUpdated(object sender, EventArgs e) { - var enable = _config.Configuration.EnableUPnP; - - if (enable && !_isStarted) - { - Reload(); - } - else if (!enable && _isStarted) + _config.ConfigurationUpdated -= _config_ConfigurationUpdated; + + if (!string.Equals(_lastConfigIdentifier, GetConfigIdentifier(), StringComparison.OrdinalIgnoreCase)) { - DisposeNat(); + if (_isStarted) + { + DisposeNat(); + } + + Run(); } } @@ -48,31 +63,36 @@ namespace MediaBrowser.Server.Implementations.EntryPoints { //NatUtility.Logger = new LogWriter(_logger); - Reload(); + if (_config.Configuration.EnableUPnP) + { + Start(); + } + + _config.ConfigurationUpdated -= _config_ConfigurationUpdated; + _config.ConfigurationUpdated += _config_ConfigurationUpdated; } - private void Reload() + private void Start() { - if (_config.Configuration.EnableUPnP) - { - _logger.Debug("Starting NAT discovery"); + _logger.Debug("Starting NAT discovery"); - NatUtility.DeviceFound += NatUtility_DeviceFound; + NatUtility.DeviceFound += NatUtility_DeviceFound; - // Mono.Nat does never rise this event. The event is there however it is useless. - // You could remove it with no risk. - NatUtility.DeviceLost += NatUtility_DeviceLost; + // Mono.Nat does never rise this event. The event is there however it is useless. + // You could remove it with no risk. + NatUtility.DeviceLost += NatUtility_DeviceLost; - // it is hard to say what one should do when an unhandled exception is raised - // because there isn't anything one can do about it. Probably save a log or ignored it. - NatUtility.UnhandledException += NatUtility_UnhandledException; - NatUtility.StartDiscovery(); + // it is hard to say what one should do when an unhandled exception is raised + // because there isn't anything one can do about it. Probably save a log or ignored it. + NatUtility.UnhandledException += NatUtility_UnhandledException; + NatUtility.StartDiscovery(); - _isStarted = true; + _timer = new Timer(s => _createdRules = new List(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); - _timer = new Timer(s => _createdRules = new List(), null, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10)); - } + _lastConfigIdentifier = GetConfigIdentifier(); + + _isStarted = true; } void NatUtility_UnhandledException(object sender, UnhandledExceptionEventArgs e) @@ -124,9 +144,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints { _createdRules.Add(address); - var info = _appHost.GetSystemInfo(); - - CreatePortMap(device, info.HttpServerPortNumber, _config.Configuration.PublicPort); + CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort); } } @@ -136,7 +154,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints device.CreatePortMap(new Mapping(Protocol.Tcp, privatePort, publicPort) { - Description = "Media Browser Server" + Description = _appHost.Name }); } diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 7022dc76d..f64e29e4d 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -3,7 +3,6 @@ using MediaBrowser.Common; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; -using MediaBrowser.Server.Implementations.HttpServer.NetListener; using MediaBrowser.Server.Implementations.HttpServer.SocketSharp; using ServiceStack; using ServiceStack.Api.Swagger; @@ -41,7 +40,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer private readonly ReaderWriterLockSlim _localEndpointLock = new ReaderWriterLockSlim(); - private string _certificatePath; + public string CertificatePath { get; private set; } /// /// Gets the local end points. @@ -206,7 +205,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer private IHttpListener GetListener() { - return new WebSocketSharpListener(_logger, OnRequestReceived, _certificatePath); + return new WebSocketSharpListener(_logger, OnRequestReceived, CertificatePath); } private void WebSocketHandler(WebSocketConnectEventArgs args) @@ -434,7 +433,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer public void StartServer(IEnumerable urlPrefixes, string certificatePath) { - _certificatePath = certificatePath; + CertificatePath = certificatePath; UrlPrefixes = urlPrefixes.ToList(); Start(UrlPrefixes.First()); } diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs index 1cf523ad2..0c5c9e9bf 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs @@ -3,12 +3,12 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Server.Implementations.Logging; using ServiceStack; using ServiceStack.Web; +using SocketHttpListener.Net; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using SocketHttpListener.Net; namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 5235f46a9..8e41dda30 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -192,9 +192,10 @@ "LabelPlayMethodDirectPlay": "Direct Playing", "LabelAudioCodec": "Audio: {0}", "LabelVideoCodec": "Video: {0}", + "LabelLocalAccessUrl": "Local access: {0}", "LabelRemoteAccessUrl": "Remote access: {0}", - "LabelRunningOnPort": "Running on port {0}.", - "LabelRunningOnHttpsPort": "Running on SSL port {0}.", + "LabelRunningOnPort": "Running on http port {0}.", + "LabelRunningOnPorts": "Running on http port {0}, and https port {1}.", "HeaderLatestFromChannel": "Latest from {0}", "ButtonDownload": "Download", "LabelUnknownLanaguage": "Unknown language", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index dc74c5f86..683a5a639 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -519,19 +519,17 @@ "LabelLocalHttpServerPortNumberHelp": "The tcp port number that Media Browser's http server should bind to.", "LabelPublicPort": "Public port number:", "LabelPublicPortHelp": "The public port number that should be mapped to the local port.", - - "LabelUseHttps": "Enable SSL", - "LabelUseHttpsHelp": "Check to enable SSL hosting.", - "LabelHttpsPort": "Local http port:", + "LabelEnableHttps": "Enable https for remote connections", + "LabelEnableHttpsHelp": "If enabled, the server will report an https url as it's external address.", + "LabelHttpsPort": "Local https port:", "LabelHttpsPortHelp": "The tcp port number that Media Browser's https server should bind to.", "LabelCertificatePath": "SSL Certificate path:", - "LabelCertificatePathHelp": "The path on the filesystem to the ssl certificate pfx file.", - + "LabelCertificatePathHelp": "The path on the file system to the ssl certificate .pfx file.", "LabelWebSocketPortNumber": "Web socket port number:", "LabelEnableAutomaticPortMap": "Enable automatic port mapping", "LabelEnableAutomaticPortMapHelp": "Attempt to automatically map the public port to the local port via UPnP. This may not work with some router models.", - "LabelExternalDDNS": "External DDNS:", - "LabelExternalDDNSHelp": "If you have a dynamic DNS enter it here. Media Browser apps will use it when connecting remotely.", + "LabelExternalDDNS": "External WAN Address:", + "LabelExternalDDNSHelp": "If you have a dynamic DNS enter it here. Media Browser apps will use it when connecting remotely. Leave empty for automatic detection.", "TabResume": "Resume", "TabWeather": "Weather", "TitleAppSettings": "App Settings", @@ -600,6 +598,7 @@ "ButtonRestart": "Restart", "ButtonShutdown": "Shutdown", "ButtonUpdateNow": "Update Now", + "TabHosting": "Hosting", "PleaseUpdateManually": "Please shutdown the server and update manually.", "NewServerVersionAvailable": "A new version of Media Browser Server is available!", "ServerUpToDate": "Media Browser Server is up to date", diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs index 1cd0b5ae6..10a6c6fb9 100644 --- a/MediaBrowser.Server.Mono/Program.cs +++ b/MediaBrowser.Server.Mono/Program.cs @@ -78,7 +78,7 @@ namespace MediaBrowser.Server.Mono var nativeApp = new NativeApp(); - _appHost = new ApplicationHost(appPaths, logManager, options, fileSystem, "MBServer.Mono", false, nativeApp); + _appHost = new ApplicationHost(appPaths, logManager, options, fileSystem, "MBServer.Mono", nativeApp); if (options.ContainsOption("-v")) { Console.WriteLine (_appHost.ApplicationVersion.ToString()); diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index b71aa2adb..16cf4258a 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -110,38 +110,6 @@ namespace MediaBrowser.Server.Startup.Common get { return (IServerConfigurationManager)ConfigurationManager; } } - /// - /// Gets the name of the web application that can be used for url building. - /// All api urls will be of the form {protocol}://{host}:{port}/{appname}/... - /// - /// The name of the web application. - public string WebApplicationName - { - get { return "mediabrowser"; } - } - - /// - /// Gets the HTTP server URL prefix. - /// - /// The HTTP server URL prefix. - private IEnumerable HttpServerUrlPrefixes - { - get - { - var list = new List - { - "http://+:" + ServerConfigurationManager.Configuration.HttpServerPortNumber + "/" - }; - - if (ServerConfigurationManager.Configuration.UseHttps) - { - list.Add("https://+:" + ServerConfigurationManager.Configuration.HttpsPortNumber + "/"); - } - - return list; - } - } - /// /// Gets the configuration manager. /// @@ -230,8 +198,6 @@ namespace MediaBrowser.Server.Startup.Common private readonly StartupOptions _startupOptions; private readonly string _remotePackageName; - private bool _supportsNativeWebSocket; - internal INativeApp NativeApp { get; set; } /// @@ -242,20 +208,17 @@ namespace MediaBrowser.Server.Startup.Common /// The options. /// The file system. /// Name of the remote package. - /// if set to true [supports native web socket]. /// The native application. public ApplicationHost(ServerApplicationPaths applicationPaths, ILogManager logManager, StartupOptions options, IFileSystem fileSystem, string remotePackageName, - bool supportsNativeWebSocket, INativeApp nativeApp) : base(applicationPaths, logManager, fileSystem) { _startupOptions = options; _remotePackageName = remotePackageName; - _supportsNativeWebSocket = supportsNativeWebSocket; NativeApp = nativeApp; SetBaseExceptionMessage(); @@ -359,6 +322,9 @@ namespace MediaBrowser.Server.Startup.Common public override async Task Init(IProgress progress) { + HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber; + HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber; + PerformPreInitMigrations(); await base.Init(progress).ConfigureAwait(false); @@ -586,10 +552,10 @@ namespace MediaBrowser.Server.Startup.Common new FFmpegValidator(Logger, ApplicationPaths).Validate(info); - MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), - JsonSerializer, - info.EncoderPath, - info.ProbePath, + MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), + JsonSerializer, + info.EncoderPath, + info.ProbePath, info.Version, ServerConfigurationManager, FileSystemManager, @@ -791,6 +757,21 @@ namespace MediaBrowser.Server.Startup.Common SyncManager.AddParts(GetExports()); } + private IEnumerable GetUrlPrefixes() + { + var prefixes = new List + { + "http://+:" + ServerConfigurationManager.Configuration.HttpServerPortNumber + "/" + }; + + if (!string.IsNullOrWhiteSpace(ServerConfigurationManager.Configuration.CertificatePath)) + { + prefixes.Add("https://+:" + ServerConfigurationManager.Configuration.HttpsPortNumber + "/"); + } + + return prefixes; + } + /// /// Starts the server. /// @@ -798,7 +779,7 @@ namespace MediaBrowser.Server.Startup.Common { try { - ServerManager.Start(HttpServerUrlPrefixes, ServerConfigurationManager.Configuration.CertificatePath); + ServerManager.Start(GetUrlPrefixes(), ServerConfigurationManager.Configuration.CertificatePath); } catch (Exception ex) { @@ -817,11 +798,29 @@ namespace MediaBrowser.Server.Startup.Common { base.OnConfigurationUpdated(sender, e); - if (!HttpServer.UrlPrefixes.SequenceEqual(HttpServerUrlPrefixes, StringComparer.OrdinalIgnoreCase)) + var requiresRestart = false; + + // Don't do anything if these haven't been set yet + if (HttpPort != 0 && HttpsPort != 0) + { + // Need to restart if ports have changed + if (ServerConfigurationManager.Configuration.HttpServerPortNumber != HttpPort || + ServerConfigurationManager.Configuration.HttpsPortNumber != HttpsPort) + { + ServerConfigurationManager.Configuration.IsPortAuthorized = false; + ServerConfigurationManager.SaveConfiguration(); + + requiresRestart = true; + } + } + + if (!HttpServer.UrlPrefixes.SequenceEqual(GetUrlPrefixes(), StringComparer.OrdinalIgnoreCase)) { - ServerConfigurationManager.Configuration.IsPortAuthorized = false; - ServerConfigurationManager.SaveConfiguration(); + requiresRestart = true; + } + if (requiresRestart) + { NotifyPendingRestart(); } } @@ -953,7 +952,7 @@ namespace MediaBrowser.Server.Startup.Common HasPendingRestart = HasPendingRestart, Version = ApplicationVersion.ToString(), IsNetworkDeployed = CanSelfUpdate, - WebSocketPortNumber = HttpServerPort, + WebSocketPortNumber = HttpPort, FailedPluginAssemblies = FailedAssemblies.ToList(), InProgressInstallations = InstallationManager.CurrentInstallations.Select(i => i.Item1).ToList(), CompletedInstallations = InstallationManager.CompletedInstallations.ToList(), @@ -964,9 +963,9 @@ namespace MediaBrowser.Server.Startup.Common InternalMetadataPath = ApplicationPaths.InternalMetadataPath, CachePath = ApplicationPaths.CachePath, MacAddress = GetMacAddress(), - HttpServerPortNumber = HttpServerPort, - UseHttps = this.ServerConfigurationManager.Configuration.UseHttps, - HttpsPortNumber = HttpsServerPort, + HttpServerPortNumber = HttpPort, + EnableHttps = EnableHttps, + HttpsPortNumber = HttpsPort, OperatingSystem = OperatingSystemDisplayName, CanSelfRestart = CanSelfRestart, CanSelfUpdate = CanSelfUpdate, @@ -981,6 +980,19 @@ namespace MediaBrowser.Server.Startup.Common }; } + public bool EnableHttps + { + get + { + return SupportsHttps && ServerConfigurationManager.Configuration.EnableHttps; + } + } + + public bool SupportsHttps + { + get { return !string.IsNullOrWhiteSpace(HttpServer.CertificatePath); } + } + /// /// Gets the local ip address. /// @@ -994,7 +1006,7 @@ namespace MediaBrowser.Server.Startup.Common { address = string.Format("http://{0}:{1}", address, - ServerConfigurationManager.Configuration.HttpServerPortNumber.ToString(CultureInfo.InvariantCulture)); + HttpPort.ToString(CultureInfo.InvariantCulture)); } return address; @@ -1036,15 +1048,9 @@ namespace MediaBrowser.Server.Startup.Common } } - public int HttpServerPort - { - get { return ServerConfigurationManager.Configuration.HttpServerPortNumber; } - } + public int HttpPort { get; private set; } - public int HttpsServerPort - { - get { return ServerConfigurationManager.Configuration.HttpsPortNumber; } - } + public int HttpsPort { get; private set; } /// /// Gets the mac address. diff --git a/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs b/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs index bb78cc02f..617ff4cae 100644 --- a/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs +++ b/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs @@ -18,7 +18,7 @@ namespace MediaBrowser.Server.Startup.Common.Browser /// The logger. public static void OpenDashboardPage(string page, IServerApplicationHost appHost, ILogger logger) { - var url = "http://localhost:" + appHost.HttpServerPort + "/web/" + page; + var url = "http://localhost:" + appHost.HttpPort + "/web/" + page; OpenUrl(url, logger); } @@ -68,7 +68,7 @@ namespace MediaBrowser.Server.Startup.Common.Browser /// The logger. public static void OpenSwagger(IServerApplicationHost appHost, ILogger logger) { - OpenUrl("http://localhost:" + appHost.HttpServerPort + "/swagger-ui/index.html", logger); + OpenUrl("http://localhost:" + appHost.HttpPort + "/swagger-ui/index.html", logger); } /// diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index 7532a2edd..6e8774eea 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -213,7 +213,6 @@ namespace MediaBrowser.ServerApplication options, fileSystem, "MBServer", - true, nativeApp); var initProgress = new Progress(); diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 46616043b..aec7a539c 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -381,6 +381,7 @@ namespace MediaBrowser.WebDashboard.Api "channelsettings.js", "connectlogin.js", "dashboardgeneral.js", + "dashboardhosting.js", "dashboardpage.js", "device.js", "devices.js", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index dbc701b6d..90a358d5c 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -96,6 +96,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -105,6 +108,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 1d5f1bc474c3d685e04f409b956ccc431cd05ee5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 20 Jan 2015 00:19:13 -0500 Subject: sync updates --- MediaBrowser.Api/ConnectService.cs | 8 ++--- MediaBrowser.Api/Playback/BaseStreamingService.cs | 30 ++++++++++++++--- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 11 +++---- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 32 ++++++++---------- MediaBrowser.Api/Playback/Hls/MpegDashService.cs | 8 ++--- MediaBrowser.Api/Playback/Hls/VideoHlsService.cs | 4 +-- .../Playback/Progressive/AudioService.cs | 3 +- .../Progressive/BaseProgressiveStreamingService.cs | 8 ++--- .../Playback/Progressive/VideoService.cs | 3 +- MediaBrowser.Api/Session/SessionsService.cs | 8 ++--- MediaBrowser.Controller/Entities/Folder.cs | 5 +-- MediaBrowser.Model/Connect/ConnectAuthorization.cs | 4 +-- .../Connect/ConnectAuthorizationRequest.cs | 4 +-- MediaBrowser.Model/Devices/DeviceQuery.cs | 2 +- MediaBrowser.Model/Session/ClientCapabilities.cs | 9 +++-- MediaBrowser.Model/Users/UserPolicy.cs | 12 +++++-- .../Connect/ConnectManager.cs | 11 ++++--- .../Devices/DeviceManager.cs | 13 +++++--- .../Library/UserManager.cs | 38 +++++++++++++++++++++- .../Localization/JavaScript/javascript.json | 3 ++ .../Localization/Server/server.json | 2 ++ .../ApplicationHost.cs | 2 +- 22 files changed, 146 insertions(+), 74 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Api/ConnectService.cs b/MediaBrowser.Api/ConnectService.cs index a5ddcb6f1..4bcd33d9e 100644 --- a/MediaBrowser.Api/ConnectService.cs +++ b/MediaBrowser.Api/ConnectService.cs @@ -39,8 +39,8 @@ namespace MediaBrowser.Api [ApiMember(Name = "SendingUserId", Description = "Sending User Id", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")] public string SendingUserId { get; set; } - [ApiMember(Name = "ExcludeLibraries", Description = "ExcludeLibraries", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")] - public string ExcludedLibraries { get; set; } + [ApiMember(Name = "EnabledLibraries", Description = "EnabledLibraries", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")] + public string EnabledLibraries { get; set; } [ApiMember(Name = "EnabledChannels", Description = "EnabledChannels", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")] public string EnabledChannels { get; set; } @@ -91,7 +91,7 @@ namespace MediaBrowser.Api public object Post(CreateConnectInvite request) { - var excludeLibraries = (request.ExcludedLibraries ?? string.Empty) + var enabledLibraries = (request.EnabledLibraries ?? string.Empty) .Split(',') .Where(i => !string.IsNullOrWhiteSpace(i)) .ToArray(); @@ -105,7 +105,7 @@ namespace MediaBrowser.Api { ConnectUserName = request.ConnectUsername, SendingUserId = request.SendingUserId, - ExcludedLibraries = excludeLibraries, + EnabledLibraries = enabledLibraries, EnabledChannels = enabledChannels, EnableLiveTv = request.EnableLiveTv }); diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 271c20f4e..b3610bc38 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Extensions; +using MediaBrowser.Controller.Devices; +using MediaBrowser.Model.Extensions; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; @@ -66,14 +67,16 @@ namespace MediaBrowser.Api.Playback protected ILiveTvManager LiveTvManager { get; private set; } protected IDlnaManager DlnaManager { get; private set; } + protected IDeviceManager DeviceManager { get; private set; } protected IChannelManager ChannelManager { get; private set; } protected ISubtitleEncoder SubtitleEncoder { get; private set; } /// /// Initializes a new instance of the class. /// - protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder) + protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager) { + DeviceManager = deviceManager; SubtitleEncoder = subtitleEncoder; ChannelManager = channelManager; DlnaManager = dlnaManager; @@ -2030,9 +2033,26 @@ namespace MediaBrowser.Api.Playback headers[key] = Request.Headers[key]; } - state.DeviceProfile = string.IsNullOrWhiteSpace(state.Request.DeviceProfileId) ? - DlnaManager.GetProfile(headers) : - DlnaManager.GetProfile(state.Request.DeviceProfileId); + if (!string.IsNullOrWhiteSpace(state.Request.DeviceProfileId)) + { + state.DeviceProfile = DlnaManager.GetProfile(state.Request.DeviceProfileId); + } + else + { + if (!string.IsNullOrWhiteSpace(state.Request.DeviceId)) + { + var caps = DeviceManager.GetCapabilities(state.Request.DeviceId); + + if (caps != null) + { + state.DeviceProfile = caps.DeviceProfile; + } + else + { + state.DeviceProfile = DlnaManager.GetProfile(headers); + } + } + } var profile = state.DeviceProfile; diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 08fa95919..2da5c33ce 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -1,20 +1,20 @@ -using MediaBrowser.Model.Extensions; -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Net; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; +using MediaBrowser.Model.Net; using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Net; namespace MediaBrowser.Api.Playback.Hls { @@ -23,8 +23,7 @@ namespace MediaBrowser.Api.Playback.Hls /// public abstract class BaseHlsService : BaseStreamingService { - protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder) - : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder) + protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager) { } diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 6044c8c5a..e639dbdfe 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Extensions; +using MediaBrowser.Controller.Devices; +using MediaBrowser.Model.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; @@ -62,38 +63,31 @@ namespace MediaBrowser.Api.Playback.Hls public class DynamicHlsService : BaseHlsService { - protected INetworkManager NetworkManager { get; private set; } - - public DynamicHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, INetworkManager networkManager) - : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder) + public DynamicHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager) { NetworkManager = networkManager; } - public object Get(GetMasterHlsVideoStream request) - { - var result = GetAsync(request, "GET").Result; + protected INetworkManager NetworkManager { get; private set; } - return result; + public Task Get(GetMasterHlsVideoStream request) + { + return GetAsync(request, "GET"); } - public object Head(GetMasterHlsVideoStream request) + public Task Head(GetMasterHlsVideoStream request) { - var result = GetAsync(request, "HEAD").Result; - - return result; + return GetAsync(request, "HEAD"); } - public object Get(GetMainHlsVideoStream request) + public Task Get(GetMainHlsVideoStream request) { - var result = GetPlaylistAsync(request, "main").Result; - - return result; + return GetPlaylistAsync(request, "main"); } - public object Get(GetDynamicHlsVideoSegment request) + public Task Get(GetDynamicHlsVideoSegment request) { - return GetDynamicSegment(request, request.SegmentId).Result; + return GetDynamicSegment(request, request.SegmentId); } private async Task GetDynamicSegment(VideoStreamRequest request, string segmentId) diff --git a/MediaBrowser.Api/Playback/Hls/MpegDashService.cs b/MediaBrowser.Api/Playback/Hls/MpegDashService.cs index a0b67a220..80451c0cc 100644 --- a/MediaBrowser.Api/Playback/Hls/MpegDashService.cs +++ b/MediaBrowser.Api/Playback/Hls/MpegDashService.cs @@ -2,6 +2,7 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; @@ -50,14 +51,13 @@ namespace MediaBrowser.Api.Playback.Hls public class MpegDashService : BaseHlsService { - protected INetworkManager NetworkManager { get; private set; } - - public MpegDashService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, INetworkManager networkManager) - : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder) + public MpegDashService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager) { NetworkManager = networkManager; } + protected INetworkManager NetworkManager { get; private set; } + public object Get(GetMasterManifest request) { var result = GetAsync(request, "GET").Result; diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs index de845c88d..8de52ea02 100644 --- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs @@ -1,6 +1,7 @@ using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; @@ -56,8 +57,7 @@ namespace MediaBrowser.Api.Playback.Hls /// public class VideoHlsService : BaseHlsService { - public VideoHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder) - : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder) + public VideoHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager) { } diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs index 725526ecd..37155b8f9 100644 --- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs +++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs @@ -2,6 +2,7 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; @@ -31,7 +32,7 @@ namespace MediaBrowser.Api.Playback.Progressive /// public class AudioService : BaseProgressiveStreamingService { - public AudioService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, imageProcessor, httpClient) + public AudioService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager, imageProcessor, httpClient) { } diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index 6bec387d4..9dbe3389e 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -1,8 +1,8 @@ -using System.Linq; -using MediaBrowser.Common.IO; +using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; @@ -15,6 +15,7 @@ using ServiceStack.Web; using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -28,8 +29,7 @@ namespace MediaBrowser.Api.Playback.Progressive protected readonly IImageProcessor ImageProcessor; protected readonly IHttpClient HttpClient; - protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IImageProcessor imageProcessor, IHttpClient httpClient) - : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder) + protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager) { ImageProcessor = imageProcessor; HttpClient = httpClient; diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index 5ef72a495..8924bb38f 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -2,6 +2,7 @@ using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; @@ -62,7 +63,7 @@ namespace MediaBrowser.Api.Playback.Progressive /// public class VideoService : BaseProgressiveStreamingService { - public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, imageProcessor, httpClient) + public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder, deviceManager, imageProcessor, httpClient) { } diff --git a/MediaBrowser.Api/Session/SessionsService.cs b/MediaBrowser.Api/Session/SessionsService.cs index e5fe69b62..319b3d28c 100644 --- a/MediaBrowser.Api/Session/SessionsService.cs +++ b/MediaBrowser.Api/Session/SessionsService.cs @@ -243,12 +243,12 @@ namespace MediaBrowser.Api.Session [ApiMember(Name = "SupportsSync", Description = "Determines whether sync is supported.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")] public bool SupportsSync { get; set; } - [ApiMember(Name = "SupportsUniqueIdentifier", Description = "Determines whether the device supports a unique identifier.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")] - public bool SupportsUniqueIdentifier { get; set; } + [ApiMember(Name = "SupportsPersistentIdentifier", Description = "Determines whether the device supports a unique identifier.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")] + public bool SupportsPersistentIdentifier { get; set; } public PostCapabilities() { - SupportsUniqueIdentifier = true; + SupportsPersistentIdentifier = true; } } @@ -561,7 +561,7 @@ namespace MediaBrowser.Api.Session SupportsSync = request.SupportsSync, - SupportsUniqueIdentifier = request.SupportsUniqueIdentifier + SupportsPersistentIdentifier = request.SupportsPersistentIdentifier }); } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 2761aa5d7..8faab4c36 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -303,10 +303,7 @@ namespace MediaBrowser.Controller.Entities { if (this is ICollectionFolder) { - if (user.Policy.BlockedMediaFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase) || - - // Backwards compatibility - user.Policy.BlockedMediaFolders.Contains(Name, StringComparer.OrdinalIgnoreCase)) + if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) { return false; } diff --git a/MediaBrowser.Model/Connect/ConnectAuthorization.cs b/MediaBrowser.Model/Connect/ConnectAuthorization.cs index 9e4537d65..e8baf7269 100644 --- a/MediaBrowser.Model/Connect/ConnectAuthorization.cs +++ b/MediaBrowser.Model/Connect/ConnectAuthorization.cs @@ -7,13 +7,13 @@ namespace MediaBrowser.Model.Connect public string UserName { get; set; } public string ImageUrl { get; set; } public string Id { get; set; } - public string[] ExcludedLibraries { get; set; } + public string[] EnabledLibraries { get; set; } public bool EnableLiveTv { get; set; } public string[] EnabledChannels { get; set; } public ConnectAuthorization() { - ExcludedLibraries = new string[] { }; + EnabledLibraries = new string[] { }; EnabledChannels = new string[] { }; } } diff --git a/MediaBrowser.Model/Connect/ConnectAuthorizationRequest.cs b/MediaBrowser.Model/Connect/ConnectAuthorizationRequest.cs index 77c574f8b..6baea15a9 100644 --- a/MediaBrowser.Model/Connect/ConnectAuthorizationRequest.cs +++ b/MediaBrowser.Model/Connect/ConnectAuthorizationRequest.cs @@ -5,13 +5,13 @@ namespace MediaBrowser.Model.Connect { public string SendingUserId { get; set; } public string ConnectUserName { get; set; } - public string[] ExcludedLibraries { get; set; } + public string[] EnabledLibraries { get; set; } public bool EnableLiveTv { get; set; } public string[] EnabledChannels { get; set; } public ConnectAuthorizationRequest() { - ExcludedLibraries = new string[] { }; + EnabledLibraries = new string[] { }; EnabledChannels = new string[] { }; } } diff --git a/MediaBrowser.Model/Devices/DeviceQuery.cs b/MediaBrowser.Model/Devices/DeviceQuery.cs index 2cd2389d8..9ae498606 100644 --- a/MediaBrowser.Model/Devices/DeviceQuery.cs +++ b/MediaBrowser.Model/Devices/DeviceQuery.cs @@ -12,7 +12,7 @@ namespace MediaBrowser.Model.Devices /// Gets or sets a value indicating whether [supports unique identifier]. /// /// null if [supports unique identifier] contains no value, true if [supports unique identifier]; otherwise, false. - public bool? SupportsUniqueIdentifier { get; set; } + public bool? SupportsPersistentIdentifier { get; set; } /// /// Gets or sets a value indicating whether [supports synchronize]. /// diff --git a/MediaBrowser.Model/Session/ClientCapabilities.cs b/MediaBrowser.Model/Session/ClientCapabilities.cs index 5a806a867..6c1b6e8b2 100644 --- a/MediaBrowser.Model/Session/ClientCapabilities.cs +++ b/MediaBrowser.Model/Session/ClientCapabilities.cs @@ -14,16 +14,21 @@ namespace MediaBrowser.Model.Session public string MessageCallbackUrl { get; set; } public bool SupportsContentUploading { get; set; } - public bool SupportsUniqueIdentifier { get; set; } + public bool SupportsPersistentIdentifier { get; set; } public bool SupportsSync { get; set; } public DeviceProfile DeviceProfile { get; set; } + /// + /// Usage should be migrated to SupportsPersistentIdentifier. Keeping this to preserve data. + /// + public bool? SupportsUniqueIdentifier { get; set; } + public ClientCapabilities() { PlayableMediaTypes = new List(); SupportedCommands = new List(); - SupportsUniqueIdentifier = true; + SupportsPersistentIdentifier = true; } } } \ No newline at end of file diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index eb8dbc6f0..cdc5077b0 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -54,6 +54,9 @@ namespace MediaBrowser.Model.Users public string[] EnabledChannels { get; set; } public bool EnableAllChannels { get; set; } + + public string[] EnabledFolders { get; set; } + public bool EnableAllFolders { get; set; } public UserPolicy() { @@ -62,9 +65,6 @@ namespace MediaBrowser.Model.Users EnableLiveTvAccess = true; EnableSharedDeviceControl = true; - EnabledChannels = new string[] { }; - - BlockedMediaFolders = new string[] { }; BlockedTags = new string[] { }; BlockUnratedItems = new UnratedItem[] { }; @@ -72,6 +72,12 @@ namespace MediaBrowser.Model.Users AccessSchedules = new AccessSchedule[] { }; + EnableAllChannels = true; + EnabledChannels = new string[] { }; + + EnableAllFolders = true; + EnabledFolders = new string[] { }; + EnabledDevices = new string[] { }; EnableAllDevices = true; } diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index 1cc3365e5..bb89f01fa 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -572,7 +572,7 @@ namespace MediaBrowser.Server.Implementations.Connect Id = response.Id, ImageUrl = response.UserImageUrl, UserName = response.UserName, - ExcludedLibraries = request.ExcludedLibraries, + EnabledLibraries = request.EnabledLibraries, EnabledChannels = request.EnabledChannels, EnableLiveTv = request.EnableLiveTv, AccessToken = accessToken @@ -833,10 +833,13 @@ namespace MediaBrowser.Server.Implementations.Connect if (currentPendingEntry != null) { - user.Policy.EnableLiveTvAccess = currentPendingEntry.EnableLiveTv; - user.Policy.BlockedMediaFolders = currentPendingEntry.ExcludedLibraries; + user.Policy.EnabledFolders = currentPendingEntry.EnabledLibraries; + user.Policy.EnableAllFolders = false; + user.Policy.EnabledChannels = currentPendingEntry.EnabledChannels; user.Policy.EnableAllChannels = false; + + user.Policy.EnableLiveTvAccess = currentPendingEntry.EnableLiveTv; } await _userManager.UpdateConfiguration(user.Id.ToString("N"), user.Configuration); @@ -964,7 +967,7 @@ namespace MediaBrowser.Server.Implementations.Connect ConnectUserId = i.ConnectUserId, EnableLiveTv = i.EnableLiveTv, EnabledChannels = i.EnabledChannels, - ExcludedLibraries = i.ExcludedLibraries, + EnabledLibraries = i.EnabledLibraries, Id = i.Id, ImageUrl = i.ImageUrl, UserName = i.UserName diff --git a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs index ddd5ef58d..e057ec5cd 100644 --- a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs +++ b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs @@ -100,11 +100,16 @@ namespace MediaBrowser.Server.Implementations.Devices devices = devices.Where(i => GetCapabilities(i.Id).SupportsSync == val); } - if (query.SupportsUniqueIdentifier.HasValue) + if (query.SupportsPersistentIdentifier.HasValue) { - var val = query.SupportsUniqueIdentifier.Value; + var val = query.SupportsPersistentIdentifier.Value; - devices = devices.Where(i => GetCapabilities(i.Id).SupportsUniqueIdentifier == val); + devices = devices.Where(i => + { + var caps = GetCapabilities(i.Id); + var deviceVal = caps.SupportsUniqueIdentifier ?? caps.SupportsPersistentIdentifier; + return deviceVal == val; + }); } if (!string.IsNullOrWhiteSpace(query.UserId)) @@ -212,7 +217,7 @@ namespace MediaBrowser.Server.Implementations.Devices { var capabilities = GetCapabilities(deviceId); - if (capabilities.SupportsUniqueIdentifier) + if (capabilities != null && capabilities.SupportsPersistentIdentifier) { return false; } diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index edcf7255d..3d6432636 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -73,10 +73,11 @@ namespace MediaBrowser.Server.Implementations.Library private readonly Func _dtoServiceFactory; private readonly Func _connectFactory; private readonly Func _channelManager; + private readonly Func _libraryManager; private readonly IServerApplicationHost _appHost; private readonly IFileSystem _fileSystem; - public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func imageProcessorFactory, Func dtoServiceFactory, Func connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem, Func channelManager) + public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func imageProcessorFactory, Func dtoServiceFactory, Func connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem, Func channelManager, Func libraryManager) { _logger = logger; UserRepository = userRepository; @@ -89,6 +90,7 @@ namespace MediaBrowser.Server.Implementations.Library _jsonSerializer = jsonSerializer; _fileSystem = fileSystem; _channelManager = channelManager; + _libraryManager = libraryManager; ConfigurationManager = configurationManager; Users = new List(); @@ -173,6 +175,7 @@ namespace MediaBrowser.Server.Implementations.Library { await DoPolicyMigration(user).ConfigureAwait(false); await DoChannelMigration(user).ConfigureAwait(false); + await DoLibraryMigration(user).ConfigureAwait(false); } // If there are no local users with admin rights, make them all admins @@ -389,6 +392,39 @@ namespace MediaBrowser.Server.Implementations.Library } } + private async Task DoLibraryMigration(User user) + { + if (user.Policy.BlockedMediaFolders != null) + { + if (user.Policy.BlockedMediaFolders.Length > 0) + { + user.Policy.EnableAllFolders = false; + + try + { + user.Policy.EnabledFolders = _libraryManager().RootFolder + .Children + .Where(i => !user.Policy.BlockedMediaFolders.Contains(i.Name, StringComparer.OrdinalIgnoreCase) && !user.Policy.BlockedMediaFolders.Contains(i.Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + .Select(i => i.Id.ToString("N")) + .ToArray(); + } + catch + { + user.Policy.EnabledFolders = new string[] { }; + } + } + else + { + user.Policy.EnableAllFolders = true; + user.Policy.EnabledFolders = new string[] { }; + } + + user.Policy.BlockedMediaFolders = null; + + await UpdateUserPolicy(user, user.Policy, false); + } + } + public UserDto GetUserDto(User user, string remoteEndPoint = null) { if (user == null) diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 8e41dda30..afc9bff62 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -6,6 +6,8 @@ "Administrator": "Administrator", "Password": "Password", "DeleteImage": "Delete Image", + "MessageThankYouForSupporting": "Thank you for supporting Media Browser.", + "MessagePleaseSupportMediaBrowser": "Please support Media Browser.", "DeleteImageConfirmation": "Are you sure you wish to delete this image?", "FileReadCancelled": "The file read has been canceled.", "FileNotFound": "File not found.", @@ -219,6 +221,7 @@ "ButtonResume": "Resume", "HeaderScenes": "Scenes", "HeaderAudioTracks": "Audio Tracks", + "HeaderLibraries": "Libraries", "LabelUnknownLanguage": "Unknown language", "HeaderSubtitles": "Subtitles", "HeaderVideoQuality": "Video Quality", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 4bd6052a0..ccba2e697 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -79,6 +79,7 @@ "ReferToMediaLibraryWiki": "Refer to the media library wiki.", "LabelCountry": "Country:", "LabelLanguage": "Language:", + "ButtonJoinTheDevelopmentTeam": "Join the Development Team", "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.", @@ -97,6 +98,7 @@ "HeaderDeviceAccess": "Device Access", "OptionEnableAccessFromAllDevices": "Enable access from all devices", "OptionEnableAccessToAllChannels": "Enable access to all channels", + "OptionEnableAccessToAllLibraries": "Enable access to all libraries", "DeviceAccessHelp": "This only applies to devices that can be uniquely identified and will not prevent browser access. Filtering user device access will prevent them from using new devices until they've been approved here.", "LabelDisplayMissingEpisodesWithinSeasons": "Display missing episodes within seasons", "LabelUnairedMissingEpisodesWithinSeasons": "Display unaired episodes within seasons", diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 2695ddaf6..49cc672ab 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -407,7 +407,7 @@ namespace MediaBrowser.Server.Startup.Common SyncRepository = await GetSyncRepository().ConfigureAwait(false); RegisterSingleInstance(SyncRepository); - UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this, JsonSerializer, FileSystemManager, () => ChannelManager); + UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this, JsonSerializer, FileSystemManager, () => ChannelManager, () => LibraryManager); RegisterSingleInstance(UserManager); LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager); -- cgit v1.2.3 From f636c10e24a6f26f1c8e41ba6d3751334d6dcb90 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 20 Jan 2015 22:54:45 -0500 Subject: sync updates --- .../Library/LibraryStructureService.cs | 32 +------- .../ScheduledTasks/ScheduledTaskService.cs | 2 +- MediaBrowser.Api/StartupWizardService.cs | 1 + MediaBrowser.Api/Sync/SyncService.cs | 28 +++++++ MediaBrowser.Controller/Channels/Channel.cs | 14 +++- MediaBrowser.Controller/Entities/Folder.cs | 21 +++++- MediaBrowser.Controller/Library/ILibraryManager.cs | 9 +-- MediaBrowser.Controller/Sync/ISyncManager.cs | 19 +++++ .../Configuration/ServerConfiguration.cs | 1 + MediaBrowser.Model/Sync/SyncJobItem.cs | 2 + .../Configuration/ServerConfigurationManager.cs | 12 ++- .../Library/LibraryManager.cs | 12 +-- .../Library/UserManager.cs | 88 +--------------------- .../Localization/JavaScript/javascript.json | 5 ++ .../Sync/SyncJobProcessor.cs | 20 +++-- .../Sync/SyncManager.cs | 83 +++++++++++++++++++- .../Sync/SyncRepository.cs | 12 ++- .../ApplicationHost.cs | 2 +- 18 files changed, 206 insertions(+), 157 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index 23f4e4e5c..27944a4ea 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -3,7 +3,6 @@ using MediaBrowser.Controller; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; using ServiceStack; using System; using System.Collections.Generic; @@ -18,7 +17,6 @@ namespace MediaBrowser.Api.Library /// Class GetDefaultVirtualFolders /// [Route("/Library/VirtualFolders", "GET")] - [Route("/Users/{UserId}/VirtualFolders", "GET")] public class GetVirtualFolders : IReturn> { /// @@ -143,11 +141,6 @@ namespace MediaBrowser.Api.Library /// private readonly IServerApplicationPaths _appPaths; - /// - /// The _user manager - /// - private readonly IUserManager _userManager; - /// /// The _library manager /// @@ -156,27 +149,21 @@ namespace MediaBrowser.Api.Library private readonly ILibraryMonitor _libraryMonitor; private readonly IFileSystem _fileSystem; - private readonly ILogger _logger; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The app paths. - /// The user manager. - /// The library manager. - public LibraryStructureService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IFileSystem fileSystem, ILogger logger) + public LibraryStructureService(IServerApplicationPaths appPaths, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IFileSystem fileSystem) { if (appPaths == null) { throw new ArgumentNullException("appPaths"); } - _userManager = userManager; _appPaths = appPaths; _libraryManager = libraryManager; _libraryMonitor = libraryMonitor; _fileSystem = fileSystem; - _logger = logger; } /// @@ -186,20 +173,9 @@ namespace MediaBrowser.Api.Library /// System.Object. public object Get(GetVirtualFolders request) { - if (string.IsNullOrEmpty(request.UserId)) - { - var result = _libraryManager.GetDefaultVirtualFolders().OrderBy(i => i.Name).ToList(); + var result = _libraryManager.GetVirtualFolders().OrderBy(i => i.Name).ToList(); - return ToOptimizedSerializedResultUsingCache(result); - } - else - { - var user = _userManager.GetUserById(request.UserId); - - var result = _libraryManager.GetVirtualFolders(user).OrderBy(i => i.Name).ToList(); - - return ToOptimizedSerializedResultUsingCache(result); - } + return ToOptimizedSerializedResultUsingCache(result); } /// diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs index f5b3d173b..947b99d35 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs @@ -141,7 +141,7 @@ namespace MediaBrowser.Api.ScheduledTasks result = result.Where(i => { - var isEnabled = false; + var isEnabled = true; var configurableTask = i.ScheduledTask as IConfigurableScheduledTask; diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 97401bbf8..cb0c54674 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -63,6 +63,7 @@ namespace MediaBrowser.Api _config.Configuration.IsStartupWizardCompleted = true; _config.Configuration.EnableLocalizedGuids = true; _config.Configuration.StoreArtistsInMetadata = true; + _config.Configuration.EnableStandaloneMetadata = true; _config.Configuration.EnableLibraryMetadataSubFolder = true; _config.SaveConfiguration(); } diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs index 8d5ec824f..c763aa8df 100644 --- a/MediaBrowser.Api/Sync/SyncService.cs +++ b/MediaBrowser.Api/Sync/SyncService.cs @@ -37,6 +37,20 @@ namespace MediaBrowser.Api.Sync { } + [Route("/Sync/JobItems/{Id}/Enable", "POST", Summary = "Enables a cancelled or queued sync job item")] + public class EnableSyncJobItem : IReturnVoid + { + [ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public string Id { get; set; } + } + + [Route("/Sync/JobItems/{Id}", "DELETE", Summary = "Cancels a sync job item")] + public class CancelSyncJobItem : IReturnVoid + { + [ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")] + public string Id { get; set; } + } + [Route("/Sync/Jobs", "GET", Summary = "Gets sync jobs.")] public class GetSyncJobs : SyncJobQuery, IReturn> { @@ -271,5 +285,19 @@ namespace MediaBrowser.Api.Sync return ToStaticFileResult(file.Path); } + + public void Post(EnableSyncJobItem request) + { + var task = _syncManager.ReEnableJobItem(request.Id); + + Task.WaitAll(task); + } + + public void Delete(CancelSyncJobItem request) + { + var task = _syncManager.CancelJobItem(request.Id); + + Task.WaitAll(task); + } } } diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index 6ee6fe006..32ad2ff12 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -14,9 +14,19 @@ namespace MediaBrowser.Controller.Channels public override bool IsVisible(User user) { - if (!user.Policy.EnableAllChannels && !user.Policy.EnabledChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + if (user.Policy.BlockedChannels != null) { - return false; + if (user.Policy.BlockedChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + else + { + if (!user.Policy.EnableAllChannels && !user.Policy.EnabledChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + { + return false; + } } return base.IsVisible(user); diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 8faab4c36..005f263f7 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -303,9 +303,22 @@ namespace MediaBrowser.Controller.Entities { if (this is ICollectionFolder) { - if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + if (user.Policy.BlockedMediaFolders != null) { - return false; + if (user.Policy.BlockedMediaFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase) || + + // Backwards compatibility + user.Policy.BlockedMediaFolders.Contains(Name, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + else + { + if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + { + return false; + } } } @@ -675,12 +688,12 @@ namespace MediaBrowser.Controller.Entities path = System.IO.Path.GetDirectoryName(path); } - if (ContainsPath(LibraryManager.GetDefaultVirtualFolders(), originalPath)) + if (ContainsPath(LibraryManager.GetVirtualFolders(), originalPath)) { return true; } - return UserManager.Users.Any(user => ContainsPath(LibraryManager.GetVirtualFolders(user), originalPath)); + return ContainsPath(LibraryManager.GetVirtualFolders(), originalPath); } /// diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 2ebd1cab9..9871ef3c5 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -123,14 +123,7 @@ namespace MediaBrowser.Controller.Library /// Gets the default view. /// /// IEnumerable{VirtualFolderInfo}. - IEnumerable GetDefaultVirtualFolders(); - - /// - /// Gets the view. - /// - /// The user. - /// IEnumerable{VirtualFolderInfo}. - IEnumerable GetVirtualFolders(User user); + IEnumerable GetVirtualFolders(); /// /// Gets the item by id. diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index 59136c0e6..8e4b6a44a 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -1,8 +1,10 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Events; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Sync; using MediaBrowser.Model.Users; +using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -10,6 +12,9 @@ namespace MediaBrowser.Controller.Sync { public interface ISyncManager { + event EventHandler> SyncJobCreated; + event EventHandler> SyncJobCancelled; + /// /// Creates the job. /// @@ -44,6 +49,20 @@ namespace MediaBrowser.Controller.Sync /// Task. Task UpdateJob(SyncJob job); + /// + /// Res the enable job item. + /// + /// The identifier. + /// Task. + Task ReEnableJobItem(string id); + + /// + /// Cnacels the job item. + /// + /// The identifier. + /// Task. + Task CancelJobItem(string id); + /// /// Cancels the job. /// diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 71580f353..c641edff7 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -169,6 +169,7 @@ namespace MediaBrowser.Model.Configuration public string DashboardSourcePath { get; set; } public bool StoreArtistsInMetadata { get; set; } + public bool EnableStandaloneMetadata { get; set; } /// /// Gets or sets the image saving convention. diff --git a/MediaBrowser.Model/Sync/SyncJobItem.cs b/MediaBrowser.Model/Sync/SyncJobItem.cs index 943014c0d..133065bf9 100644 --- a/MediaBrowser.Model/Sync/SyncJobItem.cs +++ b/MediaBrowser.Model/Sync/SyncJobItem.cs @@ -88,6 +88,8 @@ namespace MediaBrowser.Model.Sync public string TemporaryPath { get; set; } public List AdditionalFiles { get; set; } + public bool IsMarkedForRemoval { get; set; } + public SyncJobItem() { AdditionalFiles = new List(); diff --git a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs index b3b8ccbd8..5f7ccec4b 100644 --- a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs +++ b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs @@ -99,10 +99,20 @@ namespace MediaBrowser.Server.Implementations.Configuration private void UpdateMetadataPath() { ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = string.IsNullOrEmpty(Configuration.MetadataPath) ? - null : + GetInternalMetadataPath() : Configuration.MetadataPath; } + private string GetInternalMetadataPath() + { + if (Configuration.EnableStandaloneMetadata) + { + return Path.Combine(ApplicationPaths.ProgramDataPath, "metadata"); + } + + return null; + } + /// /// Updates the transcoding temporary path. /// diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index eaab469f5..b28c98728 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1124,21 +1124,11 @@ namespace MediaBrowser.Server.Implementations.Library /// Gets the default view. /// /// IEnumerable{VirtualFolderInfo}. - public IEnumerable GetDefaultVirtualFolders() + public IEnumerable GetVirtualFolders() { return GetView(ConfigurationManager.ApplicationPaths.DefaultUserViewsPath); } - /// - /// Gets the view. - /// - /// The user. - /// IEnumerable{VirtualFolderInfo}. - public IEnumerable GetVirtualFolders(User user) - { - return GetDefaultVirtualFolders(); - } - /// /// Gets the view. /// diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 3020a224d..c4c0e5395 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -3,7 +3,6 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller; -using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Connect; using MediaBrowser.Controller.Drawing; @@ -13,7 +12,6 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Channels; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Connect; using MediaBrowser.Model.Dto; @@ -72,12 +70,10 @@ namespace MediaBrowser.Server.Implementations.Library private readonly Func _imageProcessorFactory; private readonly Func _dtoServiceFactory; private readonly Func _connectFactory; - private readonly Func _channelManager; - private readonly Func _libraryManager; private readonly IServerApplicationHost _appHost; private readonly IFileSystem _fileSystem; - public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func imageProcessorFactory, Func dtoServiceFactory, Func connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem, Func channelManager, Func libraryManager) + public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func imageProcessorFactory, Func dtoServiceFactory, Func connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem) { _logger = logger; UserRepository = userRepository; @@ -89,8 +85,6 @@ namespace MediaBrowser.Server.Implementations.Library _appHost = appHost; _jsonSerializer = jsonSerializer; _fileSystem = fileSystem; - _channelManager = channelManager; - _libraryManager = libraryManager; ConfigurationManager = configurationManager; Users = new List(); @@ -174,8 +168,6 @@ namespace MediaBrowser.Server.Implementations.Library foreach (var user in users) { await DoPolicyMigration(user).ConfigureAwait(false); - await DoChannelMigration(user).ConfigureAwait(false); - await DoLibraryMigration(user).ConfigureAwait(false); } // If there are no local users with admin rights, make them all admins @@ -354,84 +346,6 @@ namespace MediaBrowser.Server.Implementations.Library } } - private async Task DoChannelMigration(User user) - { - if (user.Policy.BlockedChannels != null) - { - if (user.Policy.BlockedChannels.Length > 0) - { - user.Policy.EnableAllChannels = false; - - try - { - var channelResult = await _channelManager().GetChannelsInternal(new ChannelQuery - { - UserId = user.Id.ToString("N") - - }, CancellationToken.None).ConfigureAwait(false); - - user.Policy.EnabledChannels = channelResult.Items - .Select(i => i.Id.ToString("N")) - .Except(user.Policy.BlockedChannels) - .ToArray(); - } - catch - { - user.Policy.EnabledChannels = new string[] { }; - } - } - else - { - user.Policy.EnableAllChannels = true; - user.Policy.EnabledChannels = new string[] { }; - } - - user.Policy.BlockedChannels = null; - - await UpdateUserPolicy(user, user.Policy, false); - } - } - - private async Task DoLibraryMigration(User user) - { - if (user.Policy.BlockedMediaFolders != null) - { - if (user.Policy.BlockedMediaFolders.Length > 0) - { - user.Policy.EnableAllFolders = false; - - try - { - user.Policy.EnabledFolders = _libraryManager().RootFolder - .Children - .Where(i => !user.Policy.BlockedMediaFolders.Contains(i.Name, StringComparer.OrdinalIgnoreCase) && !user.Policy.BlockedMediaFolders.Contains(i.Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) - .Select(i => i.Id.ToString("N")) - .ToArray(); - } - catch - { - user.Policy.EnabledFolders = new string[] { }; - user.Policy.EnableAllFolders = true; - } - } - else - { - user.Policy.EnableAllFolders = true; - user.Policy.EnabledFolders = new string[] { }; - } - - // Just to be safe - if (user.Policy.EnabledFolders.Length == 0) - { - user.Policy.EnableAllFolders = true; - } - - user.Policy.BlockedMediaFolders = null; - - await UpdateUserPolicy(user, user.Policy, false); - } - } - public UserDto GetUserDto(User user, string remoteEndPoint = null) { if (user == null) diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index afc9bff62..e4d20d3a1 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -56,6 +56,9 @@ "HeaderChannelAccess": "Channel Access", "HeaderDeviceAccess": "Device Access", "HeaderSelectDevices": "Select Devices", + "ButtonCancelItem": "Cancel item", + "ButtonQueueForRetry": "Queue for retry", + "ButtonReenable": "Re-enable", "LabelAbortedByServerShutdown": "(Aborted by server shutdown)", "LabelScheduledTaskLastRan": "Last ran {0}, taking {1}.", "HeaderDeleteTaskTrigger": "Delete Task Trigger", @@ -71,6 +74,8 @@ "LabelForcedStream": "(Forced)", "LabelDefaultForcedStream": "(Default/Forced)", "LabelUnknownLanguage": "Unknown language", + "HeaderConfirmation": "Confirmation", + "MessageConfirmSyncJobItemCancellation": "Are you sure you wish to cancel this item?", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", "ButtonStop": "Stop", diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index cf0138a29..67f9d363e 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; using MediaBrowser.Common.Progress; using MediaBrowser.Controller.Entities; @@ -361,11 +360,20 @@ namespace MediaBrowser.Server.Implementations.Sync var innerProgress = new ActionableProgress(); innerProgress.RegisterAction(p => progress.Report(startingPercent + (percentPerItem * p))); - var job = _syncRepo.GetJob(item.JobId); - await ProcessJobItem(job, item, enableConversion, innerProgress, cancellationToken).ConfigureAwait(false); + // Pull it fresh from the db just to make sure it wasn't deleted or cancelled while another item was converting + var jobItem = enableConversion ? _syncRepo.GetJobItem(item.Id) : item; - job = _syncRepo.GetJob(item.JobId); - await UpdateJobStatus(job).ConfigureAwait(false); + if (jobItem != null) + { + var job = _syncRepo.GetJob(jobItem.JobId); + if (jobItem.Status != SyncJobItemStatus.Cancelled) + { + await ProcessJobItem(job, jobItem, enableConversion, innerProgress, cancellationToken).ConfigureAwait(false); + } + + job = _syncRepo.GetJob(jobItem.JobId); + await UpdateJobStatus(job).ConfigureAwait(false); + } numComplete++; double percent = numComplete; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index b8d884cee..7e4455ab3 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common; using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Events; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; @@ -16,6 +17,7 @@ using MediaBrowser.Controller.TV; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Events; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Sync; @@ -47,6 +49,9 @@ namespace MediaBrowser.Server.Implementations.Sync private ISyncProvider[] _providers = { }; + public event EventHandler> SyncJobCreated; + public event EventHandler> SyncJobCancelled; + public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func mediaEncoder, IFileSystem fileSystem, Func subtitleEncoder, IConfigurationManager config) { _libraryManager = libraryManager; @@ -144,6 +149,15 @@ namespace MediaBrowser.Server.Implementations.Sync await processor.SyncJobItems(jobItemsResult.Items, false, new Progress(), CancellationToken.None) .ConfigureAwait(false); + if (SyncJobCreated != null) + { + EventHelper.FireEventIfNotNull(SyncJobCreated, this, new GenericEventArgs + { + Argument = job + + }, _logger); + } + return new SyncJobCreationResult { Job = GetJob(jobId) @@ -275,9 +289,25 @@ namespace MediaBrowser.Server.Implementations.Sync } } - public Task CancelJob(string id) + public async Task CancelJob(string id) { - return _repo.DeleteJob(id); + var job = GetJob(id); + + if (job == null) + { + throw new ArgumentException("Job not found."); + } + + await _repo.DeleteJob(id).ConfigureAwait(false); + + if (SyncJobCancelled != null) + { + EventHelper.FireEventIfNotNull(SyncJobCancelled, this, new GenericEventArgs + { + Argument = job + + }, _logger); + } } public SyncJob GetJob(string id) @@ -496,7 +526,7 @@ namespace MediaBrowser.Server.Implementations.Sync .FirstOrDefault(i => string.Equals(i.Id, jobItem.MediaSourceId)); syncedItem.Item.MediaSources = new List(); - + // This will be null for items that are not audio/video if (mediaSource == null) { @@ -545,7 +575,12 @@ namespace MediaBrowser.Server.Implementations.Sync var job = _repo.GetJob(jobItem.JobId); var user = _userManager.GetUserById(job.UserId); - if (user == null) + if (jobItem.IsMarkedForRemoval) + { + // Tell the device to remove it since it has been marked for removal + response.ItemIdsToRemove.Add(jobItem.ItemId); + } + else if (user == null) { // Tell the device to remove it since the user is gone now response.ItemIdsToRemove.Add(jobItem.ItemId); @@ -609,5 +644,45 @@ namespace MediaBrowser.Server.Implementations.Sync return true; } + + public async Task ReEnableJobItem(string id) + { + var jobItem = _repo.GetJobItem(id); + + if (jobItem.Status != SyncJobItemStatus.Failed && jobItem.Status != SyncJobItemStatus.Cancelled) + { + throw new ArgumentException("Operation is not valid for this job item"); + } + + jobItem.Status = SyncJobItemStatus.Queued; + jobItem.Progress = 0; + jobItem.IsMarkedForRemoval = false; + + await _repo.Update(jobItem).ConfigureAwait(false); + + var processor = GetSyncJobProcessor(); + + await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); + } + + public async Task CancelJobItem(string id) + { + var jobItem = _repo.GetJobItem(id); + + if (jobItem.Status != SyncJobItemStatus.Queued && jobItem.Status != SyncJobItemStatus.Transferring && jobItem.Status != SyncJobItemStatus.Converting) + { + throw new ArgumentException("Operation is not valid for this job item"); + } + + jobItem.Status = SyncJobItemStatus.Cancelled; + jobItem.Progress = 0; + jobItem.IsMarkedForRemoval = true; + + await _repo.Update(jobItem).ConfigureAwait(false); + + var processor = GetSyncJobProcessor(); + + await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); + } } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index ae9143710..1cd8e8a9d 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -41,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.Sync public async Task Initialize() { - var dbFile = Path.Combine(_appPaths.DataPath, "sync12.db"); + var dbFile = Path.Combine(_appPaths.DataPath, "sync13.db"); _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); @@ -50,7 +50,7 @@ namespace MediaBrowser.Server.Implementations.Sync "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Quality TEXT NOT NULL, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, Category TEXT, ParentId TEXT, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)", "create index if not exists idx_SyncJobs on SyncJobs(Id)", - "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT)", + "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT)", "create index if not exists idx_SyncJobItems on SyncJobs(Id)", //pragmas @@ -95,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemCount"); _saveJobItemCommand = _connection.CreateCommand(); - _saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource)"; + _saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval)"; _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Id"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@ItemId"); @@ -110,10 +110,11 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Progress"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@AdditionalFiles"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@MediaSource"); + _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@IsMarkedForRemoval"); } private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs"; - private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource from SyncJobItems"; + private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval from SyncJobItems"; public SyncJob GetJob(string id) { @@ -572,6 +573,7 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobItemCommand.GetParameter(index++).Value = jobItem.Progress; _saveJobItemCommand.GetParameter(index++).Value = _json.SerializeToString(jobItem.AdditionalFiles); _saveJobItemCommand.GetParameter(index++).Value = jobItem.MediaSource == null ? null : _json.SerializeToString(jobItem.MediaSource); + _saveJobItemCommand.GetParameter(index++).Value = jobItem.IsMarkedForRemoval; _saveJobItemCommand.Transaction = transaction; @@ -673,6 +675,8 @@ namespace MediaBrowser.Server.Implementations.Sync } } + info.IsMarkedForRemoval = reader.GetBoolean(13); + return info; } diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index f481a902d..7eb68187a 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -407,7 +407,7 @@ namespace MediaBrowser.Server.Startup.Common SyncRepository = await GetSyncRepository().ConfigureAwait(false); RegisterSingleInstance(SyncRepository); - UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this, JsonSerializer, FileSystemManager, () => ChannelManager, () => LibraryManager); + UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this, JsonSerializer, FileSystemManager); RegisterSingleInstance(UserManager); LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager); -- cgit v1.2.3 From f5b7e1dba42f0cf9951d8f2a2324f10fda425565 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 20 Jan 2015 23:56:00 -0500 Subject: add mark for removal options --- MediaBrowser.Api/Sync/SyncService.cs | 28 +++++++++++++++++ MediaBrowser.Controller/Sync/ISyncManager.cs | 14 +++++++++ MediaBrowser.Model/ApiClient/IApiClient.cs | 31 ++++++++++++++++++- MediaBrowser.Model/Sync/SyncJobItem.cs | 9 +++++- .../Localization/JavaScript/javascript.json | 3 ++ .../Sync/SyncManager.cs | 36 ++++++++++++++++++++++ 6 files changed, 119 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs index c763aa8df..b30df572b 100644 --- a/MediaBrowser.Api/Sync/SyncService.cs +++ b/MediaBrowser.Api/Sync/SyncService.cs @@ -44,6 +44,20 @@ namespace MediaBrowser.Api.Sync public string Id { get; set; } } + [Route("/Sync/JobItems/{Id}/MarkForRemoval", "POST", Summary = "Marks a job item for removal")] + public class MarkJobItemForRemoval : IReturnVoid + { + [ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public string Id { get; set; } + } + + [Route("/Sync/JobItems/{Id}/UnmarkForRemoval", "POST", Summary = "Unmarks a job item for removal")] + public class UnmarkJobItemForRemoval : IReturnVoid + { + [ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public string Id { get; set; } + } + [Route("/Sync/JobItems/{Id}", "DELETE", Summary = "Cancels a sync job item")] public class CancelSyncJobItem : IReturnVoid { @@ -299,5 +313,19 @@ namespace MediaBrowser.Api.Sync Task.WaitAll(task); } + + public void Post(MarkJobItemForRemoval request) + { + var task = _syncManager.MarkJobItemForRemoval(request.Id); + + Task.WaitAll(task); + } + + public void Post(UnmarkJobItemForRemoval request) + { + var task = _syncManager.UnmarkJobItemForRemoval(request.Id); + + Task.WaitAll(task); + } } } diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index 8e4b6a44a..62b6a3a37 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -128,5 +128,19 @@ namespace MediaBrowser.Controller.Sync /// The request. /// Task<SyncDataResponse>. Task SyncData(SyncDataRequest request); + + /// + /// Marks the job item for removal. + /// + /// The identifier. + /// Task. + Task MarkJobItemForRemoval(string id); + + /// + /// Unmarks the job item for removal. + /// + /// The identifier. + /// Task. + Task UnmarkJobItemForRemoval(string id); } } diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index e8535278b..b6938b217 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -1449,12 +1449,41 @@ namespace MediaBrowser.Model.ApiClient /// The request. /// Task<SyncDataResponse>. Task SyncData(SyncDataRequest request); - /// /// Gets the synchronize job item file URL. /// /// The identifier. /// System.String. string GetSyncJobItemFileUrl(string id); + /// + /// Marks the synchronize job item for removal. + /// + /// The identifier. + /// Task. + Task MarkSyncJobItemForRemoval(string id); + /// + /// Unmarks the synchronize job item for removal. + /// + /// The identifier. + /// Task. + Task UnmarkSyncJobItemForRemoval(string id); + /// + /// Queues the failed synchronize job item for retry. + /// + /// The identifier. + /// Task. + Task QueueFailedSyncJobItemForRetry(string id); + /// + /// Cancels the synchronize job item. + /// + /// The identifier. + /// Task. + Task CancelSyncJobItem(string id); + /// + /// Enables the cancelled synchronize job item. + /// + /// The identifier. + /// Task. + Task EnableCancelledSyncJobItem(string id); } } \ No newline at end of file diff --git a/MediaBrowser.Model/Sync/SyncJobItem.cs b/MediaBrowser.Model/Sync/SyncJobItem.cs index 133065bf9..195d1e17e 100644 --- a/MediaBrowser.Model/Sync/SyncJobItem.cs +++ b/MediaBrowser.Model/Sync/SyncJobItem.cs @@ -86,8 +86,15 @@ namespace MediaBrowser.Model.Sync /// /// The temporary path. public string TemporaryPath { get; set; } + /// + /// Gets or sets the additional files. + /// + /// The additional files. public List AdditionalFiles { get; set; } - + /// + /// Gets or sets a value indicating whether this instance is marked for removal. + /// + /// true if this instance is marked for removal; otherwise, false. public bool IsMarkedForRemoval { get; set; } public SyncJobItem() diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index e4d20d3a1..62619a567 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -59,6 +59,7 @@ "ButtonCancelItem": "Cancel item", "ButtonQueueForRetry": "Queue for retry", "ButtonReenable": "Re-enable", + "SyncJobItemStatusSyncedMarkForRemoval": "Marked for removal", "LabelAbortedByServerShutdown": "(Aborted by server shutdown)", "LabelScheduledTaskLastRan": "Last ran {0}, taking {1}.", "HeaderDeleteTaskTrigger": "Delete Task Trigger", @@ -70,6 +71,8 @@ "LabelFree": "Free", "HeaderSelectAudio": "Select Audio", "HeaderSelectSubtitles": "Select Subtitles", + "ButtonMarkForRemoval": "Mark for removal from device", + "ButtonUnmarkForRemoval": "Unmark for removal from device", "LabelDefaultStream": "(Default)", "LabelForcedStream": "(Forced)", "LabelDefaultForcedStream": "(Default/Forced)", diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 7e4455ab3..b5e29533b 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -684,5 +684,41 @@ namespace MediaBrowser.Server.Implementations.Sync await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } + + public async Task MarkJobItemForRemoval(string id) + { + var jobItem = _repo.GetJobItem(id); + + if (jobItem.Status != SyncJobItemStatus.Synced) + { + throw new ArgumentException("Operation is not valid for this job item"); + } + + jobItem.IsMarkedForRemoval = true; + + await _repo.Update(jobItem).ConfigureAwait(false); + + var processor = GetSyncJobProcessor(); + + await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); + } + + public async Task UnmarkJobItemForRemoval(string id) + { + var jobItem = _repo.GetJobItem(id); + + if (jobItem.Status != SyncJobItemStatus.Synced) + { + throw new ArgumentException("Operation is not valid for this job item"); + } + + jobItem.IsMarkedForRemoval = false; + + await _repo.Update(jobItem).ConfigureAwait(false); + + var processor = GetSyncJobProcessor(); + + await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); + } } } -- cgit v1.2.3 From b7e5e21c975cc4953764d48c1dacbcd4dc149de9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 22 Jan 2015 11:41:34 -0500 Subject: update task buttons --- MediaBrowser.Api/BaseApiService.cs | 20 ++- MediaBrowser.Api/ConfigurationService.cs | 3 +- MediaBrowser.Api/Dlna/DlnaServerService.cs | 3 +- MediaBrowser.Api/Images/ImageService.cs | 16 +-- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- MediaBrowser.Api/PluginService.cs | 3 +- .../ScheduledTasks/ScheduledTaskService.cs | 3 +- MediaBrowser.Api/UserService.cs | 3 +- MediaBrowser.Controller/Entities/Folder.cs | 2 +- .../Entities/ISupportsBoxSetGrouping.cs | 9 +- MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 2 +- MediaBrowser.Controller/Entities/Movies/Movie.cs | 7 - MediaBrowser.Dlna/DlnaManager.cs | 31 ++-- .../MediaBrowser.Model.Portable.csproj | 3 - .../MediaBrowser.Model.net35.csproj | 3 - MediaBrowser.Model/ApiClient/IApiClient.cs | 18 --- MediaBrowser.Model/Dto/VideoStreamOptions.cs | 158 --------------------- MediaBrowser.Model/MediaBrowser.Model.csproj | 1 - .../Collections/CollectionManager.cs | 64 ++++----- .../Library/Validators/BoxSetPostScanTask.cs | 50 ------- .../Localization/JavaScript/javascript.json | 8 +- .../MediaBrowser.Server.Implementations.csproj | 1 - 22 files changed, 86 insertions(+), 324 deletions(-) delete mode 100644 MediaBrowser.Model/Dto/VideoStreamOptions.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Validators/BoxSetPostScanTask.cs (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index 297a13155..e90969655 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Logging; +using ServiceStack.Text.Controller; using ServiceStack.Web; using System; using System.Collections.Generic; @@ -21,7 +22,7 @@ namespace MediaBrowser.Api /// /// The logger. public ILogger Logger { get; set; } - + /// /// Gets or sets the HTTP result factory. /// @@ -143,7 +144,7 @@ namespace MediaBrowser.Api { if (!string.IsNullOrEmpty(parentId)) { - var folder = (Folder) libraryManager.GetItemById(new Guid(parentId)); + var folder = (Folder)libraryManager.GetItemById(new Guid(parentId)); if (userId.HasValue) { @@ -287,6 +288,20 @@ namespace MediaBrowser.Api }) ?? name; } + protected string GetPathValue(int index) + { + var pathInfo = PathInfo.Parse(Request.PathInfo); + var first = pathInfo.GetArgumentValue(0); + + // backwards compatibility + if (string.Equals(first, "mediabrowser", StringComparison.OrdinalIgnoreCase)) + { + index++; + } + + return pathInfo.GetArgumentValue(index); + } + /// /// Gets the name of the item by. /// @@ -294,7 +309,6 @@ namespace MediaBrowser.Api /// The type. /// The library manager. /// Task{BaseItem}. - /// protected BaseItem GetItemByName(string name, string type, ILibraryManager libraryManager) { BaseItem item; diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs index 3eb0296fc..d0abd18c2 100644 --- a/MediaBrowser.Api/ConfigurationService.cs +++ b/MediaBrowser.Api/ConfigurationService.cs @@ -143,8 +143,7 @@ namespace MediaBrowser.Api public void Post(UpdateNamedConfiguration request) { - var pathInfo = PathInfo.Parse(Request.PathInfo); - var key = pathInfo.GetArgumentValue(2); + var key = GetPathValue(2); var configurationType = _configurationManager.GetConfigurationType(key); var configuration = _jsonSerializer.DeserializeFromStream(request.RequestStream, configurationType); diff --git a/MediaBrowser.Api/Dlna/DlnaServerService.cs b/MediaBrowser.Api/Dlna/DlnaServerService.cs index 94d6e25b0..2383017c6 100644 --- a/MediaBrowser.Api/Dlna/DlnaServerService.cs +++ b/MediaBrowser.Api/Dlna/DlnaServerService.cs @@ -120,8 +120,7 @@ namespace MediaBrowser.Api.Dlna private async Task PostAsync(Stream requestStream, IUpnpService service) { - var pathInfo = PathInfo.Parse(Request.PathInfo); - var id = pathInfo.GetArgumentValue(2); + var id = GetPathValue(2); using (var reader = new StreamReader(requestStream)) { diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index f2586b043..f141d9df9 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -396,8 +396,7 @@ namespace MediaBrowser.Api.Images public object Get(GetItemByNameImage request) { - var pathInfo = PathInfo.Parse(Request.PathInfo); - var type = pathInfo.GetArgumentValue(0); + var type = GetPathValue(0); var item = GetItemByName(request.Name, type, _libraryManager); @@ -406,8 +405,7 @@ namespace MediaBrowser.Api.Images public object Head(GetItemByNameImage request) { - var pathInfo = PathInfo.Parse(Request.PathInfo); - var type = pathInfo.GetArgumentValue(0); + var type = GetPathValue(0); var item = GetItemByName(request.Name, type, _libraryManager); @@ -420,10 +418,9 @@ namespace MediaBrowser.Api.Images /// The request. public void Post(PostUserImage request) { - var pathInfo = PathInfo.Parse(Request.PathInfo); - var id = new Guid(pathInfo.GetArgumentValue(1)); + var id = new Guid(GetPathValue(1)); - request.Type = (ImageType)Enum.Parse(typeof(ImageType), pathInfo.GetArgumentValue(3), true); + request.Type = (ImageType)Enum.Parse(typeof(ImageType), GetPathValue(3), true); var item = _userManager.GetUserById(id); @@ -438,10 +435,9 @@ namespace MediaBrowser.Api.Images /// The request. public void Post(PostItemImage request) { - var pathInfo = PathInfo.Parse(Request.PathInfo); - var id = new Guid(pathInfo.GetArgumentValue(1)); + var id = new Guid(GetPathValue(1)); - request.Type = (ImageType)Enum.Parse(typeof(ImageType), pathInfo.GetArgumentValue(3), true); + request.Type = (ImageType)Enum.Parse(typeof(ImageType), GetPathValue(3), true); var item = _libraryManager.GetItemById(id); diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index b3610bc38..77f6dc103 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -824,7 +824,7 @@ namespace MediaBrowser.Api.Playback { get { - return false; + return true; } } diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index 62aa1e755..f9098f5bf 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -236,8 +236,7 @@ namespace MediaBrowser.Api { // We need to parse this manually because we told service stack not to with IRequiresRequestStream // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs - var pathInfo = PathInfo.Parse(Request.PathInfo); - var id = new Guid(pathInfo.GetArgumentValue(1)); + var id = new Guid(GetPathValue(1)); var plugin = _appHost.Plugins.First(p => p.Id == id); diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs index 947b99d35..e3722b4a7 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs @@ -224,8 +224,7 @@ namespace MediaBrowser.Api.ScheduledTasks { // We need to parse this manually because we told service stack not to with IRequiresRequestStream // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs - var pathInfo = PathInfo.Parse(Request.PathInfo); - var id = pathInfo.GetArgumentValue(1); + var id = GetPathValue(1); var task = TaskManager.ScheduledTasks.FirstOrDefault(i => string.Equals(i.Id, id)); diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index 51a7584b8..37553e4a4 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -449,8 +449,7 @@ namespace MediaBrowser.Api { // We need to parse this manually because we told service stack not to with IRequiresRequestStream // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs - var pathInfo = PathInfo.Parse(Request.PathInfo); - var id = new Guid(pathInfo.GetArgumentValue(1)); + var id = new Guid(GetPathValue(1)); var dtoUser = request; diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 005f263f7..ff6e8e85b 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -301,7 +301,7 @@ namespace MediaBrowser.Controller.Entities public override bool IsVisible(User user) { - if (this is ICollectionFolder) + if (this is ICollectionFolder && !(this is BasePluginFolder)) { if (user.Policy.BlockedMediaFolders != null) { diff --git a/MediaBrowser.Controller/Entities/ISupportsBoxSetGrouping.cs b/MediaBrowser.Controller/Entities/ISupportsBoxSetGrouping.cs index 0fd463155..fbe5a06d0 100644 --- a/MediaBrowser.Controller/Entities/ISupportsBoxSetGrouping.cs +++ b/MediaBrowser.Controller/Entities/ISupportsBoxSetGrouping.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; - + namespace MediaBrowser.Controller.Entities { /// @@ -10,10 +8,5 @@ namespace MediaBrowser.Controller.Entities /// public interface ISupportsBoxSetGrouping { - /// - /// Gets or sets the box set identifier list. - /// - /// The box set identifier list. - List BoxSetIdList { get; set; } } } diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index e48b8d845..63690661a 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -4,13 +4,13 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; +using MediaBrowser.Model.Users; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.Movies { diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index b3774cfe0..2fa5fc6e1 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -25,12 +25,6 @@ namespace MediaBrowser.Controller.Entities.Movies public List ThemeVideoIds { get; set; } public List ProductionLocations { get; set; } - /// - /// This is just a cache to enable quick access by Id - /// - [IgnoreDataMember] - public List BoxSetIdList { get; set; } - public Movie() { SpecialFeatureIds = new List(); @@ -40,7 +34,6 @@ namespace MediaBrowser.Controller.Entities.Movies RemoteTrailerIds = new List(); ThemeSongIds = new List(); ThemeVideoIds = new List(); - BoxSetIdList = new List(); Taglines = new List(); Keywords = new List(); ProductionLocations = new List(); diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 31f1e0a88..2c22abd4d 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -132,61 +132,74 @@ namespace MediaBrowser.Dlna { if (!string.IsNullOrWhiteSpace(profileInfo.DeviceDescription)) { - if (deviceInfo.DeviceDescription == null || !Regex.IsMatch(deviceInfo.DeviceDescription, profileInfo.DeviceDescription)) + if (deviceInfo.DeviceDescription == null || !IsRegexMatch(deviceInfo.DeviceDescription, profileInfo.DeviceDescription)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.FriendlyName)) { - if (deviceInfo.FriendlyName == null || !Regex.IsMatch(deviceInfo.FriendlyName, profileInfo.FriendlyName)) + if (deviceInfo.FriendlyName == null || !IsRegexMatch(deviceInfo.FriendlyName, profileInfo.FriendlyName)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.Manufacturer)) { - if (deviceInfo.Manufacturer == null || !Regex.IsMatch(deviceInfo.Manufacturer, profileInfo.Manufacturer)) + if (deviceInfo.Manufacturer == null || !IsRegexMatch(deviceInfo.Manufacturer, profileInfo.Manufacturer)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.ManufacturerUrl)) { - if (deviceInfo.ManufacturerUrl == null || !Regex.IsMatch(deviceInfo.ManufacturerUrl, profileInfo.ManufacturerUrl)) + if (deviceInfo.ManufacturerUrl == null || !IsRegexMatch(deviceInfo.ManufacturerUrl, profileInfo.ManufacturerUrl)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.ModelDescription)) { - if (deviceInfo.ModelDescription == null || !Regex.IsMatch(deviceInfo.ModelDescription, profileInfo.ModelDescription)) + if (deviceInfo.ModelDescription == null || !IsRegexMatch(deviceInfo.ModelDescription, profileInfo.ModelDescription)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.ModelName)) { - if (deviceInfo.ModelName == null || !Regex.IsMatch(deviceInfo.ModelName, profileInfo.ModelName)) + if (deviceInfo.ModelName == null || !IsRegexMatch(deviceInfo.ModelName, profileInfo.ModelName)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.ModelNumber)) { - if (deviceInfo.ModelNumber == null || !Regex.IsMatch(deviceInfo.ModelNumber, profileInfo.ModelNumber)) + if (deviceInfo.ModelNumber == null || !IsRegexMatch(deviceInfo.ModelNumber, profileInfo.ModelNumber)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.ModelUrl)) { - if (deviceInfo.ModelUrl == null || !Regex.IsMatch(deviceInfo.ModelUrl, profileInfo.ModelUrl)) + if (deviceInfo.ModelUrl == null || !IsRegexMatch(deviceInfo.ModelUrl, profileInfo.ModelUrl)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.SerialNumber)) { - if (deviceInfo.SerialNumber == null || !Regex.IsMatch(deviceInfo.SerialNumber, profileInfo.SerialNumber)) + if (deviceInfo.SerialNumber == null || !IsRegexMatch(deviceInfo.SerialNumber, profileInfo.SerialNumber)) return false; } return true; } + private bool IsRegexMatch(string input, string pattern) + { + try + { + return Regex.IsMatch(input, pattern); + } + catch (ArgumentException ex) + { + _logger.ErrorException("Error evaluating regex pattern {0}", ex, pattern); + return false; + } + } + public DeviceProfile GetProfile(IDictionary headers) { if (headers == null) diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index 91d0e15f8..0a350f517 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -497,9 +497,6 @@ Dto\UserItemDataDto.cs - - Dto\VideoStreamOptions.cs - Entities\BaseItemInfo.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 47e019051..0c5946d12 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -462,9 +462,6 @@ Dto\UserItemDataDto.cs - - Dto\VideoStreamOptions.cs - Entities\BaseItemInfo.cs diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index b6938b217..0e69bb91f 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -1316,24 +1316,6 @@ namespace MediaBrowser.Model.ApiClient /// Task<QueryResult<BaseItemDto>>. Task> GetPlaylistItems(PlaylistItemQuery query); - /// - /// Gets the url needed to stream a video file - /// - /// The options. - /// System.String. - /// options - [Obsolete] - string GetVideoStreamUrl(VideoStreamOptions options); - - /// - /// Formulates a url for streaming video using the HLS protocol - /// - /// The options. - /// System.String. - /// options - [Obsolete] - string GetHlsVideoStreamUrl(VideoStreamOptions options); - /// /// Sends the context message asynchronous. /// diff --git a/MediaBrowser.Model/Dto/VideoStreamOptions.cs b/MediaBrowser.Model/Dto/VideoStreamOptions.cs deleted file mode 100644 index e9a83bd12..000000000 --- a/MediaBrowser.Model/Dto/VideoStreamOptions.cs +++ /dev/null @@ -1,158 +0,0 @@ -using System; - -namespace MediaBrowser.Model.Dto -{ - /// - /// Class VideoStreamOptions - /// - [Obsolete] - public class VideoStreamOptions - { - /// - /// Gets or sets the audio bit rate. - /// - /// The audio bit rate. - public int? AudioBitRate { get; set; } - - /// - /// Gets or sets the audio codec. - /// Omit to copy the original stream - /// - /// The audio encoding format. - public string AudioCodec { get; set; } - - /// - /// Gets or sets the item id. - /// - /// The item id. - public string ItemId { get; set; } - - /// - /// Gets or sets the max audio channels. - /// - /// The max audio channels. - public int? MaxAudioChannels { get; set; } - - /// - /// Gets or sets the max audio sample rate. - /// - /// The max audio sample rate. - public int? MaxAudioSampleRate { get; set; } - - /// - /// Gets or sets the start time ticks. - /// - /// The start time ticks. - public long? StartTimeTicks { get; set; } - - /// - /// Gets or sets a value indicating whether the original media should be served statically - /// Only used with progressive streaming - /// - /// true if static; otherwise, false. - public bool? Static { get; set; } - - /// - /// Gets or sets the output file extension. - /// - /// The output file extension. - public string OutputFileExtension { get; set; } - - /// - /// Gets or sets the device id. - /// - /// The device id. - public string DeviceId { get; set; } - - /// - /// Gets or sets the video codec. - /// Omit to copy - /// - /// The video codec. - public string VideoCodec { get; set; } - - /// - /// Gets or sets the video bit rate. - /// - /// The video bit rate. - public int? VideoBitRate { get; set; } - - /// - /// Gets or sets the width. - /// - /// The width. - public int? Width { get; set; } - - /// - /// Gets or sets the height. - /// - /// The height. - public int? Height { get; set; } - - /// - /// Gets or sets the width of the max. - /// - /// The width of the max. - public int? MaxWidth { get; set; } - - /// - /// Gets or sets the height of the max. - /// - /// The height of the max. - public int? MaxHeight { get; set; } - - /// - /// Gets or sets the frame rate. - /// - /// The frame rate. - public double? FrameRate { get; set; } - - /// - /// Gets or sets the index of the audio stream. - /// - /// The index of the audio stream. - public int? AudioStreamIndex { get; set; } - - /// - /// Gets or sets the index of the video stream. - /// - /// The index of the video stream. - public int? VideoStreamIndex { get; set; } - - /// - /// Gets or sets the index of the subtitle stream. - /// - /// The index of the subtitle stream. - public int? SubtitleStreamIndex { get; set; } - - /// - /// Gets or sets the profile. - /// - /// The profile. - public string Profile { get; set; } - - /// - /// Gets or sets the level. - /// - /// The level. - public string Level { get; set; } - - /// - /// Gets or sets the baseline stream audio bit rate. - /// - /// The baseline stream audio bit rate. - public int? BaselineStreamAudioBitRate { get; set; } - - /// - /// Gets or sets a value indicating whether [append baseline stream]. - /// - /// true if [append baseline stream]; otherwise, false. - public bool AppendBaselineStream { get; set; } - - /// - /// Gets or sets the time stamp offset ms. Only used with HLS. - /// - /// The time stamp offset ms. - public int? TimeStampOffsetMs { get; set; } - } -} \ No newline at end of file diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 36d22347f..bad17abae 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -135,7 +135,6 @@ - diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs index d92db34e3..6100e3f5d 100644 --- a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs +++ b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs @@ -167,18 +167,6 @@ namespace MediaBrowser.Server.Implementations.Collections } list.Add(LinkedChild.Create(item)); - - var supportsGrouping = item as ISupportsBoxSetGrouping; - - if (supportsGrouping != null) - { - var boxsetIdList = supportsGrouping.BoxSetIdList.ToList(); - if (!boxsetIdList.Contains(collectionId)) - { - boxsetIdList.Add(collectionId); - } - supportsGrouping.BoxSetIdList = boxsetIdList; - } } collection.LinkedChildren.AddRange(list); @@ -228,15 +216,6 @@ namespace MediaBrowser.Server.Implementations.Collections { itemList.Add(childItem); } - - var supportsGrouping = childItem as ISupportsBoxSetGrouping; - - if (supportsGrouping != null) - { - var boxsetIdList = supportsGrouping.BoxSetIdList.ToList(); - boxsetIdList.Remove(collectionId); - supportsGrouping.BoxSetIdList = boxsetIdList; - } } var shortcutFiles = Directory @@ -289,29 +268,40 @@ namespace MediaBrowser.Server.Implementations.Collections public IEnumerable CollapseItemsWithinBoxSets(IEnumerable items, User user) { - var itemsToCollapse = new List(); - var boxsets = new List(); + var results = new Dictionary(); + var allBoxsets = new List(); - var list = items.ToList(); - - foreach (var item in list.OfType()) + foreach (var item in items) { - var currentBoxSets = item.BoxSetIdList - .Select(i => _libraryManager.GetItemById(i)) - .Where(i => i != null && i.IsVisible(user)) - .ToList(); + var grouping = item as ISupportsBoxSetGrouping; - if (currentBoxSets.Count > 0) + if (grouping == null) + { + results[item.Id] = item; + } + else { - itemsToCollapse.Add(item); - boxsets.AddRange(currentBoxSets); + var itemId = item.Id; + + var currentBoxSets = allBoxsets + .Where(i => i.GetLinkedChildren().Any(j => j.Id == itemId)) + .ToList(); + + if (currentBoxSets.Count > 0) + { + foreach (var boxset in currentBoxSets) + { + results[boxset.Id] = boxset; + } + } + else + { + results[item.Id] = item; + } } } - return list - .Except(itemsToCollapse.Cast()) - .Concat(boxsets) - .DistinctBy(i => i.Id); + return results.Values; } } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/BoxSetPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/BoxSetPostScanTask.cs deleted file mode 100644 index 86d88f7e0..000000000 --- a/MediaBrowser.Server.Implementations/Library/Validators/BoxSetPostScanTask.cs +++ /dev/null @@ -1,50 +0,0 @@ -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Library; -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Server.Implementations.Library.Validators -{ - public class BoxSetPostScanTask : ILibraryPostScanTask - { - private readonly ILibraryManager _libraryManager; - - public BoxSetPostScanTask(ILibraryManager libraryManager) - { - _libraryManager = libraryManager; - } - - public Task Run(IProgress progress, CancellationToken cancellationToken) - { - var items = _libraryManager.RootFolder.RecursiveChildren.ToList(); - - var boxsets = items.OfType().ToList(); - - var numComplete = 0; - - foreach (var boxset in boxsets) - { - foreach (var child in boxset.Children.Concat(boxset.GetLinkedChildren()).OfType()) - { - var boxsetIdList = child.BoxSetIdList.ToList(); - if (!boxsetIdList.Contains(boxset.Id)) - { - boxsetIdList.Add(boxset.Id); - } - child.BoxSetIdList = boxsetIdList; - } - - numComplete++; - double percent = numComplete; - percent /= boxsets.Count; - progress.Report(percent * 100); - } - - progress.Report(100); - return Task.FromResult(true); - } - } -} diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 62619a567..4206ccf59 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -45,6 +45,8 @@ "ButtonHelp": "Help", "ButtonSave": "Save", "HeaderDevices": "Devices", + "ButtonScheduledTasks": "Scheduled tasks", + "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", "HeaderWelcomeToMediaBrowserWebClient": "Welcome to the Media Browser Web Client", @@ -59,7 +61,7 @@ "ButtonCancelItem": "Cancel item", "ButtonQueueForRetry": "Queue for retry", "ButtonReenable": "Re-enable", - "SyncJobItemStatusSyncedMarkForRemoval": "Marked for removal", + "SyncJobItemStatusSyncedMarkForRemoval": "Marked for removal", "LabelAbortedByServerShutdown": "(Aborted by server shutdown)", "LabelScheduledTaskLastRan": "Last ran {0}, taking {1}.", "HeaderDeleteTaskTrigger": "Delete Task Trigger", @@ -71,8 +73,8 @@ "LabelFree": "Free", "HeaderSelectAudio": "Select Audio", "HeaderSelectSubtitles": "Select Subtitles", - "ButtonMarkForRemoval": "Mark for removal from device", - "ButtonUnmarkForRemoval": "Unmark for removal from device", + "ButtonMarkForRemoval": "Mark for removal from device", + "ButtonUnmarkForRemoval": "Unmark for removal from device", "LabelDefaultStream": "(Default)", "LabelForcedStream": "(Forced)", "LabelDefaultForcedStream": "(Default/Forced)", diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 548ac07aa..fe5642dbc 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -209,7 +209,6 @@ - -- cgit v1.2.3 From db038464814ea56fd90526dd35ce790cfc2a72e2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 23 Jan 2015 01:15:15 -0500 Subject: sync updates --- MediaBrowser.Model/Sync/SyncJobItem.cs | 5 ++ .../BoxSets/BoxSetMetadataService.cs | 2 - MediaBrowser.Providers/Photos/PhotoProvider.cs | 2 +- .../Collections/CollectionImageProvider.cs | 67 ++++++++++++++++++++++ .../Collections/ManualCollectionsFolder.cs | 4 +- .../Localization/JavaScript/javascript.json | 2 + .../Localization/Server/server.json | 2 + .../MediaBrowser.Server.Implementations.csproj | 1 + .../Persistence/SqliteItemRepository.cs | 1 - .../Photos/BaseDynamicImageProvider.cs | 2 +- .../Playlists/ManualPlaylistsFolder.cs | 2 +- .../Sync/SyncJobProcessor.cs | 7 ++- .../Sync/SyncRepository.cs | 19 +++--- .../TV/TVSeriesManager.cs | 5 +- .../ApplicationHost.cs | 42 +++++++------- 15 files changed, 124 insertions(+), 39 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/Collections/CollectionImageProvider.cs (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Model/Sync/SyncJobItem.cs b/MediaBrowser.Model/Sync/SyncJobItem.cs index 195d1e17e..77464be58 100644 --- a/MediaBrowser.Model/Sync/SyncJobItem.cs +++ b/MediaBrowser.Model/Sync/SyncJobItem.cs @@ -96,6 +96,11 @@ namespace MediaBrowser.Model.Sync /// /// true if this instance is marked for removal; otherwise, false. public bool IsMarkedForRemoval { get; set; } + /// + /// Gets or sets the index of the job item. + /// + /// The index of the job item. + public int JobItemIndex { get; set; } public SyncJobItem() { diff --git a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs index e195df7dd..3ac3cccb3 100644 --- a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs +++ b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs @@ -2,14 +2,12 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; -using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; diff --git a/MediaBrowser.Providers/Photos/PhotoProvider.cs b/MediaBrowser.Providers/Photos/PhotoProvider.cs index 29b75d830..3eaef59fb 100644 --- a/MediaBrowser.Providers/Photos/PhotoProvider.cs +++ b/MediaBrowser.Providers/Photos/PhotoProvider.cs @@ -15,7 +15,7 @@ using TagLib.IFD.Tags; namespace MediaBrowser.Providers.Photos { - public class PhotoProvider : ICustomMetadataProvider, IHasItemChangeMonitor + public class PhotoProvider : ICustomMetadataProvider, IHasItemChangeMonitor, IForcedProvider { private readonly ILogger _logger; private readonly IImageProcessor _imageProcessor; diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionImageProvider.cs b/MediaBrowser.Server.Implementations/Collections/CollectionImageProvider.cs new file mode 100644 index 000000000..27ec6cc3b --- /dev/null +++ b/MediaBrowser.Server.Implementations/Collections/CollectionImageProvider.cs @@ -0,0 +1,67 @@ +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Server.Implementations.Photos; +using MoreLinq; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.Collections +{ + public class CollectionImageProvider : BaseDynamicImageProvider, ICustomMetadataProvider + { + public CollectionImageProvider(IFileSystem fileSystem, IProviderManager providerManager) + : base(fileSystem, providerManager) + { + } + + protected override Task> GetItemsWithImages(IHasImages item) + { + var playlist = (BoxSet)item; + + var items = playlist.Children.Concat(playlist.GetLinkedChildren()) + .Select(i => + { + var subItem = i; + + var episode = subItem as Episode; + + if (episode != null) + { + var series = episode.Series; + if (series != null && series.HasImage(ImageType.Primary)) + { + return series; + } + } + + if (subItem.HasImage(ImageType.Primary)) + { + return subItem; + } + + var parent = subItem.Parent; + + if (parent != null && parent.HasImage(ImageType.Primary)) + { + if (parent is MusicAlbum) + { + return parent; + } + } + + return null; + }) + .Where(i => i != null) + .DistinctBy(i => i.Id) + .ToList(); + + return Task.FromResult(GetFinalItems(items)); + } + } +} diff --git a/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs b/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs index b02c52874..fa4de728b 100644 --- a/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs +++ b/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs @@ -13,8 +13,8 @@ namespace MediaBrowser.Server.Implementations.Collections public override bool IsVisible(User user) { - return GetChildren(user, true).Any() && - base.IsVisible(user); + return base.IsVisible(user) && GetChildren(user, false) + .Any(); } public override bool IsHidden diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 4206ccf59..5d37007e0 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -46,6 +47,7 @@ "ButtonSave": "Save", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index e4677e4d1..3a5e7c77e 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -55,6 +55,8 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 1737e6fd3..c0cc0395c 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -117,6 +117,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index cd7928290..99c59abc5 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1,7 +1,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Persistence; -using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs index dbaf23656..369e8512f 100644 --- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs @@ -14,7 +14,7 @@ using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.Photos { - public abstract class BaseDynamicImageProvider : IHasChangeMonitor + public abstract class BaseDynamicImageProvider : IHasChangeMonitor, IForcedProvider where T : IHasImages { protected IFileSystem FileSystem { get; private set; } diff --git a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs index 89395a00b..2b2c52406 100644 --- a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs +++ b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Server.Implementations.Playlists public override bool IsVisible(User user) { - return base.IsVisible(user) && GetRecursiveChildren(user, false) + return base.IsVisible(user) && GetChildren(user, false) .OfType() .Any(i => i.IsVisible(user)); } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 67f9d363e..716584084 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -90,6 +90,10 @@ namespace MediaBrowser.Server.Implementations.Sync continue; } + var index = jobItems.Count == 0 ? + 0 : + (jobItems.Select(i => i.JobItemIndex).Max() + 1); + jobItem = new SyncJobItem { Id = Guid.NewGuid().ToString("N"), @@ -97,7 +101,8 @@ namespace MediaBrowser.Server.Implementations.Sync ItemName = GetSyncJobItemName(item), JobId = job.Id, TargetId = job.TargetId, - DateCreated = DateTime.UtcNow + DateCreated = DateTime.UtcNow, + JobItemIndex = index }; await _syncRepo.Create(jobItem).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 1cd8e8a9d..0e527ea54 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -41,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.Sync public async Task Initialize() { - var dbFile = Path.Combine(_appPaths.DataPath, "sync13.db"); + var dbFile = Path.Combine(_appPaths.DataPath, "sync14.db"); _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); @@ -50,7 +50,7 @@ namespace MediaBrowser.Server.Implementations.Sync "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Quality TEXT NOT NULL, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, Category TEXT, ParentId TEXT, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)", "create index if not exists idx_SyncJobs on SyncJobs(Id)", - "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT)", + "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT, JobItemIndex INT)", "create index if not exists idx_SyncJobItems on SyncJobs(Id)", //pragmas @@ -95,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemCount"); _saveJobItemCommand = _connection.CreateCommand(); - _saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval)"; + _saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval, @JobItemIndex)"; _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Id"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@ItemId"); @@ -111,10 +111,11 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@AdditionalFiles"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@MediaSource"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@IsMarkedForRemoval"); + _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@JobItemIndex"); } private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs"; - private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval from SyncJobItems"; + private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex from SyncJobItems"; public SyncJob GetJob(string id) { @@ -496,7 +497,7 @@ namespace MediaBrowser.Server.Implementations.Sync var startIndex = query.StartIndex ?? 0; if (startIndex > 0) { - whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM SyncJobItems ORDER BY DateCreated LIMIT {0})", + whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM SyncJobItems ORDER BY JobItemIndex, DateCreated LIMIT {0})", startIndex.ToString(_usCulture))); } @@ -505,7 +506,7 @@ namespace MediaBrowser.Server.Implementations.Sync cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray()); } - cmd.CommandText += " ORDER BY DateCreated"; + cmd.CommandText += " ORDER BY JobItemIndex, DateCreated"; if (query.Limit.HasValue) { @@ -574,6 +575,7 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobItemCommand.GetParameter(index++).Value = _json.SerializeToString(jobItem.AdditionalFiles); _saveJobItemCommand.GetParameter(index++).Value = jobItem.MediaSource == null ? null : _json.SerializeToString(jobItem.MediaSource); _saveJobItemCommand.GetParameter(index++).Value = jobItem.IsMarkedForRemoval; + _saveJobItemCommand.GetParameter(index++).Value = jobItem.JobItemIndex; _saveJobItemCommand.Transaction = transaction; @@ -648,7 +650,7 @@ namespace MediaBrowser.Server.Implementations.Sync info.TargetId = reader.GetString(8); - info.DateCreated = reader.GetDateTime(9); + info.DateCreated = reader.GetDateTime(9).ToUniversalTime(); if (!reader.IsDBNull(10)) { @@ -676,7 +678,8 @@ namespace MediaBrowser.Server.Implementations.Sync } info.IsMarkedForRemoval = reader.GetBoolean(13); - + info.JobItemIndex = reader.GetInt32(14); + return info; } diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs index 66e771aa3..8c21727a4 100644 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs @@ -163,7 +163,10 @@ namespace MediaBrowser.Server.Implementations.TV return new Tuple(nextUp, lastWatchedDate); } - return new Tuple(null, lastWatchedDate); + var firstEpisode = allEpisodes.LastOrDefault(i => i.LocationType != LocationType.Virtual && !i.IsPlayed(user)); + + // Return the first episode + return new Tuple(firstEpisode, DateTime.MinValue); } private IEnumerable FilterSeries(NextUpQuery request, IEnumerable items) diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 7eb68187a..4fc6ae6fa 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -796,35 +796,35 @@ namespace MediaBrowser.Server.Startup.Common private string GetCertificatePath(bool generateCertificate) { - if (string.IsNullOrWhiteSpace(ServerConfigurationManager.Configuration.CertificatePath)) + if (!string.IsNullOrWhiteSpace(ServerConfigurationManager.Configuration.CertificatePath)) { - // Generate self-signed cert - var certHost = GetHostnameFromExternalDns(ServerConfigurationManager.Configuration.WanDdns); - var certPath = Path.Combine(ServerConfigurationManager.ApplicationPaths.ProgramDataPath, "ssl", "cert_" + certHost.GetMD5().ToString("N") + ".pfx"); + // Custom cert + return ServerConfigurationManager.Configuration.CertificatePath; + } + + // Generate self-signed cert + var certHost = GetHostnameFromExternalDns(ServerConfigurationManager.Configuration.WanDdns); + var certPath = Path.Combine(ServerConfigurationManager.ApplicationPaths.ProgramDataPath, "ssl", "cert_" + certHost.GetMD5().ToString("N") + ".pfx"); - if (generateCertificate) + if (generateCertificate) + { + if (!File.Exists(certPath)) { - if (!File.Exists(certPath)) + Directory.CreateDirectory(Path.GetDirectoryName(certPath)); + + try { - Directory.CreateDirectory(Path.GetDirectoryName(certPath)); - - try - { - NetworkManager.GenerateSelfSignedSslCertificate(certPath, certHost); - } - catch (Exception ex) - { - Logger.ErrorException("Error creating ssl cert", ex); - return null; - } + NetworkManager.GenerateSelfSignedSslCertificate(certPath, certHost); + } + catch (Exception ex) + { + Logger.ErrorException("Error creating ssl cert", ex); + return null; } } - - return certPath; } - // Custom cert - return ServerConfigurationManager.Configuration.CertificatePath; + return certPath; } /// -- cgit v1.2.3 From 1af651bc56025935cebe2762d6f36be41530eba1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 23 Jan 2015 23:50:45 -0500 Subject: add Add to collection buttons --- MediaBrowser.Controller/Channels/Channel.cs | 7 ++++++- MediaBrowser.Controller/Entities/BaseItem.cs | 17 ++++------------- MediaBrowser.Controller/Entities/UserViewBuilder.cs | 18 +++++++++++++++++- MediaBrowser.Providers/Manager/ProviderManager.cs | 9 ++++++--- .../Channels/ChannelManager.cs | 6 +++--- .../Library/LibraryManager.cs | 2 +- .../Library/Resolvers/Movies/BoxSetResolver.cs | 12 ------------ .../Localization/JavaScript/javascript.json | 7 +++++++ .../Localization/Server/server.json | 9 +++++---- .../Themes/AppThemeManager.cs | 2 +- MediaBrowser.Server.Startup.Common/ApplicationHost.cs | 2 +- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 3 ++- .../MediaBrowser.WebDashboard.csproj | 3 +++ 13 files changed, 56 insertions(+), 41 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index 32ad2ff12..87d257f12 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -60,7 +60,12 @@ namespace MediaBrowser.Controller.Channels protected override string GetInternalMetadataPath(string basePath) { - return System.IO.Path.Combine(basePath, "channels", Id.ToString("N"), "metadata"); + return GetInternalMetadataPath(basePath, Id); + } + + public static string GetInternalMetadataPath(string basePath, Guid id) + { + return System.IO.Path.Combine(basePath, "channels", id.ToString("N"), "metadata"); } } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 6a30df7fe..2be4f99e9 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -381,11 +381,6 @@ namespace MediaBrowser.Controller.Entities { var basePath = ConfigurationManager.ApplicationPaths.InternalMetadataPath; - if (ConfigurationManager.Configuration.EnableLibraryMetadataSubFolder) - { - basePath = System.IO.Path.Combine(basePath, "library"); - } - return GetInternalMetadataPath(basePath); } @@ -393,14 +388,10 @@ namespace MediaBrowser.Controller.Entities { var idString = Id.ToString("N"); - return System.IO.Path.Combine(basePath, idString.Substring(0, 2), idString); - } - - public static string GetInternalMetadataPathForId(Guid id) - { - var idString = id.ToString("N"); - - var basePath = ConfigurationManager.ApplicationPaths.InternalMetadataPath; + if (ConfigurationManager.Configuration.EnableLibraryMetadataSubFolder) + { + basePath = System.IO.Path.Combine(basePath, "library"); + } return System.IO.Path.Combine(basePath, idString.Substring(0, 2), idString); } diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 166d56c51..deb85ed6a 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -117,7 +117,7 @@ namespace MediaBrowser.Controller.Entities return await GetGameView(user, queryParent, query).ConfigureAwait(false); case CollectionType.BoxSets: - return GetResult(GetMediaFolders(user).SelectMany(i => i.GetRecursiveChildren(user)).OfType(), queryParent, query); + return await GetBoxsetView(queryParent, user, query).ConfigureAwait(false); case CollectionType.TvShows: return await GetTvView(queryParent, user, query).ConfigureAwait(false); @@ -526,6 +526,22 @@ namespace MediaBrowser.Controller.Entities return GetResult(items, queryParent, query); } + private async Task> GetBoxsetView(Folder parent, User user, InternalItemsQuery query) + { + return GetResult(GetMediaFolders(user).SelectMany(i => + { + var hasCollectionType = i as ICollectionFolder; + + if (hasCollectionType != null && string.Equals(hasCollectionType.CollectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase)) + { + return i.GetChildren(user, true); + } + + return i.GetRecursiveChildren(user); + + }).OfType(), parent, query); + } + private async Task> GetTvView(Folder parent, User user, InternalItemsQuery query) { if (query.Recursive) diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index d9982e786..823c34a75 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; +using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -58,6 +59,7 @@ namespace MediaBrowser.Providers.Manager private IMetadataProvider[] _metadataProviders = { }; private IEnumerable _savers; private IImageSaver[] _imageSavers; + private readonly IServerApplicationPaths _appPaths; private IExternalId[] _externalIds; @@ -69,13 +71,14 @@ namespace MediaBrowser.Providers.Manager /// The directory watchers. /// The log manager. /// The file system. - public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem) + public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths) { _logger = logManager.GetLogger("ProviderManager"); _httpClient = httpClient; ConfigurationManager = configurationManager; _libraryMonitor = libraryMonitor; _fileSystem = fileSystem; + _appPaths = appPaths; } /// @@ -467,7 +470,7 @@ namespace MediaBrowser.Providers.Manager // Give it a dummy path just so that it looks like a file system item var dummy = new T() { - Path = BaseItem.GetInternalMetadataPathForId(Guid.NewGuid()), + Path = Path.Combine(_appPaths.InternalMetadataPath, "dummy"), // Dummy this up to fool the local trailer check Parent = new Folder() @@ -709,7 +712,7 @@ namespace MediaBrowser.Providers.Manager // Give it a dummy path just so that it looks like a file system item var dummy = new TItemType { - Path = BaseItem.GetInternalMetadataPathForId(Guid.NewGuid()), + Path = Path.Combine(_appPaths.InternalMetadataPath, "dummy"), // Dummy this up to fool the local trailer check Parent = new Folder() diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index a7e248ea4..99ca0b5da 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -393,7 +393,9 @@ namespace MediaBrowser.Server.Implementations.Channels private async Task GetChannel(IChannel channelInfo, CancellationToken cancellationToken) { - var path = Path.Combine(_config.ApplicationPaths.ItemsByNamePath, "channels", _fileSystem.GetValidFilename(channelInfo.Name)); + var id = GetInternalChannelId(channelInfo.Name); + + var path = Channel.GetInternalMetadataPath(_config.ApplicationPaths.InternalMetadataPath, id); var fileInfo = new DirectoryInfo(path); @@ -414,8 +416,6 @@ namespace MediaBrowser.Server.Implementations.Channels isNew = true; } - var id = GetInternalChannelId(channelInfo.Name); - var item = _libraryManager.GetItemById(id) as Channel; if (item == null) diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index b28c98728..1306188da 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1646,7 +1646,7 @@ namespace MediaBrowser.Server.Implementations.Library var id = GetNewItemId("7_namedview_" + name + user.Id.ToString("N") + parentId, typeof(UserView)); - var path = BaseItem.GetInternalMetadataPathForId(id); + var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", "specialviews", id.ToString("N")); var item = GetItemById(id) as UserView; diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs index 67b9d546f..e3447afc9 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs @@ -4,7 +4,6 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; using System; using System.IO; -using System.Linq; namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies { @@ -46,17 +45,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies return null; } - private bool IsInvalid(string collectionType) - { - var validCollectionTypes = new[] - { - CollectionType.Movies, - CollectionType.BoxSets - }; - - return !validCollectionTypes.Contains(collectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase); - } - /// /// Sets the initial item values. /// diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 5d37007e0..914924f42 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -45,8 +45,14 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Save", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", @@ -223,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 3a5e7c77e..576e0493e 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -55,6 +55,8 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "", "LabelCustomCertificatePath": "Custom certificate path:", "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", @@ -516,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -891,6 +890,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -907,7 +908,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -969,6 +969,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Themes/AppThemeManager.cs b/MediaBrowser.Server.Implementations/Themes/AppThemeManager.cs index 9845f3867..2711c08aa 100644 --- a/MediaBrowser.Server.Implementations/Themes/AppThemeManager.cs +++ b/MediaBrowser.Server.Implementations/Themes/AppThemeManager.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Server.Implementations.Themes { get { - return Path.Combine(_appPaths.ItemsByNamePath, "appthemes"); + return Path.Combine(_appPaths.ProgramDataPath, "appthemes"); } } diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 4fc6ae6fa..439d74ab9 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -419,7 +419,7 @@ namespace MediaBrowser.Server.Startup.Common LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager); RegisterSingleInstance(LibraryMonitor); - ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager); + ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths); RegisterSingleInstance(ProviderManager); SeriesOrderManager = new SeriesOrderManager(); diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 90a5b4ab6..340b02be7 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -565,7 +565,8 @@ namespace MediaBrowser.WebDashboard.Api "userimage.css", "livetv.css", "nowplaying.css", - "icons.css" + "icons.css", + "materialize.css" }; var builder = new StringBuilder(); diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 1f720eb26..7613195ea 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -96,6 +96,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 8b78b69f57364bd1227d0db84663d1ffef077d36 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 25 Jan 2015 14:13:04 -0500 Subject: updated translations --- .../Entities/UserViewBuilder.cs | 63 +- .../Devices/DeviceRepository.cs | 11 + .../Localization/JavaScript/ar.json | 10 + .../Localization/JavaScript/bg_BG.json | 124 +-- .../Localization/JavaScript/ca.json | 10 + .../Localization/JavaScript/cs.json | 10 + .../Localization/JavaScript/da.json | 10 + .../Localization/JavaScript/de.json | 10 + .../Localization/JavaScript/el.json | 10 + .../Localization/JavaScript/en_GB.json | 10 + .../Localization/JavaScript/en_US.json | 10 + .../Localization/JavaScript/es.json | 10 + .../Localization/JavaScript/es_MX.json | 10 + .../Localization/JavaScript/fi.json | 10 + .../Localization/JavaScript/fr.json | 10 + .../Localization/JavaScript/he.json | 10 + .../Localization/JavaScript/hr.json | 10 + .../Localization/JavaScript/it.json | 10 + .../Localization/JavaScript/javascript.json | 1 + .../Localization/JavaScript/kk.json | 14 +- .../Localization/JavaScript/ms.json | 10 + .../Localization/JavaScript/nb.json | 10 + .../Localization/JavaScript/nl.json | 34 +- .../Localization/JavaScript/pl.json | 10 + .../Localization/JavaScript/pt_BR.json | 42 +- .../Localization/JavaScript/pt_PT.json | 10 + .../Localization/JavaScript/ru.json | 14 +- .../Localization/JavaScript/sv.json | 10 + .../Localization/JavaScript/tr.json | 10 + .../Localization/JavaScript/uk.json | 10 + .../Localization/JavaScript/vi.json | 10 + .../Localization/JavaScript/zh_CN.json | 10 + .../Localization/JavaScript/zh_TW.json | 10 + .../Localization/Server/ar.json | 13 +- .../Localization/Server/bg_BG.json | 837 +++++++++++---------- .../Localization/Server/ca.json | 13 +- .../Localization/Server/cs.json | 13 +- .../Localization/Server/da.json | 13 +- .../Localization/Server/de.json | 15 +- .../Localization/Server/el.json | 13 +- .../Localization/Server/en_GB.json | 13 +- .../Localization/Server/en_US.json | 13 +- .../Localization/Server/es.json | 15 +- .../Localization/Server/es_MX.json | 15 +- .../Localization/Server/fi.json | 13 +- .../Localization/Server/fr.json | 15 +- .../Localization/Server/he.json | 13 +- .../Localization/Server/hr.json | 13 +- .../Localization/Server/it.json | 15 +- .../Localization/Server/kk.json | 23 +- .../Localization/Server/ko.json | 13 +- .../Localization/Server/ms.json | 13 +- .../Localization/Server/nb.json | 15 +- .../Localization/Server/nl.json | 43 +- .../Localization/Server/pl.json | 13 +- .../Localization/Server/pt_BR.json | 71 +- .../Localization/Server/pt_PT.json | 13 +- .../Localization/Server/ru.json | 15 +- .../Localization/Server/sv.json | 15 +- .../Localization/Server/tr.json | 13 +- .../Localization/Server/uk.json | 13 +- .../Localization/Server/vi.json | 13 +- .../Localization/Server/zh_CN.json | 15 +- .../Localization/Server/zh_TW.json | 13 +- .../Session/SessionManager.cs | 11 +- 65 files changed, 1204 insertions(+), 703 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 7b3021306..1572c1af0 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -239,7 +239,9 @@ namespace MediaBrowser.Controller.Entities { if (query.Recursive) { - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }, i => FilterItem(i, query)); + + return PostFilterAndSort(items, parent, null, query); } var list = new List(); @@ -393,12 +395,16 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetMusicAlbums(Folder parent, User user, InternalItemsQuery query) { - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }).Where(i => i is MusicAlbum), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }, i => (i is MusicAlbum) && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, null, query); } private QueryResult GetMusicSongs(Folder parent, User user, InternalItemsQuery query) { - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }).Where(i => i is Audio.Audio), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }, i => (i is Audio.Audio) && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, null, query); } private QueryResult GetMusicLatest(Folder parent, User user, InternalItemsQuery query) @@ -446,45 +452,59 @@ namespace MediaBrowser.Controller.Entities { query.IsFavorite = true; - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }, i => (i is Movie) && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, null, query); } private QueryResult GetFavoriteSeries(Folder parent, User user, InternalItemsQuery query) { query.IsFavorite = true; - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).Where(i => i is Series), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }, i => (i is Series) && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, null, query); } private QueryResult GetFavoriteEpisodes(Folder parent, User user, InternalItemsQuery query) { query.IsFavorite = true; - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).Where(i => i is Episode), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }, i => (i is Episode) && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, null, query); } private QueryResult GetFavoriteSongs(Folder parent, User user, InternalItemsQuery query) { query.IsFavorite = true; - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music }).Where(i => i is Audio.Audio), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music }, i => (i is Audio.Audio) && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, null, query); } private QueryResult GetFavoriteAlbums(Folder parent, User user, InternalItemsQuery query) { query.IsFavorite = true; - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music }).Where(i => i is MusicAlbum), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music }, i => (i is MusicAlbum) && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, null, query); } private QueryResult GetMovieMovies(Folder parent, User user, InternalItemsQuery query) { - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }, i => (i is Movie) && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, null, query); } private QueryResult GetMovieCollections(Folder parent, User user, InternalItemsQuery query) { - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is BoxSet), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }, i => (i is BoxSet) && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, null, query); } private QueryResult GetMovieLatest(Folder parent, User user, InternalItemsQuery query) @@ -566,7 +586,9 @@ namespace MediaBrowser.Controller.Entities { if (query.Recursive) { - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).Where(i => i is Series || i is Season || i is Episode), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }, i => (i is Series || i is Season || i is Episode) && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, null, query); } var list = new List(); @@ -586,7 +608,8 @@ namespace MediaBrowser.Controller.Entities { if (query.Recursive) { - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Games }, i => FilterItem(i, query)); + return PostFilterAndSort(items, parent, null, query); } var list = new List(); @@ -625,7 +648,8 @@ namespace MediaBrowser.Controller.Entities { query.IsFavorite = true; - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }).OfType(), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Games }, i => i is Game && FilterItem(i, query)); + return PostFilterAndSort(items, parent, null, query); } private QueryResult GetTvLatest(Folder parent, User user, InternalItemsQuery query) @@ -666,7 +690,9 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetTvSeries(Folder parent, User user, InternalItemsQuery query) { - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).OfType(), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }, i => i is Series && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, null, query); } private async Task> GetTvGenres(Folder parent, User user, InternalItemsQuery query) @@ -708,14 +734,15 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetGameSystems(Folder parent, User user, InternalItemsQuery query) { - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }).OfType(), parent, query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Games }, i => i is GameSystem && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, null, query); } private async Task> GetGameGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query) { - var items = GetRecursiveChildren(queryParent, user, new[] { CollectionType.Games }) - .OfType() - .Where(i => i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase)); + var items = GetRecursiveChildren(queryParent, user, new[] {CollectionType.Games}, + i => i is Game && i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase)); return GetResult(items, queryParent, query); } diff --git a/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs b/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs index 70a04d249..6d324b1ab 100644 --- a/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs +++ b/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs @@ -60,6 +60,12 @@ namespace MediaBrowser.Server.Implementations.Devices public Task SaveCapabilities(string reportedId, ClientCapabilities capabilities) { var device = GetDevice(reportedId); + + if (device == null) + { + throw new ArgumentException("No device has been registed with id " + reportedId); + } + device.Capabilities = capabilities; SaveDevice(device); @@ -75,6 +81,11 @@ namespace MediaBrowser.Server.Implementations.Devices public DeviceInfo GetDevice(string id) { + if (string.IsNullOrWhiteSpace(id)) + { + throw new ArgumentNullException("id"); + } + return GetDevices() .FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase)); } diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json index edbb55d97..741174d91 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "\u062a\u062e\u0632\u064a\u0646", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/bg_BG.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/bg_BG.json index e318294bf..1bbbe8510 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/bg_BG.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/bg_BG.json @@ -19,9 +19,9 @@ "PasswordResetConfirmation": "Are you sure you wish to reset the password?", "PasswordSaved": "Password saved.", "PasswordMatchError": "Password and password confirmation must match.", - "OptionRelease": "Official Release", - "OptionBeta": "Beta", - "OptionDev": "Dev (Unstable)", + "OptionRelease": "\u041e\u0444\u0438\u0446\u0438\u0430\u043b\u043d\u043e \u0438\u0437\u0434\u0430\u043d\u0438\u0435", + "OptionBeta": "\u0411\u0435\u0442\u0430", + "OptionDev": "\u0417\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u0446\u0438 (\u041d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u0435\u043d)", "UninstallPluginHeader": "Uninstall Plugin", "UninstallPluginConfirmation": "Are you sure you wish to uninstall {0}?", "NoPluginConfigurationMessage": "This plugin has nothing to configure.", @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -42,10 +43,18 @@ "LabelStopping": "Stopping", "LabelCancelled": "(cancelled)", "LabelFailed": "(\u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e)", - "ButtonHelp": "Help", - "ButtonSave": "Save", + "ButtonHelp": "\u041f\u043e\u043c\u043e\u0449", + "ButtonSave": "\u0417\u0430\u043f\u043e\u043c\u043d\u0438", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "\u041f\u0440\u0438\u0432\u044a\u0440\u0436\u0435\u043d\u0441\u043a\u043e\u0442\u043e \u0447\u043b\u0435\u043d\u0441\u0442\u0432\u043e \u043e\u0441\u0438\u0433\u0443\u0440\u044f\u0432\u0430 \u0434\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0438 \u043e\u0431\u043b\u0430\u0433\u0438, \u043a\u0430\u0442\u043e \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u043f\u044a\u0440\u0432\u043e\u043a\u043b\u0430\u0441\u043d\u0438 \u043f\u043b\u044a\u0433\u0438\u043d\u0438, \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b\u0438\u0442\u0435, \u0438 \u0434\u0440\u0443\u0433\u0438. {0} \u041d\u0430\u0443\u0447\u0435\u0442\u0435 \u043f\u043e\u0432\u0435\u0447\u0435 {1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "\u0414\u043e\u0431\u0440\u0435 \u0434\u043e\u0448\u043b\u0438 \u0432 \u0433\u043b\u0430\u0432\u043d\u0438\u044f \u043f\u0430\u043d\u0435\u043b \u043d\u0430 Media Browser", @@ -56,7 +65,7 @@ "MessageNoSyncJobsFound": "No sync jobs found. Create sync jobs using the Sync buttons found throughout the web interface.", "HeaderLibraryAccess": "Library Access", "HeaderChannelAccess": "Channel Access", - "HeaderDeviceAccess": "Device Access", + "HeaderDeviceAccess": "\u0414\u043e\u0441\u0442\u044a\u043f \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0442\u0430", "HeaderSelectDevices": "Select Devices", "ButtonCancelItem": "Cancel item", "ButtonQueueForRetry": "Queue for retry", @@ -85,8 +94,8 @@ "ButtonStop": "Stop", "ButtonNextTrack": "\u0421\u043b\u0435\u0434\u0432\u0430\u0449\u0430 \u043f\u044a\u0442\u0435\u043a\u0430", "ButtonPause": "Pause", - "ButtonPlay": "Play", - "ButtonEdit": "Edit", + "ButtonPlay": "\u041f\u0443\u0441\u043d\u0438", + "ButtonEdit": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u0439", "ButtonQueue": "Queue", "ButtonPlayTrailer": "\u041f\u0443\u0441\u043d\u0438 \u0442\u0440\u0435\u0439\u043b\u044a\u0440\u0430", "ButtonPlaylist": "Playlist", @@ -101,7 +110,7 @@ "LabelAllPlaysSentToPlayer": "All plays will be sent to the selected player.", "MessageInvalidUser": "Invalid username or password. Please try again.", "HeaderLoginFailure": "Login Failure", - "HeaderAllRecordings": "All Recordings", + "HeaderAllRecordings": "\u0412\u0441\u0438\u0447\u043a\u0438 \u0417\u0430\u043f\u0438\u0441\u0438", "RecommendationBecauseYouLike": "Because you like {0}", "RecommendationBecauseYouWatched": "Because you watched {0}", "RecommendationDirectedBy": "Directed by {0}", @@ -117,13 +126,13 @@ "MessageRecordingDeleted": "Recording deleted.", "ButonCancelRecording": "Cancel Recording", "MessageRecordingSaved": "Recording saved.", - "OptionSunday": "Sunday", - "OptionMonday": "Monday", - "OptionTuesday": "Tuesday", - "OptionWednesday": "Wednesday", - "OptionThursday": "Thursday", - "OptionFriday": "Friday", - "OptionSaturday": "Saturday", + "OptionSunday": "\u041d\u0435\u0434\u0435\u043b\u044f", + "OptionMonday": "\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a", + "OptionTuesday": "\u0412\u0442\u043e\u0440\u043d\u0438\u043a", + "OptionWednesday": "\u0421\u0440\u044f\u0434\u0430", + "OptionThursday": "\u0427\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a", + "OptionFriday": "\u041f\u0435\u0442\u044a\u043a", + "OptionSaturday": "\u0421\u044a\u0431\u043e\u0442\u0430", "HeaderConfirmDeletion": "Confirm Deletion", "MessageConfirmPathSubstitutionDeletion": "Are you sure you wish to delete this path substitution?", "LiveTvUpdateAvailable": "(Update available)", @@ -145,7 +154,7 @@ "MessagePleaseSelectTwoItems": "Please select at least two items.", "MessageTheFollowingItemsWillBeGrouped": "The following titles will be grouped into one item:", "MessageConfirmItemGrouping": "Media Browser clients will automatically choose the optimal version to play based on device and network performance. Are you sure you wish to continue?", - "HeaderResume": "Resume", + "HeaderResume": "\u041f\u0440\u043e\u0436\u044a\u043b\u0436\u0438", "HeaderMyViews": "My Views", "HeaderLibraryFolders": "Media Folders", "HeaderLatestMedia": "Latest Media", @@ -169,8 +178,8 @@ "HeaderSelectChannelDownloadPath": "Select Channel Download Path", "HeaderSelectChannelDownloadPathHelp": "Browse or enter the path to use for storing channel cache files. The folder must be writeable.", "OptionNewCollection": "New...", - "ButtonAdd": "Add", - "ButtonRemove": "Remove", + "ButtonAdd": "\u0414\u043e\u0431\u0430\u0432\u0438", + "ButtonRemove": "\u041f\u0440\u0435\u043c\u0430\u0445\u043d\u0438", "LabelChapterDownloaders": "Chapter downloaders:", "LabelChapterDownloadersHelp": "Enable and rank your preferred chapter downloaders in order of priority. Lower priority downloaders will only be used to fill in missing information.", "HeaderFavoriteAlbums": "Favorite Albums", @@ -215,11 +224,12 @@ "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", "HeaderLatestTvRecordings": "Latest Recordings", - "ButtonOk": "Ok", - "ButtonCancel": "Cancel", - "ButtonRefresh": "Refresh", + "ButtonOk": "\u041e\u043a", + "ButtonCancel": "\u041e\u0442\u043c\u0435\u043d\u0438", + "ButtonRefresh": "\u041e\u0431\u043d\u043e\u0432\u0438", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", @@ -228,7 +238,7 @@ "ButtonShuffle": "Shuffle", "ButtonInstantMix": "Instant mix", "ButtonResume": "Resume", - "HeaderScenes": "Scenes", + "HeaderScenes": "\u0421\u0446\u0435\u043d\u0438", "HeaderAudioTracks": "Audio Tracks", "HeaderLibraries": "Libraries", "HeaderSubtitles": "Subtitles", @@ -246,8 +256,8 @@ "HeaderArtist": "Artist", "LabelAddedOnDate": "Added {0}", "ButtonStart": "Start", - "HeaderChannels": "Channels", - "HeaderMediaFolders": "Media Folders", + "HeaderChannels": "\u041a\u0430\u043d\u0430\u043b\u0438", + "HeaderMediaFolders": "\u041c\u0435\u0434\u0438\u0439\u043d\u0438 \u041f\u0430\u043f\u043a\u0438", "HeaderBlockItemsWithNoRating": "Block items with no rating information:", "OptionBlockOthers": "Others", "OptionBlockTvShows": "TV Shows", @@ -282,8 +292,8 @@ "MessageValueNotCorrect": "The value entered is not correct. Please try again.", "MessageItemSaved": "Item saved.", "MessagePleaseAcceptTermsOfServiceBeforeContinuing": "Please accept the terms of service before continuing.", - "OptionEnded": "Ended", - "OptionContinuing": "Continuing", + "OptionEnded": "\u041f\u0440\u0438\u043a\u043b\u044e\u0447\u0438\u043b\u043e", + "OptionContinuing": "\u041f\u0440\u043e\u0434\u044a\u043b\u0436\u0430\u0432\u0430\u0449\u043e", "OptionOff": "Off", "OptionOn": "On", "ButtonSettings": "Settings", @@ -305,9 +315,9 @@ "OptionName": "Name", "OptionOverview": "Overview", "OptionGenres": "Genres", - "OptionParentalRating": "Parental Rating", + "OptionParentalRating": "\u0420\u043e\u0434\u0438\u0442\u0435\u043b\u0441\u043a\u0438 \u0420\u0435\u0439\u0442\u0438\u043d\u0433", "OptionPeople": "People", - "OptionRuntime": "Runtime", + "OptionRuntime": "\u0412\u0440\u0435\u043c\u0435\u0442\u0440\u0430\u0435\u043d\u0435", "OptionProductionLocations": "Production Locations", "OptionBirthLocation": "Birth Location", "LabelAllChannels": "All channels", @@ -331,15 +341,15 @@ "LabelPackageInstallCompleted": "{0} installation completed.", "LabelPackageInstallFailed": "{0} installation failed.", "LabelPackageInstallCancelled": "{0} installation cancelled.", - "TabServer": "Server", + "TabServer": "\u0421\u044a\u0440\u0432\u044a\u0440", "TabUsers": "Users", "TabLibrary": "Library", - "TabMetadata": "Metadata", + "TabMetadata": "\u041c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f", "TabDLNA": "DLNA", "TabLiveTV": "Live TV", "TabAutoOrganize": "Auto-Organize", "TabPlugins": "Plugins", - "TabAdvanced": "Advanced", + "TabAdvanced": "\u0414\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0438", "TabHelp": "Help", "TabScheduledTasks": "Scheduled Tasks", "ButtonFullscreen": "\u0426\u044f\u043b \u0435\u043a\u0440\u0430\u043d", @@ -349,13 +359,13 @@ "ButtonQuality": "Quality", "HeaderNotifications": "Notifications", "HeaderSelectPlayer": "Select Player:", - "ButtonSelect": "Select", - "ButtonNew": "New", + "ButtonSelect": "\u0418\u0437\u0431\u0435\u0440\u0438", + "ButtonNew": "\u041d\u043e\u0432", "MessageInternetExplorerWebm": "For best results with Internet Explorer please install the WebM playback plugin.", "HeaderVideoError": "Video Error", "ButtonAddToPlaylist": "Add to playlist", "HeaderAddToPlaylist": "Add to Playlist", - "LabelName": "Name:", + "LabelName": "\u0418\u043c\u0435:", "ButtonSubmit": "Submit", "LabelSelectPlaylist": "Playlist:", "OptionNewPlaylist": "New playlist...", @@ -366,9 +376,9 @@ "ButtonRemoveFromPlaylist": "Remove from playlist", "HeaderSpecials": "Specials", "HeaderTrailers": "Trailers", - "HeaderAudio": "Audio", + "HeaderAudio": "\u0410\u0443\u0434\u0438\u043e", "HeaderResolution": "Resolution", - "HeaderVideo": "Video", + "HeaderVideo": "\u0412\u0438\u0434\u0435\u043e", "HeaderRuntime": "Runtime", "HeaderCommunityRating": "Community rating", "HeaderParentalRating": "Parental rating", @@ -384,11 +394,11 @@ "HeaderEmbeddedImage": "Embedded image", "HeaderTrack": "Track", "HeaderDisc": "Disc", - "OptionMovies": "Movies", + "OptionMovies": "\u0424\u0438\u043b\u043c\u0438", "OptionCollections": "Collections", "OptionSeries": "Series", "OptionSeasons": "Seasons", - "OptionEpisodes": "Episodes", + "OptionEpisodes": "\u0415\u043f\u0438\u0437\u043e\u0434\u0438", "OptionGames": "Games", "OptionGameSystems": "Game systems", "OptionMusicArtists": "Music artists", @@ -444,23 +454,23 @@ "LabelContentTypeValue": "Content type: {0}", "LabelPathSubstitutionHelp": "Optional: Path substitution can map server paths to network shares that clients can access for direct playback.", "FolderTypeUnset": "Unset (mixed content)", - "FolderTypeMovies": "Movies", - "FolderTypeMusic": "Music", - "FolderTypeAdultVideos": "Adult videos", - "FolderTypePhotos": "Photos", - "FolderTypeMusicVideos": "Music videos", - "FolderTypeHomeVideos": "Home videos", - "FolderTypeGames": "Games", - "FolderTypeBooks": "Books", + "FolderTypeMovies": "\u0424\u0438\u043b\u043c\u0438", + "FolderTypeMusic": "\u041c\u0443\u0437\u0438\u043a\u0430", + "FolderTypeAdultVideos": "\u041a\u043b\u0438\u043f\u043e\u0432\u0435 \u0437\u0430 \u0432\u044a\u0437\u0440\u0430\u0441\u0442\u043d\u0438", + "FolderTypePhotos": "\u0421\u043d\u0438\u043c\u043a\u0438", + "FolderTypeMusicVideos": "\u041c\u0443\u0437\u0438\u043a\u0430\u043b\u043d\u0438 \u043a\u043b\u0438\u043f\u043e\u0432\u0435", + "FolderTypeHomeVideos": "\u0414\u043e\u043c\u0430\u0448\u043d\u0438 \u043a\u043b\u0438\u043f\u043e\u0432\u0435", + "FolderTypeGames": "\u0418\u0433\u0440\u0438", + "FolderTypeBooks": "\u041a\u043d\u0438\u0433\u0438", "FolderTypeTvShows": "TV", - "TabMovies": "Movies", - "TabSeries": "Series", - "TabEpisodes": "Episodes", - "TabTrailers": "Trailers", - "TabGames": "Games", - "TabAlbums": "Albums", - "TabSongs": "Songs", - "TabMusicVideos": "Music Videos", + "TabMovies": "\u0424\u0438\u043b\u043c\u0438", + "TabSeries": "\u041f\u0440\u0435\u0434\u0430\u0432\u0430\u043d\u0438\u044f", + "TabEpisodes": "\u0415\u043f\u0438\u0437\u043e\u0434\u0438", + "TabTrailers": "\u0422\u0440\u0435\u0439\u043b\u044a\u0440\u0438", + "TabGames": "\u0418\u0433\u0440\u0438", + "TabAlbums": "\u0410\u043b\u0431\u0443\u043c\u0438", + "TabSongs": "\u041f\u0435\u0441\u043d\u0438", + "TabMusicVideos": "\u041c\u0443\u0437\u0438\u043a\u0430\u043b\u043d\u0438 \u043a\u043b\u0438\u043f\u043e\u0432\u0435", "BirthPlaceValue": "Birth place: {0}", "DeathDateValue": "Died: {0}", "BirthDateValue": "Born: {0}", @@ -478,7 +488,7 @@ "MessageSupporterMembershipExpiredOn": "Your supporter membership expired on {0}.", "MessageYouHaveALifetimeMembership": "You have a lifetime supporter membership. You can provide additional donations on a one-time or recurring basis using the options below. Thank you for supporting Media Browser.", "MessageYouHaveAnActiveRecurringMembership": "You have an active {0} membership. You can upgrade your plan using the options below.", - "ButtonDelete": "Delete", + "ButtonDelete": "\u0418\u0437\u0442\u0440\u0438\u0439", "HeaderMediaBrowserAccountAdded": "Media Browser Account Added", "MessageMediaBrowserAccountAdded": "The Media Browser account has been added to this user.", "MessagePendingMediaBrowserAccountAdded": "The Media Browser account has been added to this user. An email will be sent to the owner of the account. The invitation will need to be confirmed by clicking a link within the email.", @@ -596,7 +606,7 @@ "MediaInfoStreamTypeEmbeddedImage": "Embedded Image", "MediaInfoRefFrames": "Ref frames", "TabPlayback": "Playback", - "TabNotifications": "Notifications", + "TabNotifications": "\u0418\u0437\u0432\u0435\u0441\u0442\u0438\u044f", "TabExpert": "Expert", "HeaderSelectCustomIntrosPath": "Select Custom Intros Path", "HeaderRateAndReview": "Rate and Review", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json index 3afdd20a1..5c3299fbc 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Save", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json index 033d18ae9..9e73ee241 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Vyhled\u00e1v\u00e1n\u00ed", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Um\u011blec", "LabelMovie": "Film", "LabelMusicVideo": "Hudebn\u00ed video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Ulo\u017eit", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "P\u0159\u00edklad: Kolekce Star Wars", + "OptionSearchForInternetMetadata": "Prohledat internet pro nalezen\u00ed metadat a obalu.", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/da.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/da.json index cd67d2027..cfeb5e3d0 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/da.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/da.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Gem", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json index fac8234f1..67c032800 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Danke. Ihr Unterst\u00fctzerschl\u00fcssel wurde entfernt.", "ErrorLaunchingChromecast": "W\u00e4hrend des startens von Chromecast ist ein Fehler aufgetreten. Bitte stelle sicher, dass dein Ger\u00e4te mit dem WLAN verbunden ist.", "HeaderSearch": "Suche", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Interpret", "LabelMovie": "Film", "LabelMusicVideo": "Musikvideo", @@ -44,8 +45,16 @@ "LabelFailed": "(fehlgeschlagen)", "ButtonHelp": "Hilfe", "ButtonSave": "Speichern", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Zur Sammlung hinzuf\u00fcgen", + "NewCollectionNameExample": "Beispiel: Star Wars Collection", + "OptionSearchForInternetMetadata": "Suche im Internet nach Bildmaterial und Metadaten", + "LabelSelectCollection": "W\u00e4hle Zusammenstellung:", "HeaderDevices": "Ger\u00e4te", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "Eine Unterst\u00fctzer-Mitgliedschaft bietet weitere Vorteile, wie z.B. den Zugriff auf premium Plugins, weitere Internet-Channels und mehr. {0}Erfahren Sie mehr{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Willkommen zur Media Browser \u00dcbersicht", @@ -220,6 +229,7 @@ "ButtonRefresh": "Aktualisieren", "LabelCurrentPath": "Aktueller Pfad:", "HeaderSelectMediaPath": "W\u00e4hle einen Medienpfad:", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Netzwerk", "MessageDirectoryPickerInstruction": "Falls der Netzwerk Button deine Endger\u00e4te nicht automatisch findet, kannst du deren Netzwerkpfade auch manuell eintragen. Zum Beispiel {0} oder {1}.", "HeaderMenu": "Men\u00fc", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/el.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/el.json index 19d96f0e6..ae87f2a82 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/el.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/el.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "\u0391\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c3\u03c4\u03b5", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json index 4344decb6..ad3543c32 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Save", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json index f3775fc7b..e39a5d9c2 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Save", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json index 286ff7549..5355048b0 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Gracias. Su clave de seguidor ha sido eliminada.", "ErrorLaunchingChromecast": "Ha habido un error al lanzar chromecast. Asegurese que su dispositivo est\u00e1 conectado a su red inal\u00e1mbrica.", "HeaderSearch": "Buscar", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artista", "LabelMovie": "Pel\u00edcula", "LabelMusicVideo": "Video Musical", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Grabar", + "LabelCollection": "Collection", + "HeaderAddToCollection": "A\u00f1adir a la colecci\u00f3n", + "NewCollectionNameExample": "Ejemplo: Star Wars Colecci\u00f3n", + "OptionSearchForInternetMetadata": "Buscar en internet ilustraciones y metadatos", + "LabelSelectCollection": "Seleccionar colecci\u00f3n:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refrescar", "LabelCurrentPath": "Ruta actual:", "HeaderSelectMediaPath": "Seleccionar la ruta para Medios", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Red", "MessageDirectoryPickerInstruction": "Rutas de red pueden ser introducidas manualmente en el caso de que el bot\u00f3n de la red no pueda localizar sus dispositivos. Por ejemplo, {0} o {1}.", "HeaderMenu": "Men\u00fa", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json index 23415b86d..aab5891ce 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Gracias. Su clave de aficionado ha sido eliminada.", "ErrorLaunchingChromecast": "Hubo un error iniciando chromecast. Por favor aseg\u00farate de que tu dispositivo este conectado a tu red inalambrica", "HeaderSearch": "Buscar", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artista", "LabelMovie": "Pel\u00edcula", "LabelMusicVideo": "Video Musical", @@ -44,8 +45,16 @@ "LabelFailed": "(Fallido)", "ButtonHelp": "Ayuda", "ButtonSave": "Guardar", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Agregar a Colecci\u00f3n.", + "NewCollectionNameExample": "Ejemplo: Colecci\u00f3n Guerra de las Galaxias", + "OptionSearchForInternetMetadata": "Buscar en internet ilustraciones y metadatos", + "LabelSelectCollection": "Elegir colecci\u00f3n:", "HeaderDevices": "Dispositivos", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "La membres\u00eda de aficionado proporciona beneficios adicionales tales como acceso a complementos premium, contenido de canales de Internet y m\u00e1s. {0}Conocer m\u00e1s{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Bienvenido al Panel de Control de Media Browser", @@ -220,6 +229,7 @@ "ButtonRefresh": "Actualizar", "LabelCurrentPath": "Ruta actual:", "HeaderSelectMediaPath": "Seleccionar ruta a medios", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Red", "MessageDirectoryPickerInstruction": "Las rutas de red pueden ser ingresadas manualmente en caso de que el bot\u00f3n de Red no pueda localizar sus dispositivos. Por ejemplo, {0} or {1}.", "HeaderMenu": "Men\u00fa", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/fi.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/fi.json index d08cf8aba..9f8340f9b 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/fi.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/fi.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Tallenna", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json index 9c1e669f8..1063d8759 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Merci. Votre cl\u00e9 de supporteur a \u00e9t\u00e9 supprim\u00e9e.", "ErrorLaunchingChromecast": "Une erreur a \u00e9t\u00e9 rencontr\u00e9e lors du lancement de Chromecast. Veuillez vous assurer que votre appareil est bien connect\u00e9 \u00e0 votre r\u00e9seau sans-fil.", "HeaderSearch": "Recherche", + "ValueDateCreated": "Date de cr\u00e9ation : {0}", "LabelArtist": "Artiste", "LabelMovie": "Film", "LabelMusicVideo": "Clip vid\u00e9o", @@ -44,8 +45,16 @@ "LabelFailed": "(\u00e9chou\u00e9)", "ButtonHelp": "Aide", "ButtonSave": "Sauvegarder", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Ajouter \u00e0 la collection", + "NewCollectionNameExample": "Exemple: Collection Star Wars", + "OptionSearchForInternetMetadata": "Rechercher sur Internet les images et m\u00e9tadonn\u00e9es", + "LabelSelectCollection": "S\u00e9lectionner la collection :", "HeaderDevices": "Appareils", "ButtonScheduledTasks": "T\u00e2ches planifi\u00e9es", + "MessageItemsAdded": "Items ajout\u00e9s", + "ButtonAddToCollection": "Ajouter \u00e0 une collection", + "HeaderSelectCertificatePath": "S\u00e9lectionnez le chemin du certificat", "ConfirmMessageScheduledTaskButton": "Cette op\u00e9ration s'ex\u00e9cute normalement automatiquement en tant que t\u00e2che planifi\u00e9e. Elle peut aussi \u00eatre ex\u00e9cut\u00e9e manuellement ici. Pour configurer la t\u00e2che planifi\u00e9e, voir:", "HeaderSupporterBenefit": "Un partenariat de membre supporteur apporte des avantages suppl\u00e9mentaires, comme l'acc\u00e8s aux plugins premiums, aux contenus des cha\u00eenes Internet, et plus encore. {0}En savoir plus{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Bienvenue dans le centre de contr\u00f4le de Media browser", @@ -220,6 +229,7 @@ "ButtonRefresh": "Actualiser", "LabelCurrentPath": "Chemin d'acc\u00e8s actuel :", "HeaderSelectMediaPath": "S\u00e9lectionnez le chemin du m\u00e9dia", + "HeaderSelectPath": "S\u00e9lectionnez un chemin", "ButtonNetwork": "R\u00e9seau", "MessageDirectoryPickerInstruction": "Les chemins r\u00e9seaux peuvent \u00eatre saisis manuellement dans le cas o\u00f9 l'utilisation du bouton \"R\u00e9seau\" ne parvient pas \u00e0 localiser les ressources. Par exemple, {0} ou {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/he.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/he.json index 7810c43a0..8233ee705 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/he.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/he.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "\u05e9\u05de\u05d5\u05e8", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "\u05dc\u05d3\u05d5\u05d2\u05de\u05d0 :\u05d0\u05d5\u05e1\u05e3 \u05de\u05dc\u05d7\u05de\u05ea \u05d4\u05db\u05d5\u05db\u05d1\u05d9\u05dd", + "OptionSearchForInternetMetadata": "\u05d7\u05e4\u05e9 \u05d1\u05d0\u05d9\u05e0\u05e8\u05e0\u05d8 \u05d0\u05d7\u05e8\u05d9 \u05de\u05d9\u05d3\u05e2 \u05d5\u05ea\u05de\u05d5\u05e0\u05d5\u05ea", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/hr.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/hr.json index 60fb14bd8..af21fd7a8 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/hr.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/hr.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Snimi", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Naprimjer: Star Wars Kolekcija", + "OptionSearchForInternetMetadata": "Potra\u017ei na internetu grafike i metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json index b7c425552..671992034 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Grazie. La vostra chiave supporter \u00e8 stata rimossa.", "ErrorLaunchingChromecast": "Si \u00e8 verificato un errore all'avvio di chromecast. Assicurati che il tuo dispositivo sia connesso alla rete wireless.", "HeaderSearch": "Ricerca", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artista", "LabelMovie": "Film", "LabelMusicVideo": "Video Musicali", @@ -44,8 +45,16 @@ "LabelFailed": "(fallito)", "ButtonHelp": "Aiuto", "ButtonSave": "Salva", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Aggiungi alla Collezione", + "NewCollectionNameExample": "Esempio: Collezione Star wars", + "OptionSearchForInternetMetadata": "Cerca su internet le immagini e i metadati", + "LabelSelectCollection": "Seleziona Collezione:", "HeaderDevices": "Dispositivi", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "La sottoscrizione Supporter concede dei benefici come: l'accesso a plug-in premium, contenuti dei canali internet, e altro. {0}Scopri di pi\u00f9{1}", "HeaderWelcomeToMediaBrowserServerDashboard": "Benvenuti nel Dashboard di Media Browser", @@ -220,6 +229,7 @@ "ButtonRefresh": "Aggiorna", "LabelCurrentPath": "Percorso Corrente:", "HeaderSelectMediaPath": "Seleziona il percorso", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Rete", "MessageDirectoryPickerInstruction": "Percorsi di rete possono essere inseriti manualmente nel caso in cui il pulsante Rete non riesce a individuare i vostri dispositivi. Ad esempio, {0} o {1}", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 914924f42..ede08a49c 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -45,6 +45,7 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Save", + "LabelCollection": "Collection", "HeaderAddToCollection": "Add to Collection", "NewCollectionNameExample": "Example: Star Wars Collection", "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json index 86e748672..64f48f1c5 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "\u0416\u0430\u049b\u0442\u0430\u0443\u0448\u044b \u043a\u0456\u043b\u0442\u0456\u04a3\u0456\u0437 \u0430\u043b\u0430\u0441\u0442\u0430\u043b\u0434\u044b.", "ErrorLaunchingChromecast": "Chromecast \u0456\u0441\u043a\u0435 \u049b\u043e\u0441\u044b\u043b\u0443 \u043a\u0435\u0437\u0456\u043d\u0434\u0435 \u049b\u0430\u0442\u0435 \u043e\u0440\u044b\u043d \u0430\u043b\u0434\u044b. \u049a\u04b1\u0440\u044b\u043b\u0493\u044b\u04a3\u044b\u0437 \u0441\u044b\u043c\u0441\u044b\u0437 \u0436\u0435\u043b\u0456\u0433\u0435 \u049b\u043e\u0441\u044b\u043b\u0493\u0430\u043d\u044b\u043d\u0430 \u043a\u04e9\u0437 \u0436\u0435\u0442\u043a\u0456\u0437\u0456\u04a3\u0456\u0437.", "HeaderSearch": "\u0406\u0437\u0434\u0435\u0443", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "\u041e\u0440\u044b\u043d\u0434\u0430\u0443\u0448\u044b", "LabelMovie": "\u0424\u0438\u043b\u044c\u043c", "LabelMusicVideo": "\u041c\u0443\u0437\u044b\u043a\u0430\u043b\u044b\u049b \u0431\u0435\u0439\u043d\u0435", @@ -44,9 +45,17 @@ "LabelFailed": "(\u0441\u04d9\u0442\u0441\u0456\u0437)", "ButtonHelp": "\u0410\u043d\u044b\u049b\u0442\u0430\u043c\u0430", "ButtonSave": "\u0421\u0430\u049b\u0442\u0430\u0443", + "LabelCollection": "Collection", + "HeaderAddToCollection": "\u0416\u0438\u044b\u043d\u0442\u044b\u049b\u049b\u0430 \u049b\u043e\u0441\u0443", + "NewCollectionNameExample": "\u041c\u044b\u0441\u0430\u043b: \u0416\u04b1\u043b\u0434\u044b\u0437 \u0441\u043e\u0493\u044b\u0441\u0442\u0430\u0440\u044b (\u0436\u0438\u044b\u043d\u0442\u044b\u049b)", + "OptionSearchForInternetMetadata": "\u0421\u0443\u0440\u0435\u0442\u0442\u0435\u043c\u0435 \u043c\u0435\u043d \u043c\u0435\u0442\u0430\u0434\u0435\u0440\u0435\u043a\u0442\u0456 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0442\u0435\u043d \u0456\u0437\u0434\u0435\u0443", + "LabelSelectCollection": "\u0416\u0438\u044b\u043d\u0442\u044b\u049b\u0442\u044b \u0442\u0430\u04a3\u0434\u0430\u0443:", "HeaderDevices": "\u049a\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440", - "ButtonScheduledTasks": "Scheduled tasks", - "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", + "ButtonScheduledTasks": "\u0416\u043e\u0441\u043f\u0430\u0440\u043b\u0430\u0493\u0430\u043d \u0442\u0430\u043f\u0441\u044b\u0440\u043c\u0430\u043b\u0430\u0440\u0493\u0430 \u04e9\u0442\u0443", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", + "ConfirmMessageScheduledTaskButton": "\u0411\u04b1\u043b \u04d9\u0440\u0435\u043a\u0435\u0442 \u04d9\u0434\u0435\u0442\u0442\u0435 \u0436\u043e\u0441\u043f\u0430\u0440\u043b\u0430\u0493\u0430\u043d \u0442\u0430\u043f\u0441\u044b\u0440\u043c\u0430 \u0440\u0435\u0442\u0456\u043d\u0434\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0442\u044b \u0442\u04af\u0440\u0434\u0435 \u0436\u04b1\u043c\u044b\u0441 \u0456\u0441\u0442\u0435\u0439\u0434\u0456. \u041e\u0441\u044b\u043d\u044b \u0441\u043e\u043d\u0434\u0430\u0439-\u0430\u049b \u0431\u04b1\u043b \u0436\u0435\u0440\u0434\u0435 \u049b\u043e\u043b\u043c\u0435\u043d \u0456\u0441\u043a\u0435 \u049b\u043e\u0441\u0443\u0493\u0430 \u0431\u043e\u043b\u0430\u0434\u044b. \u0416\u043e\u0441\u043f\u0430\u0440\u043b\u0430\u0493\u0430\u043d \u0442\u0430\u043f\u0441\u044b\u0440\u043c\u0430\u043d\u044b \u0442\u0435\u04a3\u0448\u0435\u0443 \u04af\u0448\u0456\u043d, \u049b\u0430\u0440\u0430\u04a3\u044b\u0437:", "HeaderSupporterBenefit": "\u0416\u0430\u049b\u0442\u0430\u0443\u0448\u044b \u043c\u04af\u0448\u0435\u043b\u0456\u043a \u0441\u044b\u0439\u0430\u049b\u044b\u043b\u044b \u043f\u043b\u0430\u0433\u0438\u043d, \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u0430\u0440\u043d\u0430 \u043c\u0430\u0437\u043c\u04b1\u043d\u044b \u0436\u04d9\u043d\u0435 \u0441\u043e\u043d\u0434\u0430\u0439 \u0441\u0438\u044f\u049b\u0442\u044b\u043b\u0430\u0440\u0493\u0430 \u049b\u043e\u043b \u0436\u0435\u0442\u043a\u0456\u0437\u0443\u043c\u0435\u043d \u049b\u043e\u0441\u044b\u043c\u0448\u0430 \u0430\u0440\u0442\u044b\u049b\u0448\u044b\u043b\u044b\u049b\u0442\u0430\u0440 \u0431\u0435\u0440\u0435\u0434\u0456. {0}\u041a\u04e9\u0431\u0456\u0440\u0435\u043a \u0431\u0456\u043b\u0443{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Media Browser \u0431\u0430\u049b\u044b\u043b\u0430\u0443 \u0442\u0430\u049b\u0442\u0430\u0441\u044b\u043d\u0430 \u049b\u043e\u0448 \u043a\u0435\u043b\u0434\u0456\u04a3\u0456\u0437!", "HeaderWelcomeToMediaBrowserWebClient": "Media Browser \u0432\u0435\u0431-\u043a\u043b\u0438\u0435\u043d\u0442\u0456\u043d\u0435 \u049b\u043e\u0448 \u043a\u0435\u043b\u0434\u0456\u04a3\u0456\u0437!", @@ -220,6 +229,7 @@ "ButtonRefresh": "\u041a\u04e9\u043a\u0435\u0439\u0442\u0435\u0441\u0442\u0456 \u0435\u0442\u0443", "LabelCurrentPath": "\u0410\u0493\u044b\u043c\u0434\u044b\u049b \u0436\u043e\u043b:", "HeaderSelectMediaPath": "\u0422\u0430\u0441\u0443\u0448\u044b \u0436\u043e\u043b\u044b\u043d \u0442\u0430\u04a3\u0434\u0430\u0443", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "\u0416\u0435\u043b\u0456", "MessageDirectoryPickerInstruction": "\u0416\u0435\u043b\u0456 \u0442\u04af\u0439\u043c\u0435\u0448\u0456\u0433\u0456 \u0431\u0430\u0441\u044b\u043b\u0493\u0430\u043d\u0434\u0430 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u044b\u04a3\u044b\u0437 \u043e\u0440\u043d\u044b \u0442\u0430\u0431\u044b\u043b\u043c\u0430\u0441\u0430, \u0436\u0435\u043b\u0456\u043b\u0456\u043a \u0436\u043e\u043b\u0434\u0430\u0440 \u049b\u043e\u043b\u043c\u0435\u043d \u0435\u043d\u0433\u0456\u0437\u0456\u043b\u0443\u0456 \u043c\u04af\u043c\u043a\u0456\u043d. \u041c\u044b\u0441\u0430\u043b\u044b, {0} \u043d\u0435\u043c\u0435\u0441\u0435 {1}.", "HeaderMenu": "\u041c\u04d9\u0437\u0456\u0440", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json index 0a33c80c3..932d37fe0 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Save", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json index a9c2dba3b..2b6a9a67b 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Takk. Din supporter n\u00f8kkel har blitt fjernet.", "ErrorLaunchingChromecast": "Det var en error ved \u00e5 starte Chromecast. Vennligst forsikre deg om at enheten har korrekt forbindelse mot ditt tr\u00e5dl\u00f8se nettverk.", "HeaderSearch": "S\u00f8k", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Film", "LabelMusicVideo": "Musikk Video", @@ -44,8 +45,16 @@ "LabelFailed": "(Feilet)", "ButtonHelp": "Help", "ButtonSave": "lagre", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Legg Til I Samling", + "NewCollectionNameExample": "Eksempel: Star Wars Samling", + "OptionSearchForInternetMetadata": "S\u00f8k p\u00e5 internet for artwork og metadata", + "LabelSelectCollection": "Velg samling:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Velkommen til Media Browser Dashbord", @@ -220,6 +229,7 @@ "ButtonRefresh": "Oppdater", "LabelCurrentPath": "N\u00e5v\u00e6rende sti:", "HeaderSelectMediaPath": "Velg Media Sti", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Nettverk", "MessageDirectoryPickerInstruction": "Nettverksti kan skrives inn manuelt i tilfelle Nettverk-knappen ikke klarer \u00e5 lokalisere enhetene dine. For eksempel {0} eller {1}.", "HeaderMenu": "Meny", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json index 71432ddfb..f0ab146ee 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json @@ -6,8 +6,8 @@ "Administrator": "Beheerder", "Password": "Wachtwoord", "DeleteImage": "Verwijder afbeelding", - "MessageThankYouForSupporting": "Thank you for supporting Media Browser.", - "MessagePleaseSupportMediaBrowser": "Please support Media Browser.", + "MessageThankYouForSupporting": "Dank u voor de ondersteuning van Media Browser.", + "MessagePleaseSupportMediaBrowser": "Geef a.u.b. uw steun aan Media Browser.", "DeleteImageConfirmation": "Weet u zeker dat u deze afbeelding wilt verwijderen?", "FileReadCancelled": "Bestand lezen is geannuleerd.", "FileNotFound": "Bestand niet gevonden.", @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Dank u. Uw supporter sleutel is verwijderd.", "ErrorLaunchingChromecast": "Er is een fout opgetreden bij het starten van chromecast. Zorg ervoor dat uw apparaat is aangesloten op uw draadloze netwerk.", "HeaderSearch": "Zoeken", + "ValueDateCreated": "Datum aangemaakt: {0}", "LabelArtist": "Artiest", "LabelMovie": "Film", "LabelMusicVideo": "Muziek Video", @@ -44,9 +45,17 @@ "LabelFailed": "(mislukt)", "ButtonHelp": "Hulp", "ButtonSave": "Opslaan", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Toevoegen aan verzameling", + "NewCollectionNameExample": "Voorbeeld: Star Wars Collectie", + "OptionSearchForInternetMetadata": "Zoeken op het internet voor afbeeldingen en metadata", + "LabelSelectCollection": "Selecteer verzameling:", "HeaderDevices": "Apparaten", - "ButtonScheduledTasks": "Scheduled tasks", - "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", + "ButtonScheduledTasks": "Geplande taken", + "MessageItemsAdded": "Items toegevoegd", + "ButtonAddToCollection": "Voeg toe aan collectie", + "HeaderSelectCertificatePath": "Selecteer Certificaat Pad", + "ConfirmMessageScheduledTaskButton": "Deze operatie loopt normaal gesproken automatisch als een geplande taak. Het kan hier ook handmatig worden uitgevoerd. Om de geplande taak te configureren, zie:", "HeaderSupporterBenefit": "Een supporter lidmaatschap biedt voordelen zoals toegang tot premium plug-ins, internet kanalen en meer. {0}Meer weten{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welkom bij het Media Browser Dashboard", "HeaderWelcomeToMediaBrowserWebClient": "Welkom op de Media Browser Web Client", @@ -58,10 +67,10 @@ "HeaderChannelAccess": "Kanaal toegang", "HeaderDeviceAccess": "Apparaat Toegang", "HeaderSelectDevices": "Selecteer Apparaten", - "ButtonCancelItem": "Cancel item", - "ButtonQueueForRetry": "Queue for retry", - "ButtonReenable": "Re-enable", - "SyncJobItemStatusSyncedMarkForRemoval": "Marked for removal", + "ButtonCancelItem": "Annuleren item", + "ButtonQueueForRetry": "Wachtrij voor opnieuw proberen", + "ButtonReenable": "Opnieuw inschakelen", + "SyncJobItemStatusSyncedMarkForRemoval": "Gemarkeerd voor verwijdering", "LabelAbortedByServerShutdown": "(Afgebroken door afsluiten van de server)", "LabelScheduledTaskLastRan": "Laatste keer {0}, duur {1}.", "HeaderDeleteTaskTrigger": "Verwijderen Taak Trigger", @@ -73,13 +82,13 @@ "LabelFree": "Gratis", "HeaderSelectAudio": "Selecteer Audio", "HeaderSelectSubtitles": "Selecteer Ondertitels", - "ButtonMarkForRemoval": "Mark for removal from device", - "ButtonUnmarkForRemoval": "Unmark for removal from device", + "ButtonMarkForRemoval": "Markeren voor verwijdering uit het apparaat", + "ButtonUnmarkForRemoval": "Niet markeren voor verwijdering uit het apparaat", "LabelDefaultStream": "(Standaard)", "LabelForcedStream": "(Geforceerd)", "LabelDefaultForcedStream": "(Standaard \/ Georceerd)", "LabelUnknownLanguage": "Onbekende taal", - "MessageConfirmSyncJobItemCancellation": "Are you sure you wish to cancel this item?", + "MessageConfirmSyncJobItemCancellation": "Bent u zeker dat u dit item wilt annuleren?", "ButtonMute": "Dempen", "ButtonUnmute": "Dempen opheffen", "ButtonStop": "Stop", @@ -88,7 +97,7 @@ "ButtonPlay": "Afspelen", "ButtonEdit": "Bewerken", "ButtonQueue": "Wachtrij", - "ButtonPlayTrailer": "Speel trailer", + "ButtonPlayTrailer": "Trailer afspelen", "ButtonPlaylist": "Afspeellijst", "ButtonPreviousTrack": "Vorig Nummer", "LabelEnabled": "Ingeschakeld", @@ -220,6 +229,7 @@ "ButtonRefresh": "Vernieuwen", "LabelCurrentPath": "Huidige pad:", "HeaderSelectMediaPath": "Selecteer Media Pad", + "HeaderSelectPath": "Selecteer Pad", "ButtonNetwork": "Netwerk", "MessageDirectoryPickerInstruction": "Netwerk paden kunnen handmatig worden ingevoerd in het geval de Netwerk knop faalt om uw apparatuur te lokaliseren . Bijvoorbeeld: {0} of {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/pl.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/pl.json index 0a2f010fe..1e8b9aed5 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/pl.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/pl.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Zapisz", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json index bd52e6edb..5ccd6af43 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json @@ -6,8 +6,8 @@ "Administrator": "Administrador", "Password": "Senha", "DeleteImage": "Excluir Imagem", - "MessageThankYouForSupporting": "Thank you for supporting Media Browser.", - "MessagePleaseSupportMediaBrowser": "Please support Media Browser.", + "MessageThankYouForSupporting": "Obrigado por apoiar o Media Browser", + "MessagePleaseSupportMediaBrowser": "Por favor, ap\u00f3ie o Media Browser.", "DeleteImageConfirmation": "Deseja realmente excluir esta imagem?", "FileReadCancelled": "A leitura do arquivo foi cancelada.", "FileNotFound": "Arquivo n\u00e3o encontrado.", @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Obrigado. Sua chave de colaborador foi removida.", "ErrorLaunchingChromecast": "Ocorreu um erro ao iniciar o chromecast. Por favor verifique se seu dispositivo est\u00e1 conectado \u00e0 sua rede sem fio.", "HeaderSearch": "Busca", + "ValueDateCreated": "Data da cria\u00e7\u00e3o: {0}", "LabelArtist": "Artista", "LabelMovie": "Filme", "LabelMusicVideo": "V\u00eddeo Musical", @@ -44,9 +45,17 @@ "LabelFailed": "(falhou)", "ButtonHelp": "Ajuda", "ButtonSave": "Salvar", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Adicionar \u00e0 Cole\u00e7\u00e3o", + "NewCollectionNameExample": "Exemplo: Cole\u00e7\u00e3o Star Wars", + "OptionSearchForInternetMetadata": "Buscar artwork e metadados na internet", + "LabelSelectCollection": "Selecione cole\u00e7\u00e3o:", "HeaderDevices": "Dispositivos", - "ButtonScheduledTasks": "Scheduled tasks", - "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", + "ButtonScheduledTasks": "Tarefas Agendadas", + "MessageItemsAdded": "Itens adicionados", + "ButtonAddToCollection": "Adicionar \u00e0 Cole\u00e7\u00e3o", + "HeaderSelectCertificatePath": "Selecione o Caminho do Certificado", + "ConfirmMessageScheduledTaskButton": "Esta opera\u00e7\u00e3o normalmente \u00e9 executada automaticamente como uma tarefa agendada. Tamb\u00e9m pode ser executada manualmente. Para configurar a tarefa agendada, veja:", "HeaderSupporterBenefit": "A ades\u00e3o de colaborador fornece benef\u00edcios adicionais como acesso a plugins premium, canais de conte\u00fado da internet e mais. {0}Saiba mais{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Bem Vindo ao Painel do Media Browser", "HeaderWelcomeToMediaBrowserWebClient": "Bem-vindo ao Cliente Web do Media Browser", @@ -58,10 +67,10 @@ "HeaderChannelAccess": "Acesso ao Canal", "HeaderDeviceAccess": "Acesso ao Dispositivo", "HeaderSelectDevices": "Selecionar Dispositivos", - "ButtonCancelItem": "Cancel item", - "ButtonQueueForRetry": "Queue for retry", - "ButtonReenable": "Re-enable", - "SyncJobItemStatusSyncedMarkForRemoval": "Marked for removal", + "ButtonCancelItem": "Cancelar item", + "ButtonQueueForRetry": "Enfileirar para tentar novamente", + "ButtonReenable": "Reativar", + "SyncJobItemStatusSyncedMarkForRemoval": "Marcado para remo\u00e7\u00e3o", "LabelAbortedByServerShutdown": "(Abortada pelo desligamento do servidor)", "LabelScheduledTaskLastRan": "\u00daltima execu\u00e7\u00e3o {0}, demorando {1}.", "HeaderDeleteTaskTrigger": "Excluir Disparador da Tarefa", @@ -73,13 +82,13 @@ "LabelFree": "Gr\u00e1tis", "HeaderSelectAudio": "Selecione \u00c1udio", "HeaderSelectSubtitles": "Selecione Legendas", - "ButtonMarkForRemoval": "Mark for removal from device", - "ButtonUnmarkForRemoval": "Unmark for removal from device", + "ButtonMarkForRemoval": "Marcado para remo\u00e7\u00e3o do dispositivo", + "ButtonUnmarkForRemoval": "Desmarcado para remo\u00e7\u00e3o do dispositivo", "LabelDefaultStream": "(Padr\u00e3o)", "LabelForcedStream": "(For\u00e7ada)", "LabelDefaultForcedStream": "(Padr\u00e3o\/For\u00e7ada)", "LabelUnknownLanguage": "Idioma desconhecido", - "MessageConfirmSyncJobItemCancellation": "Are you sure you wish to cancel this item?", + "MessageConfirmSyncJobItemCancellation": "Deseja realmente cancelar este item?", "ButtonMute": "Mudo", "ButtonUnmute": "Remover Mudo", "ButtonStop": "Parar", @@ -203,10 +212,10 @@ "LabelPlayMethodDirectPlay": "Reprodu\u00e7\u00e3o Direta", "LabelAudioCodec": "\u00c1udio: {0}", "LabelVideoCodec": "V\u00eddeo: {0}", - "LabelLocalAccessUrl": "Local access: {0}", + "LabelLocalAccessUrl": "Acesso local: {0}", "LabelRemoteAccessUrl": "Acesso Remoto: {0}", - "LabelRunningOnPort": "Running on http port {0}.", - "LabelRunningOnPorts": "Running on http port {0}, and https port {1}.", + "LabelRunningOnPort": "Executando na porta http {0}.", + "LabelRunningOnPorts": "Executando na porta http {0} e porta https {1}.", "HeaderLatestFromChannel": "Mais recentes de {0}", "ButtonDownload": "Download", "LabelUnknownLanaguage": "Idioma desconhecido", @@ -220,6 +229,7 @@ "ButtonRefresh": "Atualizar", "LabelCurrentPath": "Caminho atual:", "HeaderSelectMediaPath": "Selecionar o Caminho da M\u00eddia", + "HeaderSelectPath": "Selecione o Caminho", "ButtonNetwork": "Rede", "MessageDirectoryPickerInstruction": "Os caminhos da rede podem ser digitados manualmente caso o bot\u00e3o de Rede n\u00e3o consiga localizar seus dispositivos. Por exemplo, {0} ou {1}.", "HeaderMenu": "Menu", @@ -230,7 +240,7 @@ "ButtonResume": "Retomar", "HeaderScenes": "Cenas", "HeaderAudioTracks": "Faixas de Audio", - "HeaderLibraries": "Libraries", + "HeaderLibraries": "Bibliotecas", "HeaderSubtitles": "Legendas", "HeaderVideoQuality": "Qualidade do V\u00eddeo", "MessageErrorPlayingVideo": "Houve um erro na reprodu\u00e7\u00e3o do v\u00eddeo.", @@ -597,7 +607,7 @@ "MediaInfoRefFrames": "Quadros de refer\u00eancia", "TabPlayback": "Reprodu\u00e7\u00e3o", "TabNotifications": "Notifica\u00e7\u00f5es", - "TabExpert": "Expert", + "TabExpert": "Avan\u00e7ado", "HeaderSelectCustomIntrosPath": "Selecionar o Caminho para Intros Personalizadas", "HeaderRateAndReview": "Avaliar e Comentar", "HeaderThankYou": "Obrigado", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json index 800d41556..2c5786f09 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(falhou)", "ButtonHelp": "Help", "ButtonSave": "Guardar", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Exemplo: Cole\u00e7\u00e3o Guerra das Estrelas", + "OptionSearchForInternetMetadata": "Procurar na internet por imagens e metadados", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json index 5b190421a..42db41588 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "\u041a\u043b\u044e\u0447 \u0441\u043f\u043e\u043d\u0441\u043e\u0440\u0430 \u0431\u044b\u043b \u0443\u0434\u0430\u043b\u0451\u043d.", "ErrorLaunchingChromecast": "\u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 Chromecast. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0432\u0430\u0448\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u043a \u0431\u0435\u0441\u043f\u0440\u043e\u0432\u043e\u0434\u043d\u043e\u0439 \u0441\u0435\u0442\u0438.", "HeaderSearch": "\u041f\u043e\u0438\u0441\u043a", + "ValueDateCreated": "\u0414\u0430\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f: {0}", "LabelArtist": "\u0418\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c", "LabelMovie": "\u0424\u0438\u043b\u044c\u043c", "LabelMusicVideo": "\u041c\u0443\u0437\u044b\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0438\u0434\u0435\u043e", @@ -44,9 +45,17 @@ "LabelFailed": "(\u043d\u0435\u0443\u0434\u0430\u0447\u043d\u043e)", "ButtonHelp": "\u0421\u043f\u0440\u0430\u0432\u043a\u0430", "ButtonSave": "\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c", + "LabelCollection": "Collection", + "HeaderAddToCollection": "\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438", + "NewCollectionNameExample": "\u041f\u0440\u0438\u043c\u0435\u0440: \u0417\u0432\u0451\u0437\u0434\u043d\u044b\u0435 \u0432\u043e\u0439\u043d\u044b (\u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f)", + "OptionSearchForInternetMetadata": "\u0418\u0441\u043a\u0430\u0442\u044c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435", + "LabelSelectCollection": "\u0412\u044b\u0431\u043e\u0440 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438:", "HeaderDevices": "\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430", "ButtonScheduledTasks": "\u041f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0443", - "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", + "MessageItemsAdded": "\u042d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b", + "ButtonAddToCollection": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438", + "HeaderSelectCertificatePath": "\u0412\u044b\u0431\u043e\u0440 \u043f\u0443\u0442\u0438 \u043a \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0443", + "ConfirmMessageScheduledTaskButton": "\u042d\u0442\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043e\u0431\u044b\u0447\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043a\u0430\u043a \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430. \u042d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043e \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043e\u0442\u0441\u044e\u0434\u0430. \u0427\u0442\u043e\u0431\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443, \u0441\u043c.:", "HeaderSupporterBenefit": "\u0427\u043b\u0435\u043d\u0441\u0442\u0432\u043e \u0441\u043f\u043e\u043d\u0441\u043e\u0440\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043e\u0441\u0442\u0443\u043f \u043a\u043e \u043f\u0440\u0435\u043c\u0438\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u043c, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u043a\u0430\u043d\u0430\u043b\u043e\u0432 \u0438 \u043c\u043d\u043e\u0433\u043e\u043c\u0443 \u0434\u0440\u0443\u0433\u043e\u043c\u0443. {0}\u0423\u0437\u043d\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u043c \u0432 \u0418\u043d\u0444\u043e\u043f\u0430\u043d\u0435\u043b\u0438 Media Browser", "HeaderWelcomeToMediaBrowserWebClient": "\u0412\u0435\u0431-\u043a\u043b\u0438\u0435\u043d\u0442 Media Browser \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u0430\u0441!", @@ -220,6 +229,7 @@ "ButtonRefresh": "\u041f\u043e\u0434\u043d\u043e\u0432\u0438\u0442\u044c", "LabelCurrentPath": "\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u0443\u0442\u044c:", "HeaderSelectMediaPath": "\u0412\u044b\u0431\u043e\u0440 \u043f\u0443\u0442\u0438 \u043c\u0435\u0434\u0438\u0430\u0434\u0430\u043d\u043d\u044b\u0445", + "HeaderSelectPath": "\u0412\u044b\u0431\u043e\u0440 \u043f\u0443\u0442\u0438", "ButtonNetwork": "\u0421\u0435\u0442\u044c", "MessageDirectoryPickerInstruction": "\u0421\u0435\u0442\u0435\u0432\u044b\u0435 \u043f\u0443\u0442\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432\u0432\u0435\u0441\u0442\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u0432 \u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u00ab\u0421\u0435\u0442\u044c\u00bb \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441\u0431\u043e\u0439 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: {0} \u0438\u043b\u0438 {1}.", "HeaderMenu": "\u041c\u0435\u043d\u044e", @@ -364,7 +374,7 @@ "ButtonViewSeriesRecording": "\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u044c \u0441\u0435\u0440\u0438\u0430\u043b\u0430", "ValueOriginalAirDate": "\u0414\u0430\u0442\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u044d\u0444\u0438\u0440\u0430: {0}", "ButtonRemoveFromPlaylist": "\u0418\u0437\u044a\u044f\u0442\u044c \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u0432\u043e\u0441\u043f\u0440-\u0438\u044f", - "HeaderSpecials": "\u0421\u043f\u0435\u0446\u044d\u043f\u0438\u0437\u043e\u0434\u044b", + "HeaderSpecials": "\u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435", "HeaderTrailers": "\u0422\u0440\u0435\u0439\u043b\u0435\u0440\u044b", "HeaderAudio": "\u0410\u0443\u0434\u0438\u043e", "HeaderResolution": "\u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json index 9f63be2e5..fdc185a7f 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Tack. Din donationskod har raderats.", "ErrorLaunchingChromecast": "Det gick inte att starta Chromecast. Kontrollera att enheten \u00e4r ansluten till det tr\u00e5dl\u00f6sa n\u00e4tverket.", "HeaderSearch": "S\u00f6k", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Film", "LabelMusicVideo": "Musikvideo", @@ -44,8 +45,16 @@ "LabelFailed": "(misslyckades)", "ButtonHelp": "Hj\u00e4lp", "ButtonSave": "Spara", + "LabelCollection": "Collection", + "HeaderAddToCollection": "L\u00e4gg till samling", + "NewCollectionNameExample": "Exemple: Star Wars-samling", + "OptionSearchForInternetMetadata": "S\u00f6k p\u00e5 internet efter grafik och metadata", + "LabelSelectCollection": "V\u00e4lj samling:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "V\u00e4lkommen till Media Browsers kontrollpanel", @@ -220,6 +229,7 @@ "ButtonRefresh": "Uppdatera", "LabelCurrentPath": "Aktuell s\u00f6kv\u00e4g:", "HeaderSelectMediaPath": "V\u00e4lj s\u00f6kv\u00e4g till media", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "N\u00e4tverk", "MessageDirectoryPickerInstruction": "N\u00e4tverkss\u00f6kv\u00e4gar kan anges manuellt om \"N\u00e4tverk\" inte hittar dina enheter. T ex {0} eller {1}.", "HeaderMenu": "Meny", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/tr.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/tr.json index 303434ccc..d0bec1810 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/tr.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/tr.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Kay\u0131t", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/uk.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/uk.json index 60aacc130..c3d591bd2 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/uk.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/uk.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Save", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json index 862dc731e..09a98cccf 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "L\u01b0u", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_CN.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_CN.json index 56ad8b3ef..c853a83c3 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_CN.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_CN.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "\u8c22\u8c22\u3002\u4f60\u7684\u652f\u6301\u8005\u5e8f\u53f7\u5df2\u79fb\u9664\u3002", "ErrorLaunchingChromecast": "\u542f\u52a8chromecast\u9047\u5230\u9519\u8bef\uff0c\u8bf7\u786e\u8ba4\u8bbe\u5907\u5df2\u7ecf\u8fde\u63a5\u5230\u4f60\u7684\u65e0\u7ebf\u7f51\u7edc\u3002", "HeaderSearch": "\u641c\u7d22", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "\u827a\u672f\u5bb6", "LabelMovie": "\u7535\u5f71", "LabelMusicVideo": "\u97f3\u4e50\u89c6\u9891", @@ -44,8 +45,16 @@ "LabelFailed": "(\u5931\u8d25)", "ButtonHelp": "Help", "ButtonSave": "\u50a8\u5b58", + "LabelCollection": "Collection", + "HeaderAddToCollection": "\u52a0\u5165\u5408\u96c6", + "NewCollectionNameExample": "\u4f8b\u5982\uff1a\u661f\u7403\u5927\u6218\u5408\u96c6", + "OptionSearchForInternetMetadata": "\u5728\u4e92\u8054\u7f51\u4e0a\u641c\u7d22\u5a92\u4f53\u56fe\u50cf\u548c\u8d44\u6599", + "LabelSelectCollection": "\u9009\u62e9\u5408\u96c6\uff1a", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "\u5237\u65b0", "LabelCurrentPath": "\u5f53\u524d\u8def\u5f84\uff1a", "HeaderSelectMediaPath": "\u9009\u62e9\u5a92\u4f53\u8def\u5f84", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "\u7f51\u7edc", "MessageDirectoryPickerInstruction": "\u7f51\u7edc\u6309\u94ae\u65e0\u6cd5\u627e\u5230\u60a8\u7684\u8bbe\u5907\u7684\u60c5\u51b5\u4e0b\uff0c\u7f51\u7edc\u8def\u5f84\u53ef\u4ee5\u624b\u52a8\u8f93\u5165\u3002 \u4f8b\u5982\uff0c {0} \u6216\u8005 {1}\u3002", "HeaderMenu": "\u83dc\u5355", diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json index 5a18d4f7f..ede237bf6 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json @@ -34,6 +34,7 @@ "MessageKeyRemoved": "Thank you. Your supporter key has been removed.", "ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.", "HeaderSearch": "Search", + "ValueDateCreated": "Date created: {0}", "LabelArtist": "Artist", "LabelMovie": "Movie", "LabelMusicVideo": "Music Video", @@ -44,8 +45,16 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "\u4fdd\u5b58", + "LabelCollection": "Collection", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "\u4f8b\u5b50\uff1a\u661f\u7403\u5927\u6230\u5408\u96c6", + "OptionSearchForInternetMetadata": "\u5728\u4e92\u806f\u7db2\u4e0a\u641c\u7d22\u5a92\u9ad4\u5716\u50cf\u548c\u8cc7\u6599", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", + "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", "HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard", @@ -220,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ar.json b/MediaBrowser.Server.Implementations/Localization/Server/ar.json index 73f3d31f1..394976335 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/ar.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/ar.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/bg_BG.json b/MediaBrowser.Server.Implementations/Localization/Server/bg_BG.json index 5f6754776..72a70e4c9 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/bg_BG.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/bg_BG.json @@ -26,435 +26,441 @@ "LabelWindowsService": "Windows Service", "AWindowsServiceHasBeenInstalled": "Windows Service \u0431\u0435\u0448\u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d.", "WindowsServiceIntro1": "Media Browser Server \u043e\u0431\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0438 \u043a\u0430\u0442\u043e \u0434\u0435\u0441\u043a\u0442\u043e\u043f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 tray \u0438\u043a\u043e\u043d\u0430, \u043d\u043e \u0430\u043a\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0442\u0435 \u0434\u0430 \u0433\u043e \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0442\u0435 \u043a\u0430\u0442\u043e \u0443\u0441\u043b\u0443\u0433\u0430 \u0432\u044a\u0432 \u0444\u043e\u043d\u043e\u0432 \u0440\u0435\u0436\u0438\u043c, \u0442\u043e\u0439 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u043e\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043d\u0438\u044f \u043f\u0430\u043d\u0435\u043b \u043d\u0430 Windows Services.", - "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 Server 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.", - "HeaderTermsOfService": "Media Browser Terms of Service", - "MessagePleaseAcceptTermsOfService": "Please accept the terms of service and privacy policy before continuing.", - "OptionIAcceptTermsOfService": "I accept the terms of service", - "ButtonPrivacyPolicy": "Privacy policy", - "ButtonTermsOfService": "Terms of Service", - "HeaderDeveloperOptions": "Developer Options", - "OptionEnableWebClientResponseCache": "Enable web client response caching", - "OptionDisableForDevelopmentHelp": "Configure these as needed for web client development purposes.", - "OptionEnableWebClientResourceMinification": "Enable web client resource minification", - "LabelDashboardSourcePath": "Web client source path:", - "LabelDashboardSourcePathHelp": "If running the server from source, specify the path to the dashboard-ui folder. All web client files will be served from this location.", - "ButtonConvertMedia": "Convert media", - "ButtonOrganize": "Organize", - "ButtonOk": "Ok", - "ButtonCancel": "Cancel", - "ButtonNew": "New", + "WindowsServiceIntro2": "\u0410\u043a\u043e \u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435 Windows \u0443\u0441\u043b\u0443\u0433\u0430\u0442\u0430, \u043c\u043e\u043b\u044f, \u0438\u043c\u0430\u0439\u0442\u0435 \u043f\u0440\u0435\u0434\u0432\u0438\u0434, \u0447\u0435 \u0442\u043e\u0439 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043f\u0443\u0441\u043d\u0430\u0442 \u0434\u043e\u043a\u0430\u0442\u043e \u044f \u0438\u043c\u0430 \u0438\u043a\u043e\u043d\u0430\u0442\u0430 \u0432 \u043b\u0435\u043d\u0442\u0430\u0442\u0430 ,\u0442\u0430\u043a\u0430 \u0447\u0435 \u0449\u0435 \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0438\u0437\u043b\u0435\u0437\u0435\u0442\u0435 \u043e\u0442 \u043d\u0435\u044f, \u0437\u0430 \u0434\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u0443\u0441\u043b\u0443\u0433\u0430\u0442\u0430. \u0423\u0441\u043b\u0443\u0433\u0430\u0442\u0430 \u0441\u044a\u0449\u043e \u0442\u0430\u043a\u0430 \u0449\u0435 \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u043d\u0430 \u0441 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043d\u0438 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0438 \u0447\u0440\u0435\u0437 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043d\u0438\u044f \u043f\u0430\u043d\u0435\u043b. \u041c\u043e\u043b\u044f, \u0438\u043c\u0430\u0439\u0442\u0435 \u043f\u0440\u0435\u0434\u0432\u0438\u0434, \u0447\u0435 \u0432 \u0442\u043e\u0437\u0438 \u043c\u043e\u043c\u0435\u043d\u0442 \u0443\u0441\u043b\u0443\u0433\u0430\u0442\u0430 \u043d\u0435 \u0435 \u0432 \u0441\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u0430 \u0441\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u0430 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u043d\u043e, \u0442\u0430\u043a\u0430 \u0447\u0435 \u043d\u043e\u0432\u0438\u0442\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u0449\u0435 \u0438\u0437\u0438\u0441\u043a\u0432\u0430\u0442 \u0440\u044a\u0447\u043d\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435.", + "WizardCompleted": "\u0422\u043e\u0432\u0430 \u0435 \u0432\u0441\u0438\u0447\u043a\u043e \u043e\u0442 \u043a\u043e\u0435\u0442\u043e \u0441\u0435 \u043d\u0443\u0436\u0434\u0430\u0435\u043c \u0437\u0430\u0441\u0435\u0433\u0430. Media Browser \u0435 \u0437\u0430\u043f\u043e\u0447\u043d\u0430\u043b \u0434\u0430 \u0441\u044a\u0431\u0438\u0440\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u0432\u0430\u0448\u0430\u0442\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430. \u0412\u0438\u0436\u0442\u0435 \u043d\u044f\u043a\u043e\u0438 \u043e\u0442 \u043d\u0430\u0448\u0438\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0430 \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0442\u0438\u0441\u043d\u0435\u0442\u0435 \u041a\u0440\u0430\u0439<\/b>. \u0437\u0430 \u0434\u0430 \u0432\u0438\u0434\u0438\u0442\u0435 \u0413\u043b\u0430\u0432\u0435\u043d \u043f\u0430\u043d\u0435\u043b \u043d\u0430 \u0441\u044a\u0440\u0432\u044a\u0440\u0430<\/b>.", + "LabelConfigureSettings": "\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438", + "LabelEnableVideoImageExtraction": "\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0432\u043b\u0438\u0447\u0430\u043d\u0435 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.", + "VideoImageExtractionHelp": "\u0417\u0430 \u0432\u0438\u0434\u0435\u043e\u043a\u043b\u0438\u043f\u043e\u0432\u0435, \u043a\u043e\u0438\u0442\u043e \u0432\u0441\u0435 \u043e\u0449\u0435 \u043d\u0435 \u0440\u0430\u0437\u043f\u043e\u043b\u0430\u0433\u0430\u0442 \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0438 \u0437\u0430 \u043a\u043e\u0438\u0442\u043e \u043d\u0435 \u0441\u043c\u0435 \u0432 \u0441\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u0430 \u043d\u0430\u043c\u0435\u0440\u0438\u043c \u0442\u0430\u043a\u0438\u0432\u0430. \u0422\u043e\u0432\u0430 \u0449\u0435 \u0434\u043e\u0431\u0430\u0432\u0438 \u0434\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u043e \u0432\u0440\u0435\u043c\u0435 \u043a\u044a\u043c \u043f\u044a\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u043d\u043e\u0442\u043e \u0441\u043a\u0430\u043d\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0442\u0430, \u043d\u043e \u0449\u0435 \u0434\u043e\u0432\u0435\u0434\u0435 \u0434\u043e \u043f\u043e-\u043f\u0440\u0438\u044f\u0442\u0435\u043d \u0432\u0438\u0434.", + "LabelEnableChapterImageExtractionForMovies": "\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u0438\u0437\u0432\u043b\u0438\u0447\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0433\u043b\u0430\u0432\u0438\u0442\u0435 \u0437\u0430 \u0424\u0438\u043b\u043c\u0438.", + "LabelChapterImageExtractionForMoviesHelp": "\u0418\u0437\u0432\u043b\u0438\u0447\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0433\u043b\u0430\u0432\u0438\u0442\u0435 \u0449\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0438\u0442\u0435 \u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u0432\u0430\u0442 \u0433\u0440\u0430\u0444\u0438\u0447\u043d\u0438 \u043c\u0435\u043d\u044e\u0442\u0430 \u0437\u0430 \u0438\u0437\u0431\u043e\u0440 \u043d\u0430 \u0441\u0446\u0435\u043d\u0430. \u041f\u0440\u043e\u0446\u0435\u0441\u044a\u0442 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u0431\u0430\u0432\u0435\u043d, CPU-\u0438\u043d\u0442\u0435\u043d\u0437\u0438\u0432\u0435\u043d \u0438 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u043d\u044f\u043a\u043e\u043b\u043a\u043e \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442\u0430 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e. \u0422\u043e \u0440\u0430\u0431\u043e\u0442\u0438 \u043a\u0430\u0442\u043e \u043d\u043e\u0449\u043d\u0430 \u043f\u043b\u0430\u043d\u0438\u0440\u0430\u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0432 4 \u0447\u0430\u0441\u0430 \u0441\u0443\u0442\u0440\u0438\u043d\u0442\u0430, \u0432\u044a\u043f\u0440\u0435\u043a\u0438 \u0447\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430 \u0432 \u041f\u043b\u0430\u043d\u0438\u0440\u0430\u043d\u0438 \u0437\u0430\u0434\u0430\u0447\u0438. \u041d\u0435 \u0441\u0435 \u043f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0432\u0430 \u0442\u0430\u0437\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430 \u043f\u043e \u0432\u0440\u0435\u043c\u0435 \u043d\u0430 \u043f\u0438\u043a\u043e\u0432\u0438\u0442\u0435 \u0447\u0430\u0441\u043e\u0432\u0435 \u043d\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435.", + "LabelEnableAutomaticPortMapping": "\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0430 \u043f\u043e\u0440\u0442\u043e\u0432\u0435\u0442\u0435", + "LabelEnableAutomaticPortMappingHelp": "UPnP \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0432\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043d\u0430 \u0440\u0443\u0442\u0435\u0440\u0430 \u0437\u0430 \u043b\u0435\u0441\u0435\u043d \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d \u0434\u043e\u0441\u0442\u044a\u043f. \u0422\u043e\u0432\u0430 \u043c\u043e\u0436\u0435 \u0434\u0430 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0438 \u0441 \u043d\u044f\u043a\u043e\u0438 \u0440\u0443\u0442\u0435\u0440\u0438.", + "HeaderTermsOfService": "Media Browser \u0423\u0441\u043b\u043e\u0432\u0438\u044f \u0437\u0430 \u041f\u043e\u043b\u0437\u0432\u0430\u043d\u0435", + "MessagePleaseAcceptTermsOfService": "\u041c\u043e\u043b\u044f \u043f\u0440\u0438\u0435\u043c\u0435\u0442\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0442\u0430 \u0437\u0430 \u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435 \u0438 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u044f\u0442\u0430 \u0437\u0430 \u043f\u043e\u0432\u0435\u0440\u0438\u0442\u0435\u043b\u043d\u043e\u0441\u0442, \u043f\u0440\u0435\u0434\u0438 \u0434\u0430 \u043f\u0440\u043e\u0434\u044a\u043b\u0436\u0438\u0442\u0435.", + "OptionIAcceptTermsOfService": "\u041f\u0440\u0438\u0435\u043c\u0430\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0442\u0430 \u0437\u0430 \u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435", + "ButtonPrivacyPolicy": "\u0414\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u044f \u0437\u0430 \u043f\u043e\u0432\u0435\u0440\u0438\u0442\u0435\u043b\u043d\u043e\u0441\u0442", + "ButtonTermsOfService": "\u0423\u0441\u043b\u043e\u0432\u0438\u044f \u0437\u0430 \u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435", + "HeaderDeveloperOptions": "\u041e\u043f\u0446\u0438\u0438 \u0437\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u0446\u0438", + "OptionEnableWebClientResponseCache": "\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u043a\u0435\u0448\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043e\u0442\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0435 \u043d\u0430 \u0443\u0435\u0431 \u043a\u043b\u0438\u0435\u043d\u0442\u0438\u0442\u0435", + "OptionDisableForDevelopmentHelp": "\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u0439\u0442\u0435 \u0442\u0435\u0437\u0438 \u0441\u043f\u043e\u0440\u0435\u0434 \u043d\u0443\u0436\u0434\u0438\u0442\u0435 \u0437\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043d\u0430 \u0443\u0435\u0431 \u043a\u043b\u0438\u0435\u043d\u0442\u0438.", + "OptionEnableWebClientResourceMinification": "\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u0441\u043c\u0430\u043b\u044f\u0432\u0430\u043d\u0435(\u043c\u0438\u043d\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f) \u043d\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u0438\u0442\u0435 \u043d\u0430 \u0443\u0435\u0431 \u043a\u043b\u0438\u0435\u043d\u0442\u0430", + "LabelDashboardSourcePath": "\u0413\u043b\u0430\u0432\u0435\u043d \u043f\u044a\u0442 \u043a\u044a\u043c \u0443\u0435\u0431 \u043a\u043b\u0438\u0435\u043d\u0442\u0430", + "LabelDashboardSourcePathHelp": "\u0410\u043a\u043e \u043f\u0443\u0441\u043a\u0430\u0442\u0435 \u0441\u044a\u0440\u0432\u044a\u0440\u0430 \u043e\u0442 \u0438\u0437\u0445\u043e\u0434\u0435\u043d \u043a\u043e\u0434, \u043f\u043e\u0441\u043e\u0447\u0435\u0442\u0435 \u043f\u044a\u0442\u044f \u043a\u044a\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u043e\u0442\u043e \u0442\u0430\u0431\u043b\u043e. \u0412\u0441\u0438\u0447\u043a\u0438 \u0443\u0435\u0431 \u043a\u043b\u0438\u0435\u043d\u0442\u0438 \u0449\u0435 \u0431\u044a\u0434\u0430\u0442 \u043e\u0431\u0441\u043b\u0443\u0436\u0432\u0430\u043d\u0438 \u043e\u0442 \u0442\u0430\u043c.", + "ButtonConvertMedia": "\u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0430\u0439 \u043c\u0435\u0434\u0438\u044f\u0442\u0430", + "ButtonOrganize": "\u041e\u0440\u0433\u0430\u043d\u0438\u0437\u0438\u0440\u0430\u0439", + "ButtonOk": "\u041e\u043a", + "ButtonCancel": "\u041e\u0442\u043c\u0435\u043d\u0438", + "ButtonNew": "\u041d\u043e\u0432", "HeaderTV": "TV", - "HeaderAudio": "Audio", - "HeaderVideo": "Video", - "HeaderPaths": "Paths", - "TitleNotifications": "Notifications", - "ButtonDonateWithPayPal": "Donate with PayPal", - "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", - "OptionDetectArchiveFilesAsMediaHelp": "If enabled, files with .rar and .zip extensions will be detected as media files.", - "LabelEnterConnectUserName": "User name or email:", - "LabelEnterConnectUserNameHelp": "This is your Media Browser online account user name or password.", - "HeaderSyncJobInfo": "Sync Job", - "FolderTypeMixed": "Mixed content", - "FolderTypeMovies": "Movies", - "FolderTypeMusic": "Music", - "FolderTypeAdultVideos": "Adult videos", - "FolderTypePhotos": "Photos", - "FolderTypeMusicVideos": "Music videos", - "FolderTypeHomeVideos": "Home videos", - "FolderTypeGames": "Games", - "FolderTypeBooks": "Books", + "HeaderAudio": "\u0410\u0443\u0434\u0438\u043e", + "HeaderVideo": "\u0412\u0438\u0434\u0435\u043e", + "HeaderPaths": "\u041f\u044a\u0442\u0438\u0449\u0430", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", + "TitleNotifications": "\u0418\u0437\u0432\u0435\u0441\u0442\u0438\u044f", + "ButtonDonateWithPayPal": "\u041d\u0430\u043f\u0440\u0430\u0432\u0438 \u0434\u0430\u0440\u0435\u043d\u0438\u0435 \u0441 PayPal", + "OptionDetectArchiveFilesAsMedia": "\u0420\u0430\u0437\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0430\u0440\u0445\u0438\u0432\u0438 \u043a\u0430\u0442\u043e \u043c\u0435\u0434\u0438\u0439\u043d\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0435", + "OptionDetectArchiveFilesAsMediaHelp": "\u0410\u043a\u043e \u0435 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u043e, \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0441 \u0440\u0430\u0437\u0448\u0438\u0440\u0435\u043d\u0438\u044f .rar \u0438 .zip \u0449\u0435 \u0431\u044a\u0434\u0430\u0442 \u0440\u0430\u0437\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438 \u043a\u0430\u0442\u043e \u043c\u0435\u0434\u0438\u0439\u043d\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0435.", + "LabelEnterConnectUserName": "\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u043e \u0438\u043c\u0435 \u0438\u043b\u0438 email:", + "LabelEnterConnectUserNameHelp": "\u0422\u043e\u0432\u0430 \u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u043e\u0442\u043e \u0438\u043c\u0435 \u0438\u043b\u0438 \u043f\u0430\u0440\u043e\u043b\u0430\u0442\u0430 \u043d\u0430 \u0432\u0430\u0448\u0438\u044f Media Brower \u043e\u043d\u043b\u0430\u0439\u043d \u0430\u043a\u0430\u0443\u043d\u0442.", + "HeaderSyncJobInfo": "\u0421\u0438\u043d\u0445\u0440. \u0417\u0430\u0434\u0430\u0447\u0430", + "FolderTypeMixed": "\u0421\u043c\u0435\u0441\u0435\u043d\u043e \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435", + "FolderTypeMovies": "\u0424\u0438\u043b\u043c\u0438", + "FolderTypeMusic": "\u041c\u0443\u0437\u0438\u043a\u0430", + "FolderTypeAdultVideos": "\u041a\u043b\u0438\u043f\u043e\u0432\u0435 \u0437\u0430 \u0432\u044a\u0437\u0440\u0430\u0441\u0442\u043d\u0438", + "FolderTypePhotos": "\u0421\u043d\u0438\u043c\u043a\u0438", + "FolderTypeMusicVideos": "\u041c\u0443\u0437\u0438\u043a\u0430\u043b\u043d\u0438 \u043a\u043b\u0438\u043f\u043e\u0432\u0435", + "FolderTypeHomeVideos": "\u0414\u043e\u043c\u0430\u0448\u043d\u0438 \u043a\u043b\u0438\u043f\u043e\u0432\u0435", + "FolderTypeGames": "\u0418\u0433\u0440\u0438", + "FolderTypeBooks": "\u041a\u043d\u0438\u0433\u0438", "FolderTypeTvShows": "TV", - "FolderTypeInherit": "Inherit", - "LabelContentType": "Content type:", - "TitleScheduledTasks": "Scheduled Tasks", - "HeaderSetupLibrary": "Setup your media library", - "ButtonAddMediaFolder": "Add media folder", - "LabelFolderType": "Folder type:", - "ReferToMediaLibraryWiki": "Refer to the media library wiki.", - "LabelCountry": "Country:", - "LabelLanguage": "Language:", - "ButtonJoinTheDevelopmentTeam": "Join the Development Team", - "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.", - "TabPreferences": "Preferences", - "TabPassword": "Password", - "TabLibraryAccess": "Library Access", - "TabAccess": "Access", - "TabImage": "Image", - "TabProfile": "Profile", - "TabMetadata": "Metadata", - "TabImages": "Images", - "TabNotifications": "Notifications", - "TabCollectionTitles": "Titles", - "HeaderDeviceAccess": "Device Access", - "OptionEnableAccessFromAllDevices": "Enable access from all devices", - "OptionEnableAccessToAllChannels": "Enable access to all channels", - "OptionEnableAccessToAllLibraries": "Enable access to all libraries", - "DeviceAccessHelp": "This only applies to devices that can be uniquely identified and will not prevent browser access. Filtering user device access will prevent them from using new devices until they've been approved here.", - "LabelDisplayMissingEpisodesWithinSeasons": "Display missing episodes within seasons", - "LabelUnairedMissingEpisodesWithinSeasons": "Display unaired episodes within seasons", - "HeaderVideoPlaybackSettings": "Video Playback Settings", - "HeaderPlaybackSettings": "Playback Settings", - "LabelAudioLanguagePreference": "Audio language preference:", - "LabelSubtitleLanguagePreference": "Subtitle language preference:", - "OptionDefaultSubtitles": "Default", - "OptionOnlyForcedSubtitles": "Only forced subtitles", - "OptionAlwaysPlaySubtitles": "Always play subtitles", - "OptionNoSubtitles": "No Subtitles", - "OptionDefaultSubtitlesHelp": "Subtitles matching the language preference will be loaded when the audio is in a foreign language.", - "OptionOnlyForcedSubtitlesHelp": "Only subtitles marked as forced will be loaded.", - "OptionAlwaysPlaySubtitlesHelp": "Subtitles matching the language preference will be loaded regardless of the audio language.", - "OptionNoSubtitlesHelp": "Subtitles will not be loaded by default.", - "TabProfiles": "Profiles", - "TabSecurity": "Security", - "ButtonAddUser": "Add User", - "ButtonAddLocalUser": "Add Local User", - "ButtonInviteUser": "Invite User", - "ButtonSave": "Save", - "ButtonResetPassword": "Reset Password", - "LabelNewPassword": "New password:", - "LabelNewPasswordConfirm": "New password confirm:", - "HeaderCreatePassword": "Create Password", - "LabelCurrentPassword": "Current password:", - "LabelMaxParentalRating": "Maximum allowed parental rating:", - "MaxParentalRatingHelp": "Content with a higher rating will be hidden from this user.", - "LibraryAccessHelp": "Select the media folders to share with this user. Administrators will be able to edit all folders using the metadata manager.", - "ChannelAccessHelp": "Select the channels to share with this user. Administrators will be able to edit all channels using the metadata manager.", - "ButtonDeleteImage": "Delete Image", - "LabelSelectUsers": "Select users:", - "ButtonUpload": "Upload", - "HeaderUploadNewImage": "Upload New Image", - "LabelDropImageHere": "Drop image here", - "ImageUploadAspectRatioHelp": "1:1 Aspect Ratio Recommended. JPG\/PNG only.", - "MessageNothingHere": "Nothing here.", - "MessagePleaseEnsureInternetMetadata": "Please ensure downloading of internet metadata is enabled.", - "TabSuggested": "Suggested", - "TabLatest": "Latest", - "TabUpcoming": "Upcoming", - "TabShows": "Shows", - "TabEpisodes": "Episodes", - "TabGenres": "Genres", - "TabPeople": "People", - "TabNetworks": "Networks", - "HeaderUsers": "Users", - "HeaderFilters": "Filters:", - "ButtonFilter": "Filter", - "OptionFavorite": "Favorites", - "OptionLikes": "Likes", - "OptionDislikes": "Dislikes", - "OptionActors": "Actors", - "OptionGuestStars": "Guest Stars", - "OptionDirectors": "Directors", - "OptionWriters": "Writers", - "OptionProducers": "Producers", - "HeaderResume": "Resume", - "HeaderNextUp": "Next Up", - "NoNextUpItemsMessage": "None found. Start watching your shows!", - "HeaderLatestEpisodes": "Latest Episodes", - "HeaderPersonTypes": "Person Types:", - "TabSongs": "Songs", - "TabAlbums": "Albums", - "TabArtists": "Artists", - "TabAlbumArtists": "Album Artists", - "TabMusicVideos": "Music Videos", - "ButtonSort": "Sort", - "HeaderSortBy": "Sort By:", - "HeaderSortOrder": "Sort Order:", - "OptionPlayed": "Played", - "OptionUnplayed": "Unplayed", - "OptionAscending": "Ascending", - "OptionDescending": "Descending", - "OptionRuntime": "Runtime", - "OptionReleaseDate": "Release Date", - "OptionPlayCount": "Play Count", - "OptionDatePlayed": "Date Played", - "OptionDateAdded": "Date Added", - "OptionAlbumArtist": "Album Artist", - "OptionArtist": "Artist", - "OptionAlbum": "Album", - "OptionTrackName": "Track Name", - "OptionCommunityRating": "Community Rating", + "FolderTypeInherit": "\u041d\u0430\u0441\u043b\u0435\u0434\u0438", + "LabelContentType": "\u0422\u0438\u043f \u043d\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435\u0442\u043e:", + "TitleScheduledTasks": "\u041f\u043b\u0430\u043d\u0438\u0440\u0430\u043d\u0438 \u0437\u0430\u0434\u0430\u0447\u0438", + "HeaderSetupLibrary": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u043c\u0435\u0434\u0438\u0439\u043d\u0430\u0442\u0430 \u0441\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430", + "ButtonAddMediaFolder": "\u0414\u043e\u0431\u0430\u0432\u0438 \u043c\u0435\u0434\u0438\u0439\u043d\u0430 \u043f\u0430\u043f\u043a\u0430", + "LabelFolderType": "\u0422\u0438\u043f \u043d\u0430 \u043f\u0430\u043f\u043a\u0430\u0442\u0430:", + "ReferToMediaLibraryWiki": "\u0414\u043e\u043f\u0438\u0442\u0430\u0439\u0442\u0435 \u0441\u0435 \u0434\u043e wiki \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0442\u0430 \u043d\u0430 \u043c\u0435\u0434\u0438\u0439\u043d\u0430\u0442\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430", + "LabelCountry": "\u0421\u0442\u0440\u0430\u043d\u0430:", + "LabelLanguage": "\u0415\u0437\u0438\u043a:", + "ButtonJoinTheDevelopmentTeam": "\u041f\u0440\u0438\u0441\u044a\u0435\u0434\u0438\u043d\u0435\u0442\u0435 \u0441\u0435 \u043a\u044a\u043c \u043e\u0442\u0431\u043e\u0440\u0430 \u043d\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u0446\u0438\u0442\u0435", + "HeaderPreferredMetadataLanguage": "\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u043d \u0435\u0437\u0438\u043a \u043d\u0430 \u043c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f\u0442\u0430:", + "LabelSaveLocalMetadata": "\u0417\u0430\u043f\u043e\u043c\u043d\u0438 \u0438\u0437\u043a\u0443\u0441\u0442\u0432\u043e \u0438 \u043c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0432 \u043f\u0430\u043f\u043a\u0430\u0442\u0430 \u043d\u0430 \u043c\u0435\u0434\u0438\u044f\u0442\u0430", + "LabelSaveLocalMetadataHelp": "\u0417\u0430\u043f\u043e\u043c\u043d\u044f\u043d\u0435\u0442\u043e \u043d\u0430 \u0438\u0437\u043a\u0443\u0441\u0442\u0432\u043e \u0438 \u043c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043d\u043e \u0432 \u043c\u0435\u0434\u0438\u0439\u043d\u0438\u0442\u0435 \u043f\u0430\u043f\u043a\u0438 \u0449\u0435 \u0433\u0438 \u0441\u043b\u043e\u0436\u0438 \u043d\u0430 \u043c\u044f\u0441\u0442\u043e, \u043a\u044a\u0434\u0435\u0442\u043e \u043b\u0435\u0441\u043d\u043e \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0431\u044a\u0434\u0430\u0442 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u043d\u0438.", + "LabelDownloadInternetMetadata": "\u0421\u0432\u0430\u043b\u044f\u0439 \u0438\u0437\u043a\u0443\u0441\u0442\u0432\u043e \u0438 \u043c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442", + "LabelDownloadInternetMetadataHelp": "Media Browser \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0432\u0430\u043b\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u0432\u0430\u0448\u0430\u0442\u0430 \u043c\u0435\u0434\u0438\u044f, \u043a\u043e\u0435\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0432\u0430 \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u0435.", + "TabPreferences": "\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u043d\u0438\u044f", + "TabPassword": "\u041f\u0430\u0440\u043e\u043b\u0430", + "TabLibraryAccess": "\u0414\u043e\u0441\u044a\u043f \u0434\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0442\u0430", + "TabAccess": "\u0414\u043e\u0441\u0442\u044a\u043f", + "TabImage": "\u041a\u0430\u0440\u0442\u0438\u043d\u0430", + "TabProfile": "\u041f\u0440\u043e\u0444\u0438\u043b", + "TabMetadata": "\u041c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f", + "TabImages": "\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f", + "TabNotifications": "\u0418\u0437\u0432\u0435\u0441\u0442\u0438\u044f", + "TabCollectionTitles": "\u0417\u0430\u0433\u043b\u0430\u0432\u0438\u044f", + "HeaderDeviceAccess": "\u0414\u043e\u0441\u0442\u044a\u043f \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0442\u0430", + "OptionEnableAccessFromAllDevices": "\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u0439 \u0434\u043e\u0441\u0442\u044a\u043f \u043e\u0442 \u0432\u0441\u0438\u0447\u043a\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430", + "OptionEnableAccessToAllChannels": "\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u0439 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u0432\u0441\u0438\u0447\u043a\u0438 \u043a\u0430\u043d\u0430\u043b\u0438", + "OptionEnableAccessToAllLibraries": "\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u0439 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u0432\u0441\u0438\u0447\u043a\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438", + "DeviceAccessHelp": "\u0422\u043e\u0432\u0430 \u0441\u0435 \u043e\u0442\u043d\u0430\u0441\u044f \u0441\u0430\u043c\u043e \u0437\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u043a\u043e\u0438\u0442\u043e \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0431\u044a\u0434\u0430\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u0435\u043d\u0438 \u0438 \u043d\u044f\u043c\u0430 \u0434\u0430 \u043f\u043e\u043f\u0440\u0435\u0447\u0438 \u043d\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u043e\u0442 \u0431\u0440\u0430\u0443\u0437\u044a\u0440. \u0424\u0438\u043b\u0442\u0440\u0438\u0440\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0449\u0435 \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435\u0442\u043e \u0438\u043c \u0434\u043e\u043a\u0430\u0442\u043e \u043d\u0435 \u0431\u044a\u0434\u0430\u0442 \u043e\u0434\u043e\u0431\u0440\u0435\u043d\u0438 \u0442\u0443\u043a.", + "LabelDisplayMissingEpisodesWithinSeasons": "\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u0439 \u043b\u0438\u043f\u0441\u0432\u0430\u0449\u0438 \u0435\u043f\u0438\u0437\u043e\u0434\u0438 \u0432 \u0441\u0435\u0437\u043e\u043d\u0438\u0442\u0435", + "LabelUnairedMissingEpisodesWithinSeasons": "\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u0439 \u043d\u0435\u0438\u0437\u043b\u044a\u0447\u0435\u043d\u0438 \u0435\u043f\u0438\u0437\u043e\u0434\u0438 \u0432 \u0441\u0435\u0437\u043e\u043d\u0438\u0442\u0435", + "HeaderVideoPlaybackSettings": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 \u0432\u044a\u0437\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0432\u0438\u0434\u0435\u043e", + "HeaderPlaybackSettings": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 \u0432\u044a\u0437\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435\u0442\u043e", + "LabelAudioLanguagePreference": "\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u043d \u0435\u0437\u0438\u043a \u043d\u0430 \u0430\u0443\u0434\u0438\u043e\u0442\u043e:", + "LabelSubtitleLanguagePreference": "\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u043d \u0435\u0437\u0438\u043a \u043d\u0430 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u0438\u0442\u0435:", + "OptionDefaultSubtitles": "\u041f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435", + "OptionOnlyForcedSubtitles": "\u0421\u0430\u043c\u043e \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u043d\u0438 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u0438", + "OptionAlwaysPlaySubtitles": "\u0412\u0438\u043d\u0430\u0433\u0438 \u043f\u043e\u043a\u0430\u0437\u0432\u0430\u0439 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u0438", + "OptionNoSubtitles": "\u0411\u0435\u0437 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u0438", + "OptionDefaultSubtitlesHelp": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u0438 \u043e\u0442\u0433\u043e\u0432\u0430\u0440\u044f\u0449\u0438 \u043d\u0430 \u0435\u0437\u0438\u043a\u043e\u0432\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u043d\u0438\u044f \u0449\u0435 \u0431\u044a\u0434\u0430\u0442 \u043f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0438, \u043a\u043e\u0433\u0430\u0442\u043e \u0430\u0443\u0434\u0438\u043e\u0442\u043e \u0435 \u043d\u0430 \u0434\u0440\u0443\u0433 \u0435\u0437\u0438\u043a.", + "OptionOnlyForcedSubtitlesHelp": "\u0421\u0430\u043c\u043e \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u0438, \u043c\u0430\u0440\u043a\u0438\u0440\u0430\u043d\u0438 \u043a\u0430\u0442\u043e \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u043d\u0438, \u0449\u0435 \u0431\u044a\u0434\u0430\u0442 \u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0438", + "OptionAlwaysPlaySubtitlesHelp": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u0438, \u043e\u0442\u0433\u043e\u0432\u0430\u0440\u044f\u0449\u0438 \u043d\u0430 \u0435\u0437\u0438\u043a\u043e\u0432\u043e\u0442\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u043d\u0438\u0435, \u0449\u0435 \u0431\u044a\u0434\u0430\u0442 \u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0438 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0435\u0437\u0438\u043a\u0430 \u043d\u0430 \u0430\u0443\u0434\u0438\u043e\u0442\u043e.", + "OptionNoSubtitlesHelp": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u0438 \u043d\u044f\u043c\u0430 \u0434\u0430 \u0431\u044a\u0434\u0430\u0442 \u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0438 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435.", + "TabProfiles": "\u041f\u0440\u043e\u0444\u0438\u043b\u0438", + "TabSecurity": "\u0417\u0430\u0449\u0438\u0442\u0430", + "ButtonAddUser": "\u0414\u043e\u0431\u0430\u0432\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b", + "ButtonAddLocalUser": "\u0414\u043e\u0431\u0430\u0432\u0438 \u043b\u043e\u043a\u0430\u043b\u0435\u043d \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b", + "ButtonInviteUser": "\u041f\u043e\u043a\u0430\u043d\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b", + "ButtonSave": "\u0417\u0430\u043f\u043e\u043c\u043d\u0438", + "ButtonResetPassword": "\u041d\u0443\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043f\u0430\u0440\u043e\u043b\u0430", + "LabelNewPassword": "\u041d\u043e\u0432\u0430 \u043f\u0430\u0440\u043e\u043b\u0430:", + "LabelNewPasswordConfirm": "\u041d\u043e\u0432\u0430 \u043f\u0430\u0440\u043e\u043b\u0430(\u043e\u0442\u043d\u043e\u0432\u043e):", + "HeaderCreatePassword": "\u041d\u0430\u043f\u0440\u0430\u0432\u0438 \u043f\u0430\u0440\u043e\u043b\u0430", + "LabelCurrentPassword": "\u0422\u0435\u043a\u0443\u0449\u0430 \u043f\u0430\u0440\u043e\u043b\u0430:", + "LabelMaxParentalRating": "\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u043d\u043e \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u0441\u043a\u0438 \u0440\u0435\u0439\u0442\u0438\u043d\u0433:", + "MaxParentalRatingHelp": "\u0421\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u0441 \u043f\u043e-\u0432\u0438\u0441\u043e\u043a \u0440\u0435\u0439\u0442\u0438\u043d\u0433 \u0449\u0435 \u0431\u044a\u0434\u0435 \u0441\u043a\u0440\u0438\u0442\u043e \u043e\u0442 \u0442\u043e\u0437\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b.", + "LibraryAccessHelp": "\u0418\u0437\u0431\u0435\u0440\u0435\u0442\u0435 \u043c\u0435\u0434\u0438\u0439\u043d\u0438\u0442\u0435 \u043f\u0430\u043f\u043a\u0438, \u043a\u043e\u0438\u0442\u043e \u0434\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u0438\u0442\u0435 \u0441 \u0442\u043e\u0437\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b. \u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0438\u0442\u0435 \u0449\u0435 \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u0442 \u0432\u0441\u0438\u0447\u043a\u0438 \u043f\u0430\u043f\u043a\u0438 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0439\u043a\u0438 \u043c\u0435\u043d\u0438\u0434\u0436\u044a\u0440\u0430 \u043d\u0430 \u043c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f.", + "ChannelAccessHelp": "\u0418\u0437\u0431\u0435\u0440\u0435\u0442\u0435 \u043a\u0430\u043d\u0430\u043b\u0438\u0442\u0435, \u043a\u043e\u0438\u0442\u043e \u0434\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u0438\u0442\u0435 \u0441 \u0442\u043e\u0437\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b. \u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0438\u0442\u0435 \u0449\u0435 \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u0442 \u0432\u0441\u0438\u0447\u043a\u0438 \u043a\u0430\u043d\u0430\u043b\u0438 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0439\u043a\u0438 \u043c\u0435\u043d\u0438\u0434\u0436\u044a\u0440\u0430 \u043d\u0430 \u043c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f.", + "ButtonDeleteImage": "\u0418\u0437\u0442\u0440\u0438\u0439 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435", + "LabelSelectUsers": "\u0418\u0437\u0431\u0435\u0440\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438:", + "ButtonUpload": "\u041a\u0430\u0447\u0438:", + "HeaderUploadNewImage": "\u041a\u0430\u0447\u0438 \u041d\u043e\u0432\u043e \u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435:", + "LabelDropImageHere": "\u041f\u0443\u0441\u043d\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u0442\u043e \u0442\u0443\u043a", + "ImageUploadAspectRatioHelp": "1:1 \u043f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0430\u043d\u0430 \u043f\u0440\u043e\u043f\u043e\u0440\u0446\u0438\u044f. \u0421\u0430\u043c\u043e JPG\/PNG", + "MessageNothingHere": "\u0422\u0443\u043a \u043d\u044f\u043c\u0430 \u043d\u0438\u0449\u043e.", + "MessagePleaseEnsureInternetMetadata": "\u041c\u043e\u043b\u044f, \u0443\u0432\u0435\u0440\u0435\u0442\u0435 \u0441\u0435 \u0447\u0435 \u0441\u0432\u0430\u043b\u044f\u043d\u0435\u0442\u043e \u043d\u0430 \u043c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e.", + "TabSuggested": "\u041f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f", + "TabLatest": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438", + "TabUpcoming": "\u041f\u0440\u0435\u0434\u0441\u0442\u043e\u044f\u0449\u0438", + "TabShows": "\u041f\u0440\u0435\u0434\u0430\u0432\u0430\u043d\u0438\u044f", + "TabEpisodes": "\u0415\u043f\u0438\u0437\u043e\u0434\u0438", + "TabGenres": "\u0416\u0430\u043d\u0440\u043e\u0432\u0435", + "TabPeople": "\u0425\u043e\u0440\u0430", + "TabNetworks": "\u041c\u0440\u0435\u0436\u0438", + "HeaderUsers": "\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438", + "HeaderFilters": "\u0424\u0438\u043b\u0442\u0440\u0438:", + "ButtonFilter": "\u0424\u0438\u043b\u0442\u044a\u0440", + "OptionFavorite": "\u041b\u044e\u0431\u0438\u043c\u0438:", + "OptionLikes": "\u0425\u0430\u0440\u0435\u0441\u0432\u0430\u043d\u0438\u044f", + "OptionDislikes": "\u041d\u0435\u0445\u0430\u0440\u0435\u0441\u0432\u0430\u043d\u0438\u044f", + "OptionActors": "\u0410\u043a\u0442\u044c\u043e\u0440\u0438", + "OptionGuestStars": "\u0413\u043e\u0441\u0442\u0443\u0432\u0430\u0449\u0438 \u0437\u0432\u0435\u0437\u0434\u0438", + "OptionDirectors": "\u0420\u0435\u0436\u0438\u0441\u044c\u043e\u0440\u0438", + "OptionWriters": "\u041f\u0438\u0441\u0430\u0442\u0435\u043b\u0438", + "OptionProducers": "\u041f\u0440\u043e\u0434\u0443\u0446\u0435\u043d\u0442\u0438", + "HeaderResume": "\u041f\u0440\u043e\u0436\u044a\u043b\u0436\u0438", + "HeaderNextUp": "\u0421\u043b\u0435\u0434\u0432\u0430", + "NoNextUpItemsMessage": "\u041d\u0438\u0449\u043e \u043d\u0435 \u0435 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043e. \u0417\u0430\u043f\u043e\u0447\u043d\u0435\u0442\u0435 \u0434\u0430 \u0433\u043b\u0435\u0434\u0430\u0442\u0435 \u0432\u0430\u0448\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u0430\u0432\u0430\u043d\u0438\u044f!", + "HeaderLatestEpisodes": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438 \u0415\u043f\u0438\u0437\u043e\u0434\u0438", + "HeaderPersonTypes": "\u0422\u0438\u043f\u043e\u0432\u0435 \u0425\u043e\u0440\u0430:", + "TabSongs": "\u041f\u0435\u0441\u043d\u0438", + "TabAlbums": "\u0410\u043b\u0431\u0443\u043c\u0438", + "TabArtists": "\u0410\u0440\u0442\u0438\u0441\u0442\u0438", + "TabAlbumArtists": "\u0410\u043b\u0431\u0443\u043c\u043e\u0432\u0438 \u0410\u0440\u0442\u0438\u0441\u0442\u0438", + "TabMusicVideos": "\u041c\u0443\u0437\u0438\u043a\u0430\u043b\u043d\u0438 \u043a\u043b\u0438\u043f\u043e\u0432\u0435", + "ButtonSort": "\u041f\u043e\u0434\u0440\u0435\u0434\u0438", + "HeaderSortBy": "\u041f\u043e\u0434\u0440\u0435\u0434\u0438 \u043f\u043e:", + "HeaderSortOrder": "\u0420\u0435\u0434 \u043d\u0430 \u043f\u043e\u0434\u0440\u0435\u0434\u0431\u0430:", + "OptionPlayed": "\u041f\u0443\u0441\u043a\u0430\u043d\u0438", + "OptionUnplayed": "\u041d\u0435 \u043f\u0443\u0441\u043a\u0430\u043d\u0438", + "OptionAscending": "\u0412\u044a\u0437\u0445\u043e\u0434\u044f\u0449", + "OptionDescending": "\u041d\u0438\u0437\u0445\u043e\u0434\u044f\u0449", + "OptionRuntime": "\u0412\u0440\u0435\u043c\u0435\u0442\u0440\u0430\u0435\u043d\u0435", + "OptionReleaseDate": "\u0414\u0430\u0442\u0430 \u043d\u0430 \u0438\u0437\u0434\u0430\u0432\u0430\u043d\u0435", + "OptionPlayCount": "\u0411\u0440\u043e\u0439 \u043f\u0443\u0441\u043a\u0430\u043d\u0438\u044f", + "OptionDatePlayed": "\u0414\u0430\u0442\u0430 \u043d\u0430 \u043f\u0443\u0441\u043a\u0430\u043d\u0435", + "OptionDateAdded": "\u0414\u0430\u0442\u0430 \u043d\u0430 \u0434\u043e\u0431\u0430\u0432\u044f\u043d\u0435", + "OptionAlbumArtist": "\u0410\u043b\u0431\u0443\u043c\u043e\u0432 \u0410\u0440\u0442\u0438\u0441\u0442", + "OptionArtist": "\u0410\u0440\u0442\u0438\u0441\u0442", + "OptionAlbum": "\u0410\u043b\u0431\u0443\u043c", + "OptionTrackName": "\u0418\u043c\u0435 \u043d\u0430 \u043f\u0435\u0441\u0435\u043d\u0442\u0430:", + "OptionCommunityRating": "\u041e\u0431\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u0430 \u043e\u0449\u0435\u043d\u043a\u0430", "OptionNameSort": "Name", - "OptionFolderSort": "Folders", - "OptionBudget": "Budget", - "OptionRevenue": "Revenue", - "OptionPoster": "Poster", - "OptionPosterCard": "Poster card", - "OptionBackdrop": "Backdrop", - "OptionTimeline": "Timeline", - "OptionThumb": "Thumb", - "OptionThumbCard": "Thumb card", - "OptionBanner": "Banner", - "OptionCriticRating": "Critic Rating", - "OptionVideoBitrate": "Video Bitrate", - "OptionResumable": "Resumable", - "ScheduledTasksHelp": "Click a task to adjust its schedule.", - "ScheduledTasksTitle": "Scheduled Tasks", - "TabMyPlugins": "My Plugins", - "TabCatalog": "Catalog", - "PluginsTitle": "Plugins", - "HeaderAutomaticUpdates": "Automatic Updates", - "HeaderNowPlaying": "Now Playing", - "HeaderLatestAlbums": "Latest Albums", - "HeaderLatestSongs": "Latest Songs", - "HeaderRecentlyPlayed": "Recently Played", - "HeaderFrequentlyPlayed": "Frequently Played", - "DevBuildWarning": "Dev builds are the bleeding edge. Released often, these build have not been tested. The application may crash and entire features may not work at all.", - "LabelVideoType": "Video Type:", + "OptionFolderSort": "\u041f\u0430\u043f\u043a\u0438", + "OptionBudget": "\u0411\u044e\u0434\u0436\u0435\u0442", + "OptionRevenue": "\u041f\u0440\u0438\u0445\u043e\u0434\u0438", + "OptionPoster": "\u041f\u043b\u0430\u043a\u0430\u0442", + "OptionPosterCard": "\u041a\u0430\u0440\u0442\u0430 \u043f\u043b\u0430\u043a\u0430\u0442", + "OptionBackdrop": "\u0424\u043e\u043d", + "OptionTimeline": "\u0413\u0440\u0430\u0444\u0438\u043a", + "OptionThumb": "\u041c\u0438\u043d\u0438\u0430\u0442\u044e\u0440\u0430", + "OptionThumbCard": "\u041a\u0430\u0440\u0442\u0430 \u043c\u0438\u043d\u0438\u0430\u0442\u044e\u0440\u0430", + "OptionBanner": "\u0411\u0430\u043d\u0435\u0440", + "OptionCriticRating": "\u041e\u0446\u0435\u043d\u043a\u0430 \u043d\u0430 \u043a\u0440\u0438\u0442\u0438\u0446\u0438\u0442\u0435", + "OptionVideoBitrate": "\u0412\u0438\u0434\u0435\u043e \u0431\u0438\u0442\u0440\u0435\u0439\u0442", + "OptionResumable": "\u0412\u044a\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c\u043e\u0441\u0442", + "ScheduledTasksHelp": "\u0426\u044a\u043a\u043d\u0435\u0442\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430, \u0437\u0430 \u0434\u0430 \u043d\u0430\u0433\u043b\u0430\u0441\u0438\u0442\u0435 \u043f\u043b\u0430\u043d\u0430 \u045d.", + "ScheduledTasksTitle": "\u041f\u043b\u0430\u043d\u0438\u0440\u0430\u043d\u0438 \u0417\u0430\u0434\u0430\u0447\u0438", + "TabMyPlugins": "\u041c\u043e\u0438\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438", + "TabCatalog": "\u041a\u0430\u0442\u0430\u043b\u043e\u0433", + "PluginsTitle": "\u041f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438", + "HeaderAutomaticUpdates": "\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0438 \u0412\u044a\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f", + "HeaderNowPlaying": "\u0421\u0435\u0433\u0430 \u0412\u044a\u0437\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u043e:", + "HeaderLatestAlbums": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438 \u0410\u043b\u0431\u0443\u043c\u0438", + "HeaderLatestSongs": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438 \u041f\u0435\u0441\u043d\u0438", + "HeaderRecentlyPlayed": "\u0421\u043a\u043e\u0440\u043e \u041f\u0443\u0441\u043a\u0430\u043d\u0438", + "HeaderFrequentlyPlayed": "\u0427\u0435\u0441\u0442\u043e \u041f\u0443\u0441\u043a\u0430\u043d\u0438", + "DevBuildWarning": "\u0412\u0435\u0440\u0441\u0438\u0438\u0442\u0435 \u0437\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u0446\u0438 \u0441\u0430 \u043d\u0430\u0439-\u043d\u043e\u0432\u043e\u0442\u043e. \u0422\u0435 \u0441\u0435 \u0432\u044a\u0437\u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u0442 \u0447\u0435\u0441\u0442\u043e, \u043d\u043e \u043d\u0435 \u0441\u0435 \u0442\u0435\u0441\u0442\u0432\u0430\u0442. \u041c\u043e\u0436\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u0442\u043e \u0434\u0430 \u0441\u0435 \u0447\u0443\u043f\u0438 \u0438 \u0446\u0435\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437\u043e\u0431\u0449\u043e \u0434\u0430 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u044f\u0442.", + "LabelVideoType": "\u0422\u0438\u043f \u043d\u0430 \u0432\u0438\u0434\u0435\u043e\u0442\u043e:", "OptionBluray": "Bluray", "OptionDvd": "Dvd", "OptionIso": "Iso", "Option3D": "3D", - "LabelFeatures": "Features:", - "LabelService": "Service:", - "LabelStatus": "Status:", - "LabelVersion": "Version:", - "LabelLastResult": "Last result:", - "OptionHasSubtitles": "Subtitles", - "OptionHasTrailer": "Trailer", - "OptionHasThemeSong": "Theme Song", - "OptionHasThemeVideo": "Theme Video", - "TabMovies": "Movies", - "TabStudios": "Studios", - "TabTrailers": "Trailers", - "LabelArtists": "Artists:", - "LabelArtistsHelp": "Separate multiple using ;", - "HeaderLatestMovies": "Latest Movies", - "HeaderLatestTrailers": "Latest Trailers", - "OptionHasSpecialFeatures": "Special Features", - "OptionImdbRating": "IMDb Rating", - "OptionParentalRating": "Parental Rating", - "OptionPremiereDate": "Premiere Date", - "TabBasic": "Basic", - "TabAdvanced": "Advanced", - "HeaderStatus": "Status", - "OptionContinuing": "Continuing", - "OptionEnded": "Ended", - "HeaderAirDays": "Air Days", - "OptionSunday": "Sunday", - "OptionMonday": "Monday", - "OptionTuesday": "Tuesday", - "OptionWednesday": "Wednesday", - "OptionThursday": "Thursday", - "OptionFriday": "Friday", - "OptionSaturday": "Saturday", - "HeaderManagement": "Management", - "LabelManagement": "Management:", - "OptionMissingImdbId": "Missing IMDb Id", - "OptionMissingTvdbId": "Missing TheTVDB Id", - "OptionMissingOverview": "Missing Overview", - "OptionFileMetadataYearMismatch": "File\/Metadata Years Mismatched", - "TabGeneral": "General", - "TitleSupport": "Support", - "TabLog": "Log", - "TabAbout": "About", - "TabSupporterKey": "Supporter Key", - "TabBecomeSupporter": "Become a Supporter", - "MediaBrowserHasCommunity": "Media Browser has a thriving community of users and contributors.", - "CheckoutKnowledgeBase": "Check out our knowledge base to help you get the most out of Media Browser.", - "SearchKnowledgeBase": "Search the Knowledge Base", - "VisitTheCommunity": "Visit the Community", - "VisitMediaBrowserWebsite": "Visit the Media Browser Web Site", - "VisitMediaBrowserWebsiteLong": "Visit the Media Browser Web site to catch the latest news and keep up with the developer blog.", - "OptionHideUser": "Hide this user from login screens", - "OptionHideUserFromLoginHelp": "Useful for private or hidden administrator accounts. The user will need to sign in manually by entering their username and password.", - "OptionDisableUser": "Disable this user", - "OptionDisableUserHelp": "If disabled the server will not allow any connections from this user. Existing connections will be abruptly terminated.", - "HeaderAdvancedControl": "Advanced Control", - "LabelName": "Name:", - "ButtonHelp": "Help", - "OptionAllowUserToManageServer": "Allow this user to manage the server", - "HeaderFeatureAccess": "Feature Access", - "OptionAllowMediaPlayback": "Allow media playback", - "OptionAllowBrowsingLiveTv": "Allow browsing of live tv", - "OptionAllowDeleteLibraryContent": "Allow deletion of library content", - "OptionAllowManageLiveTv": "Allow management of live tv recordings", - "OptionAllowRemoteControlOthers": "Allow remote control of other users", - "OptionAllowRemoteSharedDevices": "Allow remote control of shared devices", - "OptionAllowRemoteSharedDevicesHelp": "Dlna devices are considered shared until a user begins controlling it.", - "HeaderRemoteControl": "Remote Control", - "OptionMissingTmdbId": "Missing Tmdb Id", + "LabelFeatures": "\u0424\u0443\u043d\u043a\u0446\u0438\u0438:", + "LabelService": "\u0423\u0441\u043b\u0443\u0433\u0430:", + "LabelStatus": "\u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435:", + "LabelVersion": "\u0412\u0435\u0440\u0441\u0438\u044f:", + "LabelLastResult": "\u041f\u043e\u0441\u043b\u0435\u0434\u0435\u043d \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442:", + "OptionHasSubtitles": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u0438", + "OptionHasTrailer": "\u0422\u0440\u0435\u0439\u043b\u044a\u0440", + "OptionHasThemeSong": "\u0424\u043e\u043d\u043e\u0432\u0430 \u041f\u0435\u0441\u0435\u043d", + "OptionHasThemeVideo": "\u0424\u043e\u043d\u043e\u0432\u043e \u0412\u0438\u0434\u0435\u043e", + "TabMovies": "\u0424\u0438\u043b\u043c\u0438", + "TabStudios": "\u0421\u0442\u0443\u0434\u0438\u0430", + "TabTrailers": "\u0422\u0440\u0435\u0439\u043b\u044a\u0440\u0438", + "LabelArtists": "\u0410\u0440\u0442\u0438\u0441\u0442\u0438:", + "LabelArtistsHelp": "\u041e\u0442\u0434\u0435\u043b\u0435\u0442\u0435 \u043d\u044f\u043a\u043e\u043b\u043a\u043e \u0441 ;", + "HeaderLatestMovies": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438 \u0424\u0438\u043b\u043c\u0438", + "HeaderLatestTrailers": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438 \u0422\u0440\u0435\u0439\u043b\u044a\u0440\u0438", + "OptionHasSpecialFeatures": "\u0421\u043f\u0435\u0446\u0438\u0430\u043b\u043d\u0438 \u0414\u043e\u0431\u0430\u0432\u043a\u0438", + "OptionImdbRating": "IMDb \u0420\u0435\u0439\u0442\u0438\u043d\u0433", + "OptionParentalRating": "\u0420\u043e\u0434\u0438\u0442\u0435\u043b\u0441\u043a\u0438 \u0420\u0435\u0439\u0442\u0438\u043d\u0433", + "OptionPremiereDate": "\u0414\u0430\u0442\u0430 \u043d\u0430 \u043f\u0440\u0435\u043c\u0438\u0435\u0440\u0430", + "TabBasic": "\u041e\u0441\u043d\u043e\u0432\u043d\u0438", + "TabAdvanced": "\u0414\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0438", + "HeaderStatus": "\u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435:", + "OptionContinuing": "\u041f\u0440\u043e\u0434\u044a\u043b\u0436\u0430\u0432\u0430\u0449\u043e", + "OptionEnded": "\u041f\u0440\u0438\u043a\u043b\u044e\u0447\u0438\u043b\u043e", + "HeaderAirDays": "\u0414\u043d\u0438 \u043d\u0430 \u0438\u0437\u043b\u044a\u0447\u0432\u0430\u043d\u0435", + "OptionSunday": "\u041d\u0435\u0434\u0435\u043b\u044f", + "OptionMonday": "\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a", + "OptionTuesday": "\u0412\u0442\u043e\u0440\u043d\u0438\u043a", + "OptionWednesday": "\u0421\u0440\u044f\u0434\u0430", + "OptionThursday": "\u0427\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a", + "OptionFriday": "\u041f\u0435\u0442\u044a\u043a", + "OptionSaturday": "\u0421\u044a\u0431\u043e\u0442\u0430", + "HeaderManagement": "\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435", + "LabelManagement": "\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435:", + "OptionMissingImdbId": "\u041b\u0438\u043f\u0441\u0432\u0430\u0449\u043e IMDb ID", + "OptionMissingTvdbId": "\u041b\u0438\u043f\u0441\u0432\u0430\u0449\u043e TheTVDB ID", + "OptionMissingOverview": "\u041b\u0438\u043f\u0441\u0432\u0430\u0449\u0430 \u043e\u0431\u0449\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f", + "OptionFileMetadataYearMismatch": "\u0420\u0430\u0437\u043b\u0438\u0447\u0438\u0435 \u043d\u0430 \u0433\u043e\u0434\u0438\u043d\u0430 \u0432\u044a\u0432 \u0424\u0430\u0439\u043b\/\u041c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f", + "TabGeneral": "\u0413\u043b\u0430\u0432\u043d\u043e", + "TitleSupport": "\u041f\u043e\u0434\u0434\u0440\u044a\u0436\u043a\u0430", + "TabLog": "\u041b\u043e\u0433", + "TabAbout": "\u041e\u0442\u043d\u043e\u0441\u043d\u043e", + "TabSupporterKey": "\u041f\u043e\u0434\u0434\u0440\u044a\u0436\u043d\u0438\u043a\u043e\u0432 \u043a\u043b\u044e\u0447", + "TabBecomeSupporter": "\u0421\u0442\u0430\u043d\u0438 \u043f\u043e\u0434\u0434\u0440\u044a\u0436\u043d\u0438\u043a", + "MediaBrowserHasCommunity": "Media Browser \u0438\u043c\u0430 \u043f\u0440\u043e\u0446\u044a\u0444\u0442\u044f\u0432\u0430\u0449\u0430 \u043e\u0431\u0449\u043d\u043e\u0441\u0442 \u043e\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 \u0438 \u0441\u044a\u0442\u0440\u0443\u0434\u043d\u0438\u0446\u0438.", + "CheckoutKnowledgeBase": "\u041f\u0440\u043e\u0432\u0435\u0440\u0435\u0442\u0435 \u043d\u0430\u0448\u0430\u0442\u0430 \u0431\u0430\u0437\u0430 \u043e\u0442 \u0437\u043d\u0430\u043d\u0438\u044f, \u0437\u0430 \u0434\u0430 \u0432\u0438 \u043f\u043e\u043c\u043e\u0433\u043d\u0435 \u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u043d\u0430\u0439-\u0434\u043e\u0431\u0440\u043e\u0442\u043e \u043e\u0442 Media Browser.", + "SearchKnowledgeBase": "\u0422\u044a\u0440\u0441\u0438 \u0432 \u0411\u0430\u0437\u0430\u0442\u0430 \u043e\u0442 \u0417\u043d\u0430\u043d\u0438\u044f", + "VisitTheCommunity": "\u041f\u043e\u0441\u0435\u0442\u0435\u0442\u0435 \u041e\u0431\u0449\u0435\u0441\u0442\u0432\u043e\u0442\u043e", + "VisitMediaBrowserWebsite": "\u041f\u043e\u0441\u0435\u0442\u0435\u0442\u0435 \u0443\u0435\u0431-\u0441\u0430\u0439\u0442\u0430 \u043d\u0430 Media Browser", + "VisitMediaBrowserWebsiteLong": "\u041f\u043e\u0441\u0435\u0442\u0435\u0442\u0435 \u0443\u0435\u0431-\u0441\u0430\u0439\u0442\u0430 \u043d\u0430 Media Browser, \u0437\u0430 \u0434\u0430 \u0443\u0437\u043d\u0430\u0435\u0442\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0442\u0435 \u043d\u043e\u0432\u0438\u043d\u0438 \u0438 \u0434\u0430 \u0441\u0442\u0435 \u0432 \u043a\u0440\u0430\u043a \u0441 \u0431\u043b\u043e\u0433\u0430 \u043d\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u0446\u0438\u0442\u0435.", + "OptionHideUser": "\u0421\u043a\u0440\u0438\u0439 \u0442\u043e\u0437\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b \u043e\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0438\u0442\u0435 \u0437\u0430 \u0432\u0445\u043e\u0434", + "OptionHideUserFromLoginHelp": "\u041f\u043e\u043b\u0435\u0437\u043d\u043e \u0437\u0430 \u0447\u0430\u0441\u0442\u043d\u0438 \u0438\u043b\u0438 \u0441\u043a\u0440\u0438\u0442\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0441\u043a\u0438 \u0430\u043a\u0430\u0443\u043d\u0442\u0438. \u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u0442 \u0449\u0435 \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0432\u043b\u0435\u0437\u0435 \u0440\u044a\u0447\u043d\u043e \u0447\u0440\u0435\u0437 \u0432\u044a\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u043e \u0438\u043c\u0435 \u0438 \u043f\u0430\u0440\u043e\u043b\u0430.", + "OptionDisableUser": "\u0414\u0435\u0437\u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u0439\u0442\u0435 \u0442\u043e\u0437\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b", + "OptionDisableUserHelp": "\u0410\u043a\u043e \u0435 \u0434\u0435\u0437\u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d, \u0441\u044a\u0440\u0432\u044a\u0440\u044a\u0442 \u043d\u044f\u043c\u0430 \u0434\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u0438 \u043a\u0430\u043a\u0432\u0438\u0442\u043e \u0438 \u0434\u0430 \u0431\u0438\u043b\u043e \u0432\u0440\u044a\u0437\u043a\u0438 \u043e\u0442 \u0442\u043e\u0437\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b. \u0421\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430\u0449\u0438\u0442\u0435 \u0432\u0440\u044a\u0437\u043a\u0438 \u0449\u0435 \u0431\u044a\u0434\u0430\u0442 \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u0435\u043d\u0438.", + "HeaderAdvancedControl": "\u0414\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u0435\u043d \u041a\u043e\u043d\u0442\u0440\u043e\u043b", + "LabelName": "\u0418\u043c\u0435:", + "ButtonHelp": "\u041f\u043e\u043c\u043e\u0449", + "OptionAllowUserToManageServer": "\u0420\u0430\u0437\u0440\u0435\u0448\u0438 \u043d\u0430 \u0442\u043e\u0437\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b \u0434\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0432\u0430 \u0441\u044a\u0440\u0432\u044a\u0440\u0430", + "HeaderFeatureAccess": "\u0414\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438", + "OptionAllowMediaPlayback": "\u0420\u0430\u0437\u0440\u0435\u0448\u0438 \u043f\u0443\u0441\u043a\u0430\u043d\u0435 \u043d\u0430 \u043c\u0435\u0434\u0438\u044f", + "OptionAllowBrowsingLiveTv": "\u0420\u0430\u0437\u0440\u0435\u0448\u0438 \u0440\u0430\u0437\u0433\u043b\u0435\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0442\u0435\u043b\u0435\u0432\u0438\u0437\u0438\u044f \u043d\u0430 \u0436\u0438\u0432\u043e", + "OptionAllowDeleteLibraryContent": "\u0420\u0430\u0437\u0440\u0435\u0448\u0438 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043e\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0442\u0430", + "OptionAllowManageLiveTv": "\u0420\u0430\u0437\u0440\u0435\u0448\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0437\u0430\u043f\u0438\u0441 \u043d\u0430 \u0442\u0435\u043b\u0435\u0432\u0438\u0437\u0438\u044f \u043d\u0430 \u0436\u0438\u0432\u043e", + "OptionAllowRemoteControlOthers": "\u0420\u0430\u0437\u0440\u0435\u0448\u0438 \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0434\u0440\u0443\u0433\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438", + "OptionAllowRemoteSharedDevices": "\u0420\u0430\u0437\u0440\u0435\u0448\u0438 \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u0435\u043d\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430", + "OptionAllowRemoteSharedDevicesHelp": "DLNA \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0441\u0435 \u0441\u0447\u0438\u0442\u0430\u0442 \u0437\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u0435\u043d\u0438 \u0434\u043e\u043a\u0430\u0442\u043e \u043d\u044f\u043a\u043e\u0439 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b \u043d\u0435 \u0437\u0430\u043f\u043e\u0447\u043d\u0435 \u0434\u0430 \u0433\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0430.", + "HeaderRemoteControl": "\u041e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d \u041a\u043e\u043d\u0442\u0440\u043e\u043b", + "OptionMissingTmdbId": "\u041b\u0438\u043f\u0441\u0432\u0430\u0449\u043e Tmdb ID", "OptionIsHD": "HD", "OptionIsSD": "SD", - "OptionMetascore": "Metascore", - "ButtonSelect": "Select", - "ButtonGroupVersions": "Group Versions", + "OptionMetascore": "\u041c\u0435\u0442\u0430 \u0442\u043e\u0447\u043a\u0438", + "ButtonSelect": "\u0418\u0437\u0431\u0435\u0440\u0438", + "ButtonGroupVersions": "\u0413\u0440\u0443\u043f\u0438\u0440\u0430\u0439 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435", "ButtonAddToCollection": "Add to Collection", - "PismoMessage": "Utilizing Pismo File Mount through a donated license.", - "TangibleSoftwareMessage": "Utilizing Tangible Solutions Java\/C# converters through a donated license.", - "HeaderCredits": "Credits", + "PismoMessage": "\u0418\u0437\u043f\u043e\u043b\u0437\u0430\u043d\u0435 \u043d\u0430 Pismo File Mount \u0447\u0440\u0435\u0437 \u0434\u0430\u0440\u0435\u043d \u043b\u0438\u0446\u0435\u043d\u0437.", + "TangibleSoftwareMessage": "\u0418\u0437\u043f\u043e\u043b\u0437\u0430\u043d\u0435 \u043d\u0430 Tangible Solutions Java\/C# converters \u0447\u0440\u0435\u0437 \u0434\u0430\u0440\u0435\u043d \u043b\u0438\u0446\u0435\u043d\u0437.", + "HeaderCredits": "\u041a\u0440\u0435\u0434\u0438\u0442\u0438", "PleaseSupportOtherProduces": "Please support other free products we utilize:", - "VersionNumber": "Version {0}", - "TabPaths": "Paths", - "TabServer": "Server", - "TabTranscoding": "Transcoding", - "TitleAdvanced": "Advanced", - "LabelAutomaticUpdateLevel": "Automatic update level", - "OptionRelease": "Official Release", - "OptionBeta": "Beta", - "OptionDev": "Dev (Unstable)", - "LabelAllowServerAutoRestart": "Allow the server to restart automatically to apply updates", - "LabelAllowServerAutoRestartHelp": "The server will only restart during idle periods, when no users are active.", - "LabelEnableDebugLogging": "Enable debug logging", - "LabelRunServerAtStartup": "Run server at startup", - "LabelRunServerAtStartupHelp": "This will start the tray icon on windows startup. To start the windows service, uncheck this and run the service from the windows control panel. Please note that you cannot run both at the same time, so you will need to exit the tray icon before starting the service.", - "ButtonSelectDirectory": "Select Directory", - "LabelCustomPaths": "Specify custom paths where desired. Leave fields empty to use the defaults.", - "LabelCachePath": "Cache path:", - "LabelCachePathHelp": "Specify a custom location for server cache files, such as images.", - "LabelImagesByNamePath": "Images by name path:", - "LabelImagesByNamePathHelp": "Specify a custom location for downloaded actor, genre and studio images.", - "LabelMetadataPath": "Metadata path:", - "LabelMetadataPathHelp": "Specify a custom location for downloaded artwork and metadata, if not saving within media folders.", - "LabelTranscodingTempPath": "Transcoding temporary path:", - "LabelTranscodingTempPathHelp": "This folder contains working files used by the transcoder. Specify a custom path, or leave empty to use the default within the server's data folder.", - "TabBasics": "Basics", + "VersionNumber": "\u0412\u0435\u0440\u0441\u0438\u044f {0}", + "TabPaths": "\u041f\u044a\u0442\u0438\u0449\u0430", + "TabServer": "\u0421\u044a\u0440\u0432\u044a\u0440", + "TabTranscoding": "\u041f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435", + "TitleAdvanced": "\u0414\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0438", + "LabelAutomaticUpdateLevel": "\u041d\u0438\u0432\u043e \u043d\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0435", + "OptionRelease": "\u041e\u0444\u0438\u0446\u0438\u0430\u043b\u043d\u043e \u0438\u0437\u0434\u0430\u043d\u0438\u0435", + "OptionBeta": "\u0411\u0435\u0442\u0430", + "OptionDev": "\u0417\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u0446\u0438 (\u041d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u0435\u043d)", + "LabelAllowServerAutoRestart": "\u0420\u0430\u0437\u0440\u0435\u0448\u0438 \u043d\u0430 \u0441\u044a\u0440\u0432\u044a\u0440\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u043d \u0440\u0435\u0441\u0442\u0430\u0440\u0442 \u0437\u0430 \u043f\u0440\u0438\u043b\u0430\u0433\u0430\u043d\u0435 \u043d\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438\u0442\u0435", + "LabelAllowServerAutoRestartHelp": "\u0421\u044a\u0440\u0432\u044a\u0440\u044a\u0442 \u0449\u0435 \u0441\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u0441\u0430\u043c\u043e \u043f\u0440\u0435\u0437 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0442\u043e \u0441\u0438 \u0432\u0440\u0435\u043c\u0435, \u043a\u043e\u0433\u0430\u0442\u043e \u043d\u044f\u043c\u0430 \u0430\u043a\u0442\u0438\u0432\u043d\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438.", + "LabelEnableDebugLogging": "\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u0439 \u043b\u043e\u0433\u0438\u043d\u0433 \u043d\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u0433\u0440\u0435\u0448\u043a\u0438", + "LabelRunServerAtStartup": "\u041f\u0443\u0441\u043a\u0430\u043d\u0435 \u043d\u0430 \u0441\u044a\u0440\u0432\u044a\u0440\u0430 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435", + "LabelRunServerAtStartupHelp": "\u0422\u043e\u0432\u0430 \u0449\u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u0438\u043a\u043e\u043d\u043a\u0430\u0442\u0430 \u0432 \u0442\u0440\u0435\u0439 \u043b\u0435\u043d\u0442\u0430\u0442\u0430 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Windows. \u0417\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Windows service, \u043c\u0430\u0445\u043d\u0435\u0442\u0435 \u043e\u0442\u043c\u0435\u0442\u043a\u0430\u0442\u0430 \u043e\u0442 \u0442\u043e\u0432\u0430 \u0438 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0439\u0442\u0435 \u0443\u0441\u043b\u0443\u0433\u0430\u0442\u0430 \u043e\u0442 Windows \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043d\u0438\u044f \u043f\u0430\u043d\u0435\u043b. \u041c\u043e\u043b\u044f, \u043e\u0442\u0431\u0435\u043b\u0435\u0436\u0435\u0442\u0435, \u0447\u0435 \u0434\u0432\u0435\u0442\u0435 \u043d\u0435 \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0431\u044a\u0434\u0430\u0442 \u043f\u0443\u0441\u043d\u0430\u0442\u0438 \u043f\u043e \u0435\u0434\u043d\u043e \u0438 \u0441\u044a\u0449\u043e \u0432\u0440\u0435\u043c\u0435, \u0442\u0430\u043a\u0430 \u0447\u0435 \u0449\u0435 \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0438\u0437\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0438\u043a\u043e\u043d\u043a\u0430\u0442\u0430 \u0432 \u0442\u0440\u0435\u0439 \u043b\u0435\u043d\u0442\u0430\u0442\u0430 \u043f\u0440\u0435\u0434\u0438 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0443\u0441\u043b\u0443\u0433\u0430\u0442\u0430.", + "ButtonSelectDirectory": "\u0418\u0437\u0431\u0435\u0440\u0438 \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f", + "LabelCustomPaths": "\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u0442\u0435 \u043f\u044a\u0442\u0438\u0449\u0430 \u043f\u043e \u0438\u0437\u0431\u043e\u0440 \u043a\u044a\u0434\u0435\u0442\u043e \u0436\u0435\u043b\u0430\u0435\u0442\u0435. \u041e\u0441\u0442\u0430\u0432\u0435\u0442\u0435 \u043f\u043e\u043b\u0435\u0442\u0430\u0442\u0430 \u043f\u0440\u0430\u0437\u043d\u0438 \u0437\u0430 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442 \u043f\u044a\u0442\u0438\u0449\u0430\u0442\u0430 \u043f\u043e \u0438\u0437\u0431\u043e\u0440.", + "LabelCachePath": "\u041f\u044a\u0442 \u043a\u044a\u043c \u043a\u0435\u0448\u0430:", + "LabelCachePathHelp": "\u0417\u0430\u0434\u0430\u0439\u0442\u0435 \u043c\u044f\u0441\u0442\u043e \u043f\u043e \u0438\u0437\u0431\u043e\u0440 \u0437\u0430 \u0441\u044a\u0440\u0432\u044a\u0440\u043d\u0438 \u043a\u0435\u0448 \u0444\u0430\u0439\u043b\u043e\u0432\u0435, \u043a\u0430\u0442\u043e \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.", + "LabelImagesByNamePath": "\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u043e \u043f\u044a\u0442 \u043d\u0430 \u0438\u043c\u0435\u0442\u043e:", + "LabelImagesByNamePathHelp": "\u0417\u0430\u0434\u0430\u0439\u0442\u0435 \u043c\u044f\u0441\u0442\u043e \u043f\u043e \u0438\u0437\u0431\u043e\u0440 \u0437\u0430 \u0441\u0432\u0430\u043b\u0435\u043d\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0430\u043a\u0442\u044c\u043e\u0440\u0438, \u0436\u0430\u043d\u0440\u043e\u0432\u0435 \u0438 \u0441\u0442\u0443\u0434\u0438\u0430.", + "LabelMetadataPath": "\u041f\u044a\u0442 \u043a\u044a\u043c \u043c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f\u0442\u0430:", + "LabelMetadataPathHelp": "\u0417\u0430\u0434\u0430\u0439\u0442\u0435 \u043c\u044f\u0441\u0442\u043e \u043f\u043e \u0438\u0437\u0431\u043e\u0440 \u0437\u0430 \u0441\u0432\u0430\u043b\u0435\u043d\u043e \u0438\u0437\u043a\u0443\u0441\u0442\u0432\u043e \u0438 \u043c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f, \u0430\u043a\u043e \u043d\u0435 \u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0432\u0430\u0442 \u0432 \u043f\u0430\u043f\u043a\u0438\u0442\u0435 \u043d\u0430 \u043c\u0435\u0434\u0438\u044f\u0442\u0430.", + "LabelTranscodingTempPath": "\u0412\u0440\u0435\u043c\u0435\u043d\u0435\u043d \u043f\u044a\u0442 \u043d\u0430 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435:", + "LabelTranscodingTempPathHelp": "\u0422\u0430\u0437\u0438 \u043f\u0430\u043f\u043a\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430 \u0440\u0430\u0431\u043e\u0442\u043d\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0438 \u043e\u0442 \u0442\u0440\u0430\u043d\u0441\u043a\u043e\u0434\u0435\u0440\u0430. \u0417\u0430\u0434\u0430\u0439\u0442\u0435 \u043c\u044f\u0441\u0442\u043e \u043f\u043e \u0438\u0437\u0431\u043e\u0440 \u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u0435\u0442\u0435 \u043f\u0440\u0430\u0437\u043d\u043e \u0437\u0430 \u043c\u044f\u0441\u0442\u043e\u0442\u043e \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435.", + "TabBasics": "\u041e\u0441\u043d\u043e\u0432\u0438", "TabTV": "TV", - "TabGames": "Games", - "TabMusic": "Music", - "TabOthers": "Others", - "HeaderExtractChapterImagesFor": "Extract chapter images for:", - "OptionMovies": "Movies", - "OptionEpisodes": "Episodes", - "OptionOtherVideos": "Other Videos", - "TitleMetadata": "Metadata", - "LabelAutomaticUpdates": "Enable automatic updates", - "LabelAutomaticUpdatesTmdb": "Enable automatic updates from TheMovieDB.org", - "LabelAutomaticUpdatesTvdb": "Enable automatic updates from TheTVDB.com", - "LabelAutomaticUpdatesFanartHelp": "If enabled, new images will be downloaded automatically as they're added to fanart.tv. Existing images will not be replaced.", - "LabelAutomaticUpdatesTmdbHelp": "If enabled, new images will be downloaded automatically as they're added to TheMovieDB.org. Existing images will not be replaced.", - "LabelAutomaticUpdatesTvdbHelp": "If enabled, new images will be downloaded automatically as they're added to TheTVDB.com. Existing images will not be replaced.", - "LabelFanartApiKey": "Personal api key:", - "LabelFanartApiKeyHelp": "Requests to fanart without a personal API key return results that were approved over 7 days ago. With a personal API key that drops to 48 hours and if you are also a fanart VIP member that will further drop to around 10 minutes.", - "ExtractChapterImagesHelp": "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 when videos are discovered, and also as a nightly scheduled task at 4am. The schedule is configurable in the scheduled tasks area. It is not recommended to run this task during peak usage hours.", - "LabelMetadataDownloadLanguage": "Preferred download language:", - "ButtonAutoScroll": "Auto-scroll", + "TabGames": "\u0418\u0433\u0440\u0438", + "TabMusic": "\u041c\u0443\u0437\u0438\u043a\u0430", + "TabOthers": "\u0414\u0440\u0443\u0433\u043e", + "HeaderExtractChapterImagesFor": "\u0418\u0437\u0432\u0430\u0434\u0435\u043d\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0433\u043b\u0430\u0432\u0438\u0442\u0435 \u0437\u0430:", + "OptionMovies": "\u0424\u0438\u043b\u043c\u0438", + "OptionEpisodes": "\u0415\u043f\u0438\u0437\u043e\u0434\u0438", + "OptionOtherVideos": "\u0414\u0440\u0443\u0433\u0438 \u043a\u043b\u0438\u043f\u043e\u0432\u0435", + "TitleMetadata": "\u041c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f", + "LabelAutomaticUpdates": "\u0420\u0430\u0437\u0440\u0435\u0448\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0438\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f", + "LabelAutomaticUpdatesTmdb": "\u0420\u0430\u0437\u0440\u0435\u0448\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0442 TheMovieDB.org", + "LabelAutomaticUpdatesTvdb": "\u0420\u0430\u0437\u0440\u0435\u0448\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0442 TheTVDB.com", + "LabelAutomaticUpdatesFanartHelp": "\u0410\u043a\u043e \u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e, \u043d\u043e\u0432\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0449\u0435 \u0431\u044a\u0434\u0430\u0442 \u0441\u0432\u0430\u043b\u044f\u043d\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043a\u0430\u0442\u043e \u0441\u0435 \u0434\u043e\u0431\u0430\u0432\u044f\u0442 \u0432\u044a\u0432 fanart.tv. \u0412\u0435\u0447\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430\u0449\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u044f\u043c\u0430 \u0434\u0430 \u0431\u044a\u0434\u0430\u0442 \u0437\u0430\u043c\u0435\u043d\u044f\u043d\u0438.", + "LabelAutomaticUpdatesTmdbHelp": "\u0410\u043a\u043e \u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e, \u043d\u043e\u0432\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0449\u0435 \u0431\u044a\u0434\u0430\u0442 \u0441\u0432\u0430\u043b\u044f\u043d\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043a\u0430\u0442\u043e \u0441\u0435 \u0434\u043e\u0431\u0430\u0432\u044f\u0442 \u0432\u044a\u0432 TheMovieDB.org. \u0412\u0435\u0447\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430\u0449\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u044f\u043c\u0430 \u0434\u0430 \u0431\u044a\u0434\u0430\u0442 \u0437\u0430\u043c\u0435\u043d\u044f\u043d\u0438.", + "LabelAutomaticUpdatesTvdbHelp": "\u0410\u043a\u043e \u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e, \u043d\u043e\u0432\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0449\u0435 \u0431\u044a\u0434\u0430\u0442 \u0441\u0432\u0430\u043b\u044f\u043d\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043a\u0430\u0442\u043e \u0441\u0435 \u0434\u043e\u0431\u0430\u0432\u044f\u0442 \u0432\u044a\u0432 TheTVDB.com. \u0412\u0435\u0447\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430\u0449\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u044f\u043c\u0430 \u0434\u0430 \u0431\u044a\u0434\u0430\u0442 \u0437\u0430\u043c\u0435\u043d\u044f\u043d\u0438.", + "LabelFanartApiKey": "\u041b\u0438\u0447\u0435\u043d API \u043a\u043b\u044e\u0447:", + "LabelFanartApiKeyHelp": "\u0417\u0430\u044f\u0432\u043a\u0438 \u0434\u043e fanart \u0431\u0435\u0437 \u043b\u0438\u0447\u0435\u043d API \u043a\u043b\u044e\u0447 \u0432\u0440\u044a\u0449\u0430\u0442 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442\u0438, \u043a\u043e\u0438\u0442\u043e \u0441\u0430 \u0431\u0438\u043b\u0438 \u043e\u0434\u043e\u0431\u0440\u0435\u043d\u0438 \u043f\u0440\u0435\u0434\u0438 \u043f\u043e\u0432\u0435\u0447\u0435 \u043e\u0442 7 \u0434\u043d\u0438. \u0421 \u043b\u0438\u0447\u0435\u043d API \u043a\u043b\u044e\u0447, \u0442\u043e\u0432\u0430 \u0432\u0440\u0435\u043c\u0435 \u043f\u0430\u0434\u0430 \u043d\u0430 48 \u0447\u0430\u0441\u0430, \u0430 \u0430\u043a\u043e \u0441\u0442\u0435 \u0438 fanart VIP \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b, \u0442\u043e \u0434\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u043e \u0449\u0435 \u043f\u0430\u0434\u043d\u0435 \u0434\u043e \u043e\u043a\u043e\u043b\u043e 10 \u043c\u0438\u043d\u0443\u0442\u0438.", + "ExtractChapterImagesHelp": "\u0418\u0437\u0432\u043b\u0438\u0447\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0433\u043b\u0430\u0432\u0438\u0442\u0435 \u0449\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0438\u0442\u0435 \u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u0432\u0430\u0442 \u0433\u0440\u0430\u0444\u0438\u0447\u043d\u0438 \u043c\u0435\u043d\u044e\u0442\u0430 \u0437\u0430 \u0438\u0437\u0431\u043e\u0440 \u043d\u0430 \u0441\u0446\u0435\u043d\u0430. \u041f\u0440\u043e\u0446\u0435\u0441\u044a\u0442 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u0431\u0430\u0432\u0435\u043d, CPU-\u0438\u043d\u0442\u0435\u043d\u0437\u0438\u0432\u0435\u043d \u0438 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u043d\u044f\u043a\u043e\u043b\u043a\u043e \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442\u0430 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e. \u0422\u043e \u0440\u0430\u0431\u043e\u0442\u0438 \u043a\u0430\u0442\u043e \u043d\u043e\u0449\u043d\u0430 \u043f\u043b\u0430\u043d\u0438\u0440\u0430\u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0432 4 \u0447\u0430\u0441\u0430 \u0441\u0443\u0442\u0440\u0438\u043d\u0442\u0430, \u0432\u044a\u043f\u0440\u0435\u043a\u0438 \u0447\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430 \u0432 \u041f\u043b\u0430\u043d\u0438\u0440\u0430\u043d\u0438 \u0437\u0430\u0434\u0430\u0447\u0438. \u041d\u0435 \u0441\u0435 \u043f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0432\u0430 \u0442\u0430\u0437\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430 \u043f\u043e \u0432\u0440\u0435\u043c\u0435 \u043d\u0430 \u043f\u0438\u043a\u043e\u0432\u0438\u0442\u0435 \u0447\u0430\u0441\u043e\u0432\u0435 \u043d\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435.", + "LabelMetadataDownloadLanguage": "\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u043d \u0435\u0437\u0438\u043a \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435:", + "ButtonAutoScroll": "\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u043d \u0441\u043a\u0440\u043e\u043b", "LabelImageSavingConvention": "Image saving convention:", - "LabelImageSavingConventionHelp": "Media Browser recognizes images from most major media applications. Choosing your downloading convention is useful if you also use other products.", - "OptionImageSavingCompatible": "Compatible - Media Browser\/Kodi\/Plex", - "OptionImageSavingStandard": "Standard - MB2", - "ButtonSignIn": "Sign In", - "TitleSignIn": "Sign In", - "HeaderPleaseSignIn": "Please sign in", - "LabelUser": "User:", - "LabelPassword": "Password:", - "ButtonManualLogin": "Manual Login", - "PasswordLocalhostMessage": "Passwords are not required when logging in from localhost.", - "TabGuide": "Guide", - "TabChannels": "Channels", - "TabCollections": "Collections", - "HeaderChannels": "Channels", - "TabRecordings": "Recordings", - "TabScheduled": "Scheduled", - "TabSeries": "Series", - "TabFavorites": "Favorites", - "TabMyLibrary": "My Library", - "ButtonCancelRecording": "Cancel Recording", - "HeaderPrePostPadding": "Pre\/Post Padding", - "LabelPrePaddingMinutes": "Pre-padding minutes:", - "OptionPrePaddingRequired": "Pre-padding is required in order to record.", - "LabelPostPaddingMinutes": "Post-padding minutes:", - "OptionPostPaddingRequired": "Post-padding is required in order to record.", - "HeaderWhatsOnTV": "What's On", - "HeaderUpcomingTV": "Upcoming TV", - "TabStatus": "Status", - "TabSettings": "Settings", - "ButtonRefreshGuideData": "Refresh Guide Data", - "ButtonRefresh": "Refresh", - "ButtonAdvancedRefresh": "Advanced Refresh", - "OptionPriority": "Priority", - "OptionRecordOnAllChannels": "Record program on all channels", - "OptionRecordAnytime": "Record program at any time", - "OptionRecordOnlyNewEpisodes": "Record only new episodes", - "HeaderDays": "Days", - "HeaderActiveRecordings": "Active Recordings", - "HeaderLatestRecordings": "Latest Recordings", - "HeaderAllRecordings": "All Recordings", - "ButtonPlay": "Play", - "ButtonEdit": "Edit", - "ButtonRecord": "Record", - "ButtonDelete": "Delete", - "ButtonRemove": "Remove", - "OptionRecordSeries": "Record Series", - "HeaderDetails": "Details", - "TitleLiveTV": "Live TV", - "LabelNumberOfGuideDays": "Number of days of guide data to download:", - "LabelNumberOfGuideDaysHelp": "Downloading more days worth of guide data provides the ability to schedule out further in advance and view more listings, but it will also take longer to download. Auto will choose based on the number of channels.", - "LabelActiveService": "Active Service:", - "LabelActiveServiceHelp": "Multiple tv plugins can be installed but only one can be active at a time.", - "OptionAutomatic": "Auto", - "LiveTvPluginRequired": "A Live TV service provider plugin is required in order to continue.", - "LiveTvPluginRequiredHelp": "Please install one of our available plugins, such as Next Pvr or ServerWmc.", - "LabelCustomizeOptionsPerMediaType": "Customize for media type:", - "OptionDownloadThumbImage": "Thumb", - "OptionDownloadMenuImage": "Menu", - "OptionDownloadLogoImage": "Logo", - "OptionDownloadBoxImage": "Box", - "OptionDownloadDiscImage": "Disc", - "OptionDownloadBannerImage": "Banner", - "OptionDownloadBackImage": "Back", - "OptionDownloadArtImage": "Art", - "OptionDownloadPrimaryImage": "Primary", - "HeaderFetchImages": "Fetch Images:", - "HeaderImageSettings": "Image Settings", - "TabOther": "Other", - "LabelMaxBackdropsPerItem": "Maximum number of backdrops per item:", - "LabelMaxScreenshotsPerItem": "Maximum number of screenshots per item:", - "LabelMinBackdropDownloadWidth": "Minimum backdrop download width:", - "LabelMinScreenshotDownloadWidth": "Minimum screenshot download width:", - "ButtonAddScheduledTaskTrigger": "Add Trigger", - "HeaderAddScheduledTaskTrigger": "Add Trigger", - "ButtonAdd": "Add", - "LabelTriggerType": "Trigger Type:", - "OptionDaily": "Daily", - "OptionWeekly": "Weekly", - "OptionOnInterval": "On an interval", - "OptionOnAppStartup": "On application startup", - "OptionAfterSystemEvent": "After a system event", - "LabelDay": "Day:", - "LabelTime": "Time:", - "LabelEvent": "Event:", - "OptionWakeFromSleep": "Wake from sleep", - "LabelEveryXMinutes": "Every:", - "HeaderTvTuners": "Tuners", - "HeaderGallery": "Gallery", - "HeaderLatestGames": "Latest Games", - "HeaderRecentlyPlayedGames": "Recently Played Games", - "TabGameSystems": "Game Systems", - "TitleMediaLibrary": "Media Library", - "TabFolders": "Folders", - "TabPathSubstitution": "Path Substitution", - "LabelSeasonZeroDisplayName": "Season 0 display name:", - "LabelEnableRealtimeMonitor": "Enable real time monitoring", - "LabelEnableRealtimeMonitorHelp": "Changes will be processed immediately, on supported file systems.", - "ButtonScanLibrary": "Scan Library", - "HeaderNumberOfPlayers": "Players:", - "OptionAnyNumberOfPlayers": "Any", + "LabelImageSavingConventionHelp": "Media Browser \u0440\u0430\u0437\u043f\u043e\u0437\u043d\u0430\u0432\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043e\u0442 \u0433\u043e\u043b\u044f\u043c\u0430 \u0447\u0430\u0441\u0442 \u043c\u0435\u0434\u0438\u0439\u043d\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0418\u0437\u0431\u043e\u0440\u044a\u0442 \u0432\u0438 \u043d\u0430 \u043a\u043e\u043d\u0432\u0435\u043d\u0446\u0438\u044f \u043d\u0430 \u0438\u0437\u0442\u0435\u0433\u043b\u044f\u043d\u0435 \u0435 \u043f\u043e\u043b\u0435\u0437\u0435\u043d, \u0430\u043a\u043e \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435 \u0438 \u0434\u0440\u0443\u0433\u0438 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0438.", + "OptionImageSavingCompatible": "\u0421\u044a\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u0438 - Media Browser\/Kodi\/Plex", + "OptionImageSavingStandard": "\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438 - MB2", + "ButtonSignIn": "\u0412\u043b\u0438\u0437\u0430\u043d\u0435", + "TitleSignIn": "\u0412\u043b\u0438\u0437\u0430\u043d\u0435", + "HeaderPleaseSignIn": "\u041c\u043e\u043b\u044f, \u0432\u043b\u0435\u0437\u0442\u0435", + "LabelUser": "\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b:", + "LabelPassword": "\u041f\u0430\u0440\u043e\u043b\u0430:", + "ButtonManualLogin": "\u0412\u0445\u043e\u0434 \u0441 \u0438\u043c\u0435 \u0438 \u043f\u0430\u0440\u043e\u043b\u0430", + "PasswordLocalhostMessage": "\u041f\u0430\u0440\u043e\u043b\u0438\u0442\u0435 \u043d\u0435 \u0441\u0430 \u0437\u0430\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u0438, \u043a\u043e\u0433\u0430\u0442\u043e \u0432\u043b\u0438\u0437\u0430\u0442\u0435 \u043e\u0442 localhost", + "TabGuide": "\u0420\u044a\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e", + "TabChannels": "\u041a\u0430\u043d\u0430\u043b\u0438", + "TabCollections": "\u041a\u043e\u043b\u0435\u043a\u0446\u0438\u0438", + "HeaderChannels": "\u041a\u0430\u043d\u0430\u043b\u0438", + "TabRecordings": "\u0417\u0430\u043f\u0438\u0441\u0438", + "TabScheduled": "\u041f\u043b\u0430\u043d\u0438\u0440\u0430\u043d\u0438", + "TabSeries": "\u041f\u0440\u0435\u0434\u0430\u0432\u0430\u043d\u0438\u044f", + "TabFavorites": "\u041b\u044e\u0431\u0438\u043c\u0438", + "TabMyLibrary": "\u041c\u043e\u044f\u0442\u0430 \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430", + "ButtonCancelRecording": "\u041f\u0440\u0435\u043a\u044a\u0441\u043d\u0438 \u0417\u0430\u043f\u0438\u0441\u0432\u0430\u043d\u0435\u0442\u043e", + "HeaderPrePostPadding": "\u041f\u0440\u0435\u0434\u0435\u043d\/\u0417\u0430\u0434\u0435\u043d \u0431\u0430\u043b\u0430\u0441\u0442", + "LabelPrePaddingMinutes": "\u041f\u0440\u0435\u0434\u0435\u043d \u0431\u0430\u043b\u0430\u0441\u0442 \u0432 \u043c\u0438\u043d\u0443\u0442\u0438:", + "OptionPrePaddingRequired": "\u041f\u0440\u0435\u0434\u043d\u0438\u044f\u0442 \u0431\u0430\u043b\u0430\u0441\u0442 \u0435 \u0437\u0430\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u0435\u043d, \u0437\u0430 \u0434\u0430 \u0437\u0430\u043f\u0438\u0441\u0432\u0430\u0442\u0435. (\u0414\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0438 \u043c\u0438\u043d\u0443\u0442\u0438 \u043f\u0440\u0435\u0434\u0438 \u043d\u0430\u0447\u0430\u043b\u043e\u0442\u043e)", + "LabelPostPaddingMinutes": "\u0417\u0430\u0434\u0435\u043d \u0431\u0430\u043b\u0430\u0441\u0442 \u0432 \u043c\u0438\u043d\u0443\u0442\u0438:", + "OptionPostPaddingRequired": "\u0417\u0430\u0434\u043d\u0438\u044f\u0442 \u0431\u0430\u043b\u0430\u0441\u0442 \u0435 \u0437\u0430\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u0435\u043d, \u0437\u0430 \u0434\u0430 \u0437\u0430\u043f\u0438\u0441\u0432\u0430\u0442\u0435. (\u0414\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0438 \u043c\u0438\u043d\u0443\u0442\u0438 \u0441\u043b\u0435\u0434 \u043a\u0440\u0430\u044f)", + "HeaderWhatsOnTV": "\u0412 \u043c\u043e\u043c\u0435\u043d\u0442\u0430", + "HeaderUpcomingTV": "\u041f\u0440\u0435\u0434\u0441\u0442\u043e\u044f\u0449\u0430 TV", + "TabStatus": "\u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435", + "TabSettings": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438", + "ButtonRefreshGuideData": "\u041e\u0431\u043d\u043e\u0432\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f\u0442\u0430 \u0432 \u0433\u0438\u0434-\u0430", + "ButtonRefresh": "\u041e\u0431\u043d\u043e\u0432\u0438", + "ButtonAdvancedRefresh": "\u041e\u0431\u043d\u043e\u0432\u0438 \u0434\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u043e", + "OptionPriority": "\u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442", + "OptionRecordOnAllChannels": "\u0417\u0430\u043f\u0438\u0441\u0432\u0430\u0439 \u043f\u0440\u0435\u0434\u0430\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u043a\u0430\u043d\u0430\u043b\u0438", + "OptionRecordAnytime": "\u0417\u0430\u043f\u0438\u0441\u0432\u0430\u0439 \u043f\u0440\u0435\u0434\u0430\u0432\u0430\u043d\u0435\u0442\u043e \u043f\u043e \u0432\u0441\u044f\u043a\u043e \u0432\u0440\u0435\u043c\u0435", + "OptionRecordOnlyNewEpisodes": "\u0417\u0430\u043f\u0438\u0441\u0432\u0430\u0439 \u0441\u0430\u043c\u043e \u043d\u043e\u0432\u0438 \u0435\u043f\u0438\u0437\u043e\u0434\u0438", + "HeaderDays": "\u0414\u043d\u0438", + "HeaderActiveRecordings": "\u0410\u043a\u0442\u0438\u0432\u043d\u0438 \u0417\u0430\u043f\u0438\u0441\u0438", + "HeaderLatestRecordings": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0417\u0430\u043f\u0438\u0441\u0438", + "HeaderAllRecordings": "\u0412\u0441\u0438\u0447\u043a\u0438 \u0417\u0430\u043f\u0438\u0441\u0438", + "ButtonPlay": "\u041f\u0443\u0441\u043d\u0438", + "ButtonEdit": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u0439", + "ButtonRecord": "\u0417\u0430\u043f\u0438\u0448\u0438", + "ButtonDelete": "\u0418\u0437\u0442\u0440\u0438\u0439", + "ButtonRemove": "\u041f\u0440\u0435\u043c\u0430\u0445\u043d\u0438", + "OptionRecordSeries": "\u0417\u0430\u043f\u0438\u0448\u0438 \u041f\u0440\u0435\u0434\u0430\u0432\u0430\u043d\u0438\u044f", + "HeaderDetails": "\u0414\u0435\u0442\u0430\u0439\u043b\u0438", + "TitleLiveTV": "\u0422V \u043d\u0430 \u0436\u0438\u0432\u043e", + "LabelNumberOfGuideDays": "\u0411\u0440\u043e\u0439 \u0434\u043d\u0438 \u0437\u0430 \u043a\u043e\u0438\u0442\u043e \u0434\u0430 \u0441\u0435 \u0441\u0432\u0430\u043b\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430:", + "LabelNumberOfGuideDaysHelp": "\u0418\u0437\u0442\u0435\u0433\u043b\u044f\u043d\u0435\u0442\u043e \u043d\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430 \u0437\u0430\u043f\u043e\u0432\u0435\u0447\u0435 \u0434\u043d\u0438 \u0434\u0430\u0432\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u0434\u0430 \u043f\u043b\u0430\u043d\u0438\u0440\u0430\u0442\u0435 \u043f\u043e-\u043d\u0430\u0442\u0430\u0442\u044a\u0448\u043d\u0438\u0442\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u043d\u043e, \u043d\u043e \u0438 \u043e\u0442\u043d\u0435\u043c\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0432\u0440\u0435\u043c\u0435, \u0437\u0430 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0442\u0435\u0433\u043b\u0438. \u0410\u0432\u0442\u043e\u043c\u0430\u0442 \u0449\u0435 \u0438\u0437\u0431\u0435\u0440\u0435 \u0432\u044a\u0437 \u043e\u0441\u043d\u043e\u0432\u0430 \u043d\u0430 \u0431\u0440\u043e\u044f \u043d\u0430 \u043a\u0430\u043d\u0430\u043b\u0438\u0442\u0435.", + "LabelActiveService": "\u0410\u043a\u0442\u0438\u0432\u043d\u0430 \u0423\u0441\u043b\u0443\u0433\u0430:", + "LabelActiveServiceHelp": "\u041d\u044f\u043a\u043e\u043b\u043a\u043e TV \u0434\u043e\u0431\u0430\u0432\u043a\u0438 \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0431\u044a\u0434\u0430\u0442 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0438, \u043d\u043e \u0441\u0430\u043c\u043e \u0435\u0434\u043d\u0430 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0430 \u043f\u043e \u0435\u0434\u043d\u043e \u0438 \u0441\u044a\u0449\u043e \u0432\u0440\u0435\u043c\u0435.", + "OptionAutomatic": "\u0410\u0432\u0442\u043e\u043c\u0430\u0442", + "LiveTvPluginRequired": "\u041d\u0435\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0435 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u0437\u0430 \u0433\u043b\u0435\u0434\u0430\u043d\u0435 \u043d\u0430 \u0442\u0435\u043b\u0435\u0432\u0438\u0437\u0438\u044f \u043d\u0430 \u0436\u0438\u0432\u043e, \u0437\u0430 \u0434\u0430 \u0441\u0435 \u043f\u0440\u043e\u0434\u044a\u043b\u0436\u0438.", + "LiveTvPluginRequiredHelp": "\u041c\u043e\u043b\u044f, \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u0439\u0442\u0435 \u043d\u044f\u043a\u043e\u044f \u043e\u0442 \u043d\u0430\u043b\u0438\u0447\u043d\u0438\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438, \u043a\u0430\u0442\u043e \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 Next Pvr \u0438\u043b\u0438 ServerWmc.", + "LabelCustomizeOptionsPerMediaType": "\u041f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 \u0442\u0438\u043f \u043c\u0435\u0434\u0438\u044f:", + "OptionDownloadThumbImage": "\u041c\u0438\u043d\u0438\u0430\u0442\u044e\u0440\u0430", + "OptionDownloadMenuImage": "\u041c\u0435\u043d\u044e", + "OptionDownloadLogoImage": "\u041b\u043e\u0433\u043e", + "OptionDownloadBoxImage": "\u041a\u0443\u0442\u0438\u044f", + "OptionDownloadDiscImage": "\u0414\u0438\u0441\u043a", + "OptionDownloadBannerImage": "\u0411\u0430\u043d\u0435\u0440", + "OptionDownloadBackImage": "\u0417\u0430\u0434\u043d\u0430 \u0447\u0430\u0441\u0442", + "OptionDownloadArtImage": "\u0418\u0437\u043a\u0443\u0441\u0442\u0432\u043e", + "OptionDownloadPrimaryImage": "\u041a\u043e\u0440\u0438\u0446\u0430", + "HeaderFetchImages": "\u0421\u0432\u0430\u043b\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f:", + "HeaderImageSettings": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u0430\u0442\u0430", + "TabOther": "\u0414\u0440\u0443\u0433\u0438", + "LabelMaxBackdropsPerItem": "\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u0435\u043d \u0431\u0440\u043e\u0439 \u0444\u043e\u043d\u043e\u0432\u0435 \u043d\u0430 \u043c\u0435\u0434\u0438\u044f:", + "LabelMaxScreenshotsPerItem": "\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u0435\u043d \u0431\u0440\u043e\u0439 \u0441\u043a\u0440\u0438\u0439\u043d\u0448\u043e\u0442\u0438 \u043d\u0430 \u043c\u0435\u0434\u0438\u044f:", + "LabelMinBackdropDownloadWidth": "\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u043d\u0430 \u0448\u0438\u0440\u043e\u0447\u0438\u043d\u0430 \u043d\u0430 \u0441\u0432\u0430\u043b\u0435\u043d\u0438\u044f \u0444\u043e\u043d:", + "LabelMinScreenshotDownloadWidth": "\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u043d\u0430 \u0448\u0438\u0440\u043e\u0447\u0438\u043d\u0430 \u043d\u0430 \u0441\u0432\u0430\u043b\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u0439\u043d\u0448\u043e\u0442:", + "ButtonAddScheduledTaskTrigger": "\u0414\u043e\u0431\u0430\u0432\u0438 \u0441\u043f\u0443\u0441\u044a\u043a", + "HeaderAddScheduledTaskTrigger": "\u0414\u043e\u0431\u0430\u0432\u0438 \u0441\u043f\u0443\u0441\u044a\u043a", + "ButtonAdd": "\u0414\u043e\u0431\u0430\u0432\u0438", + "LabelTriggerType": "\u0422\u0438\u043f \u043d\u0430 \u0441\u043f\u0443\u0441\u044a\u043a\u0430:", + "OptionDaily": "\u0414\u043d\u0435\u0432\u043d\u043e", + "OptionWeekly": "\u0421\u0435\u0434\u043c\u0438\u0447\u043d\u043e", + "OptionOnInterval": "\u041f\u0440\u0435\u0437 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b", + "OptionOnAppStartup": "\u041a\u0430\u0442\u043e \u0441\u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u0442\u043e", + "OptionAfterSystemEvent": "\u0421\u043b\u0435\u0434 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e \u0441\u044a\u0431\u0438\u0442\u0438\u0435", + "LabelDay": "\u0414\u0435\u043d:", + "LabelTime": "\u0412\u0440\u0435\u043c\u0435:", + "LabelEvent": "\u0421\u044a\u0431\u0438\u0442\u0438\u0435:", + "OptionWakeFromSleep": "\u0421\u044a\u0431\u0443\u0436\u0434\u0430\u043d\u0435 \u043e\u0442 \u0441\u044a\u043d", + "LabelEveryXMinutes": "\u041d\u0430 \u0432\u0441\u0435\u043a\u0438:", + "HeaderTvTuners": "\u0422\u0443\u043d\u0435\u0440\u0438", + "HeaderGallery": "\u0413\u0430\u043b\u0435\u0440\u0438\u044f", + "HeaderLatestGames": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438 \u0418\u0433\u0440\u0438", + "HeaderRecentlyPlayedGames": "\u0421\u043a\u043e\u0440\u043e \u0418\u0433\u0440\u0430\u043d\u0438 \u0418\u0433\u0440\u0438", + "TabGameSystems": "\u0418\u0433\u0440\u043e\u0432\u0438 \u0421\u0438\u0441\u0442\u0435\u043c\u0438", + "TitleMediaLibrary": "\u041c\u0435\u0434\u0438\u0439\u043d\u0430 \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430", + "TabFolders": "\u041f\u0430\u043f\u043a\u0438", + "TabPathSubstitution": "\u0417\u0430\u043c\u0435\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u044a\u0442", + "LabelSeasonZeroDisplayName": "\u0418\u043c\u0435 \u043d\u0430 \u0421\u0435\u0437\u043e\u043d 0:", + "LabelEnableRealtimeMonitor": "\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u0435 \u0432 \u0440\u0435\u0430\u043b\u043d\u043e \u0432\u0440\u0435\u043c\u0435", + "LabelEnableRealtimeMonitorHelp": "\u041f\u0440\u043e\u043c\u0435\u043d\u0438\u0442\u0435 \u0449\u0435 \u0431\u044a\u0434\u0430\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0435\u043d\u0438 \u0432\u0435\u0434\u043d\u0430\u0433\u0430, \u043d\u0430 \u043f\u043e\u0434\u0434\u044a\u0440\u0436\u0430\u043d\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0438.", + "ButtonScanLibrary": "\u0421\u043a\u0430\u043d\u0438\u0440\u0430\u0439 \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0442\u0430", + "HeaderNumberOfPlayers": "\u041f\u043b\u0435\u0439\u044a\u0440\u0438:", + "OptionAnyNumberOfPlayers": "\u0412\u0441\u0435\u043a\u0438", "Option1Player": "1+", "Option2Player": "2+", "Option3Player": "3+", "Option4Player": "4+", - "HeaderMediaFolders": "Media Folders", - "HeaderThemeVideos": "Theme Videos", - "HeaderThemeSongs": "Theme Songs", - "HeaderScenes": "Scenes", - "HeaderAwardsAndReviews": "Awards and Reviews", - "HeaderSoundtracks": "Soundtracks", - "HeaderMusicVideos": "Music Videos", - "HeaderSpecialFeatures": "Special Features", - "HeaderCastCrew": "Cast & Crew", - "HeaderAdditionalParts": "Additional Parts", + "HeaderMediaFolders": "\u041c\u0435\u0434\u0438\u0439\u043d\u0438 \u041f\u0430\u043f\u043a\u0438", + "HeaderThemeVideos": "\u0422\u0435\u043c\u0430\u0442\u0438\u0447\u043d\u0438 \u043a\u043b\u0438\u043f\u043e\u0432\u0435", + "HeaderThemeSongs": "\u0422\u0435\u043c\u0430\u0442\u0438\u0447\u043d\u0438 \u043f\u0435\u0441\u043d\u0438", + "HeaderScenes": "\u0421\u0446\u0435\u043d\u0438", + "HeaderAwardsAndReviews": "\u041d\u0430\u0433\u0440\u0430\u0434\u0438 \u0438 \u0440\u0435\u0432\u044e\u0442\u0430", + "HeaderSoundtracks": "\u0424\u0438\u043b\u043c\u043e\u0432\u0430 \u043c\u0443\u0437\u0438\u043a\u0430", + "HeaderMusicVideos": "\u041c\u0443\u0437\u0438\u043a\u0430\u043b\u043d\u0438 \u043a\u043b\u0438\u043f\u043e\u0432\u0435", + "HeaderSpecialFeatures": "\u0421\u043f\u0435\u0446\u0438\u0430\u043b\u043d\u0438 \u0414\u043e\u0431\u0430\u0432\u043a\u0438", + "HeaderCastCrew": "\u0415\u043a\u0438\u043f", + "HeaderAdditionalParts": "\u0414\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0438 \u0427\u0430\u0441\u0442\u0438", "ButtonSplitVersionsApart": "Split Versions Apart", "ButtonPlayTrailer": "Trailer", "LabelMissing": "Missing", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ca.json b/MediaBrowser.Server.Implementations/Localization/Server/ca.json index 340a9ee7b..902d7e4b6 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/ca.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/ca.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/cs.json b/MediaBrowser.Server.Implementations/Localization/Server/cs.json index 79ca05ebc..b710000d7 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/cs.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/cs.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "P\u0159eklad programu Media Browser prob\u00edh\u00e1, a je\u0161t\u011b nen\u00ed dokon\u010den.", "LabelReadHowYouCanContribute": "P\u0159e\u010dt\u011bte si o tom, jak m\u016f\u017eete p\u0159isp\u011bt.", "HeaderNewCollection": "Nov\u00e1 kolekce", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "P\u0159\u00edklad: Kolekce Star Wars", - "OptionSearchForInternetMetadata": "Prohledat internet pro nalezen\u00ed metadat a obalu.", "ButtonCreate": "Vytvo\u0159it", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Nejsledovan\u011bj\u0161\u00ed", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Filmy", "ViewTypeTvShows": "Televize", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Slu\u017eby", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/da.json b/MediaBrowser.Server.Implementations/Localization/Server/da.json index c31bc43c2..e181b8ddd 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/da.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/da.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/de.json b/MediaBrowser.Server.Implementations/Localization/Server/de.json index 901cd8b8c..9811c65d6 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/de.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/de.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Pfade", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Benachrichtigungen", "ButtonDonateWithPayPal": "Spende mit PayPal", "OptionDetectArchiveFilesAsMedia": "Behandle Archive wie Medien", @@ -290,7 +296,7 @@ "OptionMetascore": "Metascore", "ButtonSelect": "Ausw\u00e4hlen", "ButtonGroupVersions": "Gruppiere Versionen", - "ButtonAddToCollection": "Zur Sammlung hinzuf\u00fcgen", + "ButtonAddToCollection": "Add to Collection", "PismoMessage": "Verwendet Pismo File Mount durch eine gespendete Lizenz.", "TangibleSoftwareMessage": "Verwendung konkreter L\u00f6sungen von Java\/C# Konvertern durch eine gespendete Lizenz.", "HeaderCredits": "Herausgeber", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Die \u00dcbersetzung von Media Browser ist ein andauerndes Projekt und noch nicht abgeschlossen.", "LabelReadHowYouCanContribute": "Lese wie du dazu beitragen kannst.", "HeaderNewCollection": "Neue Collection", - "HeaderAddToCollection": "Zur Sammlung hinzuf\u00fcgen", "ButtonSubmit": "Best\u00e4tigen", - "NewCollectionNameExample": "Beispiel: Star Wars Collection", - "OptionSearchForInternetMetadata": "Suche im Internet nach Bildmaterial und Metadaten", "ButtonCreate": "Kreieren", "LabelCustomCss": "Benutzerdefinierte CSS:", "LabelCustomCssHelp": "Wende deine eigene, benutzerdefinierte CSS f\u00fcr das Webinterface an.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Meistgesehen", "TabNextUp": "Als N\u00e4chstes", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "Momentan sind keine Filmvorschl\u00e4ge verf\u00fcgbar. Schaue und bewerte zuerst deine Filme. Komme danach zur\u00fcck, um deine Filmvorschl\u00e4ge anzuschauen.", "MessageNoCollectionsAvailable": "Sammlungen erlauben Ihnen eine personalisierte Gruppierung von Filmen, Serien, Alben, B\u00fcchern und Spielen. Klicken Sie die + Schaltfl\u00e4che um Sammlungen zu erstellen.", "MessageNoPlaylistsAvailable": "Wiedergabeliste erlauben es dir eine Liste mit Inhalt zu erstellen der fortlaufend abgespielt wird. Um einer Wiedergabeliste Inhalte hinzuzuf\u00fcgen klicke rechts oder mache einen langen Tap und w\u00e4hle daraufhin \"Zur Wiedergabeliste hinzuf\u00fcgen\" aus.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "L\u00f6sche Inhalt nach: (Tagen)", "LabelChannelDownloadAgeHelp": "Heruntergeladene Inhalte die \u00e4lter als dieser Wert sind werden gel\u00f6scht. Sie werden aber weiterhin \u00fcber das Internetstreaming verf\u00fcgbar sein.", "ChannelSettingsFormHelp": "Installiere Kan\u00e4le wie beispielsweise \"Trailers\" oder \"Vimeo\" aus dem Plugin Katalog.", - "LabelSelectCollection": "W\u00e4hle Zusammenstellung:", "ButtonOptions": "Optionen", "ViewTypeMovies": "Filme", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Zeige die folgenden Kan\u00e4le direkt innerhalb meiner Ansichten:", "LabelGroupChannelsIntoViewsHelp": "Falls aktiviert, werden diese Kan\u00e4le direkt neben den anderen Ansichten angezeigt. Falls deaktiviert, werden sie innerhalb einer separaten Kanalansicht angezeigt.", "LabelDisplayCollectionsView": "Zeigt eine Ansicht f\u00fcr Sammlungen, um Filmsammlungen darzustellen", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Kopiere Extrafanart in Extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "Beim downloaden von Bildern k\u00f6nnen diese sowohl als Extrafanart als auch als Extrathumb gespeichert werden, um maximale Kodi Kompatibilit\u00e4t zu erzielen.", "TabServices": "Dienste", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/el.json b/MediaBrowser.Server.Implementations/Localization/Server/el.json index 6d2060729..15c452b6c 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/el.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/el.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/en_GB.json b/MediaBrowser.Server.Implementations/Localization/Server/en_GB.json index bb0f1f098..9dcb925c2 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/en_GB.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/en_GB.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/en_US.json b/MediaBrowser.Server.Implementations/Localization/Server/en_US.json index 2947adc19..feab23007 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/en_US.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/en_US.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/es.json b/MediaBrowser.Server.Implementations/Localization/Server/es.json index 4f28ddb60..e64dcbfd5 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/es.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/es.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -290,7 +296,7 @@ "OptionMetascore": "Metavalor", "ButtonSelect": "Seleccionar", "ButtonGroupVersions": "Versiones de Grupo", - "ButtonAddToCollection": "A\u00f1adir a la colecci\u00f3n", + "ButtonAddToCollection": "Add to Collection", "PismoMessage": "Usando Pismo File Mount a trav\u00e9s de una licencia donada.", "TangibleSoftwareMessage": "Utilizamos convertidores Java\/C# de Tangible Solutions a trav\u00e9s de una licencia donada.", "HeaderCredits": "Cr\u00e9ditos", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "La traducci\u00f3n de Media Browser es un proyecto en curso y a\u00fan no est\u00e1 completado.", "LabelReadHowYouCanContribute": "Lea acerca de c\u00f3mo usted puede contribuir.", "HeaderNewCollection": "Nueva colecci\u00f3n", - "HeaderAddToCollection": "A\u00f1adir a la colecci\u00f3n", "ButtonSubmit": "Enviar", - "NewCollectionNameExample": "Ejemplo: Star Wars Colecci\u00f3n", - "OptionSearchForInternetMetadata": "Buscar en internet ilustraciones y metadatos", "ButtonCreate": "Crear", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Por defecto", "OptionCommunityMostWatchedSort": "M\u00e1s visto", "TabNextUp": "Siguiendo", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No hay sugerencias de pel\u00edculas disponibles. Comience ver y calificar sus pel\u00edculas y vuelva para ver las recomendaciones.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Borrar contenido despues de: (d\u00edas)", "LabelChannelDownloadAgeHelp": "Todo contenido descargado anterior se borrar\u00e1. Continuar\u00e1 estando disponible v\u00eda streaming de internet.", "ChannelSettingsFormHelp": "Instale canales como Trailers y Vimeo desde el cat\u00e1logo de plugins.", - "LabelSelectCollection": "Seleccionar colecci\u00f3n:", "ButtonOptions": "Options", "ViewTypeMovies": "Pel\u00edculas", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "Si est\u00e1 activado, estos canales se mostrar\u00e1n directamente junto a Mis Vistas. Si est\u00e1 desactivada, ser\u00e1n mostrados separadamente en la vista de Canales.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Servicios", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/es_MX.json b/MediaBrowser.Server.Implementations/Localization/Server/es_MX.json index 27f364018..ed9e92772 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/es_MX.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/es_MX.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Rutas", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notificaciones", "ButtonDonateWithPayPal": "Donar con PayPal", "OptionDetectArchiveFilesAsMedia": "Detectar archivos comprimidos como medios", @@ -290,7 +296,7 @@ "OptionMetascore": "Metascore", "ButtonSelect": "Seleccionar", "ButtonGroupVersions": "Agrupar Versiones", - "ButtonAddToCollection": "Agregar a Colecci\u00f3n", + "ButtonAddToCollection": "Add to Collection", "PismoMessage": "Utilizando Pismo File Mount a trav\u00e9s de una licencia donada.", "TangibleSoftwareMessage": "Utilizando convertidores Java\/C# de Tangible Solutions por medio de una licencia donada.", "HeaderCredits": "Cr\u00e9ditos", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "La traducci\u00f3n de Media Browser es un proyecto en curso y a\u00fan no se ha completado.", "LabelReadHowYouCanContribute": "Lea acerca de c\u00f3mo puede contribuir.", "HeaderNewCollection": "Nueva Colecci\u00f3n", - "HeaderAddToCollection": "Agregar a Colecci\u00f3n.", "ButtonSubmit": "Enviar", - "NewCollectionNameExample": "Ejemplo: Colecci\u00f3n Guerra de las Galaxias", - "OptionSearchForInternetMetadata": "Buscar en internet ilustraciones y metadatos", "ButtonCreate": "Crear", "LabelCustomCss": "css personalizado:", "LabelCustomCssHelp": "Aplicar tu propia css personalizada a la interfaz web.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Por defecto", "OptionCommunityMostWatchedSort": "M\u00e1s Visto", "TabNextUp": "A Continuaci\u00f3n", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No hay sugerencias de pel\u00edculas disponibles en este momento. Comienza a ver y a calificar tus pel\u00edculas, y regresa para ver tus recomendaciones.", "MessageNoCollectionsAvailable": "Las colecciones le permiten disfrutar de agrupaciones personalizadas de Pel\u00edculas, Series, \u00c1lbums, Libros y Juegos. Haga clic en el bot\u00f3n + para iniciar la creaci\u00f3n de Colecciones.", "MessageNoPlaylistsAvailable": "Las listas de reproducci\u00f3n le permiten crear listas de contenidos a ser reproducidos de manera consecutiva. Para a\u00f1adir \u00edtems a una lista de reproducci\u00f3n, haga clic derecho o seleccione y mantenga, despu\u00e9s seleccione A\u00f1adir a Lista de Reproducci\u00f3n.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Eliminar contenido despu\u00e9s de: (d\u00edas)", "LabelChannelDownloadAgeHelp": "El contenido descargado anterior a esto ser\u00e1 eliminado. Permanecer\u00e1 reproducible via transmisi\u00f3n en tiempo real por Internet.", "ChannelSettingsFormHelp": "Instale canales tales como Avances y Vimeo desde el cat\u00e1logo de complementos.", - "LabelSelectCollection": "Elegir colecci\u00f3n:", "ButtonOptions": "Opciones", "ViewTypeMovies": "Pel\u00edculas", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Desplegar los siguientes canales directamente en mis vistas:", "LabelGroupChannelsIntoViewsHelp": "Al activarse, estos canales ser\u00e1n desplegados directamente junto con otras vistas. Si permanecen deshabilitados, ser\u00e1n desplegados dentro de una vista independiente de Canales.", "LabelDisplayCollectionsView": "Desplegar una vista de colecciones para mostrar las colecciones de pel\u00edculas", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copiar extrafanart en extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "Cuando se descargan im\u00e1genes pueden ser almacenadas tanto en extrafanart como extrathumb para maximizar la compatibilidad con skins de Kodi.", "TabServices": "Servicios", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/fi.json b/MediaBrowser.Server.Implementations/Localization/Server/fi.json index 6ce491a52..e305a1011 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/fi.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/fi.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/fr.json b/MediaBrowser.Server.Implementations/Localization/Server/fr.json index 42b81e59e..9d0c62479 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/fr.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/fr.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Vid\u00e9o", "HeaderPaths": "Chemins", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "R\u00e9pertoire de fichiers temporaires :", + "LabelSyncTempPathHelp": "Sp\u00e9cifiez un r\u00e9pertoire de travail pour la synchronisation. Les fichiers r\u00e9sultant de la conversion de m\u00e9dias au cours du processus de synchronisation seront stock\u00e9s ici.", + "LabelCustomCertificatePath": "Chemin vers le certificat personnalis\u00e9 :", + "LabelCustomCertificatePathHelp": "Fournissez votre propre certificat SSL. Sinon, le serveur cr\u00e9era un certificat auto-sign\u00e9.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Faire un don avec Paypal", "OptionDetectArchiveFilesAsMedia": "Reconna\u00eetre les fichiers archives comme m\u00e9dias", @@ -290,7 +296,7 @@ "OptionMetascore": "Metascore", "ButtonSelect": "S\u00e9lectionner", "ButtonGroupVersions": "Versions des groupes", - "ButtonAddToCollection": "Ajouter \u00e0 la collection", + "ButtonAddToCollection": "Ajouter \u00e0 une collection", "PismoMessage": "Utilisation de \"Pismo File Mount\" par une licence fournie.", "TangibleSoftwareMessage": "Utilisation de convertisseurs Tangible Solutions Java\/C# par licence fournie.", "HeaderCredits": "Cr\u00e9dits", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "La traduction de Media Browser est un projet en cours et peut \u00eatre incompl\u00e8te par endroits.", "LabelReadHowYouCanContribute": "Lire comment vous pouvez contribuer.", "HeaderNewCollection": "Nouvelle collection", - "HeaderAddToCollection": "Ajouter \u00e0 la collection", "ButtonSubmit": "Soumettre", - "NewCollectionNameExample": "Exemple: Collection Star Wars", - "OptionSearchForInternetMetadata": "Rechercher sur Internet les images et m\u00e9tadonn\u00e9es", "ButtonCreate": "Cr\u00e9er", "LabelCustomCss": "Css personnalis\u00e9e :", "LabelCustomCssHelp": "Appliquez votre propre feuille de styles css personnalis\u00e9e \u00e0 l'interface web.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Par d\u00e9faut", "OptionCommunityMostWatchedSort": "Les plus lus", "TabNextUp": "Prochains \u00e0 voir", + "HeaderBecomeMediaBrowserSupporter": "Devenez supporteur de Media Browser", + "TextAccessPremiumFeatures": "Profitez de fonctionnalit\u00e9s Premium", "MessageNoMovieSuggestionsAvailable": "Aucune suggestion de film n'est actuellement disponible. Commencez \u00e0 regarder et notez vos films pour avoir des suggestions.", "MessageNoCollectionsAvailable": "Les collections vous permettent de tirer parti de groupements personnalis\u00e9s de films, de s\u00e9ries, d'albums audio, de livres et de jeux. Cliquez sur le bouton + pour commencer \u00e0 cr\u00e9er des Collections.", "MessageNoPlaylistsAvailable": "Les listes de lectures vous permettent de cr\u00e9er des listes de contenus \u00e0 lire en continu en une fois. Pour ajouter un \u00e9l\u00e9ment \u00e0 la liste, faire un clic droit ou appuyer et maintenez, puis s\u00e9lectionnez Ajouter \u00e0 la liste de lecture", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Supprimer le contenu apr\u00e8s : (jours)", "LabelChannelDownloadAgeHelp": "Le contenu t\u00e9l\u00e9charg\u00e9 plus vieux que cette valeur sera supprim\u00e9. Il restera disponible \u00e0 la lecture par streaming Internet.", "ChannelSettingsFormHelp": "Installer des cha\u00eenes comme \"Trailers\" et \"Vimeo\" dans le catalogue des plugins.", - "LabelSelectCollection": "S\u00e9lectionner la collection :", "ButtonOptions": "Options", "ViewTypeMovies": "Films", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Afficher directement les cha\u00eenes suivantes dans mes vues.", "LabelGroupChannelsIntoViewsHelp": "Si activ\u00e9, ces cha\u00eenes seront directement affich\u00e9es \u00e0 c\u00f4t\u00e9 des autres vues. Si d\u00e9sactiv\u00e9, elles seront affich\u00e9es dans une vue de cha\u00eenes s\u00e9par\u00e9es.", "LabelDisplayCollectionsView": "Afficher un aper\u00e7u de collections pour montrer les collections de film", + "LabelDisplayCollectionsViewHelp": "Ceci cr\u00e9era une vue s\u00e9par\u00e9e pour l'affichage des collections que vous avez cr\u00e9\u00e9es ou auxquelles vous avez acc\u00e8s. Pour cr\u00e9er une collection, faites un clic-droit ou tapotez et maintenez l'\u00e9cran sur un film, puis choisissez 'Ajouter \u00e0 une collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copier les extrafanart dans les extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "Pendant le t\u00e9l\u00e9chargement, les images peuvent \u00eatre sauvegard\u00e9es en tant qu'extrafanart et extrathumbs pour am\u00e9liorer la compatibilit\u00e9 avec le skin Xbmc.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/he.json b/MediaBrowser.Server.Implementations/Localization/Server/he.json index e5457fce2..6d3e7fe5d 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/he.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/he.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "\u05ea\u05e8\u05d2\u05d5\u05dd Media Browser \u05d4\u05d5\u05d0 \u05ea\u05d4\u05dc\u05d9\u05da \u05d1\u05d4\u05ea\u05d4\u05d5\u05d5\u05ea \u05d5\u05e2\u05d3\u05d9\u05df \u05dc\u05d0 \u05de\u05d5\u05e9\u05dc\u05dd.", "LabelReadHowYouCanContribute": "\u05e7\u05e8\u05d0 \u05db\u05d9\u05e6\u05d3 \u05d0\u05ea\u05d4 \u05d9\u05db\u05d5\u05dc \u05dc\u05ea\u05e8\u05d5\u05dd.", "HeaderNewCollection": "\u05d0\u05d5\u05e4\u05e1\u05d9\u05dd \u05d7\u05d3\u05e9\u05d9\u05dd", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "\u05dc\u05d3\u05d5\u05d2\u05de\u05d0 :\u05d0\u05d5\u05e1\u05e3 \u05de\u05dc\u05d7\u05de\u05ea \u05d4\u05db\u05d5\u05db\u05d1\u05d9\u05dd", - "OptionSearchForInternetMetadata": "\u05d7\u05e4\u05e9 \u05d1\u05d0\u05d9\u05e0\u05e8\u05e0\u05d8 \u05d0\u05d7\u05e8\u05d9 \u05de\u05d9\u05d3\u05e2 \u05d5\u05ea\u05de\u05d5\u05e0\u05d5\u05ea", "ButtonCreate": "\u05e6\u05d5\u05e8", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/hr.json b/MediaBrowser.Server.Implementations/Localization/Server/hr.json index 7558568b6..52c5629bf 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/hr.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/hr.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Prevo\u0111enje Media Browsera je projekt u tjeku i nije jo\u0161 zavr\u0161en.", "LabelReadHowYouCanContribute": "Pro\u010ditajte kako mo\u017eete doprinjeti.", "HeaderNewCollection": "Nova kolekcija", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Naprimjer: Star Wars Kolekcija", - "OptionSearchForInternetMetadata": "Potra\u017ei na internetu grafike i metadata", "ButtonCreate": "Kreiraj", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/it.json b/MediaBrowser.Server.Implementations/Localization/Server/it.json index 9fc4f9487..5dbb927fd 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/it.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/it.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Considera gli archivi come file multimediali", @@ -290,7 +296,7 @@ "OptionMetascore": "Punteggio", "ButtonSelect": "Seleziona", "ButtonGroupVersions": "Versione Gruppo", - "ButtonAddToCollection": "Aggiungi alla Collezione", + "ButtonAddToCollection": "Add to Collection", "PismoMessage": "Dona per avere una licenza di Pismo", "TangibleSoftwareMessage": "Utilizza Tangible Solutions Java\/C# con una licenza su donazione.", "HeaderCredits": "Crediti", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "La traduzione nella tua lingua non \u00e8 ancora completa. Scusa.", "LabelReadHowYouCanContribute": "Leggi come puoi contribuire", "HeaderNewCollection": "Nuova collezione", - "HeaderAddToCollection": "Aggiungi alla Collezione", "ButtonSubmit": "Invia", - "NewCollectionNameExample": "Esempio: Collezione Star wars", - "OptionSearchForInternetMetadata": "Cerca su internet le immagini e i metadati", "ButtonCreate": "Crea", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Predefinito", "OptionCommunityMostWatchedSort": "Pi\u00f9 visti", "TabNextUp": "Da vedere", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "Nessun suggerimento di film attualmente disponibile. Iniziare a guardare e valutare i vostri film, e poi tornare per i suggerimenti.", "MessageNoCollectionsAvailable": "Le collezioni ti permettono di goderti raccolte personalizzate di Film, Serie TV, Album, Libri e Giochi. Clicca sul + per iniziare a creare le tue Collezioni", "MessageNoPlaylistsAvailable": "Playlist ti permettere di mettere in coda gli elementi da riprodurre.Usa il tasto destro o tap e tieni premuto quindi seleziona elemento da aggiungere", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Elimina contenuto dopo: (giorni)", "LabelChannelDownloadAgeHelp": "Contenuti scaricati pi\u00f9 vecchi di questo limite sarnno cancellati. Rimarranno riproducibili via internet in streaming.", "ChannelSettingsFormHelp": "Installare canali come Trailer e Vimeo nel catalogo plugin.", - "LabelSelectCollection": "Seleziona Collezione:", "ButtonOptions": "Opzioni", "ViewTypeMovies": "Film", "ViewTypeTvShows": "Serie Tv", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Visualizzare i seguenti canali direttamente dentro le mie visite:", "LabelGroupChannelsIntoViewsHelp": "Se abilitata, questi canali verranno visualizzati direttamente con altre viste. Se disattivato, saranno visualizzati all'interno di una sezione Canali separata.", "LabelDisplayCollectionsView": "Mostra le Collezioni di film", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copia extrafanart in extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "Copia extrafanart in extrathumbs", "TabServices": "Servizi", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/kk.json b/MediaBrowser.Server.Implementations/Localization/Server/kk.json index 1c86c0882..6c65923e9 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/kk.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/kk.json @@ -46,8 +46,8 @@ "OptionEnableWebClientResourceMinification": "\u0412\u0435\u0431-\u043a\u043b\u0438\u0435\u043d\u0442 \u049b\u043e\u0440\u044b\u043d \u0430\u0437\u0430\u0439\u0442\u0443\u0434\u044b \u049b\u043e\u0441\u0443", "LabelDashboardSourcePath": "\u0412\u0435\u0431-\u043a\u043b\u0438\u0435\u043d\u0442 \u043a\u04e9\u0437\u0456\u043d\u0456\u04a3 \u0436\u043e\u043b\u044b:", "LabelDashboardSourcePathHelp": "\u0415\u0433\u0435\u0440 \u0441\u0435\u0440\u0432\u0435\u0440 \u049b\u0430\u0439\u043d\u0430\u0440 \u043a\u043e\u0434\u044b\u043d\u0430\u043d \u0436\u04b1\u043c\u044b\u0441 \u0456\u0441\u0442\u0435\u0441\u0435, dashboard-ui \u049b\u0430\u043b\u0442\u0430\u0441\u044b\u043d\u0430 \u0436\u043e\u043b\u0434\u044b \u0430\u043d\u044b\u049b\u0442\u0430\u04a3\u044b\u0437. \u0412\u0435\u0431-\u043a\u043b\u0438\u0435\u043d\u0442\u0442\u0456\u04a3 \u0431\u0430\u0440\u043b\u044b\u049b \u0444\u0430\u0439\u043b\u0434\u0430\u0440\u044b \u043e\u0441\u044b \u0436\u0430\u0439\u0493\u0430\u0441\u044b\u043c\u0434\u0430\u043d \u0448\u044b\u0493\u0430\u0440\u044b\u043b\u0430\u0434\u044b.", - "ButtonConvertMedia": "Convert media", - "ButtonOrganize": "Organize", + "ButtonConvertMedia": "\u0422\u0430\u0441\u0443\u0448\u044b\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440\u0434\u0456 \u0442\u04af\u0440\u043b\u0435\u043d\u0434\u0456\u0440\u0443", + "ButtonOrganize": "\u04b0\u0439\u044b\u043c\u0434\u0430\u0441\u0442\u044b\u0440\u0443", "ButtonOk": "\u0416\u0430\u0440\u0430\u0439\u0434\u044b", "ButtonCancel": "\u0411\u043e\u043b\u0434\u044b\u0440\u043c\u0430\u0443", "ButtonNew": "\u0416\u0430\u0441\u0430\u0443", @@ -55,6 +55,12 @@ "HeaderAudio": "\u0414\u044b\u0431\u044b\u0441", "HeaderVideo": "\u0411\u0435\u0439\u043d\u0435", "HeaderPaths": "\u0416\u043e\u043b\u0434\u0430\u0440", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "\u0425\u0430\u0431\u0430\u0440\u043b\u0430\u043d\u0434\u044b\u0440\u0443\u043b\u0430\u0440", "ButtonDonateWithPayPal": "PayPal \u0430\u0440\u049b\u044b\u043b\u044b \u049b\u0430\u0439\u044b\u0440\u043c\u0430\u043b\u0430\u0443", "OptionDetectArchiveFilesAsMedia": "\u041c\u04b1\u0440\u0430\u0493\u0430\u0442\u0442\u0430\u043b\u0493\u0430\u043d \u0444\u0430\u0439\u043b\u0434\u0430\u0440\u0434\u044b \u0442\u0430\u0441\u0443\u0448\u044b\u0434\u0435\u0440\u0435\u043a \u0440\u0435\u0442\u0456\u043d\u0434\u0435 \u0442\u0430\u0431\u0443", @@ -81,7 +87,7 @@ "ReferToMediaLibraryWiki": "\u0422\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430 \u0442\u0443\u0440\u0430\u043b\u044b \u0443\u0438\u043a\u0438 \u0456\u0448\u0456\u043d\u0435\u043d \u049b\u0430\u0440\u0430\u04a3\u044b\u0437.", "LabelCountry": "\u0415\u043b:", "LabelLanguage": "\u0422\u0456\u043b:", - "ButtonJoinTheDevelopmentTeam": "Join the Development Team", + "ButtonJoinTheDevelopmentTeam": "\u0416\u0430\u0441\u0430\u049b\u0442\u0430\u0443\u0448\u044b\u043b\u0430\u0440 \u0442\u043e\u0431\u044b\u043d\u0430 \u043a\u0456\u0440\u0443", "HeaderPreferredMetadataLanguage": "\u041c\u0435\u0442\u0430\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440 \u0442\u0456\u043b\u0456\u043d\u0456\u04a3 \u0442\u0435\u04a3\u0448\u0435\u043b\u0456\u043c\u0456:", "LabelSaveLocalMetadata": "\u0421\u0443\u0440\u0435\u0442\u0442\u0435\u043c\u0435 v\u0435\u043d \u043c\u0435\u0442\u0430\u0434\u0435\u0440\u0435\u043a\u0442\u0456 \u0442\u0430\u0441\u0443\u0448\u044b \u049b\u0430\u043b\u0442\u0430\u043b\u0430\u0440\u044b \u0456\u0448\u0456\u043d\u0434\u0435 \u0441\u0430\u049b\u0442\u0430\u0443", "LabelSaveLocalMetadataHelp": "\u0421\u0443\u0440\u0435\u0442\u0442\u0435\u043c\u0435 \u043c\u0435\u043d \u043c\u0435\u0442\u0430\u0434\u0435\u0440\u0435\u043a\u0442\u0456 \u0442\u0456\u043a\u0435\u043b\u0435\u0439 \u0442\u0430\u0441\u0443\u0448\u044b \u049b\u0430\u043b\u0442\u0430\u043b\u0430\u0440\u044b \u0456\u0448\u0456\u043d\u0434\u0435 \u0441\u0430\u049b\u0442\u0430\u043b\u0443\u044b \u043e\u043b\u0430\u0440\u0434\u044b \u0436\u0435\u04a3\u0456\u043b \u04e9\u04a3\u0434\u0435\u0439 \u0430\u043b\u0430\u0442\u044b\u043d \u043e\u0440\u044b\u043d\u0493\u0430 \u049b\u043e\u044f\u0434\u044b.", @@ -100,7 +106,7 @@ "HeaderDeviceAccess": "\u049a\u04b1\u0440\u044b\u043b\u0493\u044b\u0493\u0430 \u049b\u0430\u0442\u044b\u043d\u0430\u0441", "OptionEnableAccessFromAllDevices": "\u0411\u0430\u0440\u043b\u044b\u049b \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u0434\u0430\u043d \u049b\u0430\u0442\u044b\u043d\u0430\u0441\u0443\u0434\u044b \u049b\u043e\u0441\u0443", "OptionEnableAccessToAllChannels": "\u0411\u0430\u0440\u043b\u044b\u049b \u0430\u0440\u043d\u0430\u043b\u0430\u0440\u0493\u0430 \u049b\u0430\u0442\u044b\u043d\u0430\u0441\u0443\u0434\u044b \u049b\u043e\u0441\u0443", - "OptionEnableAccessToAllLibraries": "Enable access to all libraries", + "OptionEnableAccessToAllLibraries": "\u0411\u0430\u0440\u043b\u044b\u049b \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u043b\u0430\u0440\u0493\u0430 \u049b\u0430\u0442\u044b\u043d\u0430\u0441\u0443\u0434\u044b \u049b\u043e\u0441\u0443", "DeviceAccessHelp": "\u0411\u04b1\u043b \u0442\u0435\u043a \u049b\u0430\u043d\u0430 \u0431\u0456\u0440\u0435\u0433\u0435\u0439 \u0430\u043d\u044b\u049b\u0442\u0430\u043b\u0443\u044b \u043c\u04af\u043c\u043a\u0456\u043d \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440 \u04af\u0448\u0456\u043d \u049b\u043e\u043b\u0434\u0430\u043d\u044b\u043b\u0430\u0434\u044b \u0436\u04d9\u043d\u0435 \u0448\u043e\u043b\u0493\u044b\u0448\u043f\u0435\u043d \u049b\u0430\u043d\u0442\u044b\u043d\u0430\u0441\u0443\u0493\u0430 \u0442\u044b\u0439\u044b\u043c \u0441\u0430\u043b\u043c\u0430\u0439\u0434\u044b. \u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u0441\u044b\u043d\u0430\u043d \u049b\u0430\u0442\u044b\u043d\u0430\u0441\u0443\u0434\u044b \u0441\u04af\u0437\u0433\u0456\u043b\u0435\u0443\u0456 \u0436\u0430\u04a3\u0430 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u0434\u044b \u043c\u04b1\u043d\u0434\u0430 \u0431\u0435\u043a\u0456\u0442\u0456\u043b\u0433\u0435\u043d\u0448\u0435 \u0434\u0435\u0439\u0456\u043d \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0493\u0430 \u0442\u044b\u0439\u044b\u043c \u0441\u0430\u043b\u0430\u0434\u044b.", "LabelDisplayMissingEpisodesWithinSeasons": "\u0416\u043e\u049b \u044d\u043f\u0438\u0437\u043e\u0434\u0442\u0430\u0440\u0434\u044b \u043c\u0430\u0443\u0441\u044b\u043c \u0456\u0448\u0456\u043d\u0434\u0435 \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u0443", "LabelUnairedMissingEpisodesWithinSeasons": "\u041a\u04e9\u0440\u0441\u0435\u0442\u0456\u043b\u043c\u0435\u0433\u0435\u043d \u044d\u043f\u0438\u0437\u043e\u0434\u0442\u0430\u0440\u0434\u044b \u043c\u0430\u0443\u0441\u044b\u043c \u0456\u0448\u0456\u043d\u0434\u0435 \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u0443", @@ -290,7 +296,7 @@ "OptionMetascore": "Metascore \u0431\u0430\u0493\u0430\u043b\u0430\u0443\u044b", "ButtonSelect": "\u0411\u04e9\u043b\u0435\u043a\u0442\u0435\u0443", "ButtonGroupVersions": "\u041d\u04b1\u0441\u049b\u0430\u043b\u0430\u0440\u0434\u044b \u0442\u043e\u043f\u0442\u0430\u0441\u0442\u044b\u0440\u0443", - "ButtonAddToCollection": "\u0416\u0438\u044b\u043d\u0442\u044b\u049b\u049b\u0430 \u049b\u043e\u0441\u0443", + "ButtonAddToCollection": "Add to Collection", "PismoMessage": "\u0421\u044b\u0439\u043b\u0430\u043d\u0493\u0430\u043d \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u044f \u0430\u0440\u049b\u044b\u043b\u044b Pismo File Mount \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0434\u0430.", "TangibleSoftwareMessage": "\u0421\u044b\u0439\u043b\u0430\u043d\u0493\u0430\u043d \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u044f \u0430\u0440\u049b\u044b\u043b\u044b Tangible Solutions Java\/C# \u0442\u04af\u0440\u043b\u0435\u043d\u0434\u0456\u0440\u0433\u0456\u0448\u0442\u0435\u0440\u0456 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0434\u0430.", "HeaderCredits": "\u0428\u044b\u0493\u0430\u0440\u043c\u0430\u0448\u044b\u043b\u044b\u049b\u0442\u044b \u0440\u0430\u0441\u0442\u0430\u0443", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Media Browser \u0442\u04d9\u0440\u0436\u0456\u043c\u0435\u043b\u0435\u0443\u0456 \u0434\u0430\u043c\u044b\u0442\u043f\u0430\u043b\u044b \u0436\u043e\u0431\u0430 \u0431\u043e\u043b\u044b\u043f \u0442\u0430\u0431\u044b\u043b\u0430\u0434\u044b, \u0436\u04d9\u043d\u0435 \u0431\u04b1\u043b \u04d9\u043b\u0456 \u0434\u0435 \u0430\u044f\u049b\u0442\u0430\u043b\u0493\u0430\u043d \u0435\u043c\u0435\u0441.", "LabelReadHowYouCanContribute": "\u049a\u0430\u043b\u0430\u0439 \u0456\u0441\u043a\u0435\u0440\u043b\u0435\u0441\u0443 \u043c\u04af\u043c\u043a\u0456\u043d\u0434\u0456\u0433\u0456\u04a3\u0456\u0437 \u0442\u0443\u0440\u0430\u043b\u044b \u043e\u049b\u044b\u04a3\u044b\u0437.", "HeaderNewCollection": "\u0416\u0430\u04a3\u0430 \u0436\u0438\u044b\u043d\u0442\u044b\u049b", - "HeaderAddToCollection": "\u0416\u0438\u044b\u043d\u0442\u044b\u049b\u049b\u0430 \u049b\u043e\u0441\u0443", "ButtonSubmit": "\u0416\u0456\u0431\u0435\u0440\u0443", - "NewCollectionNameExample": "\u041c\u044b\u0441\u0430\u043b: \u0416\u04b1\u043b\u0434\u044b\u0437 \u0441\u043e\u0493\u044b\u0441\u0442\u0430\u0440\u044b (\u0436\u0438\u044b\u043d\u0442\u044b\u049b)", - "OptionSearchForInternetMetadata": "\u0421\u0443\u0440\u0435\u0442\u0442\u0435\u043c\u0435 \u043c\u0435\u043d \u043c\u0435\u0442\u0430\u0434\u0435\u0440\u0435\u043a\u0442\u0456 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0442\u0435\u043d \u0456\u0437\u0434\u0435\u0443", "ButtonCreate": "\u0416\u0430\u0441\u0430\u0443", "LabelCustomCss": "\u0422\u0435\u04a3\u0448\u0435\u0443\u043b\u0456 css:", "LabelCustomCssHelp": "\u04e8\u0437\u0456\u04a3\u0456\u0437\u0434\u0456\u04a3 \u0442\u0435\u04a3\u0448\u0435\u0443\u043b\u0456 css \u043a\u043e\u0434\u044b\u043d \u0432\u0435\u0431-\u0442\u0456\u043b\u0434\u0435\u0441\u0443\u0434\u0435 \u049b\u043e\u043b\u0434\u0430\u043d\u044b\u04a3\u044b\u0437.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "\u04d8\u0434\u0435\u043f\u043a\u0456", "OptionCommunityMostWatchedSort": "\u0415\u04a3 \u043a\u04e9\u043f \u049b\u0430\u0440\u0430\u043b\u0493\u0430\u043d\u0434\u0430\u0440", "TabNextUp": "\u041a\u0435\u0437\u0435\u043a\u0442\u0435\u0433\u0456\u043b\u0435\u0440", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "\u0415\u0448\u049b\u0430\u043d\u0434\u0430\u0439 \u0444\u0438\u043b\u044c\u043c \u04b1\u0441\u044b\u043d\u044b\u0441\u0442\u0430\u0440\u044b \u0430\u0493\u044b\u043c\u0434\u0430 \u049b\u043e\u043b \u0436\u0435\u0442\u0456\u043c\u0434\u0456 \u0435\u043c\u0435\u0441. \u0424\u0438\u043b\u044c\u043c\u0434\u0435\u0440\u0434\u0456 \u049b\u0430\u0440\u0430\u0443\u0434\u044b \u0436\u04d9\u043d\u0435 \u0431\u0430\u0493\u0430\u043b\u0430\u0443\u0434\u044b \u0431\u0430\u0441\u0442\u0430\u04a3\u044b\u0437, \u0441\u043e\u043d\u0434\u0430 \u0430\u0440\u043d\u0430\u043b\u0493\u0430\u043d \u04b1\u0441\u044b\u043d\u044b\u0442\u0430\u0440\u044b\u04a3\u044b\u0437\u0434\u044b \u043a\u04e9\u0440\u0443 \u04af\u0448\u0456\u043d \u049b\u0430\u0439\u0442\u0430 \u043a\u0435\u043b\u0456\u04a3\u0456\u0437.", "MessageNoCollectionsAvailable": "\u0416\u0438\u044b\u043d\u0442\u044b\u049b\u0442\u0430\u0440 \u0441\u0456\u0437\u0433\u0435 \u0424\u0438\u043b\u044c\u043c\u0434\u0435\u0440\u0434\u0456\u04a3, \u0421\u0435\u0440\u0438\u0430\u043b\u0434\u0430\u0440\u0434\u044b\u04a3, \u0410\u043b\u044c\u0431\u043e\u043c\u0434\u0430\u0440\u0434\u044b\u04a3, \u041a\u0456\u0442\u0430\u043f\u0442\u0430\u0440\u0434\u044b\u04a3, \u0436\u04d9\u043d\u0435 \u041e\u0439\u044b\u043d\u0434\u0430\u0440\u0434\u044b\u04a3 \u0436\u0435\u043a\u0435\u043b\u0435\u043d\u0433\u0435\u043d \u0442\u043e\u043f\u0442\u0430\u0443\u043b\u0430\u0440\u044b\u043c\u0435\u043d \u0440\u0430\u0445\u0430\u0442\u0442\u0430\u043d\u0443 \u04af\u0448\u0456\u043d \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0435\u0434\u0456. \u0416\u0438\u044b\u043d\u0442\u044b\u049b\u0442\u0430\u0440 \u0436\u0430\u0441\u0430\u0443\u044b\u043d \u0431\u0430\u0441\u0442\u0430\u0443 \u04af\u0448\u0456\u043d \"+\" \u0442\u04af\u0439\u043c\u0435\u0448\u0456\u0433\u0456\u043d \u0431\u0430\u0441\u044b\u04a3\u044b\u0437.", "MessageNoPlaylistsAvailable": "\u041e\u0439\u043d\u0430\u0442\u0443 \u0442\u0456\u0437\u0456\u043c\u0434\u0435\u0440\u0456 \u0431\u0456\u0440 \u043a\u0435\u0437\u0434\u0435 \u043e\u0439\u043d\u0430\u0442\u0443 \u04af\u0448\u0456\u043d \u043c\u0430\u0437\u043c\u04b1\u043d \u0442\u0456\u0437\u0456\u043c\u0456\u043d \u0436\u0430\u0441\u0430\u0443\u0493\u0430 \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0435\u0434\u0456. \u041e\u0439\u043d\u0430\u0442\u0443 \u0442\u0456\u0437\u0456\u043c\u0434\u0435\u0440\u0433\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0442\u0435\u0440\u0434\u0456 \u04af\u0441\u0442\u0435\u0443 \u04af\u0448\u0456\u043d, \u0442\u0456\u043d\u0442\u0443\u0456\u0440\u0434\u0456\u04a3 \u043e\u04a3 \u0436\u0430\u049b \u0442\u04af\u0439\u043c\u0435\u0448\u0456\u0433\u0456\u043d \u0431\u0430\u0441\u044b\u04a3\u044b\u0437 \u043d\u0435\u043c\u0435\u0441\u0435 \u0442\u04af\u0440\u0442\u0456\u043f \u0436\u04d9\u043d\u0435 \u04b1\u0441\u0442\u0430\u043f \u0442\u04b1\u0440\u044b\u04a3\u044b\u0437, \u0441\u043e\u043d\u0434\u0430 \u041e\u0439\u043d\u0430\u0442\u0443 \u0442\u0456\u0437\u0456\u043c\u0456\u043d\u0435 \u04af\u0441\u0442\u0435\u0443 \u0434\u0435\u0433\u0435\u043d\u0434\u0456 \u0442\u0430\u04a3\u0434\u0430\u04a3\u044b\u0437.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "\u041c\u0430\u0437\u043c\u04b1\u043d \u0436\u043e\u0439\u044b\u043b\u0443\u044b \u043a\u0435\u043b\u0435\u0441\u0456\u0434\u0435\u043d \u043a\u0435\u0439\u0456\u043d, \u043a\u04af\u043d:", "LabelChannelDownloadAgeHelp": "\u0411\u04b1\u0434\u0430\u043d \u0431\u04b1\u0440\u044b\u043d\u0493\u044b \u0436\u04af\u043a\u0442\u0435\u043f \u0430\u043b\u044b\u043d\u0493\u0430\u043d \u043c\u0430\u0437\u043c\u04af\u043d \u0436\u043e\u0439\u044b\u043b\u0430\u0434\u044b. \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u0430\u0440\u049b\u044b\u043b\u044b \u0430\u0493\u044b\u043d\u043c\u0435\u043d \u0442\u0430\u0441\u044b\u043c\u0430\u043b\u0434\u0430\u0443 \u04d9\u0434\u0456\u0441\u0456\u043d \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u044b\u043f \u043e\u0439\u043d\u0430\u0442\u0443 \u0456\u0441\u0442\u0435 \u049b\u0430\u043b\u0430\u0434\u044b.", "ChannelSettingsFormHelp": "\u041f\u043b\u0430\u0433\u0438\u043d \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0456\u043d\u0434\u0435\u0433\u0456 Trailers \u0436\u04d9\u043d\u0435 Vimeo \u0441\u0438\u044f\u049b\u0442\u044b \u0430\u0440\u043d\u0430\u043b\u0430\u0440\u0434\u044b \u043e\u0440\u043d\u0430\u0442\u044b\u04a3\u044b\u0437.", - "LabelSelectCollection": "\u0416\u0438\u044b\u043d\u0442\u044b\u049b\u0442\u044b \u0442\u0430\u04a3\u0434\u0430\u0443:", "ButtonOptions": "\u041d\u04b1\u0441\u049b\u0430\u043b\u0430\u0440", "ViewTypeMovies": "\u041a\u0438\u043d\u043e", "ViewTypeTvShows": "\u0422\u0414", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "\u041c\u0435\u043d\u0456\u04a3 \u0430\u0441\u043f\u0435\u043a\u0442\u0442\u0435\u0440\u0456\u043c\u0434\u0435 \u0442\u0456\u043a\u0435\u043b\u0435\u0439 \u043a\u0435\u043b\u0435\u0441\u0456 \u0430\u0440\u043d\u0430\u043b\u0430\u0440\u0434\u044b \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u0443:", "LabelGroupChannelsIntoViewsHelp": "\u0415\u0433\u0435\u0440 \u049b\u043e\u0441\u044b\u043b\u0441\u0430, \u043e\u0441\u044b \u0430\u0440\u043d\u0430\u043b\u0430\u0440 \u0431\u0430\u0441\u049b\u0430 \u0430\u0441\u043f\u0435\u043a\u0442\u0442\u0435\u0440\u043c\u0435\u043d \u049b\u0430\u0442\u0430\u0440 \u0442\u0456\u043a\u0435\u043b\u0435\u0439 \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u043d\u0435\u0434\u0456. \u0415\u0433\u0435\u0440 \u0430\u0436\u044b\u0440\u0430\u0442\u044b\u043b\u0441\u0430, \u043e\u043b\u0430\u0440 \u0431\u04e9\u043b\u0435\u043a \u0410\u0440\u043d\u0430\u043b\u0430\u0440 \u043a\u04e9\u0440\u0456\u043d\u0456\u0441\u0456\u043d\u0434\u0435 \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u043d\u0435\u0434\u0456.", "LabelDisplayCollectionsView": "\u0424\u0438\u043b\u044c\u043c\u0434\u0435\u0440 \u0436\u0438\u043d\u0430\u049b\u0442\u0430\u0440\u044b\u043d \u043a\u04e9\u0440\u0441\u0435\u0442\u0443 \u04af\u0448\u0456\u043d \u0416\u0438\u044b\u043d\u0442\u044b\u049b\u0442\u0430\u0440 \u0430\u0441\u043f\u0435\u043a\u0442\u0456\u043d \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u0443", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "\u04d8\u0434\u0435\u043f\u043a\u0456 extrafanart \u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440\u0456\u043d extrathumbs \u0456\u0448\u0456\u043d\u0435 \u043a\u04e9\u0448\u0456\u0440\u0443", "LabelKodiMetadataEnableExtraThumbsHelp": "\u0421\u0443\u0440\u0435\u0442\u0442\u0435\u0440\u0434\u0456 \u0436\u04af\u043a\u0442\u0435\u0433\u0435\u043d \u043a\u0435\u0437\u0434\u0435, \u043e\u043b\u0430\u0440 Kodi \u049b\u0430\u0431\u044b\u0493\u044b\u043c\u0435\u043d \u0435\u04a3 \u0436\u043e\u0493\u0430\u0440\u044b \u0441\u0438\u044b\u0441\u044b\u043c\u0434\u044b\u0493\u044b \u04af\u0448\u0456\u043d extrafanart \u0436\u04d9\u043d\u0435 extrathumbs \u0435\u043a\u0435\u0443\u0456\u043d\u0434\u0435 \u0441\u0430\u049b\u0442\u0430\u043b\u0430\u0434\u044b.", "TabServices": "\u049a\u044b\u0437\u043c\u0435\u0442\u0442\u0435\u0440", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ko.json b/MediaBrowser.Server.Implementations/Localization/Server/ko.json index 251e2054d..f6e6b98ac 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/ko.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/ko.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ms.json b/MediaBrowser.Server.Implementations/Localization/Server/ms.json index 30fc32baf..f16a4bcd0 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/ms.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/ms.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/nb.json b/MediaBrowser.Server.Implementations/Localization/Server/nb.json index 08bc7d9c5..fe53de3bc 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/nb.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/nb.json @@ -55,6 +55,12 @@ "HeaderAudio": "Lyd", "HeaderVideo": "Video", "HeaderPaths": "Stier", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Doner med PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -290,7 +296,7 @@ "OptionMetascore": "Metascore", "ButtonSelect": "Velg", "ButtonGroupVersions": "Gruppe Versjoner", - "ButtonAddToCollection": "Legg Til I Samling", + "ButtonAddToCollection": "Add to Collection", "PismoMessage": "Utnytte Pismo File Mount gjennom en donert lisens.", "TangibleSoftwareMessage": "Utnytte konkrete l\u00f8sninger Java \/ C # omformere gjennom en donert lisens.", "HeaderCredits": "Credits", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Oversetting av Media Browser er ett p\u00e5g\u00e5ende prosjekt og er enda ikke fullstendig ferdig.", "LabelReadHowYouCanContribute": "Les mer om hvordan du kan bidra.", "HeaderNewCollection": "Ny Samling", - "HeaderAddToCollection": "Legg Til I Samling", "ButtonSubmit": "Send", - "NewCollectionNameExample": "Eksempel: Star Wars Samling", - "OptionSearchForInternetMetadata": "S\u00f8k p\u00e5 internet for artwork og metadata", "ButtonCreate": "Opprett", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Standard", "OptionCommunityMostWatchedSort": "Mest Sett", "TabNextUp": "Neste", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "Ingen film forslag er forel\u00f8pig tilgjengelig. Start med \u00e5 se og ranger filmer. Kom deretter tilbake for \u00e5 f\u00e5 forslag p\u00e5 anbefalinger.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Spillelister tillater deg \u00e5 lage lister over innhold til \u00e5 spille etter hverandre p\u00e5 en gang. For \u00e5 legge til elementer i spillelister, h\u00f8yreklikk eller trykk og hold, og velg Legg til i spilleliste.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Slett innhold etter: (dager)", "LabelChannelDownloadAgeHelp": "Nedlastet innhold eldre enn dette vil bli slettet. Det vil v\u00e6re avspillbart via internett streaming.", "ChannelSettingsFormHelp": "Installer kanaler som eksempel Trailers og Vimeo i programtillegg katalogen.", - "LabelSelectCollection": "Velg samling:", "ButtonOptions": "Alternativer", "ViewTypeMovies": "Filmer", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Via f\u00f8lgende kanaler direkte gjennom Mitt Syn:", "LabelGroupChannelsIntoViewsHelp": "Hvis sl\u00e5tt p\u00e5 vil disse kanalene bli vist direkte sammen med andre visninger. Hvis avsl\u00e5tt, vil de bli vist sammen med separerte Kanaler visning.", "LabelDisplayCollectionsView": "Vis en samling for \u00e5 vise film samlinger", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "kopier extrafanart inn til extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "Ved nedlasting av bilder kan de bli lagret inn til b\u00e5de extrafanart og extrathumbs for maksimum Kodi skin kompabilitet.", "TabServices": "Tjenester", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/nl.json b/MediaBrowser.Server.Implementations/Localization/Server/nl.json index ceae61bc8..bf43cfafe 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/nl.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/nl.json @@ -41,13 +41,13 @@ "ButtonPrivacyPolicy": "Privacybeleid", "ButtonTermsOfService": "Service voorwaarden", "HeaderDeveloperOptions": "Ontwikkelaar Opties", - "OptionEnableWebClientResponseCache": "Enable web client response caching", - "OptionDisableForDevelopmentHelp": "Configure these as needed for web client development purposes.", - "OptionEnableWebClientResourceMinification": "Enable web client resource minification", + "OptionEnableWebClientResponseCache": "Web cli\u00ebnt reactie caching inschakelen", + "OptionDisableForDevelopmentHelp": "Configureer deze zo nodig voor web cli\u00ebnt ontwikkelingsdoeleinden.", + "OptionEnableWebClientResourceMinification": "Web cli\u00ebnt bron verkleining inschakelen", "LabelDashboardSourcePath": "Web client bron pad:", - "LabelDashboardSourcePathHelp": "If running the server from source, specify the path to the dashboard-ui folder. All web client files will be served from this location.", + "LabelDashboardSourcePathHelp": "Wanneer U de server draait vanaf de bron, geeft u het pad naar de map dashboard-ui op. Alle web cli\u00ebnt bestanden worden geladen vanaf deze locatie.", "ButtonConvertMedia": "Converteer media", - "ButtonOrganize": "Organize", + "ButtonOrganize": "Organiseren", "ButtonOk": "Ok", "ButtonCancel": "Annuleren", "ButtonNew": "Nieuw", @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paden", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Pad voor tijdelijke bestanden:", + "LabelSyncTempPathHelp": "Geef een afwijkende sync werk directory op. Tijdens het sync proces aangemaakte geconverteerde media zal hier opgeslagen worden.", + "LabelCustomCertificatePath": "Aangepast certificaat pad:", + "LabelCustomCertificatePathHelp": "Gebruik uw eigen ssl certificaat. Indien weggelaten zal de server een zelf-ondertekend certificaat aanmaken.", "TitleNotifications": "Meldingen", "ButtonDonateWithPayPal": "Doneer met PayPal", "OptionDetectArchiveFilesAsMedia": "Herken archief bestanden als media", @@ -100,7 +106,7 @@ "HeaderDeviceAccess": "Apparaat Toegang", "OptionEnableAccessFromAllDevices": "Toegang vanaf alle apparaten toestaan", "OptionEnableAccessToAllChannels": "Toegang tot alle kanalen inschakelen", - "OptionEnableAccessToAllLibraries": "Enable access to all libraries", + "OptionEnableAccessToAllLibraries": "Toegang tot alle bibliotheken inschakelen", "DeviceAccessHelp": "Dit geldt alleen voor apparaten die uniek ge\u00efdentificeerd kunnen worden en voorkomen niet toegang via een webbrowser. Filteren van apparaat toegang voor gebruikers voorkomt dat zij nieuwe apparaten gebruiken totdat deze hier zijn goedgekeurd.", "LabelDisplayMissingEpisodesWithinSeasons": "Toon ontbrekende afleveringen binnen een seizoen", "LabelUnairedMissingEpisodesWithinSeasons": "Toon komende afleveringen binnen een seizoen", @@ -290,7 +296,7 @@ "OptionMetascore": "Metascore", "ButtonSelect": "Selecteer", "ButtonGroupVersions": "Groepeer Versies", - "ButtonAddToCollection": "Toevoegen aan verzameling", + "ButtonAddToCollection": "Voeg toe aan Collectie", "PismoMessage": "Pismo File Mount (met een geschonken licentie).", "TangibleSoftwareMessage": "Gebruik makend van concrete oplossingen als Java \/ C converters door een geschonken licentie.", "HeaderCredits": "Credits", @@ -512,28 +518,25 @@ "LabelPreferredDisplayLanguageHelp": "Het vertalen van Media Browser is een doorlopend project en is nog niet voltooid.", "LabelReadHowYouCanContribute": "Lees meer over hoe u kunt bijdragen.", "HeaderNewCollection": "Nieuwe Verzamling", - "HeaderAddToCollection": "Toevoegen aan verzameling", "ButtonSubmit": "Uitvoeren", - "NewCollectionNameExample": "Voorbeeld: Star Wars Collectie", - "OptionSearchForInternetMetadata": "Zoeken op het internet voor afbeeldingen en metadata", "ButtonCreate": "Cre\u00ebren", - "LabelCustomCss": "Custom css:", - "LabelCustomCssHelp": "Apply your own custom css to the web interface.", + "LabelCustomCss": "Aangepaste css:", + "LabelCustomCssHelp": "Uw eigen aangepaste css voor de web-interface toepassen.", "LabelLocalHttpServerPortNumber": "Lokale http poort nummer:", "LabelLocalHttpServerPortNumberHelp": "De TCP poort waarop de Media Browser Server beschikbaar is.", "LabelPublicHttpPort": "Publieke http poort nummer:", - "LabelPublicHttpPortHelp": "The public port number that should be mapped to the local http port.", + "LabelPublicHttpPortHelp": "Het publieke poortnummer dat moet worden toegewezen aan de lokale http poort.", "LabelPublicHttpsPort": "Publieke https poort nummer:", - "LabelPublicHttpsPortHelp": "The public port number that should be mapped to the local https port.", - "LabelEnableHttps": "Report https as external address", - "LabelEnableHttpsHelp": "If enabled, the server will report an https url to clients as it's external address. This may break clients that do not yet support https.", + "LabelPublicHttpsPortHelp": "Het publieke poortnummer dat moet worden toegewezen aan de lokale https poort.", + "LabelEnableHttps": "Rapporteer https als extern adres", + "LabelEnableHttpsHelp": "Indien ingeschakeld, zal de server een https url rapporteren aan de cli\u00ebnt als het externe adres. Dit kan cli\u00ebnten die nog geen ondersteuning voor https hebben onbruikbaar maken.", "LabelHttpsPort": "Lokale https poort nummer:", - "LabelHttpsPortHelp": "The tcp port number that Media Browser's https server should bind to.", + "LabelHttpsPortHelp": "Het TCP-poortnummer waar Media Browser https server zich aan moet binden.", "LabelWebSocketPortNumber": "Web socket poortnummer:", "LabelEnableAutomaticPortMap": "Schakel automatisch poort vertalen in", "LabelEnableAutomaticPortMapHelp": "Probeer om de publieke poort automatisch te vertalen naar de lokale poort via UPnP. Dit werk niet op alle routers.", "LabelExternalDDNS": "Extern WAN Adres:", - "LabelExternalDDNSHelp": "If you have a dynamic DNS enter it here. Media Browser apps will use it when connecting remotely. Leave empty for automatic detection.", + "LabelExternalDDNSHelp": "Wanneer u een dynamische DNS heeft voer het dan hier in. Media Browser apps zullen het gebruiken bij het op afstand aansluiten. Laat leeg voor automatische detectie.", "TabResume": "Hervatten", "TabWeather": "Weer", "TitleAppSettings": "App Instellingen", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Standaard", "OptionCommunityMostWatchedSort": "Meest bekeken", "TabNextUp": "Volgend", + "HeaderBecomeMediaBrowserSupporter": "Word een Media Browser Supporter", + "TextAccessPremiumFeatures": "Toegang tot Premium Functies", "MessageNoMovieSuggestionsAvailable": "Er zijn momenteel geen film suggesties beschikbaar. Begin met het bekijken en waardeer uw films, kom daarna terug om uw aanbevelingen te bekijken.", "MessageNoCollectionsAvailable": "Collecties maken het u mogelijk om Films, Series, Albums, Boeken en Games te groeperen. Klik op de + knop om Collecties aan te maken.", "MessageNoPlaylistsAvailable": "Met afspeellijsten kunt u een lijst maken waarvan de items achter elkaar afgespeeld worden. Om een item toe te voegen klikt u met rechts of tik en houd het vast om het te selecteren, klik vervolgens op Toevoegen aan afspeellijst.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Verwijder inhoud na: (dagen)", "LabelChannelDownloadAgeHelp": "Gedownloade inhoud die ouder is zal worden verwijderd. Afspelen via internet streaming blijft mogelijk.", "ChannelSettingsFormHelp": "Installeer kanalen zoals Trailers en Vimeo in de Plug-in catalogus.", - "LabelSelectCollection": "Selecteer verzameling:", "ButtonOptions": "Opties", "ViewTypeMovies": "Films", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Toon de volgende kanalen binnen mijn overzichten:", "LabelGroupChannelsIntoViewsHelp": "Indien ingeschakeld, zullen deze kanalen direct naast andere overzichten worden weergegeven. Indien uitgeschakeld, zullen ze worden weergegeven in een aparte kanalen overzicht.", "LabelDisplayCollectionsView": "Toon verzamelingen in mijn overzichten om film verzamelingen weer te geven", + "LabelDisplayCollectionsViewHelp": "Hiermee wordt een aparte weergave gemaakt waarin collecties worden weergegeven die u hebt aangemaakt of toegang toe hebt. Klik rechts op een film of druk en houd vast en kies 'Voeg toe aan Collectie'. ", "LabelKodiMetadataEnableExtraThumbs": "Kopieer extrafanart naar extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "Als er afbeeldingen gedownload worden kunnen deze direct in extrafanart en extrathumbs opgeslagen worden voor maximale Kodi skin compatibiliteit.", "TabServices": "Meta Diensten", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/pl.json b/MediaBrowser.Server.Implementations/Localization/Server/pl.json index 8d7ed66f2..6e327e1a6 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/pl.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/pl.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json b/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json index 8055f11e8..e4a6ee43b 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json @@ -40,23 +40,29 @@ "OptionIAcceptTermsOfService": "Aceito os termos de servi\u00e7o", "ButtonPrivacyPolicy": "Pol\u00edtica de privacidade", "ButtonTermsOfService": "Termos de Servi\u00e7o", - "HeaderDeveloperOptions": "Developer Options", - "OptionEnableWebClientResponseCache": "Enable web client response caching", - "OptionDisableForDevelopmentHelp": "Configure these as needed for web client development purposes.", - "OptionEnableWebClientResourceMinification": "Enable web client resource minification", - "LabelDashboardSourcePath": "Web client source path:", - "LabelDashboardSourcePathHelp": "If running the server from source, specify the path to the dashboard-ui folder. All web client files will be served from this location.", - "ButtonConvertMedia": "Convert media", - "ButtonOrganize": "Organize", + "HeaderDeveloperOptions": "Op\u00e7\u00f5es de Desenvolvedor", + "OptionEnableWebClientResponseCache": "Ativar o cache de resposta do client web", + "OptionDisableForDevelopmentHelp": "Configure esta op\u00e7\u00e3o de acordo ao prop\u00f3sito de desenvolvimento do cliente web", + "OptionEnableWebClientResourceMinification": "Ativar a minimiza\u00e7\u00e3o de recursos do cliente web", + "LabelDashboardSourcePath": "Caminho fonte do cliente web:", + "LabelDashboardSourcePathHelp": "Se executar o servidor a partir do c\u00f3digo, especifique o caminho para a pasta da interface do painel. Todos os arquivos do cliente web ser\u00e3o usados nesta localiza\u00e7\u00e3o.", + "ButtonConvertMedia": "Converter m\u00eddia", + "ButtonOrganize": "Organizar", "ButtonOk": "Ok", "ButtonCancel": "Cancelar", "ButtonNew": "Novo", "HeaderTV": "TV", "HeaderAudio": "\u00c1udio", "HeaderVideo": "V\u00eddeo", - "HeaderPaths": "Paths", - "TitleNotifications": "Notifications", - "ButtonDonateWithPayPal": "Donate with PayPal", + "HeaderPaths": "Caminhos", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Caminho de arquivo tempor\u00e1rio:", + "LabelSyncTempPathHelp": "Especifique uma pasta de trabalho para a sincroniza\u00e7\u00e3o personalizada. M\u00eddias convertidas criadas durante o processo de sincroniza\u00e7\u00e3o ser\u00e3o aqui armazenadas.", + "LabelCustomCertificatePath": "Caminho do certificado personalizado:", + "LabelCustomCertificatePathHelp": "Forne\u00e7a seu pr\u00f3prio certificado ssl. Se omitido, o servidor criar\u00e1 um certificado auto-assinado.", + "TitleNotifications": "Notifica\u00e7\u00f5es", + "ButtonDonateWithPayPal": "Doe atrav\u00e9s do PayPal", "OptionDetectArchiveFilesAsMedia": "Detectar arquivos compactados como m\u00eddia", "OptionDetectArchiveFilesAsMediaHelp": "Se ativado, arquivos com extens\u00f5es .rar e .zip ser\u00e3o detectados como arquivos de m\u00eddia.", "LabelEnterConnectUserName": "Nome de usu\u00e1rio ou email:", @@ -74,14 +80,14 @@ "FolderTypeTvShows": "TV", "FolderTypeInherit": "Herdar", "LabelContentType": "Tipo de conte\u00fado:", - "TitleScheduledTasks": "Scheduled Tasks", + "TitleScheduledTasks": "Tarefas Agendadas", "HeaderSetupLibrary": "Configurar sua biblioteca de m\u00eddias", "ButtonAddMediaFolder": "Adicionar pasta de m\u00eddias", "LabelFolderType": "Tipo de pasta:", "ReferToMediaLibraryWiki": "Consultar wiki da biblioteca de m\u00eddias", "LabelCountry": "Pa\u00eds:", "LabelLanguage": "Idioma:", - "ButtonJoinTheDevelopmentTeam": "Join the Development Team", + "ButtonJoinTheDevelopmentTeam": "Junte-se ao Time de Desenvolvimento", "HeaderPreferredMetadataLanguage": "Idioma preferido dos metadados:", "LabelSaveLocalMetadata": "Salvar artwork e metadados dentro das pastas da m\u00eddia", "LabelSaveLocalMetadataHelp": "Salvar artwork e metadados diretamente nas pastas da m\u00eddia as deixar\u00e1 em um local f\u00e1cil para edit\u00e1-las.", @@ -100,7 +106,7 @@ "HeaderDeviceAccess": "Acesso ao Dispositivo", "OptionEnableAccessFromAllDevices": "Ativar o acesso de todos os dispositivos", "OptionEnableAccessToAllChannels": "Ativar o acesso a todos os canais", - "OptionEnableAccessToAllLibraries": "Enable access to all libraries", + "OptionEnableAccessToAllLibraries": "Ativar o acesso a todas as bibliotecas", "DeviceAccessHelp": "Isto apenas aplica para dispositivos que podem ser identificados como \u00fanicos e n\u00e3o evitar\u00e3o o acesso do navegador. Filtrar o acesso ao dispositivo do usu\u00e1rio evitar\u00e1 que sejam usados novos dispositivos at\u00e9 que sejam aprovados aqui.", "LabelDisplayMissingEpisodesWithinSeasons": "Exibir epis\u00f3dios que faltam dentro das temporadas", "LabelUnairedMissingEpisodesWithinSeasons": "Exibir epis\u00f3dios por estrear dentro das temporadas", @@ -512,28 +518,25 @@ "LabelPreferredDisplayLanguageHelp": "A tradu\u00e7\u00e3o do Media Browser \u00e9 um projeto cont\u00ednuo e ainda n\u00e3o finalizado.", "LabelReadHowYouCanContribute": "Leia sobre como voc\u00ea pode contribuir.", "HeaderNewCollection": "Nova Cole\u00e7\u00e3o", - "HeaderAddToCollection": "Adicionar \u00e0 Cole\u00e7\u00e3o", "ButtonSubmit": "Enviar", - "NewCollectionNameExample": "Exemplo: Cole\u00e7\u00e3o Star Wars", - "OptionSearchForInternetMetadata": "Buscar artwork e metadados na internet", "ButtonCreate": "Criar", - "LabelCustomCss": "Custom css:", - "LabelCustomCssHelp": "Apply your own custom css to the web interface.", - "LabelLocalHttpServerPortNumber": "Local http port number:", + "LabelCustomCss": "Css personalizado:", + "LabelCustomCssHelp": "Aplique o seu css personalizado para a interface web", + "LabelLocalHttpServerPortNumber": "N\u00famero da porta local de http:", "LabelLocalHttpServerPortNumberHelp": "O n\u00famero da porta tcp que o servidor http do Media Browser utilizar\u00e1.", - "LabelPublicHttpPort": "Public http port number:", - "LabelPublicHttpPortHelp": "The public port number that should be mapped to the local http port.", - "LabelPublicHttpsPort": "Public https port number:", - "LabelPublicHttpsPortHelp": "The public port number that should be mapped to the local https port.", - "LabelEnableHttps": "Report https as external address", - "LabelEnableHttpsHelp": "If enabled, the server will report an https url to clients as it's external address. This may break clients that do not yet support https.", - "LabelHttpsPort": "Local https port number:", - "LabelHttpsPortHelp": "The tcp port number that Media Browser's https server should bind to.", + "LabelPublicHttpPort": "N\u00famero da porta p\u00fablica de http:", + "LabelPublicHttpPortHelp": "O n\u00famero da porta p\u00fablica que dever\u00e1 ser mapeada para a porta local de http.", + "LabelPublicHttpsPort": "N\u00famero da porta p\u00fablica de https:", + "LabelPublicHttpsPortHelp": "O n\u00famero da porta p\u00fablica que dever\u00e1 ser mapeada para a porta local de https.", + "LabelEnableHttps": "Reportar https como um endere\u00e7o externo", + "LabelEnableHttpsHelp": "Se ativado, o servidor ir\u00e1 reportar uma url https para os clientes como um endere\u00e7o externo. Isto pode prejudicar o funcionamento de clientes que ainda n\u00e3o suportam https.", + "LabelHttpsPort": "N\u00famero da porta local de https:", + "LabelHttpsPortHelp": "O n\u00famero da porta tcp que o servidor https do Media Browser dever\u00e1 se vincular.", "LabelWebSocketPortNumber": "N\u00famero da porta do web socket:", "LabelEnableAutomaticPortMap": "Habilitar mapeamento autom\u00e1tico de portas", "LabelEnableAutomaticPortMapHelp": "Tentativa de mapear automaticamente a porta p\u00fablica para a local atrav\u00e9s de uPnP. Isto poder\u00e1 n\u00e3o funcionar em alguns modelos de roteadores.", - "LabelExternalDDNS": "External WAN Address:", - "LabelExternalDDNSHelp": "If you have a dynamic DNS enter it here. Media Browser apps will use it when connecting remotely. Leave empty for automatic detection.", + "LabelExternalDDNS": "Endere\u00e7o WAN externo:", + "LabelExternalDDNSHelp": "Se voc\u00ea tiver um DNS din\u00e2mico, digite aqui. As apps do Media Browser o usar\u00e3o para conectar-se remotamente. Deixe em branco para detec\u00e7\u00e3o autom\u00e1tica.", "TabResume": "Retomar", "TabWeather": "Tempo", "TitleAppSettings": "Configura\u00e7\u00f5es da App", @@ -601,7 +604,7 @@ "ButtonRestart": "Reiniciar", "ButtonShutdown": "Desligar", "ButtonUpdateNow": "Atualizar Agora", - "TabHosting": "Hosting", + "TabHosting": "Hospedagem", "PleaseUpdateManually": "Por favor, desligue o servidor e atualize-o manualmente.", "NewServerVersionAvailable": "Uma nova vers\u00e3o do Servidor Media Browser est\u00e1 dispon\u00edvel!", "ServerUpToDate": "O Servidor Media Browser est\u00e1 atualizado", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Padr\u00e3o", "OptionCommunityMostWatchedSort": "Mais Assistidos", "TabNextUp": "Pr\u00f3ximos", + "HeaderBecomeMediaBrowserSupporter": "Torne-se um Colaborador do Media Browser", + "TextAccessPremiumFeatures": "Aproveite Funcionalidades Premium", "MessageNoMovieSuggestionsAvailable": "N\u00e3o existem sugest\u00f5es de filmes dispon\u00edveis atualmente. Comece por assistir e avaliar seus filmes e, ent\u00e3o, volte para verificar suas recomenda\u00e7\u00f5es.", "MessageNoCollectionsAvailable": "Cole\u00e7\u00f5es permitem que voc\u00ea aproveite grupos personalizados de Filmes, S\u00e9ries, \u00c1lbuns, Livros e Jogos. Clique no bot\u00e3o + para come\u00e7ar a criar Cole\u00e7\u00f5es.", "MessageNoPlaylistsAvailable": "Listas de reprodu\u00e7\u00e3o permitem criar listas com conte\u00fado para reproduzir consecutivamente, de uma s\u00f3 vez. Para adicionar itens \u00e0s listas de reprodu\u00e7\u00e3o, clique com o bot\u00e3o direito ou toque a tela por alguns segundos, depois selecione Adicionar \u00e0 Lista de Reprodu\u00e7\u00e3o.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Excluir conte\u00fado depois de: (dias)", "LabelChannelDownloadAgeHelp": "O conte\u00fado transferido que for mais velho que este valor ser\u00e1 exclu\u00eddo. Poder\u00e1 seguir reproduzindo-o atrav\u00e9s de streaming da internet.", "ChannelSettingsFormHelp": "Instalar canais como, por exemplo, Trailers e Vimeo no cat\u00e1logo de plugins.", - "LabelSelectCollection": "Selecione cole\u00e7\u00e3o:", "ButtonOptions": "Op\u00e7\u00f5es", "ViewTypeMovies": "Filmes", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Exibir os seguintes canais diretamente dentro de minhas visualiza\u00e7\u00f5es:", "LabelGroupChannelsIntoViewsHelp": "Se ativados, estes canais ser\u00e3o exibidos imediatamente ao lado de outras visualiza\u00e7\u00f5es. Se desativado, eles ser\u00e3o exibidos dentro de uma visualiza\u00e7\u00e3o separada de Canais.", "LabelDisplayCollectionsView": "Exibir uma visualiza\u00e7\u00e3o de cole\u00e7\u00f5es para mostrar colet\u00e2neas de filmes", + "LabelDisplayCollectionsViewHelp": "Esta op\u00e7\u00e3o criar\u00e1 uma visualiza\u00e7\u00e3o separada para exibir cole\u00e7\u00f5es criadas ou acessadas por voc\u00ea. Para criar uma cole\u00e7\u00e3o, clique com o bot\u00e3o direito ou toque e segure qualquer filme e selecione 'Adicionar \u00e0 Cole\u00e7\u00e3o'.", "LabelKodiMetadataEnableExtraThumbs": "Copiar extrafanart para extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "Ao fazer download das imagens, elas podem ser salvas em ambas extrafanart e extrathumbs para uma maior compatibilidade com as skins do Kodi.", "TabServices": "Servi\u00e7os", @@ -1306,7 +1311,7 @@ "MessageNoTrailersFound": "Nenhum trailer encontrado. Instale o canal Trailer para melhorar sua experi\u00eancia com filmes, adicionando uma biblioteca de trailers da internet.", "HeaderNewUsers": "Novos Usu\u00e1rios", "ButtonSignUp": "Entrar", - "ButtonForgotPassword": "Forgot password", + "ButtonForgotPassword": "Esqueci a senha", "OptionDisableUserPreferences": "Desativar acesso \u00e0s prefer\u00eancias do usu\u00e1rio.", "OptionDisableUserPreferencesHelp": "Se ativado, apenas administradores poder\u00e3o configurar imagens do perfil do usu\u00e1rio, senhas e prefer\u00eancias de idioma.", "HeaderSelectServer": "Selecionar Servidor", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json b/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json index ef1b8ccca..7adb49ed1 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "A tradu\u00e7\u00e3o do Media Browser \u00e9 um projeto em andamento e ainda n\u00e3o est\u00e1 completo.", "LabelReadHowYouCanContribute": "Leia sobre como pode contribuir.", "HeaderNewCollection": "Nova Cole\u00e7\u00e3o", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Exemplo: Cole\u00e7\u00e3o Guerra das Estrelas", - "OptionSearchForInternetMetadata": "Procurar na internet por imagens e metadados", "ButtonCreate": "Criar", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ru.json b/MediaBrowser.Server.Implementations/Localization/Server/ru.json index eb1afcc1c..1689a5653 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/ru.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/ru.json @@ -55,6 +55,12 @@ "HeaderAudio": "\u0410\u0443\u0434\u0438\u043e", "HeaderVideo": "\u0412\u0438\u0434\u0435\u043e", "HeaderPaths": "\u041f\u0443\u0442\u0438", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "\u041f\u0443\u0442\u044c \u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u043c\u0443 \u0444\u0430\u0439\u043b\u0443:", + "LabelSyncTempPathHelp": "\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0447\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u0434\u043b\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438. \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0434\u0438\u0430\u0434\u0430\u043d\u043d\u044b\u0435, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438, \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u0437\u0434\u0435\u0441\u044c.", + "LabelCustomCertificatePath": "\u041f\u0443\u0442\u044c \u043a \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0443:", + "LabelCustomCertificatePathHelp": "\u041f\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 SSL-\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442. \u0415\u0441\u043b\u0438 \u043e\u043d \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d, \u0441\u0435\u0440\u0432\u0435\u0440 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0441\u0430\u043c\u043e\u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442.", "TitleNotifications": "\u0423\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f", "ButtonDonateWithPayPal": "\u041f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 PayPal", "OptionDetectArchiveFilesAsMedia": "\u0410\u0440\u0445\u0438\u0432\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a \u043c\u0435\u0434\u0438\u0430\u0434\u0430\u043d\u043d\u044b\u0435", @@ -290,7 +296,7 @@ "OptionMetascore": "\u041e\u0446\u0435\u043d\u043a\u0430 Metascore", "ButtonSelect": "\u0412\u044b\u0431\u0440\u0430\u0442\u044c", "ButtonGroupVersions": "\u0413\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u0438", - "ButtonAddToCollection": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e", + "ButtonAddToCollection": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438", "PismoMessage": "Pismo File Mount \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u043f\u043e\u0434\u0430\u0440\u0435\u043d\u043d\u043e\u0439 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0438.", "TangibleSoftwareMessage": "\u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u044b Java\/C# \u043e\u0442 Tangible Solutions \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043f\u043e \u043f\u043e\u0434\u0430\u0440\u0435\u043d\u043d\u043e\u0439 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0438.", "HeaderCredits": "\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0441\u0442\u0432\u0430", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "\u041f\u0435\u0440\u0435\u0432\u043e\u0434 Media Browser \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u043c\u0441\u044f \u0432 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0438 \u0438 \u0432\u0441\u0451 \u0435\u0449\u0451 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d.", "LabelReadHowYouCanContribute": "\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u0441\u0432\u043e\u0439 \u0432\u043a\u043b\u0430\u0434.", "HeaderNewCollection": "\u041d\u043e\u0432\u0430\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f", - "HeaderAddToCollection": "\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e", "ButtonSubmit": "\u0412\u043d\u0435\u0441\u0442\u0438", - "NewCollectionNameExample": "\u041f\u0440\u0438\u043c\u0435\u0440: \u0417\u0432\u0451\u0437\u0434\u043d\u044b\u0435 \u0432\u043e\u0439\u043d\u044b (\u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f)", - "OptionSearchForInternetMetadata": "\u0418\u0441\u043a\u0430\u0442\u044c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435", "ButtonCreate": "\u0421\u043e\u0437\u0434\u0430\u0442\u044c", "LabelCustomCss": "\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u0435 css:", "LabelCustomCssHelp": "\u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0439\u0442\u0435 \u0441\u0432\u043e\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u0435 css \u043a \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "\u0423\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u0435", "OptionCommunityMostWatchedSort": "\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u0435 \u0431\u043e\u043b\u044c\u0448\u0435", "TabNextUp": "\u041e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0435", + "HeaderBecomeMediaBrowserSupporter": "\u0421\u0442\u0430\u043d\u044c\u0442\u0435 \u0441\u043f\u043e\u043d\u0441\u043e\u0440\u043e\u043c Media Browser", + "TextAccessPremiumFeatures": "\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435 \u043e\u0442 \u043f\u0440\u0435\u043c\u0438\u0443\u043c-\u0444\u0443\u043d\u043a\u0446\u0438\u0439", "MessageNoMovieSuggestionsAvailable": "\u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u043c\u044b\u0445 \u0444\u0438\u043b\u044c\u043c\u043e\u0432. \u041d\u0430\u0447\u043d\u0438\u0442\u0435 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438 \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0444\u0438\u043b\u044c\u043c\u044b, \u0438 \u0442\u043e\u0433\u0434\u0430 \u0432\u0435\u0440\u043d\u0438\u0442\u0435\u0441\u044c \u043d\u0430\u0437\u0430\u0434, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438.", "MessageNoCollectionsAvailable": "\u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442 \u0432\u0430\u043c \u043d\u0430\u0441\u043b\u0430\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0444\u0438\u043b\u044c\u043c\u043e\u0432, \u0441\u0435\u0440\u0438\u0430\u043b\u043e\u0432, \u0430\u043b\u044c\u0431\u043e\u043c\u043e\u0432, \u043a\u043d\u0438\u0433 \u0438 \u0438\u0433\u0440. \u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043a\u043d\u043e\u043f\u043a\u0443 +, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439.", "MessageNoPlaylistsAvailable": "\u0421\u043f\u0438\u0441\u043a\u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u0438\u0437 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0440\u0430\u0437\u043e\u043c. \u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0432\u043e \u0441\u043f\u0438\u0441\u043a\u0438, \u0449\u0435\u043b\u043a\u043d\u0438\u0442\u0435 \u043f\u0440\u0430\u0432\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 \u043c\u044b\u0448\u0438 \u0438\u043b\u0438 \u043a\u043e\u0441\u043d\u0438\u0442\u0435\u0441\u044c \u0438 \u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0439\u0442\u0435, \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u00ab\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u043e \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f\u00bb.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437, \u0434\u043d\u0438:", "LabelChannelDownloadAgeHelp": "\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0440\u0448\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u043e. \u041e\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u044b\u043c \u043f\u043e \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u0438.", "ChannelSettingsFormHelp": "\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u043a\u0430\u043d\u0430\u043b\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: Trailers \u0438\u043b\u0438 Vimeo) \u0438\u0437 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432.", - "LabelSelectCollection": "\u0412\u044b\u0431\u043e\u0440 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438:", "ButtonOptions": "\u0412\u0430\u0440\u0438\u0430\u043d\u0442\u044b", "ViewTypeMovies": "\u041a\u0438\u043d\u043e", "ViewTypeTvShows": "\u0422\u0412", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u043c\u043e\u0438\u0445 \u0430\u0441\u043f\u0435\u043a\u0442\u043e\u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043a\u0430\u043d\u0430\u043b\u043e\u0432:", "LabelGroupChannelsIntoViewsHelp": "\u041f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438, \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u0430\u043d\u0430\u043b\u044b \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u043d\u0430\u0440\u044f\u0434\u0443 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0430\u0441\u043f\u0435\u043a\u0442\u0430\u043c\u0438. \u041f\u0440\u0438 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438, \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0430\u0441\u043f\u0435\u043a\u0442\u0430 \u00ab\u041a\u0430\u043d\u0430\u043b\u044b\u00bb.", "LabelDisplayCollectionsView": "\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0430\u0441\u043f\u0435\u043a\u0442 \u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0444\u0438\u043b\u044c\u043c\u043e\u0432", + "LabelDisplayCollectionsViewHelp": "\u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0430\u0441\u043f\u0435\u043a\u0442 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u0430\u043c\u0438 \u0438\u043b\u0438 \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0438\u043c\u0435\u0435\u0442\u0435 \u0434\u043e\u0441\u0442\u0443\u043f. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e, \u0449\u0435\u043b\u043a\u043d\u0438\u0442\u0435 \u043f\u0440\u0430\u0432\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 \u043c\u044b\u0448\u0438 \u0438\u043b\u0438 \u043a\u043e\u0441\u043d\u0438\u0442\u0435\u0441\u044c \u0438 \u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0439\u0442\u0435 \u043b\u044e\u0431\u043e\u0439 \u0444\u0438\u043b\u044c\u043c, \u0438 \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \"\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438\".", "LabelKodiMetadataEnableExtraThumbs": "\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c extrafanart \u0432\u043d\u0443\u0442\u0440\u044c extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "\u041f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432, \u0438\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u044c extrafanart \u0438 extrathumbs \u0434\u043b\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u0441 \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u043e\u0439 Kodi.", "TabServices": "\u0421\u043b\u0443\u0436\u0431\u044b", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/sv.json b/MediaBrowser.Server.Implementations/Localization/Server/sv.json index 0517f7fa8..c72e2fa9f 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/sv.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/sv.json @@ -55,6 +55,12 @@ "HeaderAudio": "Ljud", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Identifiera arkivfiler som media", @@ -290,7 +296,7 @@ "OptionMetascore": "Metabetyg", "ButtonSelect": "V\u00e4lj", "ButtonGroupVersions": "Gruppera versioner", - "ButtonAddToCollection": "L\u00e4gg till samling", + "ButtonAddToCollection": "Add to Collection", "PismoMessage": "Anv\u00e4nder Pismo File Mount baserat p\u00e5 en sk\u00e4nkt licens", "TangibleSoftwareMessage": "Anv\u00e4nder Tangible Solutions Java\/C#-konverterare baserat p\u00e5 en sk\u00e4nkt licens.", "HeaderCredits": "Tack till", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "\u00d6vers\u00e4ttningen av Media Browser \u00e4r ett p\u00e5g\u00e5ende projekt och \u00e4nnu ej f\u00e4rdigst\u00e4llt.", "LabelReadHowYouCanContribute": "L\u00e4s om hur du kan bidra.", "HeaderNewCollection": "Ny samling", - "HeaderAddToCollection": "L\u00e4gg till samling", "ButtonSubmit": "Bekr\u00e4fta", - "NewCollectionNameExample": "Exemple: Star Wars-samling", - "OptionSearchForInternetMetadata": "S\u00f6k p\u00e5 internet efter grafik och metadata", "ButtonCreate": "Skapa", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "F\u00f6rval", "OptionCommunityMostWatchedSort": "Oftast visade", "TabNextUp": "N\u00e4stkommande", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "Det finns inga filmf\u00f6rslag f\u00f6r tillf\u00e4llet. Efter att ha sett ett antal filmer kan du \u00e5terkomma hit f\u00f6r att se dina f\u00f6rslag.", "MessageNoCollectionsAvailable": "Samlingar g\u00f6r det m\u00f6jligt att avnjuta personliga grupperingar av filmer, serier, Album, b\u00f6cker och spel. Klicka p\u00e5 knappen + f\u00f6r att b\u00f6rja skapa samlingar.", "MessageNoPlaylistsAvailable": "Spellistor l\u00e5ter dig skapa listor med inneh\u00e5ll att spela upp i ordning. F\u00f6r att l\u00e4gga till objekt i spellistor, h\u00f6gerklicka eller tryck-och-h\u00e5ll och v\u00e4lj \"l\u00e4gg till i spellista\".", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Radera inneh\u00e5ll efter (dagar):", "LabelChannelDownloadAgeHelp": "Nedladdat inneh\u00e5ll \u00e4ldre \u00e4n s\u00e5 raderas. Det \u00e4r fortfarande tillg\u00e4ngligt via str\u00f6mning fr\u00e5n Internet.", "ChannelSettingsFormHelp": "Installera kanaler, t ex Trailers och Vimeo, via till\u00e4ggskatalogen.", - "LabelSelectCollection": "V\u00e4lj samling:", "ButtonOptions": "Alternativ", "ViewTypeMovies": "Filmer", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Visa dessa kanaler direkt i mina vyer:", "LabelGroupChannelsIntoViewsHelp": "Om aktiverat kommer dessa kanaler att visas tillsammans med andra vyer. Annars visas de i en separat vy f\u00f6r Kanaler.", "LabelDisplayCollectionsView": "Vy som visar filmsamlingar", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Kopiera extrafanart till extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "N\u00e4r bilder h\u00e4mtas fr\u00e5n Internet kan de sparas i b\u00e5de extrafanart- och extrathumbs-mapparna f\u00f6r att ge maximal kompatibilitet med Kodi-skins.", "TabServices": "Tj\u00e4nster", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/tr.json b/MediaBrowser.Server.Implementations/Localization/Server/tr.json index 66e6b854a..8f5026eb9 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/tr.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/tr.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "Yeni Koleksiyon", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Sonraki hafta", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/uk.json b/MediaBrowser.Server.Implementations/Localization/Server/uk.json index 6901b24a0..e2d455fde 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/uk.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/uk.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/vi.json b/MediaBrowser.Server.Implementations/Localization/Server/vi.json index 7eb59492d..e4139fb1d 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/vi.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/vi.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/zh_CN.json b/MediaBrowser.Server.Implementations/Localization/Server/zh_CN.json index d5e2167f3..007aca091 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/zh_CN.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/zh_CN.json @@ -55,6 +55,12 @@ "HeaderAudio": "\u97f3\u9891", "HeaderVideo": "\u89c6\u9891", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -290,7 +296,7 @@ "OptionMetascore": "\u8bc4\u5206", "ButtonSelect": "\u9009\u62e9", "ButtonGroupVersions": "\u7248\u672c\u53f7", - "ButtonAddToCollection": "\u52a0\u5165\u5408\u96c6", + "ButtonAddToCollection": "Add to Collection", "PismoMessage": "\u901a\u8fc7\u6350\u8d60\u83b7\u53d6Pismo File Mount\u7684\u4f7f\u7528\u6388\u6743\u3002", "TangibleSoftwareMessage": "\u901a\u8fc7\u6350\u8d60\u7684\u8bb8\u53ef\u8bc1\u4f7f\u7528Java \/ C\uff03\u8f6c\u6362\u5668\u5207\u5b9e\u53ef\u884c\u7684\u89e3\u51b3\u65b9\u6848\u3002", "HeaderCredits": "\u5236\u4f5c\u4eba\u5458\u540d\u5355", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "\u7ffb\u8bd1Media Browser\u662f\u4e00\u4e2a\u6b63\u5728\u8fdb\u884c\u7684\u9879\u76ee\uff0c\u5c1a\u672a\u5168\u90e8\u5b8c\u6210\u3002", "LabelReadHowYouCanContribute": "\u9605\u8bfb\u5173\u4e8e\u5982\u4f55\u4e3aMedia Browser\u8d21\u732e\u529b\u91cf\u3002", "HeaderNewCollection": "\u65b0\u5408\u96c6", - "HeaderAddToCollection": "\u52a0\u5165\u5408\u96c6", "ButtonSubmit": "\u63d0\u4ea4", - "NewCollectionNameExample": "\u4f8b\u5982\uff1a\u661f\u7403\u5927\u6218\u5408\u96c6", - "OptionSearchForInternetMetadata": "\u5728\u4e92\u8054\u7f51\u4e0a\u641c\u7d22\u5a92\u4f53\u56fe\u50cf\u548c\u8d44\u6599", "ButtonCreate": "\u521b\u5efa", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "\u9ed8\u8ba4", "OptionCommunityMostWatchedSort": "\u6700\u53d7\u77a9\u76ee", "TabNextUp": "\u4e0b\u4e00\u4e2a", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "\u6ca1\u6709\u53ef\u7528\u7684\u7535\u5f71\u5efa\u8bae\u3002\u5f00\u59cb\u89c2\u770b\u4f60\u7684\u7535\u5f71\u5e76\u8fdb\u884c\u8bc4\u5206\uff0c\u518d\u56de\u8fc7\u5934\u6765\u67e5\u770b\u4f60\u7684\u5efa\u8bae\u3002", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "\u64ad\u653e\u5217\u8868\u5141\u8bb8\u60a8\u521b\u5efa\u4e00\u4e2a\u5185\u5bb9\u5217\u8868\u6765\u8fde\u7eed\u64ad\u653e\u3002\u5c06\u9879\u76ee\u6dfb\u52a0\u5230\u64ad\u653e\u5217\u8868\uff0c\u53f3\u952e\u5355\u51fb\u6216\u70b9\u51fb\u5e76\u6309\u4f4f\uff0c\u7136\u540e\u9009\u62e9\u201c\u6dfb\u52a0\u5230\u64ad\u653e\u5217\u8868\u201d\u3002", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "\u8fc7\u591a\u4e45\u5220\u9664\u5185\u5bb9: (\u5929\u6570)", "LabelChannelDownloadAgeHelp": "\u4e0b\u8f7d\u7684\u5185\u5bb9\u8d85\u8fc7\u6b64\u671f\u9650\u5c06\u88ab\u5220\u9664\u3002\u5b83\u4ecd\u53ef\u901a\u8fc7\u4e92\u8054\u7f51\u6d41\u5a92\u4f53\u64ad\u653e\u3002", "ChannelSettingsFormHelp": "\u5728\u63d2\u4ef6\u76ee\u5f55\u91cc\u5b89\u88c5\u9891\u9053\uff0c\u4f8b\u5982\uff1aTrailers \u548c Vimeo", - "LabelSelectCollection": "\u9009\u62e9\u5408\u96c6\uff1a", "ButtonOptions": "Options", "ViewTypeMovies": "\u7535\u5f71", "ViewTypeTvShows": "\u7535\u89c6", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "\u5728\u6211\u7684\u754c\u9762\u91cc\u76f4\u63a5\u663e\u793a\u4ee5\u4e0b\u9891\u9053\uff1a", "LabelGroupChannelsIntoViewsHelp": "\u5982\u679c\u542f\u7528\uff0c\u8fd9\u4e9b\u9891\u9053\u5c06\u548c\u5176\u4ed6\u7684\u754c\u9762\u89c6\u56fe\u5e76\u5217\u663e\u793a\u3002\u5982\u679c\u7981\u7528\uff0c\u5b83\u4eec\u5c06\u88ab\u663e\u793a\u5728\u4e00\u4e2a\u5355\u72ec\u7684\u754c\u9762\u89c6\u56fe\u91cc\u3002", "LabelDisplayCollectionsView": "\u663e\u793a\u5408\u96c6\u89c6\u56fe\u6765\u5448\u73b0\u7535\u5f71\u5408\u96c6", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "\u590d\u5236\u540c\u4eba\u753b\u5230extrathumbs\u6587\u4ef6\u5939", "LabelKodiMetadataEnableExtraThumbsHelp": "\u4e3a\u4e86\u6700\u5927\u5316\u517c\u5bb9Kodi\u76ae\u80a4\uff0c\u4e0b\u8f7d\u7684\u56fe\u7247\u540c\u65f6\u50a8\u5b58\u5728 extrafanart \u548c extrathumbs \u6587\u4ef6\u5939\u3002", "TabServices": "\u670d\u52a1", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json b/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json index 88f9c19e9..043ca6061 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json @@ -55,6 +55,12 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", + "LabelCustomCertificatePath": "Custom certificate path:", + "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", "ButtonDonateWithPayPal": "Donate with PayPal", "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", @@ -512,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "\u7ffb\u8b6fMedia Browser\u662f\u4e00\u500b\u6b63\u5728\u9032\u884c\u7684\u9805\u76ee\uff0c\u5c1a\u672a\u5b8c\u6210\u3002", "LabelReadHowYouCanContribute": "\u95b1\u8b80\u95dc\u65bc\u5982\u4f55\u70baMedia Browser\u8ca2\u737b\u3002", "HeaderNewCollection": "\u65b0\u5408\u96c6", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "\u4f8b\u5b50\uff1a\u661f\u7403\u5927\u6230\u5408\u96c6", - "OptionSearchForInternetMetadata": "\u5728\u4e92\u806f\u7db2\u4e0a\u641c\u7d22\u5a92\u9ad4\u5716\u50cf\u548c\u8cc7\u6599", "ButtonCreate": "\u5275\u5efa", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -880,6 +883,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -896,7 +901,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -958,6 +962,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 5284a42e4..b4be3d788 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -899,7 +899,7 @@ namespace MediaBrowser.Server.Implementations.Session { var folder = (Folder)item; - var items = user == null ? + var items = user == null ? folder.GetRecursiveChildren(i => !i.IsFolder) : folder.GetRecursiveChildren(user, i => !i.IsFolder); @@ -1355,7 +1355,14 @@ namespace MediaBrowser.Server.Implementations.Session if (saveCapabilities) { - await SaveCapabilities(session.DeviceId, capabilities).ConfigureAwait(false); + try + { + await SaveCapabilities(session.DeviceId, capabilities).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error saving device capabilities", ex); + } } } -- cgit v1.2.3 From a6145e54d901095e5b67704e3103843b4b515681 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 29 Jan 2015 01:06:24 -0500 Subject: support in-home easy password --- MediaBrowser.Api/UserService.cs | 78 +++++++++++++++++++++- .../Networking/BaseNetworkManager.cs | 25 +++++-- MediaBrowser.Controller/Entities/User.cs | 2 +- MediaBrowser.Controller/Library/IUserManager.cs | 15 +++++ MediaBrowser.Model/Dto/UserDto.cs | 6 ++ .../Library/UserManager.cs | 54 ++++++++++----- .../Localization/JavaScript/javascript.json | 5 +- .../Localization/Server/server.json | 8 ++- 8 files changed, 165 insertions(+), 28 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index 4f49dd37d..2c497d172 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -11,7 +11,6 @@ using MediaBrowser.Model.Connect; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Users; using ServiceStack; -using ServiceStack.Text.Controller; using System; using System.Collections.Generic; using System.Linq; @@ -148,6 +147,32 @@ namespace MediaBrowser.Api public bool ResetPassword { get; set; } } + /// + /// Class UpdateUserEasyPassword + /// + [Route("/Users/{Id}/EasyPassword", "POST", Summary = "Updates a user's easy password")] + [Authenticated] + public class UpdateUserEasyPassword : IReturnVoid + { + /// + /// Gets or sets the id. + /// + /// The id. + public string Id { get; set; } + + /// + /// Gets or sets the new password. + /// + /// The new password. + public string NewPassword { get; set; } + + /// + /// Gets or sets a value indicating whether [reset password]. + /// + /// true if [reset password]; otherwise, false. + public bool ResetPassword { get; set; } + } + /// /// Class UpdateUser /// @@ -410,6 +435,8 @@ namespace MediaBrowser.Api public async Task PostAsync(UpdateUserPassword request) { + AssertCanUpdateUser(request.Id); + var user = _userManager.GetUserById(request.Id); if (user == null) @@ -434,6 +461,33 @@ namespace MediaBrowser.Api } } + public void Post(UpdateUserEasyPassword request) + { + var task = PostAsync(request); + Task.WaitAll(task); + } + + public async Task PostAsync(UpdateUserEasyPassword request) + { + AssertCanUpdateUser(request.Id); + + var user = _userManager.GetUserById(request.Id); + + if (user == null) + { + throw new ResourceNotFoundException("User not found"); + } + + if (request.ResetPassword) + { + await _userManager.ResetEasyPassword(user).ConfigureAwait(false); + } + else + { + await _userManager.ChangeEasyPassword(user, request.NewPassword).ConfigureAwait(false); + } + } + /// /// Posts the specified request. /// @@ -449,7 +503,9 @@ namespace MediaBrowser.Api { // We need to parse this manually because we told service stack not to with IRequiresRequestStream // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs - var id = new Guid(GetPathValue(1)); + var id = GetPathValue(1); + + AssertCanUpdateUser(id); var dtoUser = request; @@ -499,11 +555,29 @@ namespace MediaBrowser.Api public void Post(UpdateUserConfiguration request) { + AssertCanUpdateUser(request.Id); + var task = _userManager.UpdateConfiguration(request.Id, request); Task.WaitAll(task); } + private void AssertCanUpdateUser(string userId) + { + var auth = AuthorizationContext.GetAuthorizationInfo(Request); + + // If they're going to update the record of another user, they must be an administrator + if (!string.Equals(userId, auth.UserId, StringComparison.OrdinalIgnoreCase)) + { + var authenticatedUser = _userManager.GetUserById(auth.UserId); + + if (!authenticatedUser.Policy.IsAdministrator) + { + throw new SecurityException("Unauthorized access."); + } + } + } + public void Post(UpdateUserPolicy request) { var task = UpdateUserPolicy(request); diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs index 660ac09f9..6deda1293 100644 --- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs +++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs @@ -50,7 +50,7 @@ namespace MediaBrowser.Common.Implementations.Networking { NetworkChange.NetworkAddressChanged -= NetworkChange_NetworkAddressChanged; NetworkChange.NetworkAvailabilityChanged -= NetworkChange_NetworkAvailabilityChanged; - + NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged; NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged; } @@ -106,6 +106,11 @@ namespace MediaBrowser.Common.Implementations.Networking // Private address space: // http://en.wikipedia.org/wiki/Private_network + if (endpoint.StartsWith("172.", StringComparison.OrdinalIgnoreCase)) + { + return Is172AddressPrivate(endpoint); + } + return // If url was requested with computer name, we may see this @@ -114,11 +119,23 @@ namespace MediaBrowser.Common.Implementations.Networking endpoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) || endpoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) || endpoint.StartsWith("10.", StringComparison.OrdinalIgnoreCase) || - endpoint.StartsWith("192.", StringComparison.OrdinalIgnoreCase) || - endpoint.StartsWith("172.", StringComparison.OrdinalIgnoreCase) || + endpoint.StartsWith("192.168", StringComparison.OrdinalIgnoreCase) || endpoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase); } + private bool Is172AddressPrivate(string endpoint) + { + for (var i = 16; i <= 31; i++) + { + if (endpoint.StartsWith("172." + i.ToString(CultureInfo.InvariantCulture) + ".", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + } + public bool IsInLocalNetwork(string endpoint) { return IsInLocalNetworkInternal(endpoint, true); @@ -175,7 +192,7 @@ namespace MediaBrowser.Common.Implementations.Networking return false; } - + public IEnumerable GetIpAddresses(string hostName) { return Dns.GetHostAddresses(hostName); diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs index 1fca676a9..01a7486b3 100644 --- a/MediaBrowser.Controller/Entities/User.cs +++ b/MediaBrowser.Controller/Entities/User.cs @@ -32,7 +32,7 @@ namespace MediaBrowser.Controller.Entities /// /// The password. public string Password { get; set; } - public string LocalPassword { get; set; } + public string EasyPassword { get; set; } public string ConnectUserName { get; set; } public string ConnectUserId { get; set; } diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index f5846973e..5aa58aa57 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -117,6 +117,13 @@ namespace MediaBrowser.Controller.Library /// Task. Task ResetPassword(User user); + /// + /// Resets the easy password. + /// + /// The user. + /// Task. + Task ResetEasyPassword(User user); + /// /// Changes the password. /// @@ -125,6 +132,14 @@ namespace MediaBrowser.Controller.Library /// Task. Task ChangePassword(User user, string newPasswordSha1); + /// + /// Changes the easy password. + /// + /// The user. + /// The new password sha1. + /// Task. + Task ChangeEasyPassword(User user, string newPasswordSha1); + /// /// Gets the user dto. /// diff --git a/MediaBrowser.Model/Dto/UserDto.cs b/MediaBrowser.Model/Dto/UserDto.cs index 9b6d92030..3e2d869d6 100644 --- a/MediaBrowser.Model/Dto/UserDto.cs +++ b/MediaBrowser.Model/Dto/UserDto.cs @@ -66,6 +66,12 @@ namespace MediaBrowser.Model.Dto /// /// true if this instance has configured password; otherwise, false. public bool HasConfiguredPassword { get; set; } + + /// + /// Gets or sets a value indicating whether this instance has configured easy password. + /// + /// true if this instance has configured easy password; otherwise, false. + public bool HasConfiguredEasyPassword { get; set; } /// /// Gets or sets the last login date. diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 6b6f5b1b6..a001b25b6 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -275,9 +275,9 @@ namespace MediaBrowser.Server.Implementations.Library private string GetLocalPasswordHash(User user) { - return string.IsNullOrEmpty(user.LocalPassword) + return string.IsNullOrEmpty(user.EasyPassword) ? GetSha1String(string.Empty) - : user.LocalPassword; + : user.EasyPassword; } private bool IsPasswordEmpty(string passwordHash) @@ -355,18 +355,20 @@ namespace MediaBrowser.Server.Implementations.Library var passwordHash = GetPasswordHash(user); - var hasConfiguredDefaultPassword = !IsPasswordEmpty(passwordHash); + var hasConfiguredPassword = !IsPasswordEmpty(passwordHash); + var hasConfiguredEasyPassword = !IsPasswordEmpty(GetLocalPasswordHash(user)); var hasPassword = user.Configuration.EnableLocalPassword && !string.IsNullOrEmpty(remoteEndPoint) && _networkManager.IsInLocalNetwork(remoteEndPoint) ? - !IsPasswordEmpty(GetLocalPasswordHash(user)) : - hasConfiguredDefaultPassword; + hasConfiguredEasyPassword : + hasConfiguredPassword; var dto = new UserDto { Id = user.Id.ToString("N"), Name = user.Name, HasPassword = hasPassword, - HasConfiguredPassword = hasConfiguredDefaultPassword, + HasConfiguredPassword = hasConfiguredPassword, + HasConfiguredEasyPassword = hasConfiguredEasyPassword, LastActivityDate = user.LastActivityDate, LastLoginDate = user.LastLoginDate, Configuration = user.Configuration, @@ -613,18 +615,11 @@ namespace MediaBrowser.Server.Implementations.Library return ChangePassword(user, GetSha1String(string.Empty)); } - /// - /// Changes the password. - /// - /// The user. - /// The new password sha1. - /// Task. - /// - /// user - /// or - /// newPassword - /// - /// Passwords for guests cannot be changed. + public Task ResetEasyPassword(User user) + { + return ChangeEasyPassword(user, GetSha1String(string.Empty)); + } + public async Task ChangePassword(User user, string newPasswordSha1) { if (user == null) @@ -648,6 +643,29 @@ namespace MediaBrowser.Server.Implementations.Library EventHelper.FireEventIfNotNull(UserPasswordChanged, this, new GenericEventArgs(user), _logger); } + public async Task ChangeEasyPassword(User user, string newPasswordSha1) + { + if (user == null) + { + throw new ArgumentNullException("user"); + } + if (string.IsNullOrWhiteSpace(newPasswordSha1)) + { + throw new ArgumentNullException("newPasswordSha1"); + } + + if (user.ConnectLinkType.HasValue && user.ConnectLinkType.Value == UserLinkType.Guest) + { + throw new ArgumentException("Passwords for guests cannot be changed."); + } + + user.EasyPassword = newPasswordSha1; + + await UpdateUser(user).ConfigureAwait(false); + + EventHelper.FireEventIfNotNull(UserPasswordChanged, this, new GenericEventArgs(user), _logger); + } + /// /// Instantiates the new user. /// diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index ede08a49c..2dcd6eca5 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -14,9 +14,12 @@ "FileReadError": "An error occurred while reading the file.", "DeleteUser": "Delete User", "DeleteUserConfirmation": "Are you sure you wish to delete this user?", - "PasswordResetHeader": "Password Reset", + "PasswordResetHeader": "Reset Password", "PasswordResetComplete": "The password has been reset.", + "PinCodeResetComplete": "The pin code has been reset.", "PasswordResetConfirmation": "Are you sure you wish to reset the password?", + "PinCodeResetConfirmation": "Are you sure you wish to reset the pin code?", + "HeaderPinCodeReset": "Reset Pin Code", "PasswordSaved": "Password saved.", "PasswordMatchError": "Password and password confirmation must match.", "OptionRelease": "Official Release", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 3e9c75220..93ef75dc3 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -56,6 +56,7 @@ "HeaderVideo": "Video", "HeaderPaths": "Paths", "CategorySync": "Sync", + "HeaderEasyPinCode": "Easy Pin Code", "RegisterWithPayPal": "Register with PayPal", "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", @@ -1132,11 +1133,14 @@ "LabelDisplayFoldersView": "Display a folders view to show plain media folders", "ViewTypeLiveTvRecordingGroups": "Recordings", "ViewTypeLiveTvChannels": "Channels", - "LabelAllowLocalAccessWithoutPassword": "Allow local access without a password", - "LabelAllowLocalAccessWithoutPasswordHelp": "When enabled, a password will not be required when signing in from within your home network.", + "LabelEasyPinCode": "Easy pin code:", + "EasyPasswordHelp": "Your easy pin code is used for offline access with supported Media Browser apps, and can also be used for easy in-network sign in.", + "LabelInNetworkSignInWithEasyPassword": "Enable in-network sign in with my easy pin code", + "LabelInNetworkSignInWithEasyPasswordHelp": "If enabled, you'll be able to use your easy pin code to sign in to Media Browser apps from inside your home network. Your regular password will only be needed away from home. If the pin code is left blank, you won't need a password within your home network.", "HeaderPassword": "Password", "HeaderLocalAccess": "Local Access", "HeaderViewOrder": "View Order", + "ButtonResetEasyPassword": "Reset easy pin code", "LabelSelectUserViewOrder": "Choose the order your views will be displayed in within Media Browser apps", "LabelMetadataRefreshMode": "Metadata refresh mode:", "LabelImageRefreshMode": "Image refresh mode:", -- cgit v1.2.3 From a85cc6db21ec6a68f772c834df2ca201aec08692 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 31 Jan 2015 22:29:26 -0500 Subject: duplicate password fields on admin side --- .../Localization/JavaScript/javascript.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 2dcd6eca5..27b46db52 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -681,7 +681,7 @@ "MessageForgotPasswordFileCreated": "The following file has been created on your server and contains instructions on how to proceed:", "MessageForgotPasswordFileExpiration": "The reset pin will expire at {0}.", "MessageInvalidForgotPasswordPin": "An invalid or expired pin was entered. Please try again.", - "MessagePasswordResetForUsers": "Passwords have been reset for the following users:", + "MessagePasswordResetForUsers": "Passwords have been removed for the following users:", "HeaderInviteGuest": "Invite Guest", "ButtonLinkMyMediaBrowserAccount": "Link my account now", "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.", -- cgit v1.2.3 From 0f88525d618f3f8c7fdc0bc515a2357dac8fee63 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 3 Feb 2015 13:55:15 -0500 Subject: clean up sync temp files when canceling jobs --- .../Localization/JavaScript/javascript.json | 4 ++++ .../Sync/SyncJobProcessor.cs | 23 ++++++++++++++++------ .../Sync/SyncManager.cs | 22 +++++++++++++++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 27b46db52..4b9795b82 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -48,6 +48,10 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Save", + "SyncJobStatusQueued": "Queued", + "SyncJobStatusInProgress": "In-Progress", + "SyncJobStatusCompleted": "Synced", + "SyncJobStatusCompletedWithError": "Synced with errors", "LabelCollection": "Collection", "HeaderAddToCollection": "Add to Collection", "NewCollectionNameExample": "Example: Star Wars Collection", diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index e3db46427..572ddd3c8 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -183,7 +183,7 @@ namespace MediaBrowser.Server.Implementations.Sync job.Status = SyncJobStatus.Completed; } } - else if (pct.Equals(0)) + else if (pct.Equals(0) && jobItems.All(i => i.Status == SyncJobItemStatus.Queued)) { job.Status = SyncJobStatus.Queued; } @@ -414,7 +414,6 @@ namespace MediaBrowser.Server.Implementations.Sync } jobItem.Progress = 0; - jobItem.Status = SyncJobItemStatus.Converting; var user = _userManager.GetUserById(job.UserId); @@ -426,7 +425,7 @@ namespace MediaBrowser.Server.Implementations.Sync else if (item is Audio) { - await Sync(jobItem, (Audio)item, user, deviceProfile, enableConversion, progress, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, job, (Audio)item, user, deviceProfile, enableConversion, progress, cancellationToken).ConfigureAwait(false); } else if (item is Photo) @@ -478,6 +477,7 @@ namespace MediaBrowser.Server.Implementations.Sync { // Save the job item now since conversion could take a while await _syncRepo.Update(jobItem).ConfigureAwait(false); + await UpdateJobStatus(job).ConfigureAwait(false); try { @@ -611,7 +611,7 @@ namespace MediaBrowser.Server.Implementations.Sync }; } - private async Task Sync(SyncJobItem jobItem, Audio item, User user, DeviceProfile profile, bool enableConversion, IProgress progress, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, SyncJob job, Audio item, User user, DeviceProfile profile, bool enableConversion, IProgress progress, CancellationToken cancellationToken) { var options = _syncManager.GetAudioOptions(jobItem); @@ -636,6 +636,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Status = SyncJobItemStatus.Converting; await _syncRepo.Update(jobItem).ConfigureAwait(false); + await UpdateJobStatus(job).ConfigureAwait(false); try { @@ -710,7 +711,12 @@ namespace MediaBrowser.Server.Implementations.Sync return mediaSource.Path; } - private string GetTemporaryPath(SyncJobItem jobItem) + public string GetTemporaryPath(SyncJob job) + { + return GetTemporaryPath(job.Id); + } + + public string GetTemporaryPath(string jobId) { var basePath = _config.GetSyncOptions().TemporaryPath; @@ -719,7 +725,12 @@ namespace MediaBrowser.Server.Implementations.Sync basePath = Path.Combine(_config.CommonApplicationPaths.ProgramDataPath, "sync"); } - return Path.Combine(basePath, jobItem.JobId, jobItem.Id); + return Path.Combine(basePath, jobId); + } + + public string GetTemporaryPath(SyncJobItem jobItem) + { + return Path.Combine(GetTemporaryPath(jobItem.JobId), jobItem.Id); } private async Task GetEncodedMediaSource(string path, User user, bool isVideo) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 3c5b27d63..6a4bc9cc4 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -309,6 +309,17 @@ namespace MediaBrowser.Server.Implementations.Sync await _repo.DeleteJob(id).ConfigureAwait(false); + var path = GetSyncJobProcessor().GetTemporaryPath(id); + + try + { + _fileSystem.DeleteDirectory(path, true); + } + catch (Exception ex) + { + _logger.ErrorException("Error deleting directory {0}", ex, path); + } + if (SyncJobCancelled != null) { EventHelper.FireEventIfNotNull(SyncJobCancelled, this, new GenericEventArgs @@ -706,6 +717,17 @@ namespace MediaBrowser.Server.Implementations.Sync var processor = GetSyncJobProcessor(); await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); + + var path = processor.GetTemporaryPath(jobItem); + + try + { + _fileSystem.DeleteDirectory(path, true); + } + catch (Exception ex) + { + _logger.ErrorException("Error deleting directory {0}", ex, path); + } } public async Task MarkJobItemForRemoval(string id) -- cgit v1.2.3 From 6c3209e3f95cc537cc97984ba5a4d5eee0373424 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 4 Feb 2015 06:56:48 -0500 Subject: dlna fixes --- MediaBrowser.Dlna/DlnaManager.cs | 2 +- MediaBrowser.Dlna/Profiles/Xbox360Profile.cs | 1 + MediaBrowser.Dlna/Profiles/Xml/Default.xml | 1 + MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml | 1 + MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml | 1 + .../Profiles/Xml/Dish Hopper-Joey.xml | 1 + MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml | 1 + MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml | 1 + MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml | 1 + MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml | 1 + MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml | 1 + .../Profiles/Xml/Samsung Smart TV.xml | 1 + .../Profiles/Xml/Sony Blu-ray Player 2013.xml | 1 + .../Profiles/Xml/Sony Blu-ray Player.xml | 1 + .../Profiles/Xml/Sony Bravia (2010).xml | 1 + .../Profiles/Xml/Sony Bravia (2011).xml | 1 + .../Profiles/Xml/Sony Bravia (2012).xml | 1 + .../Profiles/Xml/Sony Bravia (2013).xml | 1 + .../Profiles/Xml/Sony PlayStation 3.xml | 1 + MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml | 1 + MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml | 1 + MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml | 1 + MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml | 1 + MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs | 17 +-- MediaBrowser.Model/Dlna/DeviceProfile.cs | 1 + MediaBrowser.Model/Dlna/StreamBuilder.cs | 18 --- MediaBrowser.Model/Sync/SyncJobQuery.cs | 23 +++- .../Localization/JavaScript/javascript.json | 4 +- .../Sync/SyncJobProcessor.cs | 6 +- .../Sync/SyncRepository.cs | 127 ++++++++++++--------- .../TV/TVSeriesManager.cs | 2 +- Nuget/MediaBrowser.Common.Internal.nuspec | 4 +- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Model.Signed.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +- 35 files changed, 139 insertions(+), 95 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index f0f295c83..0bce849ce 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -515,7 +515,7 @@ namespace MediaBrowser.Dlna public void Run() { - //DumpProfiles(); + DumpProfiles(); } private void DumpProfiles() diff --git a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs index c792eb078..7aa924be0 100644 --- a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs +++ b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs @@ -29,6 +29,7 @@ namespace MediaBrowser.Dlna.Profiles TimelineOffsetSeconds = 40; RequiresPlainFolders = true; RequiresPlainVideoItems = true; + EnableMSMediaReceiverRegistrar = true; Identification = new DeviceIdentification { diff --git a/MediaBrowser.Dlna/Profiles/Xml/Default.xml b/MediaBrowser.Dlna/Profiles/Xml/Default.xml index fd4246dec..b70cc10c2 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Default.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Default.xml @@ -28,6 +28,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml index b62580f69..6250e0f0e 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml @@ -33,6 +33,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml index 603ec554e..0079b5f8d 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml @@ -34,6 +34,7 @@ true false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml index c8eff5b1d..d338b2b6d 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml @@ -35,6 +35,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml index e625555bd..ba72f6306 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml @@ -34,6 +34,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml index 09165349e..829ce7068 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml @@ -32,6 +32,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml index c57a368b3..78ba4aba3 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml @@ -34,6 +34,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml index 515492c7f..88160b0ce 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml @@ -35,6 +35,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml index 4fa4db30b..d6acd65ca 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml @@ -28,6 +28,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml index d2b814de3..bd113b9c7 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml @@ -34,6 +34,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml index 1d0ea66bb..3104f5c68 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml @@ -34,6 +34,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml index 2a883ac67..57a32607e 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml @@ -36,6 +36,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml index d9727ecd0..b7325c53c 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml @@ -36,6 +36,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml index 1e3b48452..59157badd 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml @@ -36,6 +36,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml index 509f533b9..d2d9c181f 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml @@ -36,6 +36,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml index 35e645422..7b3d95b9d 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml @@ -36,6 +36,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml index 939f953b9..454dabe5d 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml @@ -36,6 +36,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml index 015dbbc1f..2829bfb47 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml @@ -35,6 +35,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml index 7a183396d..76e4a6c31 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml @@ -35,6 +35,7 @@ true false false + true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml index f666dfd27..c8c0a5202 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml @@ -35,6 +35,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml index 2afdcc6f8..7a8f3a09d 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml @@ -34,6 +34,7 @@ false false false + false diff --git a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs index f586e4fa1..e302fe902 100644 --- a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs +++ b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs @@ -261,14 +261,17 @@ namespace MediaBrowser.Dlna.Server EventSubUrl = "connectionmanager/events" }); - list.Add(new DeviceService + if (_profile.EnableMSMediaReceiverRegistrar) { - ServiceType = "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1", - ServiceId = "urn:microsoft.com:serviceId:X_MS_MediaReceiverRegistrar", - ScpdUrl = "mediareceiverregistrar/mediareceiverregistrar.xml", - ControlUrl = "mediareceiverregistrar/control", - EventSubUrl = "mediareceiverregistrar/events" - }); + list.Add(new DeviceService + { + ServiceType = "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1", + ServiceId = "urn:microsoft.com:serviceId:X_MS_MediaReceiverRegistrar", + ScpdUrl = "mediareceiverregistrar/mediareceiverregistrar.xml", + ControlUrl = "mediareceiverregistrar/control", + EventSubUrl = "mediareceiverregistrar/events" + }); + } return list; } diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index 1fb553010..3bbef28c5 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -78,6 +78,7 @@ namespace MediaBrowser.Model.Dlna public bool SupportsDirectRemoteContent { get; set; } public bool SupportsCustomHttpHeaders { get; set; } + public bool EnableMSMediaReceiverRegistrar { get; set; } public XmlAttribute[] XmlRootAttributes { get; set; } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 117d738f3..84c083997 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -524,11 +524,6 @@ namespace MediaBrowser.Model.Dlna { if (subtitleStream != null) { - if (!subtitleStream.IsTextSubtitleStream) - { - return false; - } - SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options); if (subtitleProfile.Method != SubtitleDeliveryMethod.External && subtitleProfile.Method != SubtitleDeliveryMethod.Embed) @@ -568,19 +563,6 @@ namespace MediaBrowser.Model.Dlna }; } - private SubtitleProfile GetSubtitleProfile(SubtitleProfile[] profiles, SubtitleDeliveryMethod method, string[] formats) - { - foreach (SubtitleProfile profile in profiles) - { - if (method == profile.Method && ListHelper.ContainsIgnoreCase(formats, profile.Format)) - { - return profile; - } - } - - return null; - } - private SubtitleProfile GetSubtitleProfile(SubtitleProfile[] profiles, SubtitleDeliveryMethod method) { foreach (SubtitleProfile profile in profiles) diff --git a/MediaBrowser.Model/Sync/SyncJobQuery.cs b/MediaBrowser.Model/Sync/SyncJobQuery.cs index 35f0e076d..233dc7878 100644 --- a/MediaBrowser.Model/Sync/SyncJobQuery.cs +++ b/MediaBrowser.Model/Sync/SyncJobQuery.cs @@ -1,4 +1,5 @@ - +using System.Collections.Generic; + namespace MediaBrowser.Model.Sync { public class SyncJobQuery @@ -14,11 +15,6 @@ namespace MediaBrowser.Model.Sync /// The limit. public int? Limit { get; set; } /// - /// Gets or sets a value indicating whether this instance is completed. - /// - /// null if [is completed] contains no value, true if [is completed]; otherwise, false. - public bool? IsCompleted { get; set; } - /// /// Gets or sets the target identifier. /// /// The target identifier. @@ -28,5 +24,20 @@ namespace MediaBrowser.Model.Sync /// /// The user identifier. public string UserId { get; set; } + /// + /// Gets or sets the status. + /// + /// The status. + public List Statuses { get; set; } + /// + /// Gets or sets a value indicating whether [synchronize new content]. + /// + /// null if [synchronize new content] contains no value, true if [synchronize new content]; otherwise, false. + public bool? SyncNewContent { get; set; } + + public SyncJobQuery() + { + Statuses = new List(); + } } } diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 4b9795b82..b494adfd8 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -89,8 +89,8 @@ "LabelFree": "Free", "HeaderSelectAudio": "Select Audio", "HeaderSelectSubtitles": "Select Subtitles", - "ButtonMarkForRemoval": "Mark for removal from device", - "ButtonUnmarkForRemoval": "Unmark for removal from device", + "ButtonMarkForRemoval": "Remove from device", + "ButtonUnmarkForRemoval": "Cancel removal from device", "LabelDefaultStream": "(Default)", "LabelForcedStream": "(Forced)", "LabelDefaultForcedStream": "(Default/Forced)", diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 3628bda2a..328b8441a 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -308,11 +308,11 @@ namespace MediaBrowser.Server.Implementations.Sync return new[] { item }; } - public async Task EnsureSyncJobs(CancellationToken cancellationToken) + public async Task EnsureSyncJobItems(CancellationToken cancellationToken) { var jobResult = _syncRepo.GetJobs(new SyncJobQuery { - IsCompleted = false + SyncNewContent = true }); foreach (var job in jobResult.Items) @@ -328,7 +328,7 @@ namespace MediaBrowser.Server.Implementations.Sync public async Task Sync(IProgress progress, CancellationToken cancellationToken) { - await EnsureSyncJobs(cancellationToken).ConfigureAwait(false); + await EnsureSyncJobItems(cancellationToken).ConfigureAwait(false); // If it already has a converting status then is must have been aborted during conversion var result = _syncRepo.GetJobItems(new SyncJobItemQuery diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 85317cb23..5a07a41e9 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -30,7 +30,8 @@ namespace MediaBrowser.Server.Implementations.Sync private IDbCommand _deleteJobCommand; private IDbCommand _deleteJobItemsCommand; - private IDbCommand _saveJobItemCommand; + private IDbCommand _insertJobItemCommand; + private IDbCommand _updateJobItemCommand; private readonly IJsonSerializer _json; @@ -120,25 +121,45 @@ namespace MediaBrowser.Server.Implementations.Sync _updateJobCommand.Parameters.Add(_updateJobCommand, "@DateLastModified"); _updateJobCommand.Parameters.Add(_updateJobCommand, "@ItemCount"); - // _saveJobItemCommand - _saveJobItemCommand = _connection.CreateCommand(); - _saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval, @JobItemIndex)"; - - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Id"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@ItemId"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@ItemName"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@MediaSourceId"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@JobId"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@TemporaryPath"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@OutputPath"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Status"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@TargetId"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@DateCreated"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Progress"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@AdditionalFiles"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@MediaSource"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@IsMarkedForRemoval"); - _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@JobItemIndex"); + // _insertJobItemCommand + _insertJobItemCommand = _connection.CreateCommand(); + _insertJobItemCommand.CommandText = "insert into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval, @JobItemIndex)"; + + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@Id"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@ItemId"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@ItemName"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@MediaSourceId"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@JobId"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@TemporaryPath"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@OutputPath"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@Status"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@TargetId"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@DateCreated"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@Progress"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@AdditionalFiles"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@MediaSource"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@IsMarkedForRemoval"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@JobItemIndex"); + + // _updateJobItemCommand + _updateJobItemCommand = _connection.CreateCommand(); + _updateJobItemCommand.CommandText = "update SyncJobItems set ItemId=@ItemId,ItemName=@ItemName,MediaSourceId=@MediaSourceId,JobId=@JobId,TemporaryPath=@TemporaryPath,OutputPath=@OutputPath,Status=@Status,TargetId=@TargetId,DateCreated=@DateCreated,Progress=@Progress,AdditionalFiles=@AdditionalFiles,MediaSource=@MediaSource,IsMarkedForRemoval=@IsMarkedForRemoval,JobItemIndex=@JobItemIndex where Id=@Id"; + + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@Id"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@ItemId"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@ItemName"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@MediaSourceId"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@JobId"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@TemporaryPath"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@OutputPath"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@Status"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@TargetId"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@DateCreated"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@Progress"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@AdditionalFiles"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@MediaSource"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@IsMarkedForRemoval"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@JobItemIndex"); } private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs"; @@ -392,17 +413,11 @@ namespace MediaBrowser.Server.Implementations.Sync var whereClauses = new List(); - if (query.IsCompleted.HasValue) + if (query.Statuses.Count > 0) { - if (query.IsCompleted.Value) - { - whereClauses.Add("Status=@Status"); - } - else - { - whereClauses.Add("Status<>@Status"); - } - cmd.Parameters.Add(cmd, "@Status", DbType.String).Value = SyncJobStatus.Completed.ToString(); + var statuses = string.Join(",", query.Statuses.Select(i => "'" + i.ToString() + "'").ToArray()); + + whereClauses.Add(string.Format("Status in ({0})", statuses)); } if (!string.IsNullOrWhiteSpace(query.TargetId)) { @@ -413,6 +428,11 @@ namespace MediaBrowser.Server.Implementations.Sync whereClauses.Add("UserId=@UserId"); cmd.Parameters.Add(cmd, "@UserId", DbType.String).Value = query.UserId; } + if (query.SyncNewContent.HasValue) + { + whereClauses.Add("SyncNewContent=@SyncNewContent"); + cmd.Parameters.Add(cmd, "@SyncNewContent", DbType.Boolean).Value = query.SyncNewContent.Value; + } var whereTextWithoutPaging = whereClauses.Count == 0 ? string.Empty : @@ -583,10 +603,15 @@ namespace MediaBrowser.Server.Implementations.Sync public Task Create(SyncJobItem jobItem) { - return Update(jobItem); + return InsertOrUpdate(jobItem, _insertJobItemCommand); + } + + public Task Update(SyncJobItem jobItem) + { + return InsertOrUpdate(jobItem, _updateJobItemCommand); } - public async Task Update(SyncJobItem jobItem) + private async Task InsertOrUpdate(SyncJobItem jobItem, IDbCommand cmd) { if (jobItem == null) { @@ -603,25 +628,25 @@ namespace MediaBrowser.Server.Implementations.Sync var index = 0; - _saveJobItemCommand.GetParameter(index++).Value = new Guid(jobItem.Id); - _saveJobItemCommand.GetParameter(index++).Value = jobItem.ItemId; - _saveJobItemCommand.GetParameter(index++).Value = jobItem.ItemName; - _saveJobItemCommand.GetParameter(index++).Value = jobItem.MediaSourceId; - _saveJobItemCommand.GetParameter(index++).Value = jobItem.JobId; - _saveJobItemCommand.GetParameter(index++).Value = jobItem.TemporaryPath; - _saveJobItemCommand.GetParameter(index++).Value = jobItem.OutputPath; - _saveJobItemCommand.GetParameter(index++).Value = jobItem.Status.ToString(); - _saveJobItemCommand.GetParameter(index++).Value = jobItem.TargetId; - _saveJobItemCommand.GetParameter(index++).Value = jobItem.DateCreated; - _saveJobItemCommand.GetParameter(index++).Value = jobItem.Progress; - _saveJobItemCommand.GetParameter(index++).Value = _json.SerializeToString(jobItem.AdditionalFiles); - _saveJobItemCommand.GetParameter(index++).Value = jobItem.MediaSource == null ? null : _json.SerializeToString(jobItem.MediaSource); - _saveJobItemCommand.GetParameter(index++).Value = jobItem.IsMarkedForRemoval; - _saveJobItemCommand.GetParameter(index++).Value = jobItem.JobItemIndex; - - _saveJobItemCommand.Transaction = transaction; - - _saveJobItemCommand.ExecuteNonQuery(); + cmd.GetParameter(index++).Value = new Guid(jobItem.Id); + cmd.GetParameter(index++).Value = jobItem.ItemId; + cmd.GetParameter(index++).Value = jobItem.ItemName; + cmd.GetParameter(index++).Value = jobItem.MediaSourceId; + cmd.GetParameter(index++).Value = jobItem.JobId; + cmd.GetParameter(index++).Value = jobItem.TemporaryPath; + cmd.GetParameter(index++).Value = jobItem.OutputPath; + cmd.GetParameter(index++).Value = jobItem.Status.ToString(); + cmd.GetParameter(index++).Value = jobItem.TargetId; + cmd.GetParameter(index++).Value = jobItem.DateCreated; + cmd.GetParameter(index++).Value = jobItem.Progress; + cmd.GetParameter(index++).Value = _json.SerializeToString(jobItem.AdditionalFiles); + cmd.GetParameter(index++).Value = jobItem.MediaSource == null ? null : _json.SerializeToString(jobItem.MediaSource); + cmd.GetParameter(index++).Value = jobItem.IsMarkedForRemoval; + cmd.GetParameter(index++).Value = jobItem.JobItemIndex; + + cmd.Transaction = transaction; + + cmd.ExecuteNonQuery(); transaction.Commit(); } diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs index 6700e9054..308784299 100644 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs @@ -129,7 +129,7 @@ namespace MediaBrowser.Server.Implementations.TV // Get them in display order, then reverse var allEpisodes = series.GetSeasons(user, true, true) .Where(i => !i.IndexNumber.HasValue || i.IndexNumber.Value != 0) - .SelectMany(i => i.GetEpisodes(user, true, true)) + .SelectMany(i => i.GetEpisodes(user)) .Reverse() .ToList(); diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index dabe7485e..a9194c05c 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.553 + 3.0.554 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 16559a41b..5bbb13e19 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.553 + 3.0.554 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index 12c2a6551..124006492 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.553 + 3.0.554 MediaBrowser.Model - Signed Edition Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 00f931034..da3283c32 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.553 + 3.0.554 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - + -- cgit v1.2.3 From f2c3e014b7b86d2e4792ce5214be44b250813ae6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 4 Feb 2015 14:13:00 -0500 Subject: sync updates --- MediaBrowser.Controller/Sync/ISyncManager.cs | 2 +- MediaBrowser.Dlna/DlnaManager.cs | 2 +- MediaBrowser.Model/ApiClient/IServerEvents.cs | 4 ++++ MediaBrowser.Model/Sync/SyncJobStatus.cs | 9 +++++--- MediaBrowser.Model/System/SystemInfo.cs | 6 ++++++ .../EntryPoints/ServerEventNotifier.cs | 7 +++++++ .../Localization/JavaScript/javascript.json | 14 ++++++++----- .../Sync/SyncJobProcessor.cs | 24 ++++++++++++++++------ .../Sync/SyncManager.cs | 1 + .../ApplicationHost.cs | 3 ++- Nuget/MediaBrowser.Common.Internal.nuspec | 4 ++-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Model.Signed.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 ++-- 14 files changed, 61 insertions(+), 23 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index e0ea6eb9a..362b9c3bc 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -1,5 +1,4 @@ using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Events; using MediaBrowser.Model.Querying; @@ -15,6 +14,7 @@ namespace MediaBrowser.Controller.Sync { event EventHandler> SyncJobCreated; event EventHandler> SyncJobCancelled; + event EventHandler> SyncJobUpdated; /// /// Creates the job. diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 0bce849ce..f0f295c83 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -515,7 +515,7 @@ namespace MediaBrowser.Dlna public void Run() { - DumpProfiles(); + //DumpProfiles(); } private void DumpProfiles() diff --git a/MediaBrowser.Model/ApiClient/IServerEvents.cs b/MediaBrowser.Model/ApiClient/IServerEvents.cs index b74d43ee0..cc51ce4c6 100644 --- a/MediaBrowser.Model/ApiClient/IServerEvents.cs +++ b/MediaBrowser.Model/ApiClient/IServerEvents.cs @@ -135,5 +135,9 @@ namespace MediaBrowser.Model.ApiClient /// Occurs when [synchronize job created]. /// event EventHandler> SyncJobCreated; + /// + /// Occurs when [synchronize job cancelled]. + /// + event EventHandler> SyncJobCancelled; } } diff --git a/MediaBrowser.Model/Sync/SyncJobStatus.cs b/MediaBrowser.Model/Sync/SyncJobStatus.cs index 961ccf544..6c0068a8a 100644 --- a/MediaBrowser.Model/Sync/SyncJobStatus.cs +++ b/MediaBrowser.Model/Sync/SyncJobStatus.cs @@ -4,8 +4,11 @@ namespace MediaBrowser.Model.Sync public enum SyncJobStatus { Queued = 0, - InProgress = 1, - Completed = 2, - CompletedWithError = 3 + Converting = 1, + Transferring = 2, + Completed = 3, + CompletedWithError = 4, + Failed = 5, + Cancelled = 6 } } diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index ce081d5f2..8c1fc759f 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -38,6 +38,12 @@ namespace MediaBrowser.Model.System /// true if this instance has pending restart; otherwise, false. public bool HasPendingRestart { get; set; } + /// + /// Gets or sets a value indicating whether [supports synchronize]. + /// + /// true if [supports synchronize]; otherwise, false. + public bool SupportsSync { get; set; } + /// /// Gets or sets a value indicating whether this instance is network deployed. /// diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs index 51e6ddc0e..b5624625f 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs @@ -75,6 +75,12 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _taskManager.TaskCompleted += _taskManager_TaskCompleted; _syncManager.SyncJobCreated += _syncManager_SyncJobCreated; + _syncManager.SyncJobCancelled += _syncManager_SyncJobCancelled; + } + + void _syncManager_SyncJobCancelled(object sender, GenericEventArgs e) + { + _sessionManager.SendMessageToUserDeviceSessions(e.Argument.TargetId, "SyncJobCancelled", e.Argument, CancellationToken.None); } void _syncManager_SyncJobCreated(object sender, GenericEventArgs e) @@ -189,6 +195,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _appHost.HasPendingRestartChanged -= kernel_HasPendingRestartChanged; _syncManager.SyncJobCreated -= _syncManager_SyncJobCreated; + _syncManager.SyncJobCancelled -= _syncManager_SyncJobCancelled; } } } diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index b494adfd8..1349881a4 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -19,7 +19,7 @@ "PinCodeResetComplete": "The pin code has been reset.", "PasswordResetConfirmation": "Are you sure you wish to reset the password?", "PinCodeResetConfirmation": "Are you sure you wish to reset the pin code?", - "HeaderPinCodeReset": "Reset Pin Code", + "HeaderPinCodeReset": "Reset Pin Code", "PasswordSaved": "Password saved.", "PasswordMatchError": "Password and password confirmation must match.", "OptionRelease": "Official Release", @@ -48,10 +48,13 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Save", - "SyncJobStatusQueued": "Queued", - "SyncJobStatusInProgress": "In-Progress", - "SyncJobStatusCompleted": "Synced", - "SyncJobStatusCompletedWithError": "Synced with errors", + "SyncJobStatusQueued": "Queued", + "SyncJobStatusConverting": "Converting", + "SyncJobStatusFailed": "Failed", + "SyncJobStatusCancelled": "Cancelled", + "SyncJobStatusCompleted": "Synced", + "SyncJobStatusTransferring": "Transferring", + "SyncJobStatusCompletedWithError": "Synced with errors", "LabelCollection": "Collection", "HeaderAddToCollection": "Add to Collection", "NewCollectionNameExample": "Example: Star Wars Collection", @@ -91,6 +94,7 @@ "HeaderSelectSubtitles": "Select Subtitles", "ButtonMarkForRemoval": "Remove from device", "ButtonUnmarkForRemoval": "Cancel removal from device", + "LabelSyncQualityHelp": "Use high quality for the maximum supported quality by the device. Medium and Low reduce the allowed bitrate.", "LabelDefaultStream": "(Default)", "LabelForcedStream": "(Forced)", "LabelDefaultForcedStream": "(Default/Forced)", diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 328b8441a..6ef74d953 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -172,7 +172,23 @@ namespace MediaBrowser.Server.Implementations.Sync job.Progress = null; } - if (pct >= 100) + if (jobItems.All(i => i.Status == SyncJobItemStatus.Queued)) + { + job.Status = SyncJobStatus.Queued; + } + else if (jobItems.All(i => i.Status == SyncJobItemStatus.Failed)) + { + job.Status = SyncJobStatus.Failed; + } + else if (jobItems.All(i => i.Status == SyncJobItemStatus.Cancelled)) + { + job.Status = SyncJobStatus.Cancelled; + } + else if (jobItems.Any(i => i.Status == SyncJobItemStatus.Converting)) + { + job.Status = SyncJobStatus.Converting; + } + else if (pct >= 100) { if (jobItems.Any(i => i.Status == SyncJobItemStatus.Failed)) { @@ -183,13 +199,9 @@ namespace MediaBrowser.Server.Implementations.Sync job.Status = SyncJobStatus.Completed; } } - else if (pct.Equals(0) && jobItems.All(i => i.Status == SyncJobItemStatus.Queued)) - { - job.Status = SyncJobStatus.Queued; - } else { - job.Status = SyncJobStatus.InProgress; + job.Status = SyncJobStatus.Transferring; } return _syncRepo.Update(job); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 6034390c6..627e94eb1 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -51,6 +51,7 @@ namespace MediaBrowser.Server.Implementations.Sync public event EventHandler> SyncJobCreated; public event EventHandler> SyncJobCancelled; + public event EventHandler> SyncJobUpdated; public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func mediaEncoder, IFileSystem fileSystem, Func subtitleEncoder, IConfigurationManager config) { diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index e3e0d1363..b72a10801 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -1023,7 +1023,8 @@ namespace MediaBrowser.Server.Startup.Common IsRunningAsService = IsRunningAsService, SupportsRunningAsService = SupportsRunningAsService, ServerName = FriendlyName, - LocalAddress = LocalApiUrl + LocalAddress = LocalApiUrl, + SupportsSync = true }; } diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index a9194c05c..37c4d9ba4 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.554 + 3.0.556 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 5bbb13e19..a2472fb84 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.554 + 3.0.556 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index 124006492..24f94d22e 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.554 + 3.0.556 MediaBrowser.Model - Signed Edition Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index da3283c32..b50c59b59 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.554 + 3.0.556 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - + -- cgit v1.2.3 From e6ea26e3ded2f37d8b8f364821cf6dd0a89b8af8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 4 Feb 2015 14:41:10 -0500 Subject: localize item counts --- .../Localization/JavaScript/javascript.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 1349881a4..5e881e3b6 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -94,7 +94,7 @@ "HeaderSelectSubtitles": "Select Subtitles", "ButtonMarkForRemoval": "Remove from device", "ButtonUnmarkForRemoval": "Cancel removal from device", - "LabelSyncQualityHelp": "Use high quality for the maximum supported quality by the device. Medium and Low reduce the allowed bitrate.", + "LabelSyncQualityHelp": "Use high quality for the maximum supported quality by the device. Medium and low quality will reduce the allowed bitrate.", "LabelDefaultStream": "(Default)", "LabelForcedStream": "(Forced)", "LabelDefaultForcedStream": "(Default/Forced)", @@ -216,6 +216,8 @@ "MessageConfirmRestart": "Are you sure you wish to restart Media Browser Server?", "MessageConfirmShutdown": "Are you sure you wish to shutdown Media Browser Server?", "ButtonUpdateNow": "Update Now", + "ValueItemCount": "{0} item", + "ValueItemCountPlural": "{0} items", "NewVersionOfSomethingAvailable": "A new version of {0} is available!", "VersionXIsAvailableForDownload": "Version {0} is now available for download.", "LabelVersionNumber": "Version {0}", -- cgit v1.2.3 From 1f1852f3cbe2a7899aea0d306a77d2eedb0434fc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 4 Feb 2015 22:01:37 -0500 Subject: sync updates --- MediaBrowser.Api/MediaBrowser.Api.csproj | 1 + MediaBrowser.Api/Sync/SyncJobWebSocketListener.cs | 120 +++++++++++++++++++++ MediaBrowser.Api/Sync/SyncService.cs | 4 +- .../Entities/UserViewBuilder.cs | 5 + .../MediaEncoding/EncodingJobOptions.cs | 7 +- MediaBrowser.Controller/Sync/ISyncManager.cs | 8 +- .../MediaBrowser.Model.Portable.csproj | 3 + .../MediaBrowser.Model.net35.csproj | 3 + MediaBrowser.Model/ApiClient/IApiClient.cs | 15 +++ MediaBrowser.Model/ApiClient/IServerEvents.cs | 4 + MediaBrowser.Model/MediaBrowser.Model.csproj | 1 + MediaBrowser.Model/Sync/CompleteSyncJobInfo.cs | 15 +++ MediaBrowser.Model/Sync/SyncJobItemStatus.cs | 11 +- MediaBrowser.Model/Sync/SyncJobStatus.cs | 11 +- .../Dto/DtoService.cs | 3 +- .../Library/LibraryManager.cs | 5 + .../Localization/JavaScript/javascript.json | 5 +- .../Sync/SyncJobProcessor.cs | 55 ++++++---- .../Sync/SyncManager.cs | 47 ++++++-- .../Sync/SyncScheduledTask.cs | 2 +- Nuget/MediaBrowser.Common.Internal.nuspec | 4 +- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Model.Signed.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +- 24 files changed, 280 insertions(+), 57 deletions(-) create mode 100644 MediaBrowser.Api/Sync/SyncJobWebSocketListener.cs create mode 100644 MediaBrowser.Model/Sync/CompleteSyncJobInfo.cs (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 552091280..23cdf8b7a 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -130,6 +130,7 @@ + diff --git a/MediaBrowser.Api/Sync/SyncJobWebSocketListener.cs b/MediaBrowser.Api/Sync/SyncJobWebSocketListener.cs new file mode 100644 index 000000000..61a26d160 --- /dev/null +++ b/MediaBrowser.Api/Sync/SyncJobWebSocketListener.cs @@ -0,0 +1,120 @@ +using MediaBrowser.Controller.Net; +using MediaBrowser.Controller.Sync; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Sync; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace MediaBrowser.Api.Sync +{ + /// + /// Class SessionInfoWebSocketListener + /// + class SyncJobWebSocketListener : BasePeriodicWebSocketListener + { + /// + /// Gets the name. + /// + /// The name. + protected override string Name + { + get { return "SyncJob"; } + } + + private readonly ISyncManager _syncManager; + private string _jobId; + + public SyncJobWebSocketListener(ILogger logger, ISyncManager syncManager) + : base(logger) + { + _syncManager = syncManager; + _syncManager.SyncJobCancelled += _syncManager_SyncJobCancelled; + _syncManager.SyncJobUpdated += _syncManager_SyncJobUpdated; + _syncManager.SyncJobItemCreated += _syncManager_SyncJobItemCreated; + _syncManager.SyncJobItemUpdated += _syncManager_SyncJobItemUpdated; + } + + void _syncManager_SyncJobItemUpdated(object sender, GenericEventArgs e) + { + if (string.Equals(e.Argument.Id, _jobId, StringComparison.Ordinal)) + { + SendData(false); + } + } + + void _syncManager_SyncJobItemCreated(object sender, GenericEventArgs e) + { + if (string.Equals(e.Argument.Id, _jobId, StringComparison.Ordinal)) + { + SendData(true); + } + } + + protected override void ParseMessageParams(string[] values) + { + base.ParseMessageParams(values); + + if (values.Length > 0) + { + _jobId = values[0]; + } + } + + void _syncManager_SyncJobUpdated(object sender, GenericEventArgs e) + { + if (string.Equals(e.Argument.Id, _jobId, StringComparison.Ordinal)) + { + SendData(false); + } + } + + void _syncManager_SyncJobCancelled(object sender, GenericEventArgs e) + { + if (string.Equals(e.Argument.Id, _jobId, StringComparison.Ordinal)) + { + SendData(true); + } + } + + /// + /// Gets the data to send. + /// + /// The state. + /// Task{SystemInfo}. + protected override Task GetDataToSend(WebSocketListenerState state) + { + var job = _syncManager.GetJob(_jobId); + var items = _syncManager.GetJobItems(new SyncJobItemQuery + { + AddMetadata = true, + JobId = _jobId + }); + + var info = new CompleteSyncJobInfo + { + Job = job, + JobItems = items.Items.ToList() + }; + + return Task.FromResult(info); + } + + protected override bool SendOnTimer + { + get + { + return false; + } + } + + protected override void Dispose(bool dispose) + { + _syncManager.SyncJobCancelled -= _syncManager_SyncJobCancelled; + _syncManager.SyncJobUpdated -= _syncManager_SyncJobUpdated; + + base.Dispose(dispose); + } + } +} diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs index 93d8a8d0a..13c716136 100644 --- a/MediaBrowser.Api/Sync/SyncService.cs +++ b/MediaBrowser.Api/Sync/SyncService.cs @@ -206,7 +206,7 @@ namespace MediaBrowser.Api.Sync { var jobItem = _syncManager.GetJobItem(request.Id); - if (jobItem.Status != SyncJobItemStatus.Transferring) + if (jobItem.Status < SyncJobItemStatus.ReadyToTransfer) { throw new ArgumentException("The job item is not yet ready for transfer."); } @@ -286,7 +286,7 @@ namespace MediaBrowser.Api.Sync { var jobItem = _syncManager.GetJobItem(request.Id); - if (jobItem.Status != SyncJobItemStatus.Transferring) + if (jobItem.Status < SyncJobItemStatus.ReadyToTransfer) { throw new ArgumentException("The job item is not yet ready for transfer."); } diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index a24a42535..318c5fff3 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -846,6 +846,11 @@ namespace MediaBrowser.Controller.Entities BaseItem queryParent, User user) { + if (items == null) + { + throw new ArgumentNullException("items"); + } + if (CollapseBoxSetItems(query, queryParent, user)) { items = BaseItem.CollectionManager.CollapseItemsWithinBoxSets(items, user); diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs index ad9ab90a0..fe0fb3295 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs @@ -81,12 +81,17 @@ namespace MediaBrowser.Controller.MediaEncoding VideoCodec = info.VideoCodec; VideoBitRate = info.VideoBitrate; AudioStreamIndex = info.AudioStreamIndex; - SubtitleStreamIndex = info.SubtitleStreamIndex; MaxRefFrames = info.MaxRefFrames; MaxVideoBitDepth = info.MaxVideoBitDepth; SubtitleMethod = info.SubtitleDeliveryMethod; Cabac = info.Cabac; Context = info.Context; + + if (info.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode || + info.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Embed) + { + SubtitleStreamIndex = info.SubtitleStreamIndex; + } } } } diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index 362b9c3bc..dc15a394e 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -15,7 +15,9 @@ namespace MediaBrowser.Controller.Sync event EventHandler> SyncJobCreated; event EventHandler> SyncJobCancelled; event EventHandler> SyncJobUpdated; - + event EventHandler> SyncJobItemUpdated; + event EventHandler> SyncJobItemCreated; + /// /// Creates the job. /// @@ -35,7 +37,7 @@ namespace MediaBrowser.Controller.Sync /// The query. /// QueryResult<SyncJobItem>. QueryResult GetJobItems(SyncJobItemQuery query); - + /// /// Gets the job. /// @@ -63,7 +65,7 @@ namespace MediaBrowser.Controller.Sync /// The identifier. /// Task. Task CancelJobItem(string id); - + /// /// Cancels the job. /// diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index 310170b5f..ba3065bc9 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -1043,6 +1043,9 @@ Session\UserDataChangeInfo.cs + + Sync\CompleteSyncJobInfo.cs + Sync\DeviceFileInfo.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 31d2e6470..8d22f25a9 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -1002,6 +1002,9 @@ Session\UserDataChangeInfo.cs + + Sync\CompleteSyncJobInfo.cs + Sync\DeviceFileInfo.cs diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 9fe138a49..a7d11d507 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -893,6 +893,21 @@ namespace MediaBrowser.Model.ApiClient /// if set to true [keep existing authentication]. void ChangeServerLocation(string address, bool keepExistingAuth = false); + /// + /// Starts the receiving synchronize job updates. + /// + /// The interval ms. + /// The job identifier. + /// Task. + Task StartReceivingSyncJobUpdates(int intervalMs, string jobId); + + /// + /// Stops the receiving synchronize job updates. + /// + /// The interval ms. + /// Task. + Task StopReceivingSyncJobUpdates(int intervalMs); + /// /// Starts the receiving synchronize jobs updates. /// diff --git a/MediaBrowser.Model/ApiClient/IServerEvents.cs b/MediaBrowser.Model/ApiClient/IServerEvents.cs index 311cb8b21..ae2d5d323 100644 --- a/MediaBrowser.Model/ApiClient/IServerEvents.cs +++ b/MediaBrowser.Model/ApiClient/IServerEvents.cs @@ -144,5 +144,9 @@ namespace MediaBrowser.Model.ApiClient /// Occurs when [synchronize jobs updated]. /// event EventHandler>> SyncJobsUpdated; + /// + /// Occurs when [synchronize job updated]. + /// + event EventHandler> SyncJobUpdated; } } diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 0962cbe7a..c8e09dd82 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -368,6 +368,7 @@ + diff --git a/MediaBrowser.Model/Sync/CompleteSyncJobInfo.cs b/MediaBrowser.Model/Sync/CompleteSyncJobInfo.cs new file mode 100644 index 000000000..52d3fab3c --- /dev/null +++ b/MediaBrowser.Model/Sync/CompleteSyncJobInfo.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace MediaBrowser.Model.Sync +{ + public class CompleteSyncJobInfo + { + public SyncJob Job { get; set; } + public List JobItems { get; set; } + + public CompleteSyncJobInfo() + { + JobItems = new List(); + } + } +} diff --git a/MediaBrowser.Model/Sync/SyncJobItemStatus.cs b/MediaBrowser.Model/Sync/SyncJobItemStatus.cs index 913f9e259..c4e23c63c 100644 --- a/MediaBrowser.Model/Sync/SyncJobItemStatus.cs +++ b/MediaBrowser.Model/Sync/SyncJobItemStatus.cs @@ -5,10 +5,11 @@ namespace MediaBrowser.Model.Sync { Queued = 0, Converting = 1, - Transferring = 2, - Synced = 3, - RemovedFromDevice = 4, - Failed = 5, - Cancelled = 6 + ReadyToTransfer = 2, + Transferring = 3, + Synced = 4, + RemovedFromDevice = 5, + Failed = 6, + Cancelled = 7 } } diff --git a/MediaBrowser.Model/Sync/SyncJobStatus.cs b/MediaBrowser.Model/Sync/SyncJobStatus.cs index 6c0068a8a..ac211a32a 100644 --- a/MediaBrowser.Model/Sync/SyncJobStatus.cs +++ b/MediaBrowser.Model/Sync/SyncJobStatus.cs @@ -5,10 +5,11 @@ namespace MediaBrowser.Model.Sync { Queued = 0, Converting = 1, - Transferring = 2, - Completed = 3, - CompletedWithError = 4, - Failed = 5, - Cancelled = 6 + ReadyToTransfer = 2, + Transferring = 3, + Completed = 4, + CompletedWithError = 5, + Failed = 6, + Cancelled = 7 } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 61c24cf54..7b36321f1 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -162,7 +162,8 @@ namespace MediaBrowser.Server.Implementations.Dto { SyncJobItemStatus.Converting, SyncJobItemStatus.Queued, - SyncJobItemStatus.Transferring + SyncJobItemStatus.Transferring, + SyncJobItemStatus.ReadyToTransfer } }); diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index d7ea444a3..29871d928 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -517,6 +517,11 @@ namespace MediaBrowser.Server.Implementations.Library public IEnumerable ReplaceVideosWithPrimaryVersions(IEnumerable items) { + if (items == null) + { + throw new ArgumentNullException("items"); + } + var dict = new Dictionary(); foreach (var item in items) diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 5e881e3b6..3fddf274c 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -53,6 +53,7 @@ "SyncJobStatusFailed": "Failed", "SyncJobStatusCancelled": "Cancelled", "SyncJobStatusCompleted": "Synced", + "SyncJobStatusReadyToTransfer": "Ready to Transfer", "SyncJobStatusTransferring": "Transferring", "SyncJobStatusCompletedWithError": "Synced with errors", "LabelCollection": "Collection", @@ -216,8 +217,8 @@ "MessageConfirmRestart": "Are you sure you wish to restart Media Browser Server?", "MessageConfirmShutdown": "Are you sure you wish to shutdown Media Browser Server?", "ButtonUpdateNow": "Update Now", - "ValueItemCount": "{0} item", - "ValueItemCountPlural": "{0} items", + "ValueItemCount": "{0} item", + "ValueItemCountPlural": "{0} items", "NewVersionOfSomethingAvailable": "A new version of {0} is available!", "VersionXIsAvailableForDownload": "Version {0} is now available for download.", "LabelVersionNumber": "Version {0}", diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index c373faf1e..e418448db 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -29,7 +29,7 @@ namespace MediaBrowser.Server.Implementations.Sync { private readonly ILibraryManager _libraryManager; private readonly ISyncRepository _syncRepo; - private readonly ISyncManager _syncManager; + private readonly SyncManager _syncManager; private readonly ILogger _logger; private readonly IUserManager _userManager; private readonly ITVSeriesManager _tvSeriesManager; @@ -38,7 +38,7 @@ namespace MediaBrowser.Server.Implementations.Sync private readonly IConfigurationManager _config; private readonly IFileSystem _fileSystem; - public SyncJobProcessor(ILibraryManager libraryManager, ISyncRepository syncRepo, ISyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager, IMediaEncoder mediaEncoder, ISubtitleEncoder subtitleEncoder, IConfigurationManager config, IFileSystem fileSystem) + public SyncJobProcessor(ILibraryManager libraryManager, ISyncRepository syncRepo, SyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager, IMediaEncoder mediaEncoder, ISubtitleEncoder subtitleEncoder, IConfigurationManager config, IFileSystem fileSystem) { _libraryManager = libraryManager; _syncRepo = syncRepo; @@ -106,6 +106,7 @@ namespace MediaBrowser.Server.Implementations.Sync }; await _syncRepo.Create(jobItem).ConfigureAwait(false); + _syncManager.OnSyncJobItemCreated(jobItem); jobItems.Add(jobItem); } @@ -184,11 +185,19 @@ namespace MediaBrowser.Server.Implementations.Sync { job.Status = SyncJobStatus.Cancelled; } + else if (jobItems.All(i => i.Status == SyncJobItemStatus.ReadyToTransfer)) + { + job.Status = SyncJobStatus.ReadyToTransfer; + } + else if (jobItems.All(i => i.Status == SyncJobItemStatus.Transferring)) + { + job.Status = SyncJobStatus.Transferring; + } else if (jobItems.Any(i => i.Status == SyncJobItemStatus.Converting)) { job.Status = SyncJobStatus.Converting; } - else if (pct >= 100) + else if (jobItems.All(i => i.Status == SyncJobItemStatus.Cancelled || i.Status == SyncJobItemStatus.Failed || i.Status == SyncJobItemStatus.Synced || i.Status == SyncJobItemStatus.RemovedFromDevice)) { if (jobItems.Any(i => i.Status == SyncJobItemStatus.Failed)) { @@ -201,12 +210,12 @@ namespace MediaBrowser.Server.Implementations.Sync } else { - job.Status = SyncJobStatus.Transferring; + job.Status = SyncJobStatus.Queued; } await _syncRepo.Update(job).ConfigureAwait(false); - ((SyncManager)_syncManager).OnSyncJobUpdated(job); + _syncManager.OnSyncJobUpdated(job); } public async Task> GetItemsForSync(SyncCategory? category, string parentId, IEnumerable itemIds, User user, bool unwatchedOnly) @@ -414,7 +423,7 @@ namespace MediaBrowser.Server.Implementations.Sync { jobItem.Status = SyncJobItemStatus.Failed; _logger.Error("Unable to locate library item for JobItem {0}, ItemId {1}", jobItem.Id, jobItem.ItemId); - await _syncRepo.Update(jobItem).ConfigureAwait(false); + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); return; } @@ -423,7 +432,7 @@ namespace MediaBrowser.Server.Implementations.Sync { jobItem.Status = SyncJobItemStatus.Failed; _logger.Error("Unable to locate SyncTarget for JobItem {0}, SyncTargetId {1}", jobItem.Id, jobItem.TargetId); - await _syncRepo.Update(jobItem).ConfigureAwait(false); + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); return; } @@ -490,7 +499,7 @@ namespace MediaBrowser.Server.Implementations.Sync if (streamInfo.PlayMethod == PlayMethod.Transcode) { // Save the job item now since conversion could take a while - await _syncRepo.Update(jobItem).ConfigureAwait(false); + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); await UpdateJobStatus(job).ConfigureAwait(false); try @@ -504,7 +513,7 @@ namespace MediaBrowser.Server.Implementations.Sync if ((DateTime.UtcNow - lastJobUpdate).TotalSeconds >= DatabaseProgressUpdateIntervalSeconds) { jobItem.Progress = pct / 2; - await _syncRepo.Update(jobItem).ConfigureAwait(false); + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); await UpdateJobStatus(job).ConfigureAwait(false); } }); @@ -528,7 +537,7 @@ namespace MediaBrowser.Server.Implementations.Sync if (jobItem.Status == SyncJobItemStatus.Failed || jobItem.Status == SyncJobItemStatus.Queued) { - await _syncRepo.Update(jobItem).ConfigureAwait(false); + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); return; } @@ -555,14 +564,14 @@ namespace MediaBrowser.Server.Implementations.Sync if (externalSubs.Count > 0) { // Save the job item now since conversion could take a while - await _syncRepo.Update(jobItem).ConfigureAwait(false); + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); await ConvertSubtitles(jobItem, externalSubs, streamInfo, cancellationToken).ConfigureAwait(false); } jobItem.Progress = 50; - jobItem.Status = SyncJobItemStatus.Transferring; - await _syncRepo.Update(jobItem).ConfigureAwait(false); + jobItem.Status = SyncJobItemStatus.ReadyToTransfer; + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); } private bool RequiresExtraction(SubtitleStreamInfo stream, MediaSourceInfo mediaSource) @@ -666,7 +675,7 @@ namespace MediaBrowser.Server.Implementations.Sync } jobItem.Status = SyncJobItemStatus.Converting; - await _syncRepo.Update(jobItem).ConfigureAwait(false); + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); await UpdateJobStatus(job).ConfigureAwait(false); try @@ -680,7 +689,7 @@ namespace MediaBrowser.Server.Implementations.Sync if ((DateTime.UtcNow - lastJobUpdate).TotalSeconds >= DatabaseProgressUpdateIntervalSeconds) { jobItem.Progress = pct / 2; - await _syncRepo.Update(jobItem).ConfigureAwait(false); + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); await UpdateJobStatus(job).ConfigureAwait(false); } }); @@ -704,7 +713,7 @@ namespace MediaBrowser.Server.Implementations.Sync if (jobItem.Status == SyncJobItemStatus.Failed || jobItem.Status == SyncJobItemStatus.Queued) { - await _syncRepo.Update(jobItem).ConfigureAwait(false); + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); return; } @@ -729,8 +738,8 @@ namespace MediaBrowser.Server.Implementations.Sync } jobItem.Progress = 50; - jobItem.Status = SyncJobItemStatus.Transferring; - await _syncRepo.Update(jobItem).ConfigureAwait(false); + jobItem.Status = SyncJobItemStatus.ReadyToTransfer; + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); } private async Task Sync(SyncJobItem jobItem, Photo item, DeviceProfile profile, CancellationToken cancellationToken) @@ -738,17 +747,17 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.OutputPath = item.Path; jobItem.Progress = 50; - jobItem.Status = SyncJobItemStatus.Transferring; - await _syncRepo.Update(jobItem).ConfigureAwait(false); + jobItem.Status = SyncJobItemStatus.ReadyToTransfer; + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); } private async Task SyncGeneric(SyncJobItem jobItem, BaseItem item, CancellationToken cancellationToken) { jobItem.OutputPath = item.Path; - + jobItem.Progress = 50; - jobItem.Status = SyncJobItemStatus.Transferring; - await _syncRepo.Update(jobItem).ConfigureAwait(false); + jobItem.Status = SyncJobItemStatus.ReadyToTransfer; + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); } private async Task DownloadFile(SyncJobItem jobItem, MediaSourceInfo mediaSource, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 6eef268b9..eecbd78d1 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -52,6 +52,8 @@ namespace MediaBrowser.Server.Implementations.Sync public event EventHandler> SyncJobCreated; public event EventHandler> SyncJobCancelled; public event EventHandler> SyncJobUpdated; + public event EventHandler> SyncJobItemUpdated; + public event EventHandler> SyncJobItemCreated; public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func mediaEncoder, IFileSystem fileSystem, Func subtitleEncoder, IConfigurationManager config) { @@ -202,6 +204,32 @@ namespace MediaBrowser.Server.Implementations.Sync } } + internal async Task UpdateSyncJobItemInternal(SyncJobItem jobItem) + { + await _repo.Update(jobItem).ConfigureAwait(false); + + if (SyncJobUpdated != null) + { + EventHelper.FireEventIfNotNull(SyncJobItemUpdated, this, new GenericEventArgs + { + Argument = jobItem + + }, _logger); + } + } + + internal void OnSyncJobItemCreated(SyncJobItem job) + { + if (SyncJobUpdated != null) + { + EventHelper.FireEventIfNotNull(SyncJobItemCreated, this, new GenericEventArgs + { + Argument = job + + }, _logger); + } + } + public async Task> GetJobs(SyncJobQuery query) { var result = _repo.GetJobs(query); @@ -504,7 +532,7 @@ namespace MediaBrowser.Server.Implementations.Sync } } - await _repo.Update(jobItem).ConfigureAwait(false); + await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); var processor = GetSyncJobProcessor(); @@ -610,7 +638,10 @@ namespace MediaBrowser.Server.Implementations.Sync var jobItemResult = GetJobItems(new SyncJobItemQuery { TargetId = targetId, - Statuses = new List { SyncJobItemStatus.Transferring } + Statuses = new List + { + SyncJobItemStatus.ReadyToTransfer + } }); return jobItemResult.Items @@ -669,7 +700,7 @@ namespace MediaBrowser.Server.Implementations.Sync { // Content is no longer on the device jobItem.Status = SyncJobItemStatus.RemovedFromDevice; - await _repo.Update(jobItem).ConfigureAwait(false); + await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); } } @@ -761,7 +792,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Progress = 0; jobItem.IsMarkedForRemoval = false; - await _repo.Update(jobItem).ConfigureAwait(false); + await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); var processor = GetSyncJobProcessor(); @@ -772,7 +803,7 @@ namespace MediaBrowser.Server.Implementations.Sync { var jobItem = _repo.GetJobItem(id); - if (jobItem.Status != SyncJobItemStatus.Queued && jobItem.Status != SyncJobItemStatus.Transferring && jobItem.Status != SyncJobItemStatus.Converting) + if (jobItem.Status != SyncJobItemStatus.Queued && jobItem.Status != SyncJobItemStatus.ReadyToTransfer && jobItem.Status != SyncJobItemStatus.Converting) { throw new ArgumentException("Operation is not valid for this job item"); } @@ -781,7 +812,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Progress = 0; jobItem.IsMarkedForRemoval = true; - await _repo.Update(jobItem).ConfigureAwait(false); + await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); var processor = GetSyncJobProcessor(); @@ -814,7 +845,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.IsMarkedForRemoval = true; - await _repo.Update(jobItem).ConfigureAwait(false); + await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); var processor = GetSyncJobProcessor(); @@ -832,7 +863,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.IsMarkedForRemoval = false; - await _repo.Update(jobItem).ConfigureAwait(false); + await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); var processor = GetSyncJobProcessor(); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs b/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs index b68a97817..ccc9508e8 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs @@ -60,7 +60,7 @@ namespace MediaBrowser.Server.Implementations.Sync public Task Execute(CancellationToken cancellationToken, IProgress progress) { - return new SyncJobProcessor(_libraryManager, _syncRepo, _syncManager, _logger, _userManager, _tvSeriesManager, _mediaEncoder, _subtitleEncoder, _config, _fileSystem) + return new SyncJobProcessor(_libraryManager, _syncRepo, (SyncManager)_syncManager, _logger, _userManager, _tvSeriesManager, _mediaEncoder, _subtitleEncoder, _config, _fileSystem) .Sync(progress, cancellationToken); } diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 4b104fe25..1a65fba67 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.559 + 3.0.560 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 40a395a63..d28f98aff 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.559 + 3.0.560 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index 17597b582..d4b030ba1 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.559 + 3.0.560 MediaBrowser.Model - Signed Edition Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index c9a635f64..e5b7a27ba 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.559 + 3.0.560 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - + -- cgit v1.2.3 From b6d59c7688fc39d4689bc9070a7a99271d5b41ee Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 6 Feb 2015 00:39:07 -0500 Subject: fixes #1001 - Support downloading --- MediaBrowser.Api/Library/LibraryService.cs | 56 +++++++++++++++------- MediaBrowser.Api/Playback/BaseStreamingService.cs | 12 ++--- .../Playback/Progressive/VideoService.cs | 1 + MediaBrowser.Controller/Channels/Channel.cs | 5 ++ .../Channels/ChannelAudioItem.cs | 7 ++- .../Channels/ChannelFolderItem.cs | 12 +++-- .../Channels/ChannelVideoItem.cs | 7 ++- .../Entities/AggregateFolder.cs | 5 ++ MediaBrowser.Controller/Entities/Audio/Audio.cs | 7 +++ .../Entities/Audio/MusicArtist.cs | 12 +++-- .../Entities/Audio/MusicGenre.cs | 5 ++ MediaBrowser.Controller/Entities/BaseItem.cs | 32 +++++++++++++ .../Entities/BasePluginFolder.cs | 5 ++ MediaBrowser.Controller/Entities/Book.cs | 8 ++++ .../Entities/CollectionFolder.cs | 5 ++ MediaBrowser.Controller/Entities/Game.cs | 9 +++- MediaBrowser.Controller/Entities/GameGenre.cs | 5 ++ MediaBrowser.Controller/Entities/Genre.cs | 5 ++ MediaBrowser.Controller/Entities/IItemByName.cs | 4 ++ MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 5 ++ MediaBrowser.Controller/Entities/Person.cs | 5 ++ MediaBrowser.Controller/Entities/Studio.cs | 5 ++ MediaBrowser.Controller/Entities/UserView.cs | 5 ++ MediaBrowser.Controller/Entities/Video.cs | 13 +++++ MediaBrowser.Controller/Entities/Year.cs | 5 ++ MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs | 4 ++ .../LiveTv/LiveTvAudioRecording.cs | 6 +++ MediaBrowser.Controller/LiveTv/LiveTvChannel.cs | 9 +++- MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 13 +++-- .../LiveTv/LiveTvVideoRecording.cs | 5 ++ MediaBrowser.Controller/Playlists/Playlist.cs | 7 ++- MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs | 8 ++-- MediaBrowser.Model/Dto/BaseItemDto.cs | 2 + MediaBrowser.Model/LiveTv/RecordingInfoDto.cs | 6 +++ MediaBrowser.Model/Querying/ItemFields.cs | 13 ++++- MediaBrowser.Model/Users/UserPolicy.cs | 5 +- .../Dto/DtoService.cs | 14 ++++++ .../HttpServer/Security/AuthService.cs | 26 +++++++++- .../LiveTv/LiveTvDtoService.cs | 4 ++ .../Localization/JavaScript/javascript.json | 2 + .../Localization/Server/server.json | 13 ++--- .../Sync/SyncJobProcessor.cs | 4 +- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 1 - .../MediaBrowser.WebDashboard.csproj | 6 --- 44 files changed, 322 insertions(+), 66 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index f147234fe..a97e2b52e 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -226,6 +226,18 @@ namespace MediaBrowser.Api.Library public string TvdbId { get; set; } } + [Route("/Items/{Id}/Download", "GET", Summary = "Downloads item media")] + [Authenticated(Roles = "download")] + public class GetDownload + { + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + /// /// Class LibraryService /// @@ -273,7 +285,7 @@ namespace MediaBrowser.Api.Library } var dtoOptions = GetDtoOptions(request); - + var result = new ItemsResult { TotalRecordCount = items.Count, @@ -289,6 +301,28 @@ namespace MediaBrowser.Api.Library Task.Run(() => _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None)); } + public object Get(GetDownload request) + { + var item = _libraryManager.GetItemById(request.Id); + + if (!item.CanDelete()) + { + throw new ArgumentException("Item does not support downloading"); + } + + var headers = new Dictionary(); + + // Quotes are valid in linux. They'll possibly cause issues here + var filename = Path.GetFileName(item.Path).Replace("\"", string.Empty); + headers["Content-Disposition"] = string.Format("inline; filename=\"{0}\"", filename); + + return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions + { + Path = item.Path, + ResponseHeaders = headers + }); + } + public object Get(GetFile request) { var item = _libraryManager.GetItemById(request.Id); @@ -347,7 +381,7 @@ namespace MediaBrowser.Api.Library var dtoOptions = GetDtoOptions(request); BaseItem parent = item.Parent; - + while (parent != null) { if (user != null) @@ -458,23 +492,9 @@ namespace MediaBrowser.Api.Library var auth = _authContext.GetAuthorizationInfo(Request); var user = _userManager.GetUserById(auth.UserId); - if (item is Playlist || item is BoxSet) + if (!item.CanDelete(user)) { - // For now this is allowed if user can see the playlist - } - else if (item is ILiveTvRecording) - { - if (!user.Policy.EnableLiveTvManagement) - { - throw new UnauthorizedAccessException(); - } - } - else - { - if (!user.Policy.EnableContentDeletion) - { - throw new UnauthorizedAccessException(); - } + throw new UnauthorizedAccessException(); } var task = _libraryManager.DeleteItem(item); diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 6d555e136..d26ca2721 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -123,7 +123,7 @@ namespace MediaBrowser.Api.Playback private string GetOutputFilePath(StreamState state) { var folder = ServerConfigurationManager.ApplicationPaths.TranscodingTempPath; - + var outputFileExtension = GetOutputFileExtension(state); var data = GetCommandLineArguments("dummy\\dummy", "dummyTranscodingId", state, false); @@ -323,13 +323,13 @@ namespace MediaBrowser.Api.Playback switch (qualitySetting) { case EncodingQuality.HighSpeed: - param += " -crf 23"; + param += " -subq 0 -crf 23"; break; case EncodingQuality.HighQuality: - param += " -crf 20"; + param += " -subq 3 -crf 20"; break; case EncodingQuality.MaxQuality: - param += " -crf 18"; + param += " -subq 6 -crf 18"; break; } } @@ -507,7 +507,7 @@ namespace MediaBrowser.Api.Playback } } - return param; + return "-pix_fmt yuv420p " + param; } protected string GetAudioFilterParam(StreamState state, bool isHls) @@ -918,7 +918,7 @@ namespace MediaBrowser.Api.Playback if (SupportsThrottleWithStream) { var url = "http://localhost:" + ServerConfigurationManager.Configuration.HttpServerPortNumber.ToString(UsCulture) + "/videos/" + state.Request.Id + "/stream?static=true&Throttle=true&mediaSourceId=" + state.Request.MediaSourceId; - + url += "&transcodingJobId=" + transcodingJobId; return string.Format("\"{0}\"", url); diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index 8924bb38f..7e86b867f 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -97,6 +97,7 @@ namespace MediaBrowser.Api.Playback.Progressive if (string.Equals(Path.GetExtension(outputPath), ".mp4", StringComparison.OrdinalIgnoreCase)) { + // Comparison: https://github.com/jansmolders86/mediacenterjs/blob/master/lib/transcoding/desktop.js format = " -f mp4 -movflags frag_keyframe+empty_moov"; } diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index 87d257f12..a482f45fe 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -67,5 +67,10 @@ namespace MediaBrowser.Controller.Channels { return System.IO.Path.Combine(basePath, "channels", id.ToString("N"), "metadata"); } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/Channels/ChannelAudioItem.cs b/MediaBrowser.Controller/Channels/ChannelAudioItem.cs index d9330f8a3..91b2407be 100644 --- a/MediaBrowser.Controller/Channels/ChannelAudioItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelAudioItem.cs @@ -3,10 +3,10 @@ using MediaBrowser.Model.Channels; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; using System.Collections.Generic; using System.Linq; using System.Threading; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Channels { @@ -89,5 +89,10 @@ namespace MediaBrowser.Controller.Channels return list; } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/Channels/ChannelFolderItem.cs b/MediaBrowser.Controller/Channels/ChannelFolderItem.cs index dce9840ed..7ba73d126 100644 --- a/MediaBrowser.Controller/Channels/ChannelFolderItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelFolderItem.cs @@ -1,11 +1,10 @@ -using System; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Channels; -using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Querying; +using MediaBrowser.Model.Users; +using System; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Channels { @@ -76,5 +75,10 @@ namespace MediaBrowser.Controller.Channels { return System.IO.Path.Combine(basePath, "channels", ChannelId, Id.ToString("N")); } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs index e3fad56e9..d7d4483cd 100644 --- a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs @@ -4,11 +4,11 @@ using MediaBrowser.Model.Channels; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Channels { @@ -119,5 +119,10 @@ namespace MediaBrowser.Controller.Channels { return System.IO.Path.Combine(basePath, "channels", ChannelId, Id.ToString("N")); } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index af2cca5e6..66a0d551b 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -32,6 +32,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + /// /// The _virtual children /// diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 2dcea37bd..a7b91b868 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -113,6 +113,13 @@ namespace MediaBrowser.Controller.Entities.Audio } } + public override bool CanDownload() + { + var locationType = LocationType; + return locationType != LocationType.Remote && + locationType != LocationType.Virtual; + } + /// /// Gets or sets the artist. /// diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 038aa98aa..e65d3c0e7 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -1,14 +1,13 @@ -using System.Runtime.Serialization; -using MediaBrowser.Common.Progress; -using MediaBrowser.Controller.Providers; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.Audio { @@ -35,6 +34,11 @@ namespace MediaBrowser.Controller.Entities.Audio get { return true; } } + public override bool CanDelete() + { + return !IsAccessedByName; + } + protected override IEnumerable ActualChildren { get diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index 9689d7cce..ed0956073 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -39,6 +39,11 @@ namespace MediaBrowser.Controller.Entities.Audio } } + public override bool CanDelete() + { + return false; + } + /// /// Gets a value indicating whether this instance is owned item. /// diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 4925bcd8a..1443d99d3 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -239,6 +239,38 @@ namespace MediaBrowser.Controller.Entities get { return this.GetImagePath(ImageType.Primary); } } + public virtual bool CanDelete() + { + var locationType = LocationType; + return locationType != LocationType.Remote && + locationType != LocationType.Virtual; + } + + public virtual bool IsAuthorizedToDelete(User user) + { + return user.Policy.EnableContentDeletion; + } + + public bool CanDelete(User user) + { + return CanDelete() && IsAuthorizedToDelete(user); + } + + public virtual bool CanDownload() + { + return false; + } + + public virtual bool IsAuthorizedToDownload(User user) + { + return user.Policy.EnableContentDownloading; + } + + public bool CanDownload(User user) + { + return CanDownload() && IsAuthorizedToDownload(user); + } + /// /// Gets or sets the date created. /// diff --git a/MediaBrowser.Controller/Entities/BasePluginFolder.cs b/MediaBrowser.Controller/Entities/BasePluginFolder.cs index b30bd81b9..785c441d3 100644 --- a/MediaBrowser.Controller/Entities/BasePluginFolder.cs +++ b/MediaBrowser.Controller/Entities/BasePluginFolder.cs @@ -11,5 +11,10 @@ namespace MediaBrowser.Controller.Entities { get { return null; } } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs index 381b2101d..e59db67a6 100644 --- a/MediaBrowser.Controller/Entities/Book.cs +++ b/MediaBrowser.Controller/Entities/Book.cs @@ -2,6 +2,7 @@ using MediaBrowser.Model.Configuration; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities @@ -37,6 +38,13 @@ namespace MediaBrowser.Controller.Entities Tags = new List(); } + public override bool CanDownload() + { + var locationType = LocationType; + return locationType != LocationType.Remote && + locationType != LocationType.Virtual; + } + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Book); diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index f82934a51..a39357f2b 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -35,6 +35,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + public string CollectionType { get; set; } /// diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index 71642ea90..899e5628f 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -1,10 +1,10 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; using System; using System.Collections.Generic; using System.Linq; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { @@ -38,6 +38,13 @@ namespace MediaBrowser.Controller.Entities public List LocalTrailerIds { get; set; } public List RemoteTrailerIds { get; set; } + public override bool CanDownload() + { + var locationType = LocationType; + return locationType != LocationType.Remote && + locationType != LocationType.Virtual; + } + /// /// Gets or sets the tags. /// diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs index 41ce0c12a..b246b9388 100644 --- a/MediaBrowser.Controller/Entities/GameGenre.cs +++ b/MediaBrowser.Controller/Entities/GameGenre.cs @@ -43,6 +43,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + public IEnumerable GetTaggedItems(IEnumerable inputItems) { return inputItems.Where(GetItemFilter()); diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index f581c55e8..e17a5c1d8 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -34,6 +34,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + /// /// Gets a value indicating whether this instance is owned item. /// diff --git a/MediaBrowser.Controller/Entities/IItemByName.cs b/MediaBrowser.Controller/Entities/IItemByName.cs index b48ad788f..14b69b8fd 100644 --- a/MediaBrowser.Controller/Entities/IItemByName.cs +++ b/MediaBrowser.Controller/Entities/IItemByName.cs @@ -15,6 +15,10 @@ namespace MediaBrowser.Controller.Entities /// IEnumerable{BaseItem}. IEnumerable GetTaggedItems(IEnumerable inputItems); + /// + /// Gets the item filter. + /// + /// Func<BaseItem, System.Boolean>. Func GetItemFilter(); } diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 7f74e3379..d874046ef 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -74,6 +74,11 @@ namespace MediaBrowser.Controller.Entities.Movies } } + public override bool IsAuthorizedToDelete(User user) + { + return true; + } + /// /// Gets the trailer ids. /// diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 25509b153..d8cb69ca1 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -45,6 +45,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + /// /// Gets a value indicating whether this instance is owned item. /// diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 76193d6c4..31bbaf422 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -40,6 +40,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + /// /// Gets a value indicating whether this instance is owned item. /// diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index cd179eb42..5f7ca3d3f 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -40,6 +40,11 @@ namespace MediaBrowser.Controller.Entities return result.Items; } + public override bool CanDelete() + { + return false; + } + public override IEnumerable GetRecursiveChildren(User user, Func filter) { var result = GetItems(new InternalItemsQuery diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 3abaf095c..12c377c90 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -64,6 +64,19 @@ namespace MediaBrowser.Controller.Entities LinkedAlternateVersions = new List(); } + public override bool CanDownload() + { + if (VideoType == VideoType.HdDvd || VideoType == VideoType.Dvd || + VideoType == VideoType.BluRay) + { + return false; + } + + var locationType = LocationType; + return locationType != LocationType.Remote && + locationType != LocationType.Virtual; + } + [IgnoreDataMember] public override bool SupportsAddingToPlaylist { diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs index 59a4bf16d..cf3ad3b6a 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -34,6 +34,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + /// /// Gets a value indicating whether this instance is owned item. /// diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs index ba1cb3043..784cb6ea1 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs @@ -25,5 +25,9 @@ namespace MediaBrowser.Controller.LiveTv Task RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken); PlayAccess GetPlayAccess(User user); + + bool CanDelete(); + + bool CanDelete(User user); } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index 8faaa895c..9815066ef 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -1,4 +1,5 @@ using System.Runtime.Serialization; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; @@ -93,5 +94,10 @@ namespace MediaBrowser.Controller.LiveTv { return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N")); } + + public override bool IsAuthorizedToDelete(User user) + { + return user.Policy.EnableLiveTvManagement; + } } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index 1948ce0d5..eaea6cfa4 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -1,5 +1,4 @@ -using System.Runtime.Serialization; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; @@ -8,6 +7,7 @@ using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Users; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; namespace MediaBrowser.Controller.LiveTv { @@ -135,5 +135,10 @@ namespace MediaBrowser.Controller.LiveTv { return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N"), "metadata"); } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index a66aaad6f..ee85ce20b 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -1,13 +1,13 @@ -using System.Runtime.Serialization; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Users; using System; +using System.Linq; +using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using System.Linq; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.LiveTv { @@ -215,5 +215,10 @@ namespace MediaBrowser.Controller.LiveTv { return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N")); } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index 34fe757a7..207684d55 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -92,5 +92,10 @@ namespace MediaBrowser.Controller.LiveTv { return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N")); } + + public override bool IsAuthorizedToDelete(User user) + { + return user.Policy.EnableLiveTvManagement; + } } } diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 0f0c6a97e..3479902cb 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -1,7 +1,5 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using System; @@ -40,6 +38,11 @@ namespace MediaBrowser.Controller.Playlists } } + public override bool IsAuthorizedToDelete(User user) + { + return true; + } + public override bool IsSaveLocalMetadataEnabled() { return true; diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index 344eb9fbd..5a00c3d3f 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -631,13 +631,13 @@ namespace MediaBrowser.MediaEncoding.Encoder switch (qualitySetting) { case EncodingQuality.HighSpeed: - param += " -crf 23"; + param += " -subq 0 -crf 23"; break; case EncodingQuality.HighQuality: - param += " -crf 20"; + param += " -subq 3 -crf 20"; break; case EncodingQuality.MaxQuality: - param += " -crf 18"; + param += " -subq 6 -crf 18"; break; } } @@ -740,7 +740,7 @@ namespace MediaBrowser.MediaEncoding.Encoder param += " -level " + state.Options.Level.Value.ToString(UsCulture); } - return param; + return "-pix_fmt yuv420p " + param; } protected string GetVideoBitrateParam(EncodingJob state, string videoCodec, bool isHls) diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index c1a34a7f6..be3cd99be 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -56,6 +56,8 @@ namespace MediaBrowser.Model.Dto public int? AirsBeforeEpisodeNumber { get; set; } public int? AbsoluteEpisodeNumber { get; set; } public bool? DisplaySpecialsWithSeasons { get; set; } + public bool? CanDelete { get; set; } + public bool? CanDownload { get; set; } public string PreferredMetadataLanguage { get; set; } public string PreferredMetadataCountryCode { get; set; } diff --git a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs index 15378a9af..a6cd85d8d 100644 --- a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs @@ -99,6 +99,12 @@ namespace MediaBrowser.Model.LiveTv /// The path. public string Path { get; set; } + /// + /// Gets or sets a value indicating whether this instance can delete. + /// + /// null if [can delete] contains no value, true if [can delete]; otherwise, false. + public bool? CanDelete { get; set; } + /// /// Overview of the recording. /// diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs index 5018f8e51..7a91d77ff 100644 --- a/MediaBrowser.Model/Querying/ItemFields.cs +++ b/MediaBrowser.Model/Querying/ItemFields.cs @@ -1,5 +1,4 @@ - -namespace MediaBrowser.Model.Querying +namespace MediaBrowser.Model.Querying { /// /// Used to control the data that gets attached to DtoBaseItems @@ -26,6 +25,16 @@ namespace MediaBrowser.Model.Querying /// Budget, + /// + /// The can delete + /// + CanDelete, + + /// + /// The can download + /// + CanDownload, + /// /// The chapters /// diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index cdc5077b0..9606cbe3f 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -42,7 +42,8 @@ namespace MediaBrowser.Model.Users public bool EnableMediaPlayback { get; set; } public bool EnableContentDeletion { get; set; } - + public bool EnableContentDownloading { get; set; } + /// /// Gets or sets a value indicating whether [enable synchronize]. /// @@ -80,6 +81,8 @@ namespace MediaBrowser.Model.Users EnabledDevices = new string[] { }; EnableAllDevices = true; + + EnableContentDownloading = true; } } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 7b36321f1..75bddda72 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -284,6 +284,20 @@ namespace MediaBrowser.Server.Implementations.Dto AttachLinkedChildImages(dto, playlist, user, options); } + if (fields.Contains(ItemFields.CanDelete)) + { + dto.CanDelete = user == null + ? item.CanDelete() + : item.CanDelete(user); + } + + if (fields.Contains(ItemFields.CanDownload)) + { + dto.CanDownload = user == null + ? item.CanDownload() + : item.CanDownload(user); + } + return dto; } diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs index c374a31b3..77953ee43 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs @@ -74,7 +74,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security ValidateUserAccess(user, request, authAttribtues, auth); } - if (!IsExemptFromRoles(auth, authAttribtues)) + var info = (AuthenticationInfo)request.Items["OriginalAuthenticationInfo"]; + + if (!IsExemptFromRoles(auth, authAttribtues, info)) { var roles = authAttribtues.GetRoles().ToList(); @@ -142,7 +144,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security StringComparer.OrdinalIgnoreCase); } - private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues) + private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, AuthenticationInfo tokenInfo) { if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard) @@ -150,6 +152,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security return true; } + if (string.IsNullOrWhiteSpace(auth.Token)) + { + return true; + } + + if (tokenInfo != null && string.IsNullOrWhiteSpace(tokenInfo.UserId)) + { + return true; + } + return false; } @@ -175,6 +187,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security }; } } + if (roles.Contains("download", StringComparer.OrdinalIgnoreCase)) + { + if (user == null || !user.Policy.EnableContentDownloading) + { + throw new SecurityException("User does not have download access.") + { + SecurityExceptionType = SecurityExceptionType.Unauthenticated + }; + } + } } private bool IsValidConnectKey(string token) diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index b3066b460..f1bb5c13a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -229,6 +229,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv ServerId = _appHost.SystemId }; + dto.CanDelete = user == null + ? recording.CanDelete() + : recording.CanDelete(user); + dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToList(); if (info.Status == RecordingStatus.InProgress) diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 3fddf274c..184a7f9a4 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -48,6 +48,7 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Save", + "ButtonDownload": "Download", "SyncJobStatusQueued": "Queued", "SyncJobStatusConverting": "Converting", "SyncJobStatusFailed": "Failed", @@ -56,6 +57,7 @@ "SyncJobStatusReadyToTransfer": "Ready to Transfer", "SyncJobStatusTransferring": "Transferring", "SyncJobStatusCompletedWithError": "Synced with errors", + "SyncJobItemStatusReadyToTransfer": "Ready to Transfer", "LabelCollection": "Collection", "HeaderAddToCollection": "Add to Collection", "NewCollectionNameExample": "Example: Star Wars Collection", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index aaf05d1ff..c280b32ea 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -285,10 +285,10 @@ "ButtonHelp": "Help", "OptionAllowUserToManageServer": "Allow this user to manage the server", "HeaderFeatureAccess": "Feature Access", - "OptionAllowMediaPlayback": "Allow media playback", - "OptionAllowBrowsingLiveTv": "Allow browsing of live tv", - "OptionAllowDeleteLibraryContent": "Allow deletion of library content", - "OptionAllowManageLiveTv": "Allow management of live tv recordings", + "OptionAllowMediaPlayback": "Media playback", + "OptionAllowBrowsingLiveTv": "Live TV", + "OptionAllowDeleteLibraryContent": "Media deletion", + "OptionAllowManageLiveTv": "Live TV recording management", "OptionAllowRemoteControlOthers": "Allow remote control of other users", "OptionAllowRemoteSharedDevices": "Allow remote control of shared devices", "OptionAllowRemoteSharedDevicesHelp": "Dlna devices are considered shared until a user begins controlling it.", @@ -1133,7 +1133,7 @@ "ViewTypeLiveTvRecordingGroups": "Recordings", "ViewTypeLiveTvChannels": "Channels", "LabelEasyPinCode": "Easy pin code:", - "EasyPasswordHelp": "Your easy pin code is used for offline access with supported Media Browser apps, and can also be used for easy in-network sign in.", + "EasyPasswordHelp": "Your easy pin code is used for offline access with supported Media Browser apps, and can also be used for easy in-network sign in.", "LabelInNetworkSignInWithEasyPassword": "Enable in-network sign in with my easy pin code", "LabelInNetworkSignInWithEasyPasswordHelp": "If enabled, you'll be able to use your easy pin code to sign in to Media Browser apps from inside your home network. Your regular password will only be needed away from home. If the pin code is left blank, you won't need a password within your home network.", "HeaderPassword": "Password", @@ -1362,7 +1362,8 @@ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.", "TabActivity": "Activity", "TitleSync": "Sync", - "OptionAllowSyncContent": "Allow syncing media to devices", + "OptionAllowSyncContent": "Sync", + "OptionAllowContentDownloading": "Media downloading", "NameSeasonUnknown": "Season Unknown", "NameSeasonNumber": "Season {0}", "LabelNewUserNameHelp": "Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)", diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index e418448db..9ecb80f3b 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -311,8 +311,10 @@ namespace MediaBrowser.Server.Implementations.Sync var itemByName = item as IItemByName; if (itemByName != null) { + var itemByNameFilter = itemByName.GetItemFilter(); + return user.RootFolder - .GetRecursiveChildren(user, itemByName.GetItemFilter()); + .GetRecursiveChildren(user, i => !i.IsFolder && itemByNameFilter(i)); } if (item.IsFolder) diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 3eb98e95d..8bf005021 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -414,7 +414,6 @@ namespace MediaBrowser.WebDashboard.Api "indexpage.js", "itembynamedetailpage.js", "itemdetailpage.js", - "itemgallery.js", "itemlistpage.js", "librarypathmapping.js", "reports.js", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 34b0e9e88..bc610b7b6 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1656,9 +1656,6 @@ - - PreserveNewest - PreserveNewest @@ -1707,9 +1704,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest -- cgit v1.2.3 From 01828f19a766b8bdddb022665cb5302f5cd745fd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 9 Feb 2015 01:17:11 -0500 Subject: added an allow mode filter for tags --- MediaBrowser.Controller/Channels/Channel.cs | 6 ++++ MediaBrowser.Controller/Entities/BaseItem.cs | 32 +++++++++++++++++++++- MediaBrowser.Controller/Entities/Folder.cs | 14 ++++++++++ MediaBrowser.Dlna/Profiles/Xbox360Profile.cs | 4 +-- MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml | 4 +-- .../MediaBrowser.Model.Portable.csproj | 6 ++++ .../MediaBrowser.Model.net35.csproj | 6 ++++ MediaBrowser.Model/MediaBrowser.Model.csproj | 2 ++ MediaBrowser.Model/Users/TagFilter.cs | 9 ++++++ MediaBrowser.Model/Users/TagFilterMode.cs | 9 ++++++ MediaBrowser.Model/Users/UserPolicy.cs | 5 +++- .../Library/UserManager.cs | 20 ++++++++++++++ .../Localization/JavaScript/javascript.json | 2 +- .../Localization/Server/server.json | 8 ++++-- .../MediaBrowser.WebDashboard.csproj | 2 +- 15 files changed, 119 insertions(+), 10 deletions(-) create mode 100644 MediaBrowser.Model/Users/TagFilter.cs create mode 100644 MediaBrowser.Model/Users/TagFilterMode.cs (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index a482f45fe..ab76f4e67 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Channels { @@ -72,5 +73,10 @@ namespace MediaBrowser.Controller.Channels { return false; } + + protected override bool IsTagFilterEnforced(TagFilterMode mode) + { + return false; + } } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 1379ba829..75a09a7b0 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1080,7 +1080,7 @@ namespace MediaBrowser.Controller.Entities if (hasTags != null) { - if (user.Policy.BlockedTags.Any(i => hasTags.Tags.Contains(i, StringComparer.OrdinalIgnoreCase))) + if (user.Policy.TagFilters.Any(i => !IsTagFilterAccepted(hasTags, i))) { return false; } @@ -1089,6 +1089,36 @@ namespace MediaBrowser.Controller.Entities return true; } + private bool IsTagFilterAccepted(IHasTags hasTags, TagFilter filter) + { + if (IsTagFilterEnforced(filter.Mode)) + { + if (filter.Mode == TagFilterMode.Block) + { + // If content has the tag, it's not allowed + if (hasTags.Tags.Contains(filter.Tag, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + else if (filter.Mode == TagFilterMode.Allow) + { + // If content doesn't have the tag, it's not allowed + if (!hasTags.Tags.Contains(filter.Tag, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + } + + return true; + } + + protected virtual bool IsTagFilterEnforced(TagFilterMode mode) + { + return true; + } + /// /// Gets the block unrated value. /// diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index e85dee354..fe9bea53b 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -14,6 +14,7 @@ using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { @@ -79,6 +80,19 @@ namespace MediaBrowser.Controller.Entities } } + protected override bool IsTagFilterEnforced(TagFilterMode mode) + { + if (this is ICollectionFolder) + { + return false; + } + if (this is UserView) + { + return false; + } + return true; + } + /// /// Gets or sets a value indicating whether this instance is physical root. /// diff --git a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs index 7aa924be0..e3dd83224 100644 --- a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs +++ b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs @@ -15,11 +15,11 @@ namespace MediaBrowser.Dlna.Profiles Name = "Xbox 360"; // Required according to above - ModelName = "Windows Media Connect"; + ModelName = "Windows Media Player Sharing"; ModelNumber = "12.0"; - FriendlyName = "${HostName} : 1 : Windows Media Connect"; + FriendlyName = "${HostName} : 1"; ModelUrl = "http://www.microsoft.com/"; Manufacturer = "Microsoft Corporation"; diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml index 96b728bdc..da5572407 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml @@ -8,10 +8,10 @@ - ${HostName} : 1 : Windows Media Connect + ${HostName} : 1 Microsoft Corporation http://www.microsoft.com/ - Windows Media Connect + Windows Media Player Sharing Media Browser 12.0 http://www.microsoft.com/ diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index ba3065bc9..561ae1e41 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -1181,6 +1181,12 @@ Users\PinRedeemResult.cs + + Users\TagFilter.cs + + + Users\TagFilterMode.cs + Users\UserAction.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 8d22f25a9..bf5624f7a 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -1140,6 +1140,12 @@ Users\PinRedeemResult.cs + + Users\TagFilter.cs + + + Users\TagFilterMode.cs + Users\UserAction.cs diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index c8e09dd82..7f71c85c5 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -433,6 +433,8 @@ + + diff --git a/MediaBrowser.Model/Users/TagFilter.cs b/MediaBrowser.Model/Users/TagFilter.cs new file mode 100644 index 000000000..5a30c435c --- /dev/null +++ b/MediaBrowser.Model/Users/TagFilter.cs @@ -0,0 +1,9 @@ + +namespace MediaBrowser.Model.Users +{ + public class TagFilter + { + public string Tag { get; set; } + public TagFilterMode Mode { get; set; } + } +} diff --git a/MediaBrowser.Model/Users/TagFilterMode.cs b/MediaBrowser.Model/Users/TagFilterMode.cs new file mode 100644 index 000000000..bce75b41f --- /dev/null +++ b/MediaBrowser.Model/Users/TagFilterMode.cs @@ -0,0 +1,9 @@ + +namespace MediaBrowser.Model.Users +{ + public enum TagFilterMode + { + Block = 0, + Allow = 1 + } +} diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index 9606cbe3f..c82b887ba 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -58,6 +58,8 @@ namespace MediaBrowser.Model.Users public string[] EnabledFolders { get; set; } public bool EnableAllFolders { get; set; } + + public TagFilter[] TagFilters { get; set; } public UserPolicy() { @@ -66,7 +68,6 @@ namespace MediaBrowser.Model.Users EnableLiveTvAccess = true; EnableSharedDeviceControl = true; - BlockedTags = new string[] { }; BlockUnratedItems = new UnratedItem[] { }; EnableUserPreferenceAccess = true; @@ -83,6 +84,8 @@ namespace MediaBrowser.Model.Users EnableAllDevices = true; EnableContentDownloading = true; + + TagFilters = new TagFilter[] { }; } } } diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 37f7e31fa..47903525b 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -168,6 +168,7 @@ namespace MediaBrowser.Server.Implementations.Library foreach (var user in users) { await DoPolicyMigration(user).ConfigureAwait(false); + await DoBlockedTagMigration(user).ConfigureAwait(false); } // If there are no local users with admin rights, make them all admins @@ -346,6 +347,25 @@ namespace MediaBrowser.Server.Implementations.Library } } + private async Task DoBlockedTagMigration(User user) + { + if (user.Policy.BlockedTags != null) + { + user.Policy.TagFilters = user.Policy + .BlockedTags + .Select(i => new TagFilter + { + Tag = i, + Mode = TagFilterMode.Block + }) + .ToArray(); + + user.Policy.BlockedTags = null; + + await UpdateUserPolicy(user, user.Policy, false); + } + } + public UserDto GetUserDto(User user, string remoteEndPoint = null) { if (user == null) diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 184a7f9a4..cb99b57bb 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -276,7 +276,7 @@ "ButtonStart": "Start", "HeaderChannels": "Channels", "HeaderMediaFolders": "Media Folders", - "HeaderBlockItemsWithNoRating": "Block items with no rating information:", + "HeaderBlockItemsWithNoRating": "Block content with no rating information:", "OptionBlockOthers": "Others", "OptionBlockTvShows": "TV Shows", "OptionBlockTrailers": "Trailers", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index a75f4c83b..e78b19c05 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -1356,8 +1356,10 @@ "HeaderVideoTypes": "Video Types", "HeaderYears": "Years", "HeaderAddTag": "Add Tag", - "LabelBlockItemsWithTags": "Block items with tags:", + "LabelBlockOrAllowItemsWithTags": "Block or allow content with tags:", "LabelTag": "Tag:", + "OptionBlockItemWithTag": "Block all content with this tag", + "OptionAllowItemWithTag": "Allow only content with this tag", "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image", "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.", "TabActivity": "Activity", @@ -1368,5 +1370,7 @@ "NameSeasonNumber": "Season {0}", "LabelNewUserNameHelp": "Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)", "TabJobs": "Jobs", - "TabSyncJobs": "Sync Jobs" + "TabSyncJobs": "Sync Jobs", + "LabelTagFilterMode": "Mode:", + "LabelTagFilterAllowModeHelp": "If used as part of a deeply nested folder structure, content that is tagged with this mechanism will require parent folders to be tagged as well." } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index bc610b7b6..19098a3ee 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -90,7 +90,7 @@ PreserveNewest - + PreserveNewest -- cgit v1.2.3 From d5c4655361c0567d6a97b9bd68552ee654e91d62 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 9 Feb 2015 01:22:28 -0500 Subject: update text --- .../Localization/JavaScript/javascript.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index cb99b57bb..b31db164a 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -728,5 +728,6 @@ "SyncJobItemStatusFailed": "Failed", "SyncJobItemStatusRemovedFromDevice": "Removed from device", "SyncJobItemStatusCancelled": "Cancelled", - "MessageJobItemHasNoActions": "d" + "MessageBlockContentWithThisTag": "Block all content with this tag", + "MessageAllowContentWithThisTag": "Allow only content with this tag" } -- cgit v1.2.3 From f03f2346f387010c84159ac2d2b3b22e9cc3b5c6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 9 Feb 2015 01:56:45 -0500 Subject: revise opt-in tags --- MediaBrowser.Controller/Channels/Channel.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 27 ++++------------------ MediaBrowser.Controller/Entities/Folder.cs | 2 +- .../MediaBrowser.Model.Portable.csproj | 6 ----- .../MediaBrowser.Model.net35.csproj | 6 ----- MediaBrowser.Model/MediaBrowser.Model.csproj | 2 -- MediaBrowser.Model/Users/TagFilter.cs | 9 -------- MediaBrowser.Model/Users/TagFilterMode.cs | 9 -------- MediaBrowser.Model/Users/UserPolicy.cs | 9 ++++---- .../Library/UserManager.cs | 22 +----------------- .../Localization/JavaScript/javascript.json | 4 +--- .../Localization/Server/server.json | 7 +++--- 12 files changed, 16 insertions(+), 89 deletions(-) delete mode 100644 MediaBrowser.Model/Users/TagFilter.cs delete mode 100644 MediaBrowser.Model/Users/TagFilterMode.cs (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index ab76f4e67..b6514ca0a 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -74,7 +74,7 @@ namespace MediaBrowser.Controller.Channels return false; } - protected override bool IsTagFilterEnforced(TagFilterMode mode) + protected override bool IsAllowTagFilterEnforced() { return false; } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 75a09a7b0..89706f917 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1080,31 +1080,14 @@ namespace MediaBrowser.Controller.Entities if (hasTags != null) { - if (user.Policy.TagFilters.Any(i => !IsTagFilterAccepted(hasTags, i))) + var policy = user.Policy; + if (policy.BlockedTags.Any(i => hasTags.Tags.Contains(i, StringComparer.OrdinalIgnoreCase))) { return false; } - } - - return true; - } - - private bool IsTagFilterAccepted(IHasTags hasTags, TagFilter filter) - { - if (IsTagFilterEnforced(filter.Mode)) - { - if (filter.Mode == TagFilterMode.Block) - { - // If content has the tag, it's not allowed - if (hasTags.Tags.Contains(filter.Tag, StringComparer.OrdinalIgnoreCase)) - { - return false; - } - } - else if (filter.Mode == TagFilterMode.Allow) + if (policy.AllowedTags.Length > 0 && IsAllowTagFilterEnforced()) { - // If content doesn't have the tag, it's not allowed - if (!hasTags.Tags.Contains(filter.Tag, StringComparer.OrdinalIgnoreCase)) + if (policy.AllowedTags.Any(i => !hasTags.Tags.Contains(i, StringComparer.OrdinalIgnoreCase))) { return false; } @@ -1114,7 +1097,7 @@ namespace MediaBrowser.Controller.Entities return true; } - protected virtual bool IsTagFilterEnforced(TagFilterMode mode) + protected virtual bool IsAllowTagFilterEnforced() { return true; } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index fe9bea53b..0d9bb03ac 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -80,7 +80,7 @@ namespace MediaBrowser.Controller.Entities } } - protected override bool IsTagFilterEnforced(TagFilterMode mode) + protected override bool IsAllowTagFilterEnforced() { if (this is ICollectionFolder) { diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index 561ae1e41..ba3065bc9 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -1181,12 +1181,6 @@ Users\PinRedeemResult.cs - - Users\TagFilter.cs - - - Users\TagFilterMode.cs - Users\UserAction.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index bf5624f7a..8d22f25a9 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -1140,12 +1140,6 @@ Users\PinRedeemResult.cs - - Users\TagFilter.cs - - - Users\TagFilterMode.cs - Users\UserAction.cs diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 7f71c85c5..c8e09dd82 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -433,8 +433,6 @@ - - diff --git a/MediaBrowser.Model/Users/TagFilter.cs b/MediaBrowser.Model/Users/TagFilter.cs deleted file mode 100644 index 5a30c435c..000000000 --- a/MediaBrowser.Model/Users/TagFilter.cs +++ /dev/null @@ -1,9 +0,0 @@ - -namespace MediaBrowser.Model.Users -{ - public class TagFilter - { - public string Tag { get; set; } - public TagFilterMode Mode { get; set; } - } -} diff --git a/MediaBrowser.Model/Users/TagFilterMode.cs b/MediaBrowser.Model/Users/TagFilterMode.cs deleted file mode 100644 index bce75b41f..000000000 --- a/MediaBrowser.Model/Users/TagFilterMode.cs +++ /dev/null @@ -1,9 +0,0 @@ - -namespace MediaBrowser.Model.Users -{ - public enum TagFilterMode - { - Block = 0, - Allow = 1 - } -} diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index c82b887ba..3e27340d8 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -29,6 +29,7 @@ namespace MediaBrowser.Model.Users public int? MaxParentalRating { get; set; } public string[] BlockedTags { get; set; } + public string[] AllowedTags { get; set; } public bool EnableUserPreferenceAccess { get; set; } public AccessSchedule[] AccessSchedules { get; set; } public UnratedItem[] BlockUnratedItems { get; set; } @@ -59,8 +60,6 @@ namespace MediaBrowser.Model.Users public string[] EnabledFolders { get; set; } public bool EnableAllFolders { get; set; } - public TagFilter[] TagFilters { get; set; } - public UserPolicy() { EnableLiveTvManagement = true; @@ -68,6 +67,8 @@ namespace MediaBrowser.Model.Users EnableLiveTvAccess = true; EnableSharedDeviceControl = true; + BlockedTags = new string[] { }; + AllowedTags = new string[] { }; BlockUnratedItems = new UnratedItem[] { }; EnableUserPreferenceAccess = true; @@ -84,8 +85,6 @@ namespace MediaBrowser.Model.Users EnableAllDevices = true; EnableContentDownloading = true; - - TagFilters = new TagFilter[] { }; } } -} +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 47903525b..b8bc8585e 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -168,7 +168,6 @@ namespace MediaBrowser.Server.Implementations.Library foreach (var user in users) { await DoPolicyMigration(user).ConfigureAwait(false); - await DoBlockedTagMigration(user).ConfigureAwait(false); } // If there are no local users with admin rights, make them all admins @@ -347,25 +346,6 @@ namespace MediaBrowser.Server.Implementations.Library } } - private async Task DoBlockedTagMigration(User user) - { - if (user.Policy.BlockedTags != null) - { - user.Policy.TagFilters = user.Policy - .BlockedTags - .Select(i => new TagFilter - { - Tag = i, - Mode = TagFilterMode.Block - }) - .ToArray(); - - user.Policy.BlockedTags = null; - - await UpdateUserPolicy(user, user.Policy, false); - } - } - public UserDto GetUserDto(User user, string remoteEndPoint = null) { if (user == null) @@ -1036,4 +1016,4 @@ namespace MediaBrowser.Server.Implementations.Library } } } -} +} \ 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 b31db164a..9d2c98c83 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -727,7 +727,5 @@ "SyncJobItemStatusSynced": "Synced", "SyncJobItemStatusFailed": "Failed", "SyncJobItemStatusRemovedFromDevice": "Removed from device", - "SyncJobItemStatusCancelled": "Cancelled", - "MessageBlockContentWithThisTag": "Block all content with this tag", - "MessageAllowContentWithThisTag": "Allow only content with this tag" + "SyncJobItemStatusCancelled": "Cancelled" } diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index e78b19c05..c28a61da4 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -1356,10 +1356,9 @@ "HeaderVideoTypes": "Video Types", "HeaderYears": "Years", "HeaderAddTag": "Add Tag", - "LabelBlockOrAllowItemsWithTags": "Block or allow content with tags:", + "LabelBlockContentWithTags": "Block content with tags:", + "LabelAllowContentWithTags": "Allow only content with tags:", "LabelTag": "Tag:", - "OptionBlockItemWithTag": "Block all content with this tag", - "OptionAllowItemWithTag": "Allow only content with this tag", "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image", "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.", "TabActivity": "Activity", @@ -1372,5 +1371,5 @@ "TabJobs": "Jobs", "TabSyncJobs": "Sync Jobs", "LabelTagFilterMode": "Mode:", - "LabelTagFilterAllowModeHelp": "If used as part of a deeply nested folder structure, content that is tagged with this mechanism will require parent folders to be tagged as well." + "LabelTagFilterAllowModeHelp": "If allowed tags are used as part of a deeply nested folder structure, content that is tagged will require parent folders to be tagged as well." } -- cgit v1.2.3 From 6f55ff220a891fd63f6da7e329d8f4765341bdf3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 9 Feb 2015 15:54:04 -0500 Subject: added sync original quality --- MediaBrowser.Model/Sync/SyncQuality.cs | 6 +++++- .../Localization/JavaScript/javascript.json | 3 ++- .../Sync/SyncJobProcessor.cs | 9 +++++---- .../Sync/SyncManager.cs | 20 ++++++++++++++++++++ 4 files changed, 32 insertions(+), 6 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json') diff --git a/MediaBrowser.Model/Sync/SyncQuality.cs b/MediaBrowser.Model/Sync/SyncQuality.cs index d34ad22c2..27ee756a3 100644 --- a/MediaBrowser.Model/Sync/SyncQuality.cs +++ b/MediaBrowser.Model/Sync/SyncQuality.cs @@ -16,6 +16,10 @@ namespace MediaBrowser.Model.Sync /// /// The best /// - High = 2 + High = 2, + /// + /// The original + /// + Original = 3 } } diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 9d2c98c83..d5958358d 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -97,7 +97,7 @@ "HeaderSelectSubtitles": "Select Subtitles", "ButtonMarkForRemoval": "Remove from device", "ButtonUnmarkForRemoval": "Cancel removal from device", - "LabelSyncQualityHelp": "Use high quality for the maximum supported quality by the device. Medium and low quality will reduce the allowed bitrate.", + "LabelSyncQualityHelp": "Use high quality for the maximum supported quality by the device. Medium and low quality will reduce the allowed bitrate. Original will sync the original file, regardless of whether the device is capable of playing it or not.", "LabelDefaultStream": "(Default)", "LabelForcedStream": "(Forced)", "LabelDefaultForcedStream": "(Default/Forced)", @@ -708,6 +708,7 @@ "LabelSyncTo": "Sync to:", "LabelSyncJobName": "Sync job name:", "LabelQuality": "Quality:", + "OptionOriginal": "Original", "OptionHigh": "High", "OptionMedium": "Medium", "OptionLow": "Low", diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index e9d9dc46f..a254d862c 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -486,7 +486,8 @@ namespace MediaBrowser.Server.Implementations.Sync streamInfo.GetExternalSubtitles("dummy", false); // Mark as requiring conversion if transcoding the video, or if any subtitles need to be extracted - var requiresConversion = streamInfo.PlayMethod == PlayMethod.Transcode || externalSubs.Any(i => RequiresExtraction(i, mediaSource)); + var requiresVideoTranscoding = streamInfo.PlayMethod == PlayMethod.Transcode && job.Quality != SyncQuality.Original; + var requiresConversion = requiresVideoTranscoding || externalSubs.Any(i => RequiresExtraction(i, mediaSource)); if (requiresConversion && !enableConversion) { @@ -501,7 +502,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Status = SyncJobItemStatus.Converting; } - if (streamInfo.PlayMethod == PlayMethod.Transcode) + if (requiresVideoTranscoding) { // Save the job item now since conversion could take a while await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); @@ -673,7 +674,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.MediaSourceId = streamInfo.MediaSourceId; jobItem.TemporaryPath = GetTemporaryPath(jobItem); - if (streamInfo.PlayMethod == PlayMethod.Transcode) + if (streamInfo.PlayMethod == PlayMethod.Transcode && job.Quality != SyncQuality.Original) { if (!enableConversion) { @@ -760,7 +761,7 @@ namespace MediaBrowser.Server.Implementations.Sync private async Task SyncGeneric(SyncJobItem jobItem, BaseItem item, CancellationToken cancellationToken) { jobItem.OutputPath = item.Path; - + jobItem.Progress = 50; jobItem.Status = SyncJobItemStatus.ReadyToTransfer; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 0114d734a..098e2b095 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -457,10 +457,30 @@ namespace MediaBrowser.Server.Implementations.Sync return false; } + if (video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd || video.VideoType == VideoType.HdDvd) + { + return false; + } + + if (video.IsPlaceHolder) + { + return false; + } + + if (video.IsArchive) + { + return false; + } + if (video.IsStacked) { return false; } + + if (video.IsShortcut) + { + return false; + } } var game = item as Game; -- cgit v1.2.3