ja achei aki, eles usam umas 4 APIs para traduzir:

//

// Translator.swift

// damus

//

// Created by Terry Yiu on 2/4/23.

//

import Foundation

#if canImport(FoundationNetworking)

import FoundationNetworking

#endif

public struct Translator {

private let userSettingsStore: UserSettingsStore

private let purple: DamusPurple

private let session = URLSession.shared

private let encoder = JSONEncoder()

private let decoder = JSONDecoder()

init(_ userSettingsStore: UserSettingsStore, purple: DamusPurple) {

self.userSettingsStore = userSettingsStore

self.purple = purple

}

public func translate(_ text: String, from sourceLanguage: String, to targetLanguage: String) async throws -> String? {

// Do not attempt to translate if the source and target languages are the same.

guard sourceLanguage != targetLanguage else {

return nil

}

switch userSettingsStore.translation_service {

case .purple:

return try await translateWithPurple(text, from: sourceLanguage, to: targetLanguage)

case .libretranslate:

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:

return nil

}

}

private func translateWithLibreTranslate(_ text: String, from sourceLanguage: String, to targetLanguage: String) async throws -> String? {

let url = try makeURL(userSettingsStore.libretranslate_url, 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.libretranslate_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 translateWithDeepL(_ text: String, from sourceLanguage: String, to targetLanguage: String) async throws -> String? {

if userSettingsStore.deepl_api_key == "" {

return nil

}

let url = try makeURL(userSettingsStore.deepl_plan.model.url, path: "/v2/translate")

var request = URLRequest(url: url)

request.httpMethod = "POST"

request.setValue("application/json", forHTTPHeaderField: "Content-Type")

request.setValue("DeepL-Auth-Key \(userSettingsStore.deepl_api_key)", forHTTPHeaderField: "Authorization")

struct RequestBody: Encodable {

let text: [String]

let source_lang: String

let target_lang: String

}

let body = RequestBody(text: [text], source_lang: sourceLanguage.uppercased(), target_lang: targetLanguage.uppercased())

request.httpBody = try encoder.encode(body)

struct Response: Decodable {

let translations: [DeepLTranslations]

}

struct DeepLTranslations: Decodable {

let detected_source_language: String

let text: String

}

let response: Response = try await decodedData(for: request)

return response.translations.map { $0.text }.joined(separator: " ")

}

private func translateWithPurple(_ text: String, from sourceLanguage: String, to targetLanguage: String) async throws -> String? {

return try await self.purple.translate(text: text, source: sourceLanguage, target: targetLanguage)

}

private func translateWithNoKYCTranslate(_ text: String, from sourceLanguage: String, to targetLanguage: String) async throws -> String? {

let url = try makeURL("https://translate.nokyctranslate.com", 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.nokyctranslate_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 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)

}

components.path = path

guard let url = components.url else {

throw URLError(.badURL)

}

return url

}

private func decodedData(for request: URLRequest) async throws -> Output {

let data = try await session.data(for: request)

let result = try decoder.decode(Output.self, from: data)

return result

}

}

private extension URLSession {

func data(for request: URLRequest) async throws -> Data {

var task: URLSessionDataTask?

let onCancel = { task?.cancel() }

return try await withTaskCancellationHandler(

operation: {

try await withCheckedThrowingContinuation { continuation in

task = dataTask(with: request) { data, _, error in

guard let data = data else {

let error = error ?? URLError(.badServerResponse)

return continuation.resume(throwing: error)

}

continuation.resume(returning: data)

}

task?.resume()

}

},

onCancel: { onCancel() }

)

}

}

Reply to this note

Please Login to reply.

Discussion

Serviços e APIs de tradução no Damus:

[Libretranslate](https://libretranslate.com/) - [[código]](https://github.com/LibreTranslate/LibreTranslate)

Winetranslate - …

[DeepL](https://www.deepl.com/) - [[código]](https://github.com/DeepLcom)

Nokyctranslate - Acabou… [[código]](https://github.com/symbsrcool/nokyctranslate)

O deepl tem limite curto, o libretranslate não é semple que funciona.

A api do google é muito melhor!

A minha ideia é que tivesse vários deles disponíveis no client, mas uns deles pagos, justamente para ter limites maiores e que fosse diretamente pago com zap.

E que esse mecanismo de zap também estivesse disponível para os serviços de upload de arquivos. Já que todos limitam até certo ponto.