From e60eed49c734cf648aeceaa5ed72d33c98da3599 Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Wed, 3 Jan 2024 21:41:16 +0100 Subject: [PATCH] Translate Notifications settings (cherry picked from commit 8f7f23c9380036e87669fa663e846321cf7ebf87) Closes #9550 --- src/NzbDrone.Core/Localization/Core/en.json | 172 +++++++++++++++++- .../Notifications/Apprise/AppriseProxy.cs | 14 +- .../Notifications/Apprise/AppriseSettings.cs | 14 +- .../CustomScript/CustomScript.cs | 10 +- .../CustomScript/CustomScriptSettings.cs | 2 +- .../Notifications/Discord/Discord.cs | 7 +- .../Notifications/Discord/DiscordSettings.cs | 14 +- .../Notifications/Email/Email.cs | 9 +- .../Notifications/Email/EmailSettings.cs | 12 +- .../Notifications/Gotify/Gotify.cs | 7 +- .../Notifications/Gotify/GotifySettings.cs | 8 +- .../Notifications/Join/JoinProxy.cs | 14 +- .../Notifications/Join/JoinSettings.cs | 8 +- .../Notifications/Mailgun/Mailgun.cs | 7 +- .../Notifications/Mailgun/MailgunSettings.cs | 10 +- .../MediaBrowser/MediaBrowserService.cs | 10 +- .../MediaBrowser/MediaBrowserSettings.cs | 9 +- .../Notifications/Notifiarr/Notifiarr.cs | 7 +- .../Notifiarr/NotifiarrSettings.cs | 2 +- .../Notifications/Ntfy/NtfyProxy.cs | 17 +- .../Notifications/Ntfy/NtfySettings.cs | 15 +- .../Plex/Server/PlexServerService.cs | 13 +- .../Plex/Server/PlexServerSettings.cs | 15 +- .../Notifications/Prowl/ProwlProxy.cs | 8 +- .../Notifications/Prowl/ProwlSettings.cs | 2 +- .../PushBullet/PushBulletProxy.cs | 11 +- .../PushBullet/PushBulletSettings.cs | 8 +- .../Notifications/Pushcut/PushcutProxy.cs | 12 +- .../Notifications/Pushcut/PushcutSettings.cs | 6 +- .../Notifications/Pushover/PushoverProxy.cs | 8 +- .../Pushover/PushoverSettings.cs | 12 +- .../Notifications/SendGrid/SendGrid.cs | 7 +- .../SendGrid/SendGridSettings.cs | 6 +- .../Notifications/Signal/SignalProxy.cs | 18 +- .../Notifications/Signal/SignalSettings.cs | 15 +- .../Simplepush/SimplepushProxy.cs | 8 +- .../Simplepush/SimplepushSettings.cs | 4 +- .../Notifications/Slack/Slack.cs | 7 +- .../Notifications/Slack/SlackSettings.cs | 8 +- .../Notifications/Synology/SynologyIndexer.cs | 9 +- .../Synology/SynologyIndexerSettings.cs | 2 +- .../Notifications/Telegram/TelegramProxy.cs | 12 +- .../Telegram/TelegramSettings.cs | 8 +- .../Notifications/Trakt/Trakt.cs | 11 +- .../Notifications/Trakt/TraktSettings.cs | 10 +- .../Notifications/Twitter/TwitterService.cs | 8 +- .../Notifications/Twitter/TwitterSettings.cs | 14 +- .../Notifications/Webhook/Webhook.cs | 7 +- .../Notifications/Webhook/WebhookBase.cs | 6 +- .../Notifications/Webhook/WebhookSettings.cs | 4 +- .../Notifications/Xbmc/XbmcService.cs | 9 +- .../Notifications/Xbmc/XbmcSettings.cs | 13 +- 52 files changed, 455 insertions(+), 194 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index e4c01b564..f542a57dc 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -771,6 +771,176 @@ "NotificationStatusSingleClientHealthCheckMessage": "Notifications unavailable due to failures: {notificationNames}", "NotificationTriggers": "Notification Triggers", "NotificationTriggersHelpText": "Select which events should trigger this notification", + "NotificationsAppriseSettingsConfigurationKey": "Apprise Configuration Key", + "NotificationsAppriseSettingsConfigurationKeyHelpText": "Configuration Key for the Persistent Storage Solution. Leave empty if Stateless URLs is used.", + "NotificationsAppriseSettingsNotificationType": "Apprise Notification Type", + "NotificationsAppriseSettingsPasswordHelpText": "HTTP Basic Auth Password", + "NotificationsAppriseSettingsServerUrl": "Apprise Server URL", + "NotificationsAppriseSettingsServerUrlHelpText": "Apprise server URL, including http(s):// and port if needed", + "NotificationsAppriseSettingsStatelessUrls": "Apprise Stateless URLs", + "NotificationsAppriseSettingsStatelessUrlsHelpText": "One or more URLs separated by commas identifying where the notification should be sent to. Leave empty if Persistent Storage is used.", + "NotificationsAppriseSettingsTags": "Apprise Tags", + "NotificationsAppriseSettingsTagsHelpText": "Optionally notify only those tagged accordingly.", + "NotificationsAppriseSettingsUsernameHelpText": "HTTP Basic Auth Username", + "NotificationsCustomScriptSettingsArguments": "Arguments", + "NotificationsCustomScriptSettingsArgumentsHelpText": "Arguments to pass to the script", + "NotificationsCustomScriptSettingsName": "Custom Script", + "NotificationsCustomScriptSettingsProviderMessage": "Testing will execute the script with the EventType set to {eventTypeTest}, ensure your script handles this correctly", + "NotificationsCustomScriptValidationFileDoesNotExist": "File does not exist", + "NotificationsDiscordSettingsAuthor": "Author", + "NotificationsDiscordSettingsAuthorHelpText": "Override the embed author that shows for this notification. Blank is instance name", + "NotificationsDiscordSettingsAvatar": "Avatar", + "NotificationsDiscordSettingsAvatarHelpText": "Change the avatar that is used for messages from this integration", + "NotificationsDiscordSettingsOnGrabFields": "On Grab Fields", + "NotificationsDiscordSettingsOnGrabFieldsHelpText": "Change the fields that are passed in for this 'on grab' notification", + "NotificationsDiscordSettingsOnImportFields": "On Import Fields", + "NotificationsDiscordSettingsOnImportFieldsHelpText": "Change the fields that are passed in for this 'on import' notification", + "NotificationsDiscordSettingsOnManualInteractionFields": "On Manual Interaction Fields", + "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText": "Change the fields that are passed in for this 'on manual interation' notification", + "NotificationsDiscordSettingsUsernameHelpText": "The username to post as, defaults to Discord webhook default", + "NotificationsDiscordSettingsWebhookUrlHelpText": "Discord channel webhook url", + "NotificationsEmailSettingsBccAddress": "BCC Address(es)", + "NotificationsEmailSettingsBccAddressHelpText": "Comma separated list of email bcc recipients", + "NotificationsEmailSettingsCcAddress": "CC Address(es)", + "NotificationsEmailSettingsCcAddressHelpText": "Comma separated list of email cc recipients", + "NotificationsEmailSettingsFromAddress": "From Address", + "NotificationsEmailSettingsName": "Email", + "NotificationsEmailSettingsRecipientAddress": "Recipient Address(es)", + "NotificationsEmailSettingsRecipientAddressHelpText": "Comma separated list of email recipients", + "NotificationsEmailSettingsRequireEncryption": "Require Encryption", + "NotificationsEmailSettingsRequireEncryptionHelpText": "Require SSL (Port 465 only) or StartTLS (any other port)", + "NotificationsEmailSettingsServer": "Server", + "NotificationsEmailSettingsServerHelpText": "Hostname or IP of Email server", + "NotificationsEmbySettingsSendNotifications": "Send Notifications", + "NotificationsEmbySettingsSendNotificationsHelpText": "Have MediaBrowser send notifications to configured providers", + "NotificationsEmbySettingsUpdateLibraryHelpText": "Update Library on Import, Rename, or Delete?", + "NotificationsGotifySettingIncludeMoviePoster": "Include Movie Poster", + "NotificationsGotifySettingIncludeMoviePosterHelpText": "Include movie poster in message", + "NotificationsGotifySettingsAppToken": "App Token", + "NotificationsGotifySettingsAppTokenHelpText": "The Application Token generated by Gotify", + "NotificationsGotifySettingsPriorityHelpText": "Priority of the notification", + "NotificationsGotifySettingsServer": "Gotify Server", + "NotificationsGotifySettingsServerHelpText": "Gotify server URL, including http(s):// and port if needed", + "NotificationsJoinSettingsApiKeyHelpText": "The API Key from your Join account settings (click Join API button).", + "NotificationsJoinSettingsDeviceIds": "Device IDs", + "NotificationsJoinSettingsDeviceIdsHelpText": "Deprecated, use Device Names instead. Comma separated list of Device IDs you'd like to send notifications to. If unset, all devices will receive notifications.", + "NotificationsJoinSettingsDeviceNames": "Device Names", + "NotificationsJoinSettingsDeviceNamesHelpText": "Comma separated list of full or partial device names you'd like to send notifications to. If unset, all devices will receive notifications.", + "NotificationsJoinSettingsNotificationPriority": "Notification Priority", + "NotificationsJoinValidationInvalidDeviceId": "Device IDs appear invalid.", + "NotificationsKodiSettingAlwaysUpdate": "Always Update", + "NotificationsKodiSettingAlwaysUpdateHelpText": "Update library even when a video is playing?", + "NotificationsKodiSettingsCleanLibrary": "Clean Library", + "NotificationsKodiSettingsCleanLibraryHelpText": "Clean library after update", + "NotificationsKodiSettingsDisplayTime": "Display Time", + "NotificationsKodiSettingsDisplayTimeHelpText": "How long the notification will be displayed for (In seconds)", + "NotificationsKodiSettingsGuiNotification": "GUI Notification", + "NotificationsKodiSettingsUpdateLibraryHelpText": "Update library on Import & Rename?", + "NotificationsMailgunSettingsApiKeyHelpText": "The API key generated from MailGun", + "NotificationsMailgunSettingsSenderDomain": "Sender Domain", + "NotificationsMailgunSettingsUseEuEndpoint": "Use EU Endpoint", + "NotificationsMailgunSettingsUseEuEndpointHelpText": "Enable to use the EU MailGun endpoint", + "NotificationsNotifiarrSettingsApiKeyHelpText": "Your API key from your profile", + "NotificationsNtfySettingsAccessToken": "Access Token", + "NotificationsNtfySettingsAccessTokenHelpText": "Optional token-based authorization. Takes priority over username/password", + "NotificationsNtfySettingsClickUrl": "Click Url", + "NotificationsNtfySettingsClickUrlHelpText": "Optional link when user clicks notification", + "NotificationsNtfySettingsPasswordHelpText": "Optional password", + "NotificationsNtfySettingsServerUrl": "Server URL", + "NotificationsNtfySettingsServerUrlHelpText": "Leave blank to use public server ({url})", + "NotificationsNtfySettingsTagsEmojis": "Ntfy Tags and Emojis", + "NotificationsNtfySettingsTagsEmojisHelpText": "Optional list of tags or emojis to use", + "NotificationsNtfySettingsTopics": "Topics", + "NotificationsNtfySettingsTopicsHelpText": "List of Topics to send notifications to", + "NotificationsNtfySettingsUsernameHelpText": "Optional username", + "NotificationsNtfyValidationAuthorizationRequired": "Authorization is required", + "NotificationsPlexSettingsAuthToken": "Auth Token", + "NotificationsPlexSettingsAuthenticateWithPlexTv": "Authenticate with Plex.tv", + "NotificationsPlexValidationNoMovieLibraryFound": "At least one Movie library is required", + "NotificationsPushBulletSettingSenderId": "Sender ID", + "NotificationsPushBulletSettingSenderIdHelpText": "The device ID to send notifications from, use device_iden in the device's URL on pushbullet.com (leave blank to send from yourself)", + "NotificationsPushBulletSettingsAccessToken": "Access Token", + "NotificationsPushBulletSettingsChannelTags": "Channel Tags", + "NotificationsPushBulletSettingsChannelTagsHelpText": "List of Channel Tags to send notifications to", + "NotificationsPushBulletSettingsDeviceIds": "Device IDs", + "NotificationsPushBulletSettingsDeviceIdsHelpText": "List of device IDs (leave blank to send to all devices)", + "NotificationsPushcutSettingsApiKeyHelpText": "API Keys can be managed in the Account view of the Pushcut app", + "NotificationsPushcutSettingsNotificationName": "Notification Name", + "NotificationsPushcutSettingsNotificationNameHelpText": "Notification name from Notifications tab of the Pushcut app", + "NotificationsPushcutSettingsTimeSensitive": "Time Sensitive", + "NotificationsPushcutSettingsTimeSensitiveHelpText": "Enable to mark the notification as \"Time Sensitive\"", + "NotificationsPushoverSettingsDevices": "Devices", + "NotificationsPushoverSettingsDevicesHelpText": "List of device names (leave blank to send to all devices)", + "NotificationsPushoverSettingsExpire": "Expire", + "NotificationsPushoverSettingsExpireHelpText": "Maximum time to retry Emergency alerts, maximum 86400 seconds\"", + "NotificationsPushoverSettingsRetry": "Retry", + "NotificationsPushoverSettingsRetryHelpText": "Interval to retry Emergency alerts, minimum 30 seconds", + "NotificationsPushoverSettingsSound": "Sound", + "NotificationsPushoverSettingsSoundHelpText": "Notification sound, leave blank to use the default", + "NotificationsPushoverSettingsUserKey": "User Key", + "NotificationsSendGridSettingsApiKeyHelpText": "The API Key generated by SendGrid", + "NotificationsSettingsUpdateLibrary": "Update Library", + "NotificationsSettingsUpdateMapPathsFrom": "Map Paths From", + "NotificationsSettingsUpdateMapPathsFromHelpText": "{appName} path, used to modify series paths when {serviceName} sees library path location differently from {appName} (Requires 'Update Library')", + "NotificationsSettingsUpdateMapPathsTo": "Map Paths To", + "NotificationsSettingsUpdateMapPathsToHelpText": "{serviceName} path, used to modify series paths when {serviceName} sees library path location differently from {appName} (Requires 'Update Library')", + "NotificationsSettingsUseSslHelpText": "Connect to {serviceName} over HTTPS instead of HTTP", + "NotificationsSettingsWebhookMethod": "Method", + "NotificationsSettingsWebhookMethodHelpText": "Which HTTP method to use submit to the Webservice", + "NotificationsSettingsWebhookUrl": "Webhook URL", + "NotificationsSignalSettingsGroupIdPhoneNumber": "Group ID / Phone Number", + "NotificationsSignalSettingsGroupIdPhoneNumberHelpText": "Group ID / Phone Number of the receiver", + "NotificationsSignalSettingsPasswordHelpText": "Password used to authenticate requests toward signal-api", + "NotificationsSignalSettingsSenderNumber": "Sender Number", + "NotificationsSignalSettingsSenderNumberHelpText": "Phone number of the sender register in signal-api", + "NotificationsSignalSettingsUsernameHelpText": "Username used to authenticate requests toward signal-api", + "NotificationsSignalValidationSslRequired": "SSL seems to be required", + "NotificationsSimplepushSettingsEvent": "Event", + "NotificationsSimplepushSettingsEventHelpText": "Customize the behavior of push notifications", + "NotificationsSimplepushSettingsKey": "Key", + "NotificationsSlackSettingsChannel": "Channel", + "NotificationsSlackSettingsChannelHelpText": "Overrides the default channel for the incoming webhook (#other-channel)", + "NotificationsSlackSettingsIcon": "Icon", + "NotificationsSlackSettingsIconHelpText": "Change the icon that is used for messages posted to Slack (Emoji or URL)", + "NotificationsSlackSettingsUsernameHelpText": "Username to post to Slack as", + "NotificationsSlackSettingsWebhookUrlHelpText": "Slack channel webhook url", + "NotificationsSynologySettingsUpdateLibraryHelpText": "Call synoindex on localhost to update a library file", + "NotificationsSynologyValidationInvalidOs": "Must be a Synology", + "NotificationsSynologyValidationTestFailed": "Not a Synology or synoindex not available", + "NotificationsTelegramSettingsBotToken": "Bot Token", + "NotificationsTelegramSettingsChatId": "Chat ID", + "NotificationsTelegramSettingsChatIdHelpText": "You must start a conversation with the bot or add it to your group to receive messages", + "NotificationsTelegramSettingsSendSilently": "Send Silently", + "NotificationsTelegramSettingsSendSilentlyHelpText": "Sends the message silently. Users will receive a notification with no sound", + "NotificationsTelegramSettingsTopicId": "Topic ID", + "NotificationsTelegramSettingsTopicIdHelpText": "Specify a Topic ID to send notifications to that topic. Leave blank to use the general topic (Supergroups only)", + "NotificationsTraktSettingsAccessToken": "Access Token", + "NotificationsTraktSettingsAuthUser": "Auth User", + "NotificationsTraktSettingsAuthenticateWithTrakt": "Authenticate with Trakt", + "NotificationsTraktSettingsExpires": "Expires", + "NotificationsTraktSettingsRefreshToken": "Refresh Token", + "NotificationsTwitterSettingsAccessToken": "Access Token", + "NotificationsTwitterSettingsAccessTokenSecret": "Access Token Secret", + "NotificationsTwitterSettingsConnectToTwitter": "Connect to Twitter / X", + "NotificationsTwitterSettingsConsumerKey": "Consumer Key", + "NotificationsTwitterSettingsConsumerKeyHelpText": "Consumer key from a Twitter application", + "NotificationsTwitterSettingsConsumerSecret": "Consumer Secret", + "NotificationsTwitterSettingsConsumerSecretHelpText": "Consumer secret from a Twitter application", + "NotificationsTwitterSettingsDirectMessage": "Direct Message", + "NotificationsTwitterSettingsDirectMessageHelpText": "Send a direct message instead of a public message", + "NotificationsTwitterSettingsMention": "Mention", + "NotificationsTwitterSettingsMentionHelpText": "Mention this user in sent tweets", + "NotificationsValidationInvalidAccessToken": "Access Token is invalid", + "NotificationsValidationInvalidApiKey": "API Key is invalid", + "NotificationsValidationInvalidApiKeyExceptionMessage": "API Key is invalid: {exceptionMessage}", + "NotificationsValidationInvalidAuthenticationToken": "Authentication Token is invalid", + "NotificationsValidationInvalidHttpCredentials": "HTTP Auth credentials are invalid: {exceptionMessage}", + "NotificationsValidationInvalidUsernamePassword": "Invalid username or password", + "NotificationsValidationUnableToConnect": "Unable to connect: {exceptionMessage}", + "NotificationsValidationUnableToConnectToApi": "Unable to connect to {service} API. Server connection failed: ({responseCode}) {exceptionMessage}", + "NotificationsValidationUnableToConnectToService": "Unable to connect to {serviceName}", + "NotificationsValidationUnableToSendTestMessage": "Unable to send test message: {exceptionMessage}", + "NotificationsValidationUnableToSendTestMessageApiResponse": "Unable to send test message. Response from API: {error}", "OAuthPopupMessage": "Pop-ups are being blocked by your browser", "Ok": "Ok", "OnApplicationUpdate": "On Application Update", @@ -1069,11 +1239,11 @@ "SearchForMovie": "Search for movie", "SearchMissing": "Search Missing", "SearchMovie": "Search Movie", + "SearchMoviesConfirmationMessageText": "Are you sure you want to run a search for {count} movie(s)?", "SearchOnAdd": "Search on Add", "SearchOnAddCollectionHelpText": "Search for movies on this collection when added to library", "SearchOnAddHelpText": "Search for movies on this list when added to library", "SearchSelected": "Search Selected", - "SearchMoviesConfirmationMessageText": "Are you sure you want to run a search for {count} movie(s)?", "Seconds": "Seconds", "Security": "Security", "Seeders": "Seeders", diff --git a/src/NzbDrone.Core/Notifications/Apprise/AppriseProxy.cs b/src/NzbDrone.Core/Notifications/Apprise/AppriseProxy.cs index 3a0cb26e0..86a5e395b 100644 --- a/src/NzbDrone.Core/Notifications/Apprise/AppriseProxy.cs +++ b/src/NzbDrone.Core/Notifications/Apprise/AppriseProxy.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Net; using FluentValidation.Results; @@ -6,6 +7,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Common.Serializer; +using NzbDrone.Core.Localization; namespace NzbDrone.Core.Notifications.Apprise { @@ -18,11 +20,13 @@ public interface IAppriseProxy public class AppriseProxy : IAppriseProxy { private readonly IHttpClient _httpClient; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public AppriseProxy(IHttpClient httpClient, Logger logger) + public AppriseProxy(IHttpClient httpClient, ILocalizationService localizationService, Logger logger) { _httpClient = httpClient; + _localizationService = localizationService; _logger = logger; } @@ -92,7 +96,7 @@ public ValidationFailure Test(AppriseSettings settings) if (httpException.Response.StatusCode == HttpStatusCode.Unauthorized) { _logger.Error(ex, $"HTTP Auth credentials are invalid: {0}", ex.Message); - return new ValidationFailure("AuthUsername", $"HTTP Auth credentials are invalid: {ex.Message}"); + return new ValidationFailure("AuthUsername", _localizationService.GetLocalizedString("NotificationsValidationInvalidHttpCredentials", new Dictionary { { "exceptionMessage", ex.Message } })); } if (httpException.Response.Content.IsNotNullOrWhiteSpace()) @@ -100,16 +104,16 @@ public ValidationFailure Test(AppriseSettings settings) var error = Json.Deserialize(httpException.Response.Content); _logger.Error(ex, $"Unable to send test message. Response from API: {0}", error.Error); - return new ValidationFailure(string.Empty, $"Unable to send test message. Response from API: {error.Error}"); + return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessageApiResponse", new Dictionary { { "error", error.Error } })); } _logger.Error(ex, "Unable to send test message. Server connection failed: ({0}) {1}", httpException.Response.StatusCode, ex.Message); - return new ValidationFailure("Url", $"Unable to connect to Apprise API. Server connection failed: ({httpException.Response.StatusCode}) {ex.Message}"); + return new ValidationFailure("Url", _localizationService.GetLocalizedString("NotificationsValidationUnableToConnectToApi", new Dictionary { { "service", "Apprise" }, { "responseCode", httpException.Response.StatusCode }, { "exceptionMessage", ex.Message } })); } catch (Exception ex) { _logger.Error(ex, "Unable to send test message: {0}", ex.Message); - return new ValidationFailure("Url", $"Unable to send test message: {ex.Message}"); + return new ValidationFailure("Url", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Apprise/AppriseSettings.cs b/src/NzbDrone.Core/Notifications/Apprise/AppriseSettings.cs index 31c709253..3b86e20ed 100644 --- a/src/NzbDrone.Core/Notifications/Apprise/AppriseSettings.cs +++ b/src/NzbDrone.Core/Notifications/Apprise/AppriseSettings.cs @@ -45,25 +45,25 @@ public AppriseSettings() Tags = Array.Empty(); } - [FieldDefinition(1, Label = "Apprise Server URL", Type = FieldType.Url, Placeholder = "http://localhost:8000", HelpText = "Apprise server URL, including http(s):// and port if needed", HelpLink = "https://github.com/caronc/apprise-api")] + [FieldDefinition(1, Label = "NotificationsAppriseSettingsServerUrl", Type = FieldType.Url, Placeholder = "http://localhost:8000", HelpText = "NotificationsAppriseSettingsServerUrlHelpText", HelpLink = "https://github.com/caronc/apprise-api")] public string ServerUrl { get; set; } - [FieldDefinition(2, Label = "Apprise Configuration Key", Type = FieldType.Textbox, HelpText = "Configuration Key for the Persistent Storage Solution. Leave empty if Stateless URLs is used.", HelpLink = "https://github.com/caronc/apprise-api#persistent-storage-solution")] + [FieldDefinition(2, Label = "NotificationsAppriseSettingsConfigurationKey", Type = FieldType.Textbox, HelpText = "NotificationsAppriseSettingsConfigurationKeyHelpText", HelpLink = "https://github.com/caronc/apprise-api#persistent-storage-solution")] public string ConfigurationKey { get; set; } - [FieldDefinition(3, Label = "Apprise Stateless URLs", Type = FieldType.Textbox, HelpText = "One or more URLs separated by commas identifying where the notification should be sent to. Leave empty if Persistent Storage is used.", HelpLink = "https://github.com/caronc/apprise#productivity-based-notifications")] + [FieldDefinition(3, Label = "NotificationsAppriseSettingsStatelessUrls", Type = FieldType.Textbox, HelpText = "NotificationsAppriseSettingsStatelessUrlsHelpText", HelpLink = "https://github.com/caronc/apprise#productivity-based-notifications")] public string StatelessUrls { get; set; } - [FieldDefinition(4, Label = "Apprise Notification Type", Type = FieldType.Select, SelectOptions = typeof(AppriseNotificationType))] + [FieldDefinition(4, Label = "NotificationsAppriseSettingsNotificationType", Type = FieldType.Select, SelectOptions = typeof(AppriseNotificationType))] public int NotificationType { get; set; } - [FieldDefinition(5, Label = "Apprise Tags", Type = FieldType.Tag, HelpText = "Optionally notify only those tagged accordingly.")] + [FieldDefinition(5, Label = "NotificationsAppriseSettingsTags", Type = FieldType.Tag, HelpText = "NotificationsAppriseSettingsTagsHelpText")] public IEnumerable Tags { get; set; } - [FieldDefinition(6, Label = "Username", Type = FieldType.Textbox, HelpText = "HTTP Basic Auth Username", Privacy = PrivacyLevel.UserName)] + [FieldDefinition(6, Label = "Username", Type = FieldType.Textbox, HelpText = "NotificationsAppriseSettingsUsernameHelpText", Privacy = PrivacyLevel.UserName)] public string AuthUsername { get; set; } - [FieldDefinition(7, Label = "Password", Type = FieldType.Password, HelpText = "HTTP Basic Auth Password", Privacy = PrivacyLevel.Password)] + [FieldDefinition(7, Label = "Password", Type = FieldType.Password, HelpText = "NotificationsAppriseSettingsPasswordHelpText", Privacy = PrivacyLevel.Password)] public string AuthPassword { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs b/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs index 29de9bd3d..21e9e1249 100755 --- a/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs +++ b/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs @@ -10,6 +10,7 @@ using NzbDrone.Common.Processes; using NzbDrone.Core.Configuration; using NzbDrone.Core.HealthCheck; +using NzbDrone.Core.Localization; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.MediaInfo; using NzbDrone.Core.Movies; @@ -27,6 +28,7 @@ public class CustomScript : NotificationBase private readonly IDiskProvider _diskProvider; private readonly IProcessProvider _processProvider; private readonly ITagRepository _tagRepository; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; public CustomScript(IConfigFileProvider configFileProvider, @@ -34,6 +36,7 @@ public CustomScript(IConfigFileProvider configFileProvider, IDiskProvider diskProvider, IProcessProvider processProvider, ITagRepository tagRepository, + ILocalizationService localizationService, Logger logger) { _configFileProvider = configFileProvider; @@ -41,14 +44,15 @@ public CustomScript(IConfigFileProvider configFileProvider, _diskProvider = diskProvider; _processProvider = processProvider; _tagRepository = tagRepository; + _localizationService = localizationService; _logger = logger; } - public override string Name => "Custom Script"; + public override string Name => _localizationService.GetLocalizedString("NotificationsCustomScriptSettingsName"); public override string Link => "https://wiki.servarr.com/radarr/settings#connections"; - public override ProviderMessage Message => new ProviderMessage("Testing will execute the script with the EventType set to Test, ensure your script handles this correctly", ProviderMessageType.Warning); + public override ProviderMessage Message => new ProviderMessage(_localizationService.GetLocalizedString("NotificationsCustomScriptSettingsProviderMessage", new Dictionary { { "eventTypeTest", "Test" } }), ProviderMessageType.Warning); public override void OnGrab(GrabMessage message) { @@ -333,7 +337,7 @@ public override ValidationResult Test() if (!_diskProvider.FileExists(Settings.Path)) { - failures.Add(new NzbDroneValidationFailure("Path", "File does not exist")); + failures.Add(new NzbDroneValidationFailure("Path", _localizationService.GetLocalizedString("NotificationsCustomScriptValidationFileDoesNotExist"))); } if (failures.Empty()) diff --git a/src/NzbDrone.Core/Notifications/CustomScript/CustomScriptSettings.cs b/src/NzbDrone.Core/Notifications/CustomScript/CustomScriptSettings.cs index ce5a398ed..8c52308e5 100644 --- a/src/NzbDrone.Core/Notifications/CustomScript/CustomScriptSettings.cs +++ b/src/NzbDrone.Core/Notifications/CustomScript/CustomScriptSettings.cs @@ -23,7 +23,7 @@ public class CustomScriptSettings : IProviderConfig [FieldDefinition(0, Label = "Path", Type = FieldType.FilePath)] public string Path { get; set; } - [FieldDefinition(1, Label = "Arguments", HelpText = "Arguments to pass to the script", Hidden = HiddenType.HiddenIfNotSet)] + [FieldDefinition(1, Label = "NotificationsCustomScriptSettingsArguments", HelpText = "NotificationsCustomScriptSettingsArgumentsHelpText", Hidden = HiddenType.HiddenIfNotSet)] public string Arguments { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Discord/Discord.cs b/src/NzbDrone.Core/Notifications/Discord/Discord.cs index 672765bca..7c9166495 100644 --- a/src/NzbDrone.Core/Notifications/Discord/Discord.cs +++ b/src/NzbDrone.Core/Notifications/Discord/Discord.cs @@ -3,6 +3,7 @@ using System.Linq; using FluentValidation.Results; using NzbDrone.Common.Extensions; +using NzbDrone.Core.Localization; using NzbDrone.Core.MediaCover; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.MediaInfo; @@ -17,11 +18,13 @@ public class Discord : NotificationBase { private readonly IDiscordProxy _proxy; private readonly ITagRepository _tagRepository; + private readonly ILocalizationService _localizationService; - public Discord(IDiscordProxy proxy, ITagRepository tagRepository) + public Discord(IDiscordProxy proxy, ITagRepository tagRepository, ILocalizationService localizationService) { _proxy = proxy; _tagRepository = tagRepository; + _localizationService = localizationService; } public override string Name => "Discord"; @@ -547,7 +550,7 @@ public ValidationFailure TestMessage() } catch (DiscordException ex) { - return new NzbDroneValidationFailure("Unable to post", ex.Message); + return new NzbDroneValidationFailure(string.Empty, _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Discord/DiscordSettings.cs b/src/NzbDrone.Core/Notifications/Discord/DiscordSettings.cs index 6455cb646..139fdab81 100644 --- a/src/NzbDrone.Core/Notifications/Discord/DiscordSettings.cs +++ b/src/NzbDrone.Core/Notifications/Discord/DiscordSettings.cs @@ -71,25 +71,25 @@ public DiscordSettings() private static readonly DiscordSettingsValidator Validator = new (); - [FieldDefinition(0, Label = "Webhook URL", HelpText = "Discord channel webhook url")] + [FieldDefinition(0, Label = "NotificationsSettingsWebhookUrl", HelpText = "NotificationsDiscordSettingsWebhookUrlHelpText")] public string WebHookUrl { get; set; } - [FieldDefinition(1, Label = "Username", Privacy = PrivacyLevel.UserName, HelpText = "The username to post as, defaults to Discord webhook default")] + [FieldDefinition(1, Label = "Username", Privacy = PrivacyLevel.UserName, HelpText = "NotificationsDiscordSettingsUsernameHelpText")] public string Username { get; set; } - [FieldDefinition(2, Label = "Avatar", HelpText = "Change the avatar that is used for messages from this integration", Type = FieldType.Textbox)] + [FieldDefinition(2, Label = "NotificationsDiscordSettingsAvatar", HelpText = "NotificationsDiscordSettingsAvatarHelpText", Type = FieldType.Textbox)] public string Avatar { get; set; } - [FieldDefinition(3, Label = "Author", Advanced = true, HelpText = "Override the embed author that shows for this notification, Blank is instance name", Type = FieldType.Textbox)] + [FieldDefinition(3, Label = "NotificationsDiscordSettingsAuthor", Advanced = true, HelpText = "NotificationsDiscordSettingsAuthorHelpText", Type = FieldType.Textbox)] public string Author { get; set; } - [FieldDefinition(4, Label = "On Grab Fields", Advanced = true, SelectOptions = typeof(DiscordGrabFieldType), HelpText = "Change the fields that are passed in for this 'on grab' notification", Type = FieldType.Select)] + [FieldDefinition(4, Label = "NotificationsDiscordSettingsOnGrabFields", Advanced = true, SelectOptions = typeof(DiscordGrabFieldType), HelpText = "NotificationsDiscordSettingsOnGrabFieldsHelpText", Type = FieldType.Select)] public IEnumerable GrabFields { get; set; } - [FieldDefinition(5, Label = "On Import Fields", Advanced = true, SelectOptions = typeof(DiscordImportFieldType), HelpText = "Change the fields that are passed for this 'on import' notification", Type = FieldType.Select)] + [FieldDefinition(5, Label = "NotificationsDiscordSettingsOnImportFields", Advanced = true, SelectOptions = typeof(DiscordImportFieldType), HelpText = "NotificationsDiscordSettingsOnImportFieldsHelpText", Type = FieldType.Select)] public IEnumerable ImportFields { get; set; } - [FieldDefinition(6, Label = "On Manual Interaction Fields", Advanced = true, SelectOptions = typeof(DiscordManualInteractionFieldType), HelpText = "Change the fields that are passed for this 'on manual interaction' notification", Type = FieldType.Select)] + [FieldDefinition(6, Label = "NotificationsDiscordSettingsOnManualInteractionFields", Advanced = true, SelectOptions = typeof(DiscordManualInteractionFieldType), HelpText = "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText", Type = FieldType.Select)] public IEnumerable ManualInteractionFields { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Email/Email.cs b/src/NzbDrone.Core/Notifications/Email/Email.cs index 8ef38c5eb..f1f305a10 100644 --- a/src/NzbDrone.Core/Notifications/Email/Email.cs +++ b/src/NzbDrone.Core/Notifications/Email/Email.cs @@ -8,6 +8,7 @@ using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Common.Http.Dispatchers; +using NzbDrone.Core.Localization; using NzbDrone.Core.Movies; namespace NzbDrone.Core.Notifications.Email @@ -15,13 +16,15 @@ namespace NzbDrone.Core.Notifications.Email public class Email : NotificationBase { private readonly ICertificateValidationService _certificateValidationService; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public override string Name => "Email"; + public override string Name => _localizationService.GetLocalizedString("NotificationsEmailSettingsName"); - public Email(ICertificateValidationService certificateValidationService, Logger logger) + public Email(ICertificateValidationService certificateValidationService, ILocalizationService localizationService, Logger logger) { _certificateValidationService = certificateValidationService; + _localizationService = localizationService; _logger = logger; } @@ -181,7 +184,7 @@ public ValidationFailure Test(EmailSettings settings) catch (Exception ex) { _logger.Error(ex, "Unable to send test email"); - return new ValidationFailure("Server", "Unable to send test email"); + return new ValidationFailure("Server", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs b/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs index 0c79c351a..da1f1ba1f 100644 --- a/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs +++ b/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs @@ -39,13 +39,13 @@ public EmailSettings() Bcc = Array.Empty(); } - [FieldDefinition(0, Label = "Server", HelpText = "Hostname or IP of Email server", Placeholder = "smtp.gmail.com")] + [FieldDefinition(0, Label = "NotificationsEmailSettingsServer", HelpText = "NotificationsEmailSettingsServerHelpText", Placeholder = "smtp.gmail.com")] public string Server { get; set; } [FieldDefinition(1, Label = "Port")] public int Port { get; set; } - [FieldDefinition(2, Label = "Require Encryption", HelpText = "Require SSL (Port 465 only) or StartTLS (any other port)", Type = FieldType.Checkbox)] + [FieldDefinition(2, Label = "NotificationsEmailSettingsRequireEncryption", HelpText = "NotificationsEmailSettingsRequireEncryptionHelpText", Type = FieldType.Checkbox)] public bool RequireEncryption { get; set; } [FieldDefinition(3, Label = "Username", Privacy = PrivacyLevel.UserName)] @@ -54,16 +54,16 @@ public EmailSettings() [FieldDefinition(4, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)] public string Password { get; set; } - [FieldDefinition(5, Label = "From Address", Placeholder = "example@email.com")] + [FieldDefinition(5, Label = "NotificationsEmailSettingsFromAddress", Placeholder = "example@email.com")] public string From { get; set; } - [FieldDefinition(6, Label = "Recipient Address(es)", HelpText = "Comma separated list of email recipients", Placeholder = "example@email.com,example1@email.com")] + [FieldDefinition(6, Label = "NotificationsEmailSettingsRecipientAddress", HelpText = "NotificationsEmailSettingsRecipientAddressHelpText", Placeholder = "example@email.com,example1@email.com")] public IEnumerable To { get; set; } - [FieldDefinition(7, Label = "CC Address(es)", HelpText = "Comma separated list of email cc recipients", Placeholder = "example@email.com,example1@email.com", Advanced = true)] + [FieldDefinition(7, Label = "NotificationsEmailSettingsCcAddress", HelpText = "NotificationsEmailSettingsCcAddressHelpText", Placeholder = "example@email.com,example1@email.com", Advanced = true)] public IEnumerable Cc { get; set; } - [FieldDefinition(8, Label = "BCC Address(es)", HelpText = "Comma separated list of email bcc recipients", Placeholder = "example@email.com,example1@email.com", Advanced = true)] + [FieldDefinition(8, Label = "NotificationsEmailSettingsBccAddress", HelpText = "NotificationsEmailSettingsBccAddressHelpText", Placeholder = "example@email.com,example1@email.com", Advanced = true)] public IEnumerable Bcc { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs b/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs index b981e2817..05ce83963 100644 --- a/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs +++ b/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs @@ -4,6 +4,7 @@ using System.Text; using FluentValidation.Results; using NLog; +using NzbDrone.Core.Localization; using NzbDrone.Core.MediaCover; using NzbDrone.Core.Movies; @@ -12,11 +13,13 @@ namespace NzbDrone.Core.Notifications.Gotify public class Gotify : NotificationBase { private readonly IGotifyProxy _proxy; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public Gotify(IGotifyProxy proxy, Logger logger) + public Gotify(IGotifyProxy proxy, ILocalizationService localizationService, Logger logger) { _proxy = proxy; + _localizationService = localizationService; _logger = logger; } @@ -101,7 +104,7 @@ public override ValidationResult Test() catch (Exception ex) { _logger.Error(ex, "Unable to send test message"); - failures.Add(new ValidationFailure("", "Unable to send test message")); + failures.Add(new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } }))); } return new ValidationResult(failures); diff --git a/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs b/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs index dc84de665..936c49def 100644 --- a/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs +++ b/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs @@ -23,16 +23,16 @@ public GotifySettings() Priority = 5; } - [FieldDefinition(0, Label = "Gotify Server", HelpText = "Gotify server URL, including http(s):// and port if needed")] + [FieldDefinition(0, Label = "NotificationsGotifySettingsServer", HelpText = "")] public string Server { get; set; } - [FieldDefinition(1, Label = "App Token", Privacy = PrivacyLevel.ApiKey, HelpText = "The Application Token generated by Gotify")] + [FieldDefinition(1, Label = "NotificationsGotifySettingsAppToken", Privacy = PrivacyLevel.ApiKey, HelpText = "NotificationsGotifySettingsAppTokenHelpText")] public string AppToken { get; set; } - [FieldDefinition(2, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(GotifyPriority), HelpText = "Priority of the notification")] + [FieldDefinition(2, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(GotifyPriority), HelpText = "NotificationsGotifySettingsPriorityHelpText")] public int Priority { get; set; } - [FieldDefinition(3, Label = "Include Movie Poster", Type = FieldType.Checkbox, HelpText = "Include movie poster in message")] + [FieldDefinition(3, Label = "NotificationsGotifySettingIncludeMoviePoster", Type = FieldType.Checkbox, HelpText = "NotificationsGotifySettingIncludeMoviePosterHelpText")] public bool IncludeMoviePoster { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Join/JoinProxy.cs b/src/NzbDrone.Core/Notifications/Join/JoinProxy.cs index 8c144bea3..cc03b85fc 100644 --- a/src/NzbDrone.Core/Notifications/Join/JoinProxy.cs +++ b/src/NzbDrone.Core/Notifications/Join/JoinProxy.cs @@ -1,10 +1,12 @@ using System; +using System.Collections.Generic; using System.Net.Http; using FluentValidation.Results; using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Common.Serializer; +using NzbDrone.Core.Localization; namespace NzbDrone.Core.Notifications.Join { @@ -18,11 +20,13 @@ public class JoinProxy : IJoinProxy { private const string URL = "https://joinjoaomgcd.appspot.com/_ah/api/messaging/v1/sendPush?"; private readonly IHttpClient _httpClient; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public JoinProxy(IHttpClient httpClient, Logger logger) + public JoinProxy(IHttpClient httpClient, ILocalizationService localizationService, Logger logger) { _httpClient = httpClient; + _localizationService = localizationService; _logger = logger; } @@ -54,22 +58,22 @@ public ValidationFailure Test(JoinSettings settings) catch (JoinInvalidDeviceException ex) { _logger.Error(ex, "Unable to send test Join message. Invalid Device IDs supplied."); - return new ValidationFailure("DeviceIds", "Device IDs appear invalid."); + return new ValidationFailure("DeviceIds", _localizationService.GetLocalizedString("NotificationsJoinValidationInvalidDeviceId")); } catch (JoinException ex) { _logger.Error(ex, "Unable to send test Join message."); - return new ValidationFailure("ApiKey", ex.Message); + return new ValidationFailure("ApiKey", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } catch (HttpException ex) { _logger.Error(ex, "Unable to send test Join message. Server connection failed."); - return new ValidationFailure("ApiKey", "Unable to connect to Join API. Please try again later."); + return new ValidationFailure("ApiKey", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "service", "Join" }, { "responseCode", ex.Response.StatusCode }, { "exceptionMessage", ex.Message } })); } catch (Exception ex) { _logger.Error(ex, "Unable to send test Join message. Unknown error."); - return new ValidationFailure("ApiKey", ex.Message); + return new ValidationFailure("ApiKey", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } } diff --git a/src/NzbDrone.Core/Notifications/Join/JoinSettings.cs b/src/NzbDrone.Core/Notifications/Join/JoinSettings.cs index 301f1f87f..4d188c61d 100644 --- a/src/NzbDrone.Core/Notifications/Join/JoinSettings.cs +++ b/src/NzbDrone.Core/Notifications/Join/JoinSettings.cs @@ -23,16 +23,16 @@ public JoinSettings() private static readonly JoinSettingsValidator Validator = new JoinSettingsValidator(); - [FieldDefinition(0, Label = "API Key", Privacy = PrivacyLevel.ApiKey, HelpText = "The API Key from your Join account settings (click Join API button).", HelpLink = "https://joinjoaomgcd.appspot.com/")] + [FieldDefinition(0, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpText = "NotificationsJoinSettingsApiKeyHelpText", HelpLink = "https://joinjoaomgcd.appspot.com/")] public string ApiKey { get; set; } - [FieldDefinition(1, Label = "Device IDs", HelpText = "Deprecated, use Device Names instead. Comma separated list of Device IDs you'd like to send notifications to. If unset, all devices will receive notifications.")] + [FieldDefinition(1, Label = "NotificationsJoinSettingsDeviceIds", HelpText = "NotificationsJoinSettingsDeviceIdsHelpText", Hidden = HiddenType.HiddenIfNotSet)] public string DeviceIds { get; set; } - [FieldDefinition(2, Label = "Device Names", HelpText = "Comma separated list of full or partial device names you'd like to send notifications to. If unset, all devices will receive notifications.", HelpLink = "https://joaoapps.com/join/api/")] + [FieldDefinition(2, Label = "NotificationsJoinSettingsDeviceNames", HelpText = "NotificationsJoinSettingsDeviceNamesHelpText", HelpLink = "https://joaoapps.com/join/api/")] public string DeviceNames { get; set; } - [FieldDefinition(3, Label = "Notification Priority", Type = FieldType.Select, SelectOptions = typeof(JoinPriority))] + [FieldDefinition(3, Label = "NotificationsJoinSettingsNotificationPriority", Type = FieldType.Select, SelectOptions = typeof(JoinPriority))] public int Priority { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Mailgun/Mailgun.cs b/src/NzbDrone.Core/Notifications/Mailgun/Mailgun.cs index 49e98c445..fdef135a2 100644 --- a/src/NzbDrone.Core/Notifications/Mailgun/Mailgun.cs +++ b/src/NzbDrone.Core/Notifications/Mailgun/Mailgun.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using FluentValidation.Results; using NLog; +using NzbDrone.Core.Localization; using NzbDrone.Core.Movies; namespace NzbDrone.Core.Notifications.Mailgun @@ -9,11 +10,13 @@ namespace NzbDrone.Core.Notifications.Mailgun public class MailGun : NotificationBase { private readonly IMailgunProxy _proxy; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public MailGun(IMailgunProxy proxy, Logger logger) + public MailGun(IMailgunProxy proxy, ILocalizationService localizationService, Logger logger) { _proxy = proxy; + _localizationService = localizationService; _logger = logger; } @@ -84,7 +87,7 @@ public override ValidationResult Test() catch (Exception ex) { _logger.Error(ex, "Unable to send test message though Mailgun."); - failures.Add(new ValidationFailure("", "Unable to send test message though Mailgun.")); + failures.Add(new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } }))); } return new ValidationResult(failures); diff --git a/src/NzbDrone.Core/Notifications/Mailgun/MailgunSettings.cs b/src/NzbDrone.Core/Notifications/Mailgun/MailgunSettings.cs index 896239ef5..33e0bfb9a 100644 --- a/src/NzbDrone.Core/Notifications/Mailgun/MailgunSettings.cs +++ b/src/NzbDrone.Core/Notifications/Mailgun/MailgunSettings.cs @@ -26,19 +26,19 @@ public MailgunSettings() Recipients = Array.Empty(); } - [FieldDefinition(0, Label = "API Key", HelpText = "The API key generated from MailGun")] + [FieldDefinition(0, Label = "ApiKey", HelpText = "NotificationsMailgunSettingsApiKeyHelpText")] public string ApiKey { get; set; } - [FieldDefinition(1, Label = "Use EU Endpoint?", HelpText = "Use the EU MailGun endpoint", Type = FieldType.Checkbox)] + [FieldDefinition(1, Label = "NotificationsMailgunSettingsUseEuEndpoint", HelpText = "NotificationsMailgunSettingsUseEuEndpointHelpText", Type = FieldType.Checkbox)] public bool UseEuEndpoint { get; set; } - [FieldDefinition(2, Label = "From Address")] + [FieldDefinition(2, Label = "NotificationsEmailSettingsFromAddress")] public string From { get; set; } - [FieldDefinition(3, Label = "Sender Domain")] + [FieldDefinition(3, Label = "NotificationsMailgunSettingsSenderDomain")] public string SenderDomain { get; set; } - [FieldDefinition(4, Label = "Recipient Address(es)", Type = FieldType.Tag, Placeholder = "example@email.com,example1@email.com")] + [FieldDefinition(4, Label = "NotificationsEmailSettingsRecipientAddress", Type = FieldType.Tag, Placeholder = "example@email.com,example1@email.com")] public IEnumerable Recipients { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserService.cs b/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserService.cs index 3ff3b1f2f..b77ecc339 100644 --- a/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserService.cs +++ b/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserService.cs @@ -1,8 +1,10 @@ using System; +using System.Collections.Generic; using System.Net; using FluentValidation.Results; using NLog; using NzbDrone.Common.Http; +using NzbDrone.Core.Localization; using NzbDrone.Core.Movies; namespace NzbDrone.Core.Notifications.Emby @@ -17,11 +19,13 @@ public interface IMediaBrowserService public class MediaBrowserService : IMediaBrowserService { private readonly MediaBrowserProxy _proxy; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public MediaBrowserService(MediaBrowserProxy proxy, Logger logger) + public MediaBrowserService(MediaBrowserProxy proxy, ILocalizationService localizationService, Logger logger) { _proxy = proxy; + _localizationService = localizationService; _logger = logger; } @@ -47,13 +51,13 @@ public ValidationFailure Test(MediaBrowserSettings settings) { if (ex.Response.StatusCode == HttpStatusCode.Unauthorized) { - return new ValidationFailure("ApiKey", "API Key is incorrect"); + return new ValidationFailure("ApiKey", _localizationService.GetLocalizedString("NotificationsValidationInvalidApiKey")); } } catch (Exception ex) { _logger.Error(ex, "Unable to send test message"); - return new ValidationFailure("Host", "Unable to send test message: " + ex.Message); + return new ValidationFailure("Host", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserSettings.cs b/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserSettings.cs index c9102f7c8..1b6aa54e7 100644 --- a/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserSettings.cs +++ b/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserSettings.cs @@ -31,16 +31,17 @@ public MediaBrowserSettings() [FieldDefinition(1, Label = "Port")] public int Port { get; set; } - [FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Connect to Emby over HTTPS instead of HTTP")] + [FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "NotificationsSettingsUseSslHelpText")] + [FieldToken(TokenField.HelpText, "UseSsl", "serviceName", "Emby/Jellyfin")] public bool UseSsl { get; set; } - [FieldDefinition(3, Label = "API Key", Privacy = PrivacyLevel.ApiKey)] + [FieldDefinition(3, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey)] public string ApiKey { get; set; } - [FieldDefinition(4, Label = "Send Notifications", HelpText = "Have MediaBrowser send notifications to configured providers", Type = FieldType.Checkbox)] + [FieldDefinition(4, Label = "NotificationsEmbySettingsSendNotifications", HelpText = "NotificationsEmbySettingsSendNotificationsHelpText", Type = FieldType.Checkbox)] public bool Notify { get; set; } - [FieldDefinition(5, Label = "Update Library", HelpText = "Update Library on Import, Rename or Delete?", Type = FieldType.Checkbox)] + [FieldDefinition(5, Label = "NotificationsSettingsUpdateLibrary", HelpText = "NotificationsEmbySettingsUpdateLibraryHelpText", Type = FieldType.Checkbox)] public bool UpdateLibrary { get; set; } [JsonIgnore] diff --git a/src/NzbDrone.Core/Notifications/Notifiarr/Notifiarr.cs b/src/NzbDrone.Core/Notifications/Notifiarr/Notifiarr.cs index 705dfaf77..8a7ee29b2 100644 --- a/src/NzbDrone.Core/Notifications/Notifiarr/Notifiarr.cs +++ b/src/NzbDrone.Core/Notifications/Notifiarr/Notifiarr.cs @@ -2,6 +2,7 @@ using FluentValidation.Results; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Localization; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies; using NzbDrone.Core.Notifications.Webhook; @@ -13,8 +14,8 @@ public class Notifiarr : WebhookBase { private readonly INotifiarrProxy _proxy; - public Notifiarr(INotifiarrProxy proxy, IConfigFileProvider configFileProvider, IConfigService configService) - : base(configFileProvider, configService) + public Notifiarr(INotifiarrProxy proxy, IConfigFileProvider configFileProvider, IConfigService configService, ILocalizationService localizationService) + : base(configFileProvider, configService, localizationService) { _proxy = proxy; } @@ -89,7 +90,7 @@ private ValidationFailure SendWebhookTest() } catch (NotifiarrException ex) { - return new NzbDroneValidationFailure("APIKey", ex.Message); + return new NzbDroneValidationFailure("APIKey", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrSettings.cs b/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrSettings.cs index 1a8bb06c9..7b50efcbd 100644 --- a/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrSettings.cs +++ b/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrSettings.cs @@ -17,7 +17,7 @@ public class NotifiarrSettings : IProviderConfig { private static readonly NotifiarrSettingsValidator Validator = new NotifiarrSettingsValidator(); - [FieldDefinition(0, Label = "API Key", Privacy = PrivacyLevel.ApiKey, HelpText = "Your API key from your profile", HelpLink = "https://notifiarr.com")] + [FieldDefinition(0, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpText = "NotificationsNotifiarrSettingsApiKeyHelpText", HelpLink = "https://notifiarr.com")] public string APIKey { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Ntfy/NtfyProxy.cs b/src/NzbDrone.Core/Notifications/Ntfy/NtfyProxy.cs index cba8aab12..e487e59be 100644 --- a/src/NzbDrone.Core/Notifications/Ntfy/NtfyProxy.cs +++ b/src/NzbDrone.Core/Notifications/Ntfy/NtfyProxy.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Net; @@ -6,6 +7,7 @@ using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; +using NzbDrone.Core.Localization; namespace NzbDrone.Core.Notifications.Ntfy { @@ -21,12 +23,13 @@ public class NtfyProxy : INtfyProxy private const string DEFAULT_PUSH_URL = "https://ntfy.sh"; private readonly IHttpClient _httpClient; - + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public NtfyProxy(IHttpClient httpClient, Logger logger) + public NtfyProxy(IHttpClient httpClient, ILocalizationService localizationService, Logger logger) { _httpClient = httpClient; + _localizationService = localizationService; _logger = logger; } @@ -83,26 +86,26 @@ public ValidationFailure Test(NtfySettings settings) if (!settings.AccessToken.IsNullOrWhiteSpace()) { _logger.Error(ex, "Invalid token"); - return new ValidationFailure("AccessToken", "Invalid token"); + return new ValidationFailure("AccessToken", _localizationService.GetLocalizedString("NotificationsValidationInvalidAccessToken")); } if (!settings.UserName.IsNullOrWhiteSpace() && !settings.Password.IsNullOrWhiteSpace()) { _logger.Error(ex, "Invalid username or password"); - return new ValidationFailure("UserName", "Invalid username or password"); + return new ValidationFailure("UserName", _localizationService.GetLocalizedString("NotificationsValidationInvalidUsernamePassword")); } _logger.Error(ex, "Authorization is required"); - return new ValidationFailure("AccessToken", "Authorization is required"); + return new ValidationFailure("AccessToken", _localizationService.GetLocalizedString("NotificationsNtfyValidationAuthorizationRequired")); } _logger.Error(ex, "Unable to send test message"); - return new ValidationFailure("ServerUrl", "Unable to send test message"); + return new ValidationFailure("ServerUrl", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } catch (Exception ex) { _logger.Error(ex, "Unable to send test message"); - return new ValidationFailure("", "Unable to send test message"); + return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Ntfy/NtfySettings.cs b/src/NzbDrone.Core/Notifications/Ntfy/NtfySettings.cs index 7a93d3639..4b64f8660 100644 --- a/src/NzbDrone.Core/Notifications/Ntfy/NtfySettings.cs +++ b/src/NzbDrone.Core/Notifications/Ntfy/NtfySettings.cs @@ -34,28 +34,29 @@ public NtfySettings() Priority = 3; } - [FieldDefinition(0, Label = "Server Url", Type = FieldType.Url, HelpLink = "https://ntfy.sh/docs/install/", HelpText = "Leave blank to use public server (https://ntfy.sh)", Placeholder = "https://ntfy.sh")] + [FieldDefinition(0, Label = "NotificationsNtfySettingsServerUrl", Type = FieldType.Url, HelpLink = "https://ntfy.sh/docs/install/", HelpText = "NotificationsNtfySettingsServerUrlHelpText", Placeholder = "https://ntfy.sh")] + [FieldToken(TokenField.HelpText, "NotificationsNtfySettingsServerUrl", "url", "https://ntfy.sh")] public string ServerUrl { get; set; } - [FieldDefinition(1, Label = "Access Token", Type = FieldType.Password, Privacy = PrivacyLevel.ApiKey, HelpText = "Optional token-based authorization. Takes priority over username/password", HelpLink = "https://docs.ntfy.sh/config/#access-tokens")] + [FieldDefinition(1, Label = "NotificationsNtfySettingsAccessToken", Type = FieldType.Password, Privacy = PrivacyLevel.ApiKey, HelpText = "NotificationsNtfySettingsAccessTokenHelpText", HelpLink = "https://docs.ntfy.sh/config/#access-tokens")] public string AccessToken { get; set; } - [FieldDefinition(2, Label = "User Name", HelpText = "Optional Authorization", Privacy = PrivacyLevel.UserName)] + [FieldDefinition(2, Label = "Username", HelpText = "NotificationsNtfySettingsUsernameHelpText", Privacy = PrivacyLevel.UserName)] public string UserName { get; set; } - [FieldDefinition(3, Label = "Password", Type = FieldType.Password, HelpText = "Optional Password", Privacy = PrivacyLevel.Password)] + [FieldDefinition(3, Label = "Password", Type = FieldType.Password, HelpText = "NotificationsNtfySettingsPasswordHelpText", Privacy = PrivacyLevel.Password)] public string Password { get; set; } [FieldDefinition(4, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(NtfyPriority))] public int Priority { get; set; } - [FieldDefinition(5, Label = "Topics", HelpText = "List of Topics to send notifications to", Type = FieldType.Tag, Placeholder = "Topic1234,Topic4321")] + [FieldDefinition(5, Label = "NotificationsNtfySettingsTopics", HelpText = "NotificationsNtfySettingsTopicsHelpText", Type = FieldType.Tag, Placeholder = "Topic1234,Topic4321")] public IEnumerable Topics { get; set; } - [FieldDefinition(6, Label = "Ntfy Tags and Emojis", Type = FieldType.Tag, HelpText = "Optional list of tags or emojis to use", Placeholder = "warning,skull", HelpLink = "https://ntfy.sh/docs/emojis/")] + [FieldDefinition(6, Label = "NotificationsNtfySettingsTagsEmojis", Type = FieldType.Tag, HelpText = "", Placeholder = "warning,skull", HelpLink = "https://ntfy.sh/docs/emojis/")] public IEnumerable Tags { get; set; } - [FieldDefinition(7, Label = "Click URL", Type = FieldType.Url, HelpText = "Optional link when user clicks notification", Placeholder = "https://myserver.example.com/radarr")] + [FieldDefinition(7, Label = "NotificationsNtfySettingsClickUrl", Type = FieldType.Url, HelpText = "NotificationsNtfySettingsClickUrlHelpText", Placeholder = "https://myserver.example.com/radarr")] public string ClickUrl { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerService.cs b/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerService.cs index 6702a9e3e..63c0c7c21 100644 --- a/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerService.cs +++ b/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerService.cs @@ -8,6 +8,7 @@ using NzbDrone.Common.Cache; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; +using NzbDrone.Core.Localization; using NzbDrone.Core.Movies; using NzbDrone.Core.RootFolders; using NzbDrone.Core.Validation; @@ -26,13 +27,15 @@ public class PlexServerService : IPlexServerService private readonly ICached _versionCache; private readonly IPlexServerProxy _plexServerProxy; private readonly IRootFolderService _rootFolderService; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public PlexServerService(ICacheManager cacheManager, IPlexServerProxy plexServerProxy, IRootFolderService rootFolderService, Logger logger) + public PlexServerService(ICacheManager cacheManager, IPlexServerProxy plexServerProxy, IRootFolderService rootFolderService, ILocalizationService localizationService, Logger logger) { _versionCache = cacheManager.GetCache(GetType(), "versionCache"); _plexServerProxy = plexServerProxy; _rootFolderService = rootFolderService; + _localizationService = localizationService; _logger = logger; } @@ -154,23 +157,23 @@ public ValidationFailure Test(PlexServerSettings settings) if (sections.Empty()) { - return new ValidationFailure("Host", "At least one Movie library is required"); + return new ValidationFailure("Host", _localizationService.GetLocalizedString("NotificationsPlexValidationNoMovieLibraryFound")); } } catch (PlexAuthenticationException ex) { _logger.Error(ex, "Unable to connect to Plex Media Server"); - return new ValidationFailure("AuthToken", "Invalid authentication token"); + return new ValidationFailure("AuthToken", _localizationService.GetLocalizedString("NotificationsValidationInvalidAuthenticationToken")); } catch (PlexException ex) { - return new NzbDroneValidationFailure("Host", ex.Message); + return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("NotificationsValidationUnableToConnect", new Dictionary { { "exceptionMessage", ex.Message } })); } catch (Exception ex) { _logger.Error(ex, "Unable to connect to Plex Media Server"); - return new NzbDroneValidationFailure("Host", "Unable to connect to Plex Media Server") + return new NzbDroneValidationFailure("Host", _localizationService.GetLocalizedString("NotificationsValidationUnableToConnectToService", new Dictionary { { "serviceName", "Plex Media Server" } })) { DetailedDescription = ex.Message }; diff --git a/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerSettings.cs b/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerSettings.cs index e5bbcb1ba..ff6fd7789 100644 --- a/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerSettings.cs +++ b/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerSettings.cs @@ -34,22 +34,25 @@ public PlexServerSettings() [FieldDefinition(1, Label = "Port")] public int Port { get; set; } - [FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Connect to Plex over HTTPS instead of HTTP")] + [FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "NotificationsSettingsUseSslHelpText")] + [FieldToken(TokenField.HelpText, "UseSsl", "serviceName", "Plex")] public bool UseSsl { get; set; } - [FieldDefinition(3, Label = "Auth Token", Type = FieldType.Textbox, Privacy = PrivacyLevel.ApiKey, Advanced = true)] + [FieldDefinition(3, Label = "NotificationsPlexSettingsAuthToken", Type = FieldType.Textbox, Privacy = PrivacyLevel.ApiKey, Advanced = true)] public string AuthToken { get; set; } - [FieldDefinition(4, Label = "Authenticate with Plex.tv", Type = FieldType.OAuth)] + [FieldDefinition(4, Label = "NotificationsPlexSettingsAuthenticateWithPlexTv", Type = FieldType.OAuth)] public string SignIn { get; set; } - [FieldDefinition(5, Label = "Update Library", Type = FieldType.Checkbox)] + [FieldDefinition(5, Label = "NotificationsSettingsUpdateLibrary", Type = FieldType.Checkbox)] public bool UpdateLibrary { get; set; } - [FieldDefinition(6, Label = "Map Paths From", Type = FieldType.Textbox, Advanced = true, HelpText = "Radarr path, used to modify movie paths when Plex sees library path location differently from Radarr")] + [FieldDefinition(6, Label = "NotificationsSettingsUpdateMapPathsFrom", Type = FieldType.Textbox, Advanced = true, HelpText = "NotificationsSettingsUpdateMapPathsFromHelpText")] + [FieldToken(TokenField.HelpText, "NotificationsSettingsUpdateMapPathsFrom", "serviceName", "Plex")] public string MapFrom { get; set; } - [FieldDefinition(7, Label = "Map Paths To", Type = FieldType.Textbox, Advanced = true, HelpText = "Plex path, used to modify movie paths when Plex sees library path location differently from Radarr")] + [FieldDefinition(7, Label = "NotificationsSettingsUpdateMapPathsTo", Type = FieldType.Textbox, Advanced = true, HelpText = "NotificationsSettingsUpdateMapPathsToHelpText")] + [FieldToken(TokenField.HelpText, "NotificationsSettingsUpdateMapPathsTo", "serviceName", "Plex")] public string MapTo { get; set; } public bool IsValid => !string.IsNullOrWhiteSpace(Host); diff --git a/src/NzbDrone.Core/Notifications/Prowl/ProwlProxy.cs b/src/NzbDrone.Core/Notifications/Prowl/ProwlProxy.cs index 394fd0757..05f53fe5e 100644 --- a/src/NzbDrone.Core/Notifications/Prowl/ProwlProxy.cs +++ b/src/NzbDrone.Core/Notifications/Prowl/ProwlProxy.cs @@ -1,9 +1,11 @@ using System; +using System.Collections.Generic; using System.Net; using FluentValidation.Results; using NLog; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Http; +using NzbDrone.Core.Localization; namespace NzbDrone.Core.Notifications.Prowl { @@ -17,11 +19,13 @@ public class ProwlProxy : IProwlProxy { private const string PUSH_URL = "https://api.prowlapp.com/publicapi/add"; private readonly IHttpClient _httpClient; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public ProwlProxy(IHttpClient httpClient, Logger logger) + public ProwlProxy(IHttpClient httpClient, ILocalizationService localizationService, Logger logger) { _httpClient = httpClient; + _localizationService = localizationService; _logger = logger; } @@ -68,7 +72,7 @@ public ValidationFailure Test(ProwlSettings settings) } catch (Exception ex) { - return new ValidationFailure("ApiKey", ex.Message); + return new ValidationFailure("ApiKey", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs b/src/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs index 21c5ec7b9..502266559 100644 --- a/src/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs +++ b/src/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs @@ -17,7 +17,7 @@ public class ProwlSettings : IProviderConfig { private static readonly ProwlSettingsValidator Validator = new ProwlSettingsValidator(); - [FieldDefinition(0, Label = "API Key", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://www.prowlapp.com/api_settings.php")] + [FieldDefinition(0, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://www.prowlapp.com/api_settings.php")] public string ApiKey { get; set; } [FieldDefinition(1, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(ProwlPriority))] diff --git a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs index ce0354d27..445785772 100644 --- a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs +++ b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs @@ -8,6 +8,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Common.Serializer; +using NzbDrone.Core.Localization; namespace NzbDrone.Core.Notifications.PushBullet { @@ -23,11 +24,13 @@ public class PushBulletProxy : IPushBulletProxy private const string PUSH_URL = "https://api.pushbullet.com/v2/pushes"; private const string DEVICE_URL = "https://api.pushbullet.com/v2/devices"; private readonly IHttpClient _httpClient; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public PushBulletProxy(IHttpClient httpClient, Logger logger) + public PushBulletProxy(IHttpClient httpClient, ILocalizationService localizationService, Logger logger) { _httpClient = httpClient; + _localizationService = localizationService; _logger = logger; } @@ -134,16 +137,16 @@ public ValidationFailure Test(PushBulletSettings settings) if (ex.Response.StatusCode == HttpStatusCode.Unauthorized) { _logger.Error(ex, "API Key is invalid"); - return new ValidationFailure("ApiKey", "API Key is invalid"); + return new ValidationFailure("ApiKey", _localizationService.GetLocalizedString("NotificationsValidationInvalidApiKey")); } _logger.Error(ex, "Unable to send test message"); - return new ValidationFailure("ApiKey", "Unable to send test message"); + return new ValidationFailure("ApiKey", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } catch (Exception ex) { _logger.Error(ex, "Unable to send test message"); - return new ValidationFailure("", "Unable to send test message"); + return new ValidationFailure("", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs index 93ec03a38..01c8dcf18 100644 --- a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs +++ b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs @@ -25,16 +25,16 @@ public PushBulletSettings() ChannelTags = Array.Empty(); } - [FieldDefinition(0, Label = "Access Token", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://www.pushbullet.com/#settings/account")] + [FieldDefinition(0, Label = "NotificationsPushBulletSettingsAccessToken", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://www.pushbullet.com/#settings/account")] public string ApiKey { get; set; } - [FieldDefinition(1, Label = "Device IDs", HelpText = "List of device IDs (leave blank to send to all devices)", Type = FieldType.Device, Placeholder = "123456789,987654321")] + [FieldDefinition(1, Label = "NotificationsPushBulletSettingsDeviceIds", HelpText = "NotificationsPushBulletSettingsDeviceIdsHelpText", Type = FieldType.Device, Placeholder = "123456789,987654321")] public IEnumerable DeviceIds { get; set; } - [FieldDefinition(2, Label = "Channel Tags", HelpText = "List of Channel Tags to send notifications to", Type = FieldType.Tag, Placeholder = "Channel1234,Channel4321")] + [FieldDefinition(2, Label = "NotificationsPushBulletSettingsChannelTags", HelpText = "NotificationsPushBulletSettingsChannelTagsHelpText", Type = FieldType.Tag, Placeholder = "Channel1234,Channel4321")] public IEnumerable ChannelTags { get; set; } - [FieldDefinition(3, Label = "Sender ID", HelpText = "The device ID to send notifications from, use device_iden in the device's URL on pushbullet.com (leave blank to send from yourself)")] + [FieldDefinition(3, Label = "NotificationsPushBulletSettingSenderId", HelpText = "NotificationsPushBulletSettingSenderIdHelpText")] public string SenderId { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Pushcut/PushcutProxy.cs b/src/NzbDrone.Core/Notifications/Pushcut/PushcutProxy.cs index ce11f2107..9c555c34b 100644 --- a/src/NzbDrone.Core/Notifications/Pushcut/PushcutProxy.cs +++ b/src/NzbDrone.Core/Notifications/Pushcut/PushcutProxy.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Net; using System.Net.Http; using FluentValidation.Results; @@ -5,6 +6,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Common.Serializer; +using NzbDrone.Core.Localization; namespace NzbDrone.Core.Notifications.Pushcut { @@ -17,11 +19,13 @@ public interface IPushcutProxy public class PushcutProxy : IPushcutProxy { private readonly IHttpClient _httpClient; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public PushcutProxy(IHttpClient httpClient, Logger logger) + public PushcutProxy(IHttpClient httpClient, ILocalizationService localizationService, Logger logger) { _httpClient = httpClient; + _localizationService = localizationService; _logger = logger; } @@ -67,7 +71,7 @@ public ValidationFailure Test(PushcutSettings settings) if (httpException.Response.StatusCode == HttpStatusCode.Forbidden) { _logger.Error(pushcutException, "API Key is invalid: {0}", pushcutException.Message); - return new ValidationFailure("API Key", $"API Key is invalid: {pushcutException.Message}"); + return new ValidationFailure("API Key", _localizationService.GetLocalizedString("NotificationsValidationInvalidApiKeyExceptionMessage", new Dictionary { { "exceptionMessage", pushcutException.Message } })); } if (httpException.Response.Content.IsNotNullOrWhiteSpace()) @@ -75,11 +79,11 @@ public ValidationFailure Test(PushcutSettings settings) var response = Json.Deserialize(httpException.Response.Content); _logger.Error(pushcutException, "Unable to send test notification. Response from Pushcut: {0}", response.Error); - return new ValidationFailure("Url", $"Unable to send test notification. Response from Pushcut: {response.Error}"); + return new ValidationFailure("Url", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessageApiResponse", new Dictionary { { "error", response.Error } })); } _logger.Error(pushcutException, "Unable to connect to Pushcut API. Server connection failed: ({0}) {1}", httpException.Response.StatusCode, pushcutException.Message); - return new ValidationFailure("Host", $"Unable to connect to Pushcut API. Server connection failed: ({httpException.Response.StatusCode}) {pushcutException.Message}"); + return new ValidationFailure("Host", _localizationService.GetLocalizedString("NotificationsValidationUnableToConnectToApi", new Dictionary { { "responseCode", httpException.Response.StatusCode }, { "exceptionMessage", pushcutException.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Pushcut/PushcutSettings.cs b/src/NzbDrone.Core/Notifications/Pushcut/PushcutSettings.cs index 625bca01e..87ee342b2 100644 --- a/src/NzbDrone.Core/Notifications/Pushcut/PushcutSettings.cs +++ b/src/NzbDrone.Core/Notifications/Pushcut/PushcutSettings.cs @@ -18,13 +18,13 @@ public class PushcutSettings : IProviderConfig { private static readonly PushcutSettingsValidator Validator = new (); - [FieldDefinition(0, Label = "Notification name", Type = FieldType.Textbox, HelpText = "Notification name from Notifications tab of the Pushcut app.")] + [FieldDefinition(0, Label = "NotificationsPushcutSettingsNotificationName", Type = FieldType.Textbox, HelpText = "")] public string NotificationName { get; set; } - [FieldDefinition(1, Label = "API Key", Type = FieldType.Textbox, Privacy = PrivacyLevel.ApiKey, HelpText = "API Keys can be managed in the Account view of the Pushcut app.")] + [FieldDefinition(1, Label = "ApiKey", Type = FieldType.Textbox, Privacy = PrivacyLevel.ApiKey, HelpText = "NotificationsPushcutSettingsApiKeyHelpText")] public string ApiKey { get; set; } - [FieldDefinition(2, Label = "Time sensitive", Type = FieldType.Checkbox, HelpText = "Check to mark the notification as \"Time-Sensitive\"")] + [FieldDefinition(2, Label = "NotificationsPushcutSettingsTimeSensitive", Type = FieldType.Checkbox, HelpText = "NotificationsPushcutSettingsTimeSensitiveHelpText")] public bool TimeSensitive { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Pushover/PushoverProxy.cs b/src/NzbDrone.Core/Notifications/Pushover/PushoverProxy.cs index 1caba7ab2..df5658ce3 100644 --- a/src/NzbDrone.Core/Notifications/Pushover/PushoverProxy.cs +++ b/src/NzbDrone.Core/Notifications/Pushover/PushoverProxy.cs @@ -1,8 +1,10 @@ using System; +using System.Collections.Generic; using FluentValidation.Results; using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; +using NzbDrone.Core.Localization; namespace NzbDrone.Core.Notifications.Pushover { @@ -16,11 +18,13 @@ public class PushoverProxy : IPushoverProxy { private const string URL = "https://api.pushover.net/1/messages.json"; private readonly IHttpClient _httpClient; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public PushoverProxy(IHttpClient httpClient, Logger logger) + public PushoverProxy(IHttpClient httpClient, ILocalizationService localizationService, Logger logger) { _httpClient = httpClient; + _localizationService = localizationService; _logger = logger; } @@ -63,7 +67,7 @@ public ValidationFailure Test(PushoverSettings settings) catch (Exception ex) { _logger.Error(ex, "Unable to send test message"); - return new ValidationFailure("ApiKey", "Unable to send test message"); + return new ValidationFailure("ApiKey", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs b/src/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs index d01297eb0..cfebca9ad 100644 --- a/src/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs +++ b/src/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs @@ -27,25 +27,25 @@ public PushoverSettings() Devices = Array.Empty(); } - [FieldDefinition(0, Label = "API Key", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://pushover.net/apps/clone/radarr")] + [FieldDefinition(0, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://pushover.net/apps/clone/radarr")] public string ApiKey { get; set; } - [FieldDefinition(1, Label = "User Key", Privacy = PrivacyLevel.UserName, HelpLink = "https://pushover.net/")] + [FieldDefinition(1, Label = "NotificationsPushoverSettingsUserKey", Privacy = PrivacyLevel.UserName, HelpLink = "https://pushover.net/")] public string UserKey { get; set; } - [FieldDefinition(2, Label = "Devices", HelpText = "List of device names (leave blank to send to all devices)", Type = FieldType.Tag, Placeholder = "device1")] + [FieldDefinition(2, Label = "NotificationsPushoverSettingsDevices", HelpText = "NotificationsPushoverSettingsDevicesHelpText", Type = FieldType.Tag, Placeholder = "device1")] public IEnumerable Devices { get; set; } [FieldDefinition(3, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(PushoverPriority))] public int Priority { get; set; } - [FieldDefinition(4, Label = "Retry", Type = FieldType.Textbox, HelpText = "Interval to retry Emergency alerts, minimum 30 seconds")] + [FieldDefinition(4, Label = "NotificationsPushoverSettingsRetry", Type = FieldType.Textbox, HelpText = "NotificationsPushoverSettingsRetryHelpText")] public int Retry { get; set; } - [FieldDefinition(5, Label = "Expire", Type = FieldType.Textbox, HelpText = "Maximum time to retry Emergency alerts, maximum 86400 seconds")] + [FieldDefinition(5, Label = "NotificationsPushoverSettingsExpire", Type = FieldType.Textbox, HelpText = "NotificationsPushoverSettingsExpireHelpText")] public int Expire { get; set; } - [FieldDefinition(6, Label = "Sound", Type = FieldType.Textbox, HelpText = "Notification sound, leave blank to use the default", HelpLink = "https://pushover.net/api#sounds")] + [FieldDefinition(6, Label = "NotificationsPushoverSettingsSound", Type = FieldType.Textbox, HelpText = "NotificationsPushoverSettingsSoundHelpText", HelpLink = "https://pushover.net/api#sounds")] public string Sound { get; set; } public bool IsValid => !string.IsNullOrWhiteSpace(UserKey) && Priority >= -1 && Priority <= 2; diff --git a/src/NzbDrone.Core/Notifications/SendGrid/SendGrid.cs b/src/NzbDrone.Core/Notifications/SendGrid/SendGrid.cs index 548df011e..5510f2159 100644 --- a/src/NzbDrone.Core/Notifications/SendGrid/SendGrid.cs +++ b/src/NzbDrone.Core/Notifications/SendGrid/SendGrid.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using FluentValidation.Results; using NLog; +using NzbDrone.Core.Localization; using NzbDrone.Core.Movies; namespace NzbDrone.Core.Notifications.SendGrid @@ -9,11 +10,13 @@ namespace NzbDrone.Core.Notifications.SendGrid public class SendGrid : NotificationBase { private readonly ISendGridProxy _proxy; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public SendGrid(ISendGridProxy proxy, Logger logger) + public SendGrid(ISendGridProxy proxy, ILocalizationService localizationService, Logger logger) { _proxy = proxy; + _localizationService = localizationService; _logger = logger; } @@ -79,7 +82,7 @@ public override ValidationResult Test() catch (Exception ex) { _logger.Error(ex, "Unable to send test message"); - failures.Add(new ValidationFailure("", "Unable to send test message")); + failures.Add(new ValidationFailure("", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } }))); } return new ValidationResult(failures); diff --git a/src/NzbDrone.Core/Notifications/SendGrid/SendGridSettings.cs b/src/NzbDrone.Core/Notifications/SendGrid/SendGridSettings.cs index fa9ef39ae..e65ae95d1 100644 --- a/src/NzbDrone.Core/Notifications/SendGrid/SendGridSettings.cs +++ b/src/NzbDrone.Core/Notifications/SendGrid/SendGridSettings.cs @@ -30,13 +30,13 @@ public SendGridSettings() public string BaseUrl { get; set; } - [FieldDefinition(1, Label = "API Key", Privacy = PrivacyLevel.ApiKey, HelpText = "The API Key generated by SendGrid")] + [FieldDefinition(1, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpText = "NotificationsSendGridSettingsApiKeyHelpText", HelpLink = "https://sendgrid.com/docs/ui/account-and-settings/api-keys/#creating-an-api-key")] public string ApiKey { get; set; } - [FieldDefinition(2, Label = "From Address")] + [FieldDefinition(2, Label = "NotificationsEmailSettingsFromAddress")] public string From { get; set; } - [FieldDefinition(3, Label = "Recipient Address(es)", Type = FieldType.Tag, Placeholder = "example@email.com,example1@email.com")] + [FieldDefinition(3, Label = "NotificationsEmailSettingsRecipientAddress", Type = FieldType.Tag, Placeholder = "example@email.com,example1@email.com")] public IEnumerable Recipients { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Signal/SignalProxy.cs b/src/NzbDrone.Core/Notifications/Signal/SignalProxy.cs index bd4d3608c..32c4bfc09 100644 --- a/src/NzbDrone.Core/Notifications/Signal/SignalProxy.cs +++ b/src/NzbDrone.Core/Notifications/Signal/SignalProxy.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Net; using System.Text; using FluentValidation.Results; @@ -6,6 +7,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Common.Serializer; +using NzbDrone.Core.Localization; namespace NzbDrone.Core.Notifications.Signal { @@ -18,11 +20,13 @@ public interface ISignalProxy public class SignalProxy : ISignalProxy { private readonly IHttpClient _httpClient; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public SignalProxy(IHttpClient httpClient, Logger logger) + public SignalProxy(IHttpClient httpClient, ILocalizationService localizationService, Logger logger) { _httpClient = httpClient; + _localizationService = localizationService; _logger = logger; } @@ -71,7 +75,7 @@ public ValidationFailure Test(SignalSettings settings) catch (WebException ex) { _logger.Error(ex, "Unable to send test message: {0}", ex.Message); - return new ValidationFailure("Host", $"Unable to send test message: {ex.Message}"); + return new ValidationFailure("Host", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } catch (HttpException ex) { @@ -81,7 +85,7 @@ public ValidationFailure Test(SignalSettings settings) { if (ex.Response.Content.ContainsIgnoreCase("400 The plain HTTP request was sent to HTTPS port")) { - return new ValidationFailure("UseSsl", "SSL seems to be required"); + return new ValidationFailure("UseSsl", _localizationService.GetLocalizedString("NotificationsSignalValidationSslRequired")); } var error = Json.Deserialize(ex.Response.Content); @@ -97,20 +101,20 @@ public ValidationFailure Test(SignalSettings settings) property = "SenderNumber"; } - return new ValidationFailure(property, $"Unable to send test message: {error.Error}"); + return new ValidationFailure(property, _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", error.Error } })); } if (ex.Response.StatusCode == HttpStatusCode.Unauthorized) { - return new ValidationFailure("AuthUsername", "Login/Password invalid"); + return new ValidationFailure("AuthUsername", _localizationService.GetLocalizedString("NotificationsValidationInvalidUsernamePassword")); } - return new ValidationFailure("Host", $"Unable to send test message: {ex.Message}"); + return new ValidationFailure("Host", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } catch (Exception ex) { _logger.Error(ex, "Unable to send test message: {0}", ex.Message); - return new ValidationFailure("Host", $"Unable to send test message: {ex.Message}"); + return new ValidationFailure("Host", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Signal/SignalSettings.cs b/src/NzbDrone.Core/Notifications/Signal/SignalSettings.cs index 8906a45e3..500215730 100644 --- a/src/NzbDrone.Core/Notifications/Signal/SignalSettings.cs +++ b/src/NzbDrone.Core/Notifications/Signal/SignalSettings.cs @@ -20,25 +20,26 @@ public class SignalSettings : IProviderConfig { private static readonly SignalSettingsValidator Validator = new (); - [FieldDefinition(0, Label = "Host", Type = FieldType.Textbox, HelpText = "localhost")] + [FieldDefinition(0, Label = "Host", Type = FieldType.Textbox, Placeholder = "localhost")] public string Host { get; set; } - [FieldDefinition(1, Label = "Port", Type = FieldType.Textbox, HelpText = "8080")] + [FieldDefinition(1, Label = "Port", Type = FieldType.Textbox, Placeholder = "8080")] public int Port { get; set; } - [FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Use a secure connection.")] + [FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "NotificationsSettingsUseSslHelpText")] + [FieldToken(TokenField.HelpText, "UseSsl", "serviceName", "Signal")] public bool UseSsl { get; set; } - [FieldDefinition(3, Label = "Sender Number", Privacy = PrivacyLevel.ApiKey, HelpText = "Phone number of the sender register in signal-api")] + [FieldDefinition(3, Label = "NotificationsSignalSettingsSenderNumber", Privacy = PrivacyLevel.ApiKey, HelpText = "NotificationsSignalSettingsSenderNumberHelpText")] public string SenderNumber { get; set; } - [FieldDefinition(4, Label = "Group ID / PhoneNumber", HelpText = "GroupID / PhoneNumber of the receiver")] + [FieldDefinition(4, Label = "NotificationsSignalSettingsGroupIdPhoneNumber", HelpText = "NotificationsSignalSettingsGroupIdPhoneNumberHelpText")] public string ReceiverId { get; set; } - [FieldDefinition(5, Label = "Login", Privacy = PrivacyLevel.UserName, HelpText = "Username used to authenticate requests toward signal-api")] + [FieldDefinition(5, Label = "Username", Privacy = PrivacyLevel.UserName, HelpText = "NotificationsSignalSettingsUsernameHelpText")] public string AuthUsername { get; set; } - [FieldDefinition(6, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password, HelpText = "Password used to authenticate requests toward signal-api")] + [FieldDefinition(6, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password, HelpText = "NotificationsSignalSettingsPasswordHelpText")] public string AuthPassword { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Simplepush/SimplepushProxy.cs b/src/NzbDrone.Core/Notifications/Simplepush/SimplepushProxy.cs index f0f6788f2..72a3eba8b 100644 --- a/src/NzbDrone.Core/Notifications/Simplepush/SimplepushProxy.cs +++ b/src/NzbDrone.Core/Notifications/Simplepush/SimplepushProxy.cs @@ -1,7 +1,9 @@ using System; +using System.Collections.Generic; using FluentValidation.Results; using NLog; using NzbDrone.Common.Http; +using NzbDrone.Core.Localization; namespace NzbDrone.Core.Notifications.Simplepush { @@ -15,11 +17,13 @@ public class SimplepushProxy : ISimplepushProxy { private const string URL = "https://api.simplepush.io/send"; private readonly IHttpClient _httpClient; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public SimplepushProxy(IHttpClient httpClient, Logger logger) + public SimplepushProxy(IHttpClient httpClient, ILocalizationService localizationService, Logger logger) { _httpClient = httpClient; + _localizationService = localizationService; _logger = logger; } @@ -49,7 +53,7 @@ public ValidationFailure Test(SimplepushSettings settings) catch (Exception ex) { _logger.Error(ex, "Unable to send test message"); - return new ValidationFailure("ApiKey", "Unable to send test message"); + return new ValidationFailure("ApiKey", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Simplepush/SimplepushSettings.cs b/src/NzbDrone.Core/Notifications/Simplepush/SimplepushSettings.cs index af8b211ef..2e285aeed 100644 --- a/src/NzbDrone.Core/Notifications/Simplepush/SimplepushSettings.cs +++ b/src/NzbDrone.Core/Notifications/Simplepush/SimplepushSettings.cs @@ -17,10 +17,10 @@ public class SimplepushSettings : IProviderConfig { private static readonly SimplepushSettingsValidator Validator = new SimplepushSettingsValidator(); - [FieldDefinition(0, Label = "Key", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://simplepush.io/features")] + [FieldDefinition(0, Label = "NotificationsSimplepushSettingsKey", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://simplepush.io/features")] public string Key { get; set; } - [FieldDefinition(1, Label = "Event", HelpText = "Customize the behavior of push notifications", HelpLink = "https://simplepush.io/features")] + [FieldDefinition(1, Label = "NotificationsSimplepushSettingsEvent", HelpText = "NotificationsSimplepushSettingsEventHelpText", HelpLink = "https://simplepush.io/features")] public string Event { get; set; } public bool IsValid => !string.IsNullOrWhiteSpace(Key); diff --git a/src/NzbDrone.Core/Notifications/Slack/Slack.cs b/src/NzbDrone.Core/Notifications/Slack/Slack.cs index b1ea493a1..2cd448943 100644 --- a/src/NzbDrone.Core/Notifications/Slack/Slack.cs +++ b/src/NzbDrone.Core/Notifications/Slack/Slack.cs @@ -3,6 +3,7 @@ using System.IO; using FluentValidation.Results; using NzbDrone.Common.Extensions; +using NzbDrone.Core.Localization; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies; using NzbDrone.Core.Notifications.Slack.Payloads; @@ -13,10 +14,12 @@ namespace NzbDrone.Core.Notifications.Slack public class Slack : NotificationBase { private readonly ISlackProxy _proxy; + private readonly ILocalizationService _localizationService; - public Slack(ISlackProxy proxy) + public Slack(ISlackProxy proxy, ILocalizationService localizationService) { _proxy = proxy; + _localizationService = localizationService; } public override string Name => "Slack"; @@ -195,7 +198,7 @@ public ValidationFailure TestMessage() } catch (SlackExeption ex) { - return new NzbDroneValidationFailure("Unable to post", ex.Message); + return new NzbDroneValidationFailure("Unable to post", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Slack/SlackSettings.cs b/src/NzbDrone.Core/Notifications/Slack/SlackSettings.cs index 399a1ae46..bd7f10c33 100644 --- a/src/NzbDrone.Core/Notifications/Slack/SlackSettings.cs +++ b/src/NzbDrone.Core/Notifications/Slack/SlackSettings.cs @@ -18,16 +18,16 @@ public class SlackSettings : IProviderConfig { private static readonly SlackSettingsValidator Validator = new SlackSettingsValidator(); - [FieldDefinition(0, Label = "Webhook URL", HelpText = "Slack channel webhook url", Type = FieldType.Url, HelpLink = "https://my.slack.com/services/new/incoming-webhook/")] + [FieldDefinition(0, Label = "NotificationsSettingsWebhookUrl", HelpText = "NotificationsSlackSettingsWebhookUrlHelpText", Type = FieldType.Url, HelpLink = "https://my.slack.com/services/new/incoming-webhook/")] public string WebHookUrl { get; set; } - [FieldDefinition(1, Label = "Username", Privacy = PrivacyLevel.UserName, HelpText = "Choose the username that this integration will post as", Type = FieldType.Textbox)] + [FieldDefinition(1, Label = "Username", Privacy = PrivacyLevel.UserName, HelpText = "NotificationsSlackSettingsUsernameHelpText", Type = FieldType.Textbox)] public string Username { get; set; } - [FieldDefinition(2, Label = "Icon", HelpText = "Change the icon that is used for messages from this integration (Emoji or URL)", Type = FieldType.Textbox, HelpLink = "http://www.emoji-cheat-sheet.com/")] + [FieldDefinition(2, Label = "NotificationsSlackSettingsIcon", HelpText = "NotificationsSlackSettingsIconHelpText", Type = FieldType.Textbox, HelpLink = "http://www.emoji-cheat-sheet.com/")] public string Icon { get; set; } - [FieldDefinition(3, Label = "Channel", HelpText = "Overrides the default channel for the incoming webhook (#other-channel)", Type = FieldType.Textbox)] + [FieldDefinition(3, Label = "NotificationsSlackSettingsChannel", HelpText = "NotificationsSlackSettingsChannelHelpText", Type = FieldType.Textbox)] public string Channel { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Synology/SynologyIndexer.cs b/src/NzbDrone.Core/Notifications/Synology/SynologyIndexer.cs index fe0ae926d..ea5a699a5 100644 --- a/src/NzbDrone.Core/Notifications/Synology/SynologyIndexer.cs +++ b/src/NzbDrone.Core/Notifications/Synology/SynologyIndexer.cs @@ -3,6 +3,7 @@ using FluentValidation.Results; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Extensions; +using NzbDrone.Core.Localization; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies; @@ -11,10 +12,12 @@ namespace NzbDrone.Core.Notifications.Synology public class SynologyIndexer : NotificationBase { private readonly ISynologyIndexerProxy _indexerProxy; + private readonly ILocalizationService _localizationService; - public SynologyIndexer(ISynologyIndexerProxy indexerProxy) + public SynologyIndexer(ISynologyIndexerProxy indexerProxy, ILocalizationService localizationService) { _indexerProxy = indexerProxy; + _localizationService = localizationService; } public override string Link => "https://www.synology.com"; @@ -80,12 +83,12 @@ protected virtual ValidationFailure TestConnection() { if (!OsInfo.IsLinux) { - return new ValidationFailure(null, "Must be a Synology"); + return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("NotificationsSynologyValidationInvalidOs")); } if (!_indexerProxy.Test()) { - return new ValidationFailure(null, "Not a Synology or synoindex not available"); + return new ValidationFailure(string.Empty, _localizationService.GetLocalizedString("NotificationsSynologyValidationTestFailed")); } return null; diff --git a/src/NzbDrone.Core/Notifications/Synology/SynologyIndexerSettings.cs b/src/NzbDrone.Core/Notifications/Synology/SynologyIndexerSettings.cs index 58b4322e8..8bad70a04 100644 --- a/src/NzbDrone.Core/Notifications/Synology/SynologyIndexerSettings.cs +++ b/src/NzbDrone.Core/Notifications/Synology/SynologyIndexerSettings.cs @@ -18,7 +18,7 @@ public SynologyIndexerSettings() UpdateLibrary = true; } - [FieldDefinition(0, Label = "Update Library", Type = FieldType.Checkbox, HelpText = "Call synoindex on localhost to update a library file")] + [FieldDefinition(0, Label = "NotificationsSettingsUpdateLibrary", Type = FieldType.Checkbox, HelpText = "NotificationsSynologySettingsUpdateLibraryHelpText")] public bool UpdateLibrary { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Telegram/TelegramProxy.cs b/src/NzbDrone.Core/Notifications/Telegram/TelegramProxy.cs index 2c8f926a2..5be6cda98 100644 --- a/src/NzbDrone.Core/Notifications/Telegram/TelegramProxy.cs +++ b/src/NzbDrone.Core/Notifications/Telegram/TelegramProxy.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Net; using System.Web; using FluentValidation.Results; @@ -6,6 +7,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Common.Serializer; +using NzbDrone.Core.Localization; namespace NzbDrone.Core.Notifications.Telegram { @@ -19,11 +21,13 @@ public class TelegramProxy : ITelegramProxy { private const string URL = "https://api.telegram.org"; private readonly IHttpClient _httpClient; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public TelegramProxy(IHttpClient httpClient, Logger logger) + public TelegramProxy(IHttpClient httpClient, ILocalizationService localizationService, Logger logger) { _httpClient = httpClient; + _localizationService = localizationService; _logger = logger; } @@ -60,7 +64,7 @@ public ValidationFailure Test(TelegramSettings settings) if (ex is WebException webException) { - return new ValidationFailure("Connection", $"{webException.Status.ToString()}: {webException.Message}"); + return new ValidationFailure("Connection", _localizationService.GetLocalizedString("NotificationsValidationUnableToConnectToApi", new Dictionary { { "service", "Telegram" }, { "responseCode", webException.Status.ToString() }, { "exceptionMessage", webException.Message } })); } else if (ex is Common.Http.HttpException restException && restException.Response.StatusCode == HttpStatusCode.BadRequest) { @@ -76,10 +80,10 @@ public ValidationFailure Test(TelegramSettings settings) property = "TopicId"; } - return new ValidationFailure(property, error.Description); + return new ValidationFailure(property, _localizationService.GetLocalizedString("NotificationsValidationUnableToConnect", new Dictionary { { "exceptionMessage", error.Description } })); } - return new ValidationFailure("BotToken", "Unable to send test message"); + return new ValidationFailure("BotToken", _localizationService.GetLocalizedString("NotificationsValidationUnableToConnect", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs b/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs index 774fd4ca0..ede7b3ad3 100644 --- a/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs +++ b/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs @@ -20,16 +20,16 @@ public class TelegramSettings : IProviderConfig { private static readonly TelegramSettingsValidator Validator = new TelegramSettingsValidator(); - [FieldDefinition(0, Label = "Bot Token", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://core.telegram.org/bots")] + [FieldDefinition(0, Label = "NotificationsTelegramSettingsBotToken", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://core.telegram.org/bots")] public string BotToken { get; set; } - [FieldDefinition(1, Label = "Chat ID", HelpLink = "http://stackoverflow.com/a/37396871/882971", HelpText = "You must start a conversation with the bot or add it to your group to receive messages")] + [FieldDefinition(1, Label = "NotificationsTelegramSettingsChatId", HelpLink = "http://stackoverflow.com/a/37396871/882971", HelpText = "NotificationsTelegramSettingsChatIdHelpText")] public string ChatId { get; set; } - [FieldDefinition(2, Label = "Topic ID", HelpLink = "https://stackoverflow.com/a/75178418", HelpText = "Specify a Topic ID to send notifications to that topic. Leave blank to use the general topic (Supergroups only)")] + [FieldDefinition(2, Label = "NotificationsTelegramSettingsTopicId", HelpLink = "https://stackoverflow.com/a/75178418", HelpText = "NotificationsTelegramSettingsTopicIdHelpText")] public int? TopicId { get; set; } - [FieldDefinition(3, Label = "Send Silently", Type = FieldType.Checkbox, HelpText = "Sends the message silently. Users will receive a notification with no sound")] + [FieldDefinition(3, Label = "NotificationsTelegramSettingsSendSilently", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsSendSilentlyHelpText")] public bool SendSilently { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Trakt/Trakt.cs b/src/NzbDrone.Core/Notifications/Trakt/Trakt.cs index 335c8aefb..078e65060 100644 --- a/src/NzbDrone.Core/Notifications/Trakt/Trakt.cs +++ b/src/NzbDrone.Core/Notifications/Trakt/Trakt.cs @@ -5,6 +5,7 @@ using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; +using NzbDrone.Core.Localization; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.MediaInfo; using NzbDrone.Core.Movies; @@ -18,12 +19,14 @@ public class Trakt : NotificationBase { private readonly ITraktProxy _proxy; private readonly INotificationRepository _notificationRepository; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public Trakt(ITraktProxy proxy, INotificationRepository notificationRepository, Logger logger) + public Trakt(ITraktProxy proxy, INotificationRepository notificationRepository, ILocalizationService localizationService, Logger logger) { _proxy = proxy; _notificationRepository = notificationRepository; + _localizationService = localizationService; _logger = logger; } @@ -64,20 +67,20 @@ public override ValidationResult Test() { _logger.Error(ex, "Access Token is invalid: " + ex.Message); - failures.Add(new ValidationFailure("Token", "Access Token is invalid")); + failures.Add(new ValidationFailure("Token", _localizationService.GetLocalizedString("NotificationsValidationInvalidAccessToken"))); } else { _logger.Error(ex, "Unable to send test message: " + ex.Message); - failures.Add(new ValidationFailure("Token", "Unable to send test message")); + failures.Add(new ValidationFailure("Token", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } }))); } } catch (Exception ex) { _logger.Error(ex, "Unable to send test message: " + ex.Message); - failures.Add(new ValidationFailure("", "Unable to send test message")); + failures.Add(new ValidationFailure("", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } }))); } return new ValidationResult(failures); diff --git a/src/NzbDrone.Core/Notifications/Trakt/TraktSettings.cs b/src/NzbDrone.Core/Notifications/Trakt/TraktSettings.cs index 1d5c7b47d..0be5677da 100644 --- a/src/NzbDrone.Core/Notifications/Trakt/TraktSettings.cs +++ b/src/NzbDrone.Core/Notifications/Trakt/TraktSettings.cs @@ -25,19 +25,19 @@ public TraktSettings() SignIn = "startOAuth"; } - [FieldDefinition(0, Label = "Access Token", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] + [FieldDefinition(0, Label = "NotificationsTraktSettingsAccessToken", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] public string AccessToken { get; set; } - [FieldDefinition(0, Label = "Refresh Token", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] + [FieldDefinition(1, Label = "NotificationsTraktSettingsRefreshToken", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] public string RefreshToken { get; set; } - [FieldDefinition(0, Label = "Expires", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] + [FieldDefinition(2, Label = "NotificationsTraktSettingsExpires", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] public DateTime Expires { get; set; } - [FieldDefinition(0, Label = "Auth User", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] + [FieldDefinition(3, Label = "NotificationsTraktSettingsAuthUser", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] public string AuthUser { get; set; } - [FieldDefinition(99, Label = "Authenticate with Trakt", Type = FieldType.OAuth)] + [FieldDefinition(4, Label = "NotificationsTraktSettingsAuthenticateWithTrakt", Type = FieldType.OAuth)] public string SignIn { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Twitter/TwitterService.cs b/src/NzbDrone.Core/Notifications/Twitter/TwitterService.cs index 22e7fb81d..b3c877868 100644 --- a/src/NzbDrone.Core/Notifications/Twitter/TwitterService.cs +++ b/src/NzbDrone.Core/Notifications/Twitter/TwitterService.cs @@ -1,9 +1,11 @@ using System; +using System.Collections.Generic; using System.IO; using System.Net; using FluentValidation.Results; using NLog; using NzbDrone.Common.Extensions; +using NzbDrone.Core.Localization; namespace NzbDrone.Core.Notifications.Twitter { @@ -18,11 +20,13 @@ public interface ITwitterService public class TwitterService : ITwitterService { private readonly ITwitterProxy _twitterProxy; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public TwitterService(ITwitterProxy twitterProxy, Logger logger) + public TwitterService(ITwitterProxy twitterProxy, ILocalizationService localizationService, Logger logger) { _twitterProxy = twitterProxy; + _localizationService = localizationService; _logger = logger; } @@ -96,7 +100,7 @@ public ValidationFailure Test(TwitterSettings settings) catch (Exception ex) { _logger.Error(ex, "Unable to send test message"); - return new ValidationFailure("Host", "Unable to send test message"); + return new ValidationFailure("Host", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Twitter/TwitterSettings.cs b/src/NzbDrone.Core/Notifications/Twitter/TwitterSettings.cs index be052226e..d43155ed6 100644 --- a/src/NzbDrone.Core/Notifications/Twitter/TwitterSettings.cs +++ b/src/NzbDrone.Core/Notifications/Twitter/TwitterSettings.cs @@ -38,25 +38,25 @@ public TwitterSettings() AuthorizeNotification = "startOAuth"; } - [FieldDefinition(0, Label = "Consumer Key", Privacy = PrivacyLevel.ApiKey, HelpText = "Consumer key from a Twitter application", HelpLink = "https://wiki.servarr.com/useful-tools#twitter-connect")] + [FieldDefinition(0, Label = "NotificationsTwitterSettingsConsumerKey", Privacy = PrivacyLevel.ApiKey, HelpText = "NotificationsTwitterSettingsConsumerKeyHelpText", HelpLink = "https://wiki.servarr.com/useful-tools#twitter-connect")] public string ConsumerKey { get; set; } - [FieldDefinition(1, Label = "Consumer Secret", Privacy = PrivacyLevel.ApiKey, HelpText = "Consumer secret from a Twitter application", HelpLink = "https://wiki.servarr.com/useful-tools#twitter-connect")] + [FieldDefinition(1, Label = "NotificationsTwitterSettingsConsumerSecret", Privacy = PrivacyLevel.ApiKey, HelpText = "NotificationsTwitterSettingsConsumerSecretHelpText", HelpLink = "https://wiki.servarr.com/useful-tools#twitter-connect")] public string ConsumerSecret { get; set; } - [FieldDefinition(2, Label = "Access Token", Privacy = PrivacyLevel.ApiKey, Advanced = true)] + [FieldDefinition(2, Label = "NotificationsTwitterSettingsAccessToken", Privacy = PrivacyLevel.ApiKey, Advanced = true)] public string AccessToken { get; set; } - [FieldDefinition(3, Label = "Access Token Secret", Privacy = PrivacyLevel.ApiKey, Advanced = true)] + [FieldDefinition(3, Label = "NotificationsTwitterSettingsAccessTokenSecret", Privacy = PrivacyLevel.ApiKey, Advanced = true)] public string AccessTokenSecret { get; set; } - [FieldDefinition(4, Label = "Mention", HelpText = "Mention this user in sent tweets")] + [FieldDefinition(4, Label = "NotificationsTwitterSettingsMention", HelpText = "NotificationsTwitterSettingsMentionHelpText")] public string Mention { get; set; } - [FieldDefinition(5, Label = "Direct Message", Type = FieldType.Checkbox, HelpText = "Send a direct message instead of a public message")] + [FieldDefinition(5, Label = "NotificationsTwitterSettingsDirectMessage", Type = FieldType.Checkbox, HelpText = "NotificationsTwitterSettingsDirectMessageHelpText")] public bool DirectMessage { get; set; } - [FieldDefinition(6, Label = "Connect to Twitter", Type = FieldType.OAuth)] + [FieldDefinition(6, Label = "NotificationsTwitterSettingsConnectToTwitter", Type = FieldType.OAuth)] public string AuthorizeNotification { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs b/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs index 89929a522..5115ef92f 100755 --- a/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs @@ -2,6 +2,7 @@ using FluentValidation.Results; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Localization; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies; using NzbDrone.Core.Validation; @@ -12,8 +13,8 @@ public class Webhook : WebhookBase { private readonly IWebhookProxy _proxy; - public Webhook(IWebhookProxy proxy, IConfigFileProvider configFileProvider, IConfigService configService) - : base(configFileProvider, configService) + public Webhook(IWebhookProxy proxy, IConfigFileProvider configFileProvider, IConfigService configService, ILocalizationService localizationService) + : base(configFileProvider, configService, localizationService) { _proxy = proxy; } @@ -89,7 +90,7 @@ private ValidationFailure SendWebhookTest() } catch (WebhookException ex) { - return new NzbDroneValidationFailure("Url", ex.Message); + return new NzbDroneValidationFailure("Url", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs index bf2b019e8..4f23b177f 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Localization; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies; using NzbDrone.Core.ThingiProvider; @@ -13,12 +14,13 @@ public abstract class WebhookBase : NotificationBase { private readonly IConfigFileProvider _configFileProvider; private readonly IConfigService _configService; + protected readonly ILocalizationService _localizationService; - protected WebhookBase(IConfigFileProvider configFileProvider, IConfigService configService) - : base() + protected WebhookBase(IConfigFileProvider configFileProvider, IConfigService configService, ILocalizationService localizationService) { _configFileProvider = configFileProvider; _configService = configService; + _localizationService = localizationService; } protected WebhookGrabPayload BuildOnGrabPayload(GrabMessage message) diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookSettings.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookSettings.cs index dd850e5d5..1ee1c7e54 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookSettings.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookSettings.cs @@ -23,10 +23,10 @@ public WebhookSettings() Method = Convert.ToInt32(WebhookMethod.POST); } - [FieldDefinition(0, Label = "URL", Type = FieldType.Url)] + [FieldDefinition(0, Label = "NotificationsSettingsWebhookUrl", Type = FieldType.Url)] public string Url { get; set; } - [FieldDefinition(1, Label = "Method", Type = FieldType.Select, SelectOptions = typeof(WebhookMethod), HelpText = "Which HTTP method to use submit to the Webservice")] + [FieldDefinition(1, Label = "NotificationsSettingsWebhookMethod", Type = FieldType.Select, SelectOptions = typeof(WebhookMethod), HelpText = "NotificationsSettingsWebhookMethodHelpText")] public int Method { get; set; } [FieldDefinition(2, Label = "Username", Privacy = PrivacyLevel.UserName)] diff --git a/src/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs b/src/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs index da3ebeb03..56092c92e 100644 --- a/src/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs +++ b/src/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs @@ -1,7 +1,9 @@ using System; +using System.Collections.Generic; using System.Linq; using FluentValidation.Results; using NLog; +using NzbDrone.Core.Localization; using NzbDrone.Core.Movies; namespace NzbDrone.Core.Notifications.Xbmc @@ -17,12 +19,13 @@ public interface IXbmcService public class XbmcService : IXbmcService { private readonly IXbmcJsonApiProxy _proxy; + private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public XbmcService(IXbmcJsonApiProxy proxy, - Logger logger) + public XbmcService(IXbmcJsonApiProxy proxy, ILocalizationService localizationService, Logger logger) { _proxy = proxy; + _localizationService = localizationService; _logger = logger; } @@ -128,7 +131,7 @@ public ValidationFailure Test(XbmcSettings settings, string message) catch (Exception ex) { _logger.Error(ex, "Unable to send test message"); - return new ValidationFailure("Host", "Unable to send test message"); + return new ValidationFailure("Host", _localizationService.GetLocalizedString("NotificationsValidationUnableToSendTestMessage", new Dictionary { { "exceptionMessage", ex.Message } })); } return null; diff --git a/src/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs b/src/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs index 9fd4010cc..94652a587 100644 --- a/src/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs +++ b/src/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs @@ -33,7 +33,8 @@ public XbmcSettings() [FieldDefinition(1, Label = "Port")] public int Port { get; set; } - [FieldDefinition(2, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Connect to Kodi over HTTPS instead of HTTP")] + [FieldDefinition(2, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "NotificationsSettingsUseSslHelpText")] + [FieldToken(TokenField.HelpText, "UseSsl", "serviceName", "Kodi")] public bool UseSsl { get; set; } [FieldDefinition(3, Label = "Username", Privacy = PrivacyLevel.UserName)] @@ -43,19 +44,19 @@ public XbmcSettings() public string Password { get; set; } [DefaultValue(5)] - [FieldDefinition(5, Label = "Display Time", HelpText = "How long the notification will be displayed for (In seconds)")] + [FieldDefinition(5, Label = "NotificationsKodiSettingsDisplayTime", HelpText = "NotificationsKodiSettingsDisplayTimeHelpText")] public int DisplayTime { get; set; } - [FieldDefinition(6, Label = "GUI Notification", Type = FieldType.Checkbox)] + [FieldDefinition(6, Label = "NotificationsKodiSettingsGuiNotification", Type = FieldType.Checkbox)] public bool Notify { get; set; } - [FieldDefinition(7, Label = "Update Library", HelpText = "Update Library on Import & Rename?", Type = FieldType.Checkbox)] + [FieldDefinition(7, Label = "NotificationsSettingsUpdateLibrary", HelpText = "NotificationsKodiSettingsUpdateLibraryHelpText", Type = FieldType.Checkbox)] public bool UpdateLibrary { get; set; } - [FieldDefinition(8, Label = "Clean Library", HelpText = "Clean Library after update?", Type = FieldType.Checkbox)] + [FieldDefinition(8, Label = "NotificationsKodiSettingsCleanLibrary", HelpText = "NotificationsKodiSettingsCleanLibraryHelpText", Type = FieldType.Checkbox)] public bool CleanLibrary { get; set; } - [FieldDefinition(9, Label = "Always Update", HelpText = "Update Library even when a video is playing?", Type = FieldType.Checkbox)] + [FieldDefinition(9, Label = "NotificationsKodiSettingAlwaysUpdate", HelpText = "NotificationsKodiSettingAlwaysUpdateHelpText", Type = FieldType.Checkbox)] public bool AlwaysUpdate { get; set; } [JsonIgnore]