Character conversion relies on the setlocale(LC_TYPE, "") in main(), but maybe there are better ways of doing this.
177 lines
7.9 KiB
C++
177 lines
7.9 KiB
C++
/*
|
|
WordReferenceCLI, a c++ program to access WordReference.com.
|
|
Copyright (C) 2013 King_DuckZ
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "main.hpp"
|
|
#include "WordReference.hpp"
|
|
#include "HttpReader.hpp"
|
|
#include "libjson.h"
|
|
#include <sstream>
|
|
|
|
namespace {
|
|
const char* ApiVersion = "0.8";
|
|
|
|
typedef std::map<std::string, std::string> LanguageMapType;
|
|
const LanguageMapType SupportedLanguages {
|
|
std::pair<std::string, std::string>("ar", "Arabic"),
|
|
std::pair<std::string, std::string>("zh", "Chinese"),
|
|
std::pair<std::string, std::string>("cz", "Czech"),
|
|
std::pair<std::string, std::string>("en", "English"),
|
|
std::pair<std::string, std::string>("fr", "French"),
|
|
std::pair<std::string, std::string>("gr", "Greek"),
|
|
std::pair<std::string, std::string>("it", "Italian"),
|
|
std::pair<std::string, std::string>("ja", "Japanese"),
|
|
std::pair<std::string, std::string>("ko", "Korean"),
|
|
std::pair<std::string, std::string>("pl", "Polish"),
|
|
std::pair<std::string, std::string>("pt", "Portuguese"),
|
|
std::pair<std::string, std::string>("ro", "Romanian"),
|
|
std::pair<std::string, std::string>("es", "Spanish"),
|
|
std::pair<std::string, std::string>("tr", "Turkish")
|
|
};
|
|
|
|
///-------------------------------------------------------------------------
|
|
///-------------------------------------------------------------------------
|
|
JSONNode QueryJSon (HttpReader& parHttp, const std::string& parFrom, const std::string& parTo, const std::string& parKey, const std::wstring& parWord) {
|
|
std::ostringstream oss;
|
|
oss << "http://api.wordreference.com/" << ApiVersion << "/"
|
|
<< parKey << "/json/" << parFrom << parTo << "/" << parHttp.UrlEncode(parWord);
|
|
|
|
std::string jsonResponse(parHttp.GetPage(oss.str()));
|
|
return libjson::parse(libjson::to_json_string(jsonResponse));
|
|
}
|
|
|
|
///-------------------------------------------------------------------------
|
|
///-------------------------------------------------------------------------
|
|
void PrintTranslation (std::wostream& parStream, const JSONNode& parNode) {
|
|
for (JSONNode::const_iterator itTr = parNode.begin(), itTrEND = parNode.end(); itTr != itTrEND; ++itTr) {
|
|
JSONNode::const_iterator originalTerm = itTr->find(json_string(L"OriginalTerm"));
|
|
if (originalTerm != itTr->end()) {
|
|
JSONNode::const_iterator term(originalTerm->find(L"term")),
|
|
sense(originalTerm->find(L"sense"));
|
|
if (term != originalTerm->end() and sense != originalTerm->end()) {
|
|
parStream << originalTerm->find(L"term")->as_string();
|
|
parStream << L": (" << originalTerm->find(L"sense")->as_string() << L")\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} //unnamed namespace
|
|
|
|
///-----------------------------------------------------------------------------
|
|
///-----------------------------------------------------------------------------
|
|
void GetAvailableLanguages (std::vector<const std::string*>& parCodes, std::vector<const std::string*>& parNames) {
|
|
typedef std::vector<std::pair<const std::string*, const std::string*> > SortedListType;
|
|
SortedListType sorted;
|
|
sorted.reserve(SupportedLanguages.size());
|
|
parCodes.reserve(SupportedLanguages.size());
|
|
parNames.reserve(SupportedLanguages.size());
|
|
|
|
for (LanguageMapType::const_iterator itCurr = SupportedLanguages.begin(), itEND = SupportedLanguages.end(); itCurr != itEND; ++itCurr) {
|
|
sorted.push_back(std::make_pair(&itCurr->first, &itCurr->second));
|
|
}
|
|
std::sort(sorted.begin(), sorted.end(), [](const SortedListType::value_type& parA, const SortedListType::value_type& parB) { return *(parA.second) < *(parB.second); });
|
|
for (SortedListType::const_iterator itCurr = sorted.begin(), itEND = sorted.end(); itCurr != itEND; ++itCurr) {
|
|
parCodes.push_back(itCurr->first);
|
|
parNames.push_back(itCurr->second);
|
|
}
|
|
}
|
|
|
|
///-----------------------------------------------------------------------------
|
|
///-----------------------------------------------------------------------------
|
|
ErrBadLanguage::ErrBadLanguage (std::string&& parMessage) :
|
|
std::runtime_error(parMessage)
|
|
{
|
|
}
|
|
|
|
///-----------------------------------------------------------------------------
|
|
///-----------------------------------------------------------------------------
|
|
WordReference::WordReference (const std::string& parFrom, const std::string& parTo, const char* parApiKey) :
|
|
m_httpReader(new HttpReader),
|
|
m_langFrom(parFrom),
|
|
m_langTo(parTo),
|
|
m_apiKey(parApiKey)
|
|
{
|
|
if (SupportedLanguages.find(parFrom) == SupportedLanguages.end()) {
|
|
std::ostringstream oss;
|
|
oss << "Invalid source language: \"" << m_langFrom << "\"";
|
|
throw ErrBadLanguage(oss.str());
|
|
}
|
|
if (SupportedLanguages.find(parTo) == SupportedLanguages.end()) {
|
|
std::ostringstream oss;
|
|
oss << "Invalid destination language: \"" << m_langTo << "\"";
|
|
throw ErrBadLanguage(oss.str());
|
|
}
|
|
}
|
|
|
|
///-----------------------------------------------------------------------------
|
|
///-----------------------------------------------------------------------------
|
|
WordReference::~WordReference() {
|
|
}
|
|
|
|
///-----------------------------------------------------------------------------
|
|
///-----------------------------------------------------------------------------
|
|
const std::string& WordReference::GetLanguageCode (WordReferenceLangDirection parDir) const {
|
|
if (WordRefLangFrom == parDir)
|
|
return m_langFrom;
|
|
else
|
|
return m_langTo;
|
|
}
|
|
|
|
///-----------------------------------------------------------------------------
|
|
///-----------------------------------------------------------------------------
|
|
const std::string& WordReference::GetLanguageName (WordReferenceLangDirection parDir) const {
|
|
return SupportedLanguages.at(GetLanguageCode(parDir));
|
|
}
|
|
|
|
///-----------------------------------------------------------------------------
|
|
///-----------------------------------------------------------------------------
|
|
std::string WordReference::GetApiVersion() {
|
|
return std::string(ApiVersion);
|
|
}
|
|
|
|
///-----------------------------------------------------------------------------
|
|
///-----------------------------------------------------------------------------
|
|
void WordReference::Translate (const std::wstring& parWord, std::wostream& parStream) {
|
|
JSONNode root = QueryJSon(*m_httpReader, m_langFrom, m_langTo, m_apiKey, parWord);
|
|
for (JSONNode::const_iterator itCur = root.begin(), itCurEND = root.end(); itCur != itCurEND; ++itCur) {
|
|
const std::wstring nodeName(libjson::to_std_wstring(itCur->name()));
|
|
if (itCur->type() == JSON_NODE and nodeName.compare(0, 4, L"term") == 0) {
|
|
JSONNode::const_iterator principTranslations(itCur->find(L"PrincipalTranslations"));
|
|
if (principTranslations != itCur->end()) {
|
|
PrintTranslation(parStream, *principTranslations);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
///-----------------------------------------------------------------------------
|
|
///-----------------------------------------------------------------------------
|
|
std::string WordReference::GetHttpLink (const wchar_t* parWord) {
|
|
std::ostringstream oss;
|
|
oss << "http://www.wordreference.com/redirect/translation.aspx?w=";
|
|
oss << m_httpReader->UrlEncode(parWord) << "&dict=" << m_langFrom << m_langTo;
|
|
return oss.str();
|
|
}
|
|
|
|
///-----------------------------------------------------------------------------
|
|
///-----------------------------------------------------------------------------
|
|
std::string WordReference::GetHttpLink (const std::wstring& parWord) {
|
|
std::ostringstream oss;
|
|
oss << "http://www.wordreference.com/redirect/translation.aspx?w=";
|
|
oss << m_httpReader->UrlEncode(parWord) << "&dict=" << m_langFrom << m_langTo;
|
|
return oss.str();
|
|
}
|