From d5be87992df0c176335562a5ae1985e466c67f8b Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Fri, 2 Dec 2022 12:12:46 +0100 Subject: [PATCH] feat: Implement /translate endpoint --- .../Provider/DataSourceFacade+Translate.swift | 16 ++++++- .../API/APIService+Status+Translate.swift | 34 +++++++++++++ .../API/Mastodon+API+Statuses+Translate.swift | 48 +++++++++++++++++++ .../Entity/Mastodon+Entity+Translation.swift | 22 +++++++++ 4 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonCore/Service/API/APIService+Status+Translate.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+Translate.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Translation.swift diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift index 61e836ed2..f2d439cf6 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift @@ -18,7 +18,19 @@ extension DataSourceFacade { let selectionFeedbackGenerator = await UISelectionFeedbackGenerator() await selectionFeedbackGenerator.selectionChanged() - let status = status.object(in: provider.context.managedObjectContext) - status?.translatedContent = "LOREM IPSUM TRANSLATED TEXT" + guard + let status = status.object(in: provider.context.managedObjectContext) + else { + return + } + + let result = try await provider.context + .apiService + .translateStatus( + statusID: status.id, + authenticationBox: provider.authContext.mastodonAuthenticationBox + ).value + + status.translatedContent = result.content } } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Status+Translate.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Status+Translate.swift new file mode 100644 index 000000000..a802d6489 --- /dev/null +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Status+Translate.swift @@ -0,0 +1,34 @@ +// +// APIService+Status+Translate.swift +// Mastodon +// +// Created by Marcus Kida on 02.12.2022. +// + +import Foundation +import Combine +import CoreData +import CoreDataStack +import CommonOSLog +import MastodonSDK + +extension APIService { + + public func translateStatus( + statusID: Mastodon.Entity.Status.ID, + authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content { + let domain = authenticationBox.domain + let authorization = authenticationBox.userAuthorization + + let response = try await Mastodon.API.Statuses.translate( + session: session, + domain: domain, + statusID: statusID, + authorization: authorization + ).singleOutput() + + return response + } + +} diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+Translate.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+Translate.swift new file mode 100644 index 000000000..c3e790b67 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+Translate.swift @@ -0,0 +1,48 @@ +// +// Mastodon+API+Statuses+Translate.swift +// +// +// Created by Marcus Kida on 02.12.2022. +// + +import Foundation +import Combine + +extension Mastodon.API.Statuses { + + private static func translateEndpointURL(domain: String, statusID: Mastodon.Entity.Status.ID) -> URL { + return Mastodon.API.endpointURL(domain: domain) + .appendingPathComponent("statuses") + .appendingPathComponent(statusID) + .appendingPathComponent("translate") + } + + /// Translate Status + /// + /// Translate a given Status. + /// + /// - Parameters: + /// - session: `URLSession` + /// - domain: Mastodon instance domain. e.g. "example.com" + /// - statusID: id for status + /// - authorization: User token. Could be nil if status is public + /// - Returns: `AnyPublisher` contains `Status` nested in the response + public static func translate( + session: URLSession, + domain: String, + statusID: Mastodon.Entity.Status.ID, + authorization: Mastodon.API.OAuth.Authorization? + ) -> AnyPublisher, Error> { + let request = Mastodon.API.post( + url: translateEndpointURL(domain: domain, statusID: statusID), + query: nil, + authorization: authorization + ) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value = try Mastodon.API.decode(type: Mastodon.Entity.Translation.self, from: data, response: response) + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Translation.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Translation.swift new file mode 100644 index 000000000..b8993de9e --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Translation.swift @@ -0,0 +1,22 @@ +// +// File.swift +// +// +// Created by Marcus Kida on 02.12.22. +// + +import Foundation + +extension Mastodon.Entity { + public struct Translation: Codable { + public let content: String? + public let sourceLanguage: String? + public let provider: String? + + enum CodingKeys: String, CodingKey { + case content + case sourceLanguage = "detected_source_language" + case provider + } + } +}