commit 957ac1dc03bf6a250fad08f24e323076049a9994
parent a58ca2918a9e319af4f3cdb29818804aa7a68812
Author: Mazin <cm@monstaboyent.com>
Date: Tue, 9 May 2023 22:38:11 -0400
Add translate.nostr.wine to available translation services
Closes: https://github.com/damus-io/damus/pull/1113
Signed-off-by: William Casarin <jb55@jb55.com>
Diffstat:
4 files changed, 53 insertions(+), 0 deletions(-)
diff --git a/damus/Models/TranslationService.swift b/damus/Models/TranslationService.swift
@@ -32,6 +32,7 @@ enum TranslationService: String, CaseIterable, Identifiable, StringCodable {
case libretranslate
case deepl
case nokyctranslate
+ case winetranslate
var model: Model {
switch self {
@@ -43,6 +44,8 @@ enum TranslationService: String, CaseIterable, Identifiable, StringCodable {
return .init(tag: self.rawValue, displayName: NSLocalizedString("DeepL (Proprietary, Higher Accuracy)", comment: "Dropdown option for selecting DeepL as the translation service."))
case .nokyctranslate:
return .init(tag: self.rawValue, displayName: NSLocalizedString("NoKYCTranslate.com (Prepay with BTC)", comment: "Dropdown option for selecting NoKYCTranslate.com as the translation service."))
+ case .winetranslate:
+ return .init(tag: self.rawValue, displayName: NSLocalizedString("translate.nostr.wine (DeepL, Pay with BTC)", comment: "Dropdown option for selecting translate.nostr.wine as the translation service."))
}
}
}
diff --git a/damus/Models/UserSettingsStore.swift b/damus/Models/UserSettingsStore.swift
@@ -244,6 +244,15 @@ class UserSettingsStore: ObservableObject {
internal_nokyctranslate_api_key = newValue == "" ? nil : newValue
}
}
+
+ var winetranslate_api_key: String {
+ get {
+ return internal_winetranslate_api_key ?? ""
+ }
+ set {
+ internal_winetranslate_api_key = newValue == "" ? nil : newValue
+ }
+ }
// These internal keys are necessary because entries in the keychain need to be Optional,
// but the translation view needs non-Optional String in order to use them as Bindings.
@@ -252,6 +261,9 @@ class UserSettingsStore: ObservableObject {
@KeychainStorage(account: "nokyctranslate_apikey")
var internal_nokyctranslate_api_key: String?
+
+ @KeychainStorage(account: "winetranslate_apikey")
+ var internal_winetranslate_api_key: String?
@KeychainStorage(account: "libretranslate_apikey")
var internal_libretranslate_api_key: String?
@@ -269,6 +281,8 @@ class UserSettingsStore: ObservableObject {
return internal_deepl_api_key != nil
case .nokyctranslate:
return internal_nokyctranslate_api_key != nil
+ case .winetranslate:
+ return internal_winetranslate_api_key != nil
}
}
}
diff --git a/damus/Util/Translator.swift b/damus/Util/Translator.swift
@@ -26,6 +26,8 @@ public struct Translator {
return try await translateWithLibreTranslate(text, from: sourceLanguage, to: targetLanguage)
case .nokyctranslate:
return try await translateWithNoKYCTranslate(text, from: sourceLanguage, to: targetLanguage)
+ case .winetranslate:
+ return try await translateWithWineTranslate(text, from: sourceLanguage, to: targetLanguage)
case .deepl:
return try await translateWithDeepL(text, from: sourceLanguage, to: targetLanguage)
case .none:
@@ -111,6 +113,29 @@ public struct Translator {
return response.translatedText
}
+ private func translateWithWineTranslate(_ text: String, from sourceLanguage: String, to targetLanguage: String) async throws -> String? {
+ let url = try makeURL("https://translate.nostr.wine", path: "/translate")
+
+ var request = URLRequest(url: url)
+ request.httpMethod = "POST"
+ request.setValue("application/json", forHTTPHeaderField: "Content-Type")
+
+ struct RequestBody: Encodable {
+ let q: String
+ let source: String
+ let target: String
+ let api_key: String?
+ }
+ let body = RequestBody(q: text, source: sourceLanguage, target: targetLanguage, api_key: userSettingsStore.winetranslate_api_key)
+ request.httpBody = try encoder.encode(body)
+
+ struct Response: Decodable {
+ let translatedText: String
+ }
+ let response: Response = try await decodedData(for: request)
+ return response.translatedText
+ }
+
private func makeURL(_ baseUrl: String, path: String) throws -> URL {
guard var components = URLComponents(string: baseUrl) else {
throw URLError(.badURL)
diff --git a/damus/Views/Settings/TranslationSettingsView.swift b/damus/Views/Settings/TranslationSettingsView.swift
@@ -73,6 +73,17 @@ struct TranslationSettingsView: View {
Link(NSLocalizedString("Get API Key with BTC/Lightning", comment: "Button to navigate to nokyctranslate website to get a translation API key."), destination: URL(string: "https://nokyctranslate.com")!)
}
}
+
+ if settings.translation_service == .winetranslate {
+ SecureField(NSLocalizedString("API Key (required)", comment: "Prompt for required entry of API Key to use translation server."), text: $settings.winetranslate_api_key)
+ .disableAutocorrection(true)
+ .disabled(settings.translation_service != .winetranslate)
+ .autocapitalization(UITextAutocapitalizationType.none)
+
+ if settings.winetranslate_api_key == "" {
+ Link(NSLocalizedString("Get API Key with BTC/Lightning", comment: "Button to navigate to translate.nostr.wine to get a translation API key."), destination: URL(string: "https://translate.nostr.wine")!)
+ }
+ }
if settings.translation_service != .none {
Toggle(NSLocalizedString("Automatically translate notes", comment: "Toggle to automatically translate notes."), isOn: $settings.auto_translate)