IceCubesApp/Packages/Network/Sources/Network/DeepLClient.swift
Paul Schuetz da0b92e13d
Allow translation of an account bio/note (#1276)
The bio (note) of an account can now be translated via DeepL. If the user has
put in his own DeepL API key, that is used, otherwise, the standard one is
used. See #1267

Signed-off-by: Paul Schuetz <pa.schuetz@web.de>
2023-03-19 16:18:13 +01:00

74 lines
2.3 KiB
Swift

import Foundation
import Models
public struct DeepLClient {
public enum DeepLError: Error {
case notFound
}
private var deeplUserAPIKey: String?
private var deeplUserAPIFree: Bool
private var endpoint: String {
"https://api\(deeplUserAPIFree && (deeplUserAPIKey != nil) ? "-free" : "").deepl.com/v2/translate"
}
private var APIKey: String {
if let deeplUserAPIKey {
return deeplUserAPIKey
}
if let path = Bundle.main.path(forResource: "Secret", ofType: "plist") {
let secret = NSDictionary(contentsOfFile: path)
return secret?["DEEPL_SECRET"] as? String ?? ""
}
return ""
}
private var authorizationHeaderValue: String {
"DeepL-Auth-Key \(APIKey)"
}
public struct Response: Decodable {
public struct Translation: Decodable {
public let detectedSourceLanguage: String
public let text: String
}
public let translations: [Translation]
}
private var decoder: JSONDecoder {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
return decoder
}
public init(userAPIKey: String?, userAPIFree: Bool) {
deeplUserAPIKey = userAPIKey
deeplUserAPIFree = userAPIFree
}
public func request(target: String, text: String) async throws -> Translation {
do {
var components = URLComponents(string: endpoint)!
var queryItems: [URLQueryItem] = []
queryItems.append(.init(name: "text", value: text))
queryItems.append(.init(name: "target_lang", value: target.uppercased()))
components.queryItems = queryItems
var request = URLRequest(url: components.url!)
request.httpMethod = "POST"
request.setValue(authorizationHeaderValue, forHTTPHeaderField: "Authorization")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let (result, _) = try await URLSession.shared.data(for: request)
let response = try decoder.decode(Response.self, from: result)
if let translation = response.translations.first {
return .init(content: translation.text.removingPercentEncoding ?? "",
detectedSourceLanguage: translation.detectedSourceLanguage,
provider: "DeepL.com")
}
throw DeepLError.notFound
} catch {
throw error
}
}
}