1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <linguistic/translate.hxx>
11 #include <sal/log.hxx>
12 #include <curl/curl.h>
13 #include <rtl/string.h>
14 #include <boost/property_tree/ptree.hpp>
15 #include <boost/property_tree/json_parser.hpp>
16 #include <systools/curlinit.hxx>
17 #include <vcl/htmltransferable.hxx>
18 #include <tools/long.hxx>
22 OString
Translate(const OString
& rTargetLang
, const OString
& rAPIUrl
, const OString
& rAuthKey
,
25 constexpr tools::Long CURL_TIMEOUT
= 10L;
27 std::unique_ptr
<CURL
, std::function
<void(CURL
*)>> curl(curl_easy_init(),
28 [](CURL
* p
) { curl_easy_cleanup(p
); });
30 ::InitCurl_easy(curl
.get());
32 (void)curl_easy_setopt(curl
.get(), CURLOPT_URL
, rAPIUrl
.getStr());
33 (void)curl_easy_setopt(curl
.get(), CURLOPT_FAILONERROR
, 1L);
34 (void)curl_easy_setopt(curl
.get(), CURLOPT_TIMEOUT
, CURL_TIMEOUT
);
36 std::string response_body
;
37 (void)curl_easy_setopt(curl
.get(), CURLOPT_WRITEFUNCTION
,
38 +[](void* buffer
, size_t size
, size_t nmemb
, void* userp
) -> size_t {
41 std::string
* response
= static_cast<std::string
*>(userp
);
42 size_t real_size
= size
* nmemb
;
43 response
->append(static_cast<char*>(buffer
), real_size
);
46 (void)curl_easy_setopt(curl
.get(), CURLOPT_WRITEDATA
, static_cast<void*>(&response_body
));
47 OString
aLang(curl_easy_escape(curl
.get(), rTargetLang
.getStr(), rTargetLang
.getLength()));
48 OString
aAuthKey(curl_easy_escape(curl
.get(), rAuthKey
.getStr(), rAuthKey
.getLength()));
49 OString
aData(curl_easy_escape(curl
.get(), rData
.getStr(), rData
.getLength()));
50 OString
aPostData("auth_key=" + aAuthKey
+ "&target_lang=" + aLang
+ "&text=" + aData
);
52 (void)curl_easy_setopt(curl
.get(), CURLOPT_POSTFIELDS
, aPostData
.getStr());
53 CURLcode cc
= curl_easy_perform(curl
.get());
56 SAL_WARN("linguistic",
57 "Translate: CURL perform returned with error: " << static_cast<sal_Int32
>(cc
));
60 tools::Long nStatusCode
;
61 curl_easy_getinfo(curl
.get(), CURLINFO_RESPONSE_CODE
, &nStatusCode
);
62 if (nStatusCode
!= 200)
64 SAL_WARN("linguistic",
65 "Translate: CURL request returned with status code: " << nStatusCode
);
69 boost::property_tree::ptree root
;
70 std::stringstream
aStream(response_body
.data());
71 boost::property_tree::read_json(aStream
, root
);
72 boost::property_tree::ptree
& translations
= root
.get_child("translations");
73 size_t size
= translations
.size();
76 SAL_WARN("linguistic", "Translate: API did not return any translations");
79 const boost::property_tree::ptree
& translation
= translations
.begin()->second
;
80 const std::string text
= translation
.get
<std::string
>("text");
85 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */