+
+ @doc "GET /api/v1/statuses/:id/translations/:language"
+ def translate(%{assigns: %{user: user}} = conn, %{id: id, language: language} = params) do
+ with {:enabled, true} <- {:enabled, Config.get([:translator, :enabled])},
+ %Activity{} = activity <- Activity.get_by_id_with_object(id),
+ {:visible, true} <- {:visible, Visibility.visible_for_user?(activity, user)},
+ translation_module <- Config.get([:translator, :module]),
+ {:ok, detected, translation} <-
+ fetch_or_translate(
+ activity.id,
+ activity.object.data["content"],
+ Map.get(params, :from, nil),
+ language,
+ translation_module
+ ) do
+ json(conn, %{detected_language: detected, text: translation})
+ else
+ {:enabled, false} ->
+ conn
+ |> put_status(:bad_request)
+ |> json(%{"error" => "Translation is not enabled"})
+
+ {:visible, false} ->
+ {:error, :not_found}
+
+ e ->
+ e
+ end
+ end
+
+ defp fetch_or_translate(status_id, text, source_language, target_language, translation_module) do
+ @cachex.fetch!(
+ :translations_cache,
+ "translations:#{status_id}:#{source_language}:#{target_language}",
+ fn _ ->
+ value = translation_module.translate(text, source_language, target_language)
+
+ with {:ok, _, _} <- value do
+ value
+ else
+ _ -> {:ignore, value}
+ end
+ end
+ )
+ end
+
+ defp put_application(params, %{assigns: %{token: %Token{user: %User{} = user} = token}} = _conn) do
+ if user.disclose_client do
+ %{client_name: client_name, website: website} = Repo.preload(token, :app).app
+ Map.put(params, :generator, %{type: "Application", name: client_name, url: website})
+ else
+ Map.put(params, :generator, nil)
+ end
+ end
+
+ defp put_application(params, _), do: Map.put(params, :generator, nil)