1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
#include "stdafx.h"
static CMStringW build_url(const CMStringW &rsURL, const CMStringW &from, const CMStringW &to)
{
CMStringW res = rsURL + L"?q=" + from + L"_" + to + L"&compact=ultra";
if (mir_wstrlen(g_plugin.wszApiKey))
res.AppendFormat(L"&apiKey=%S", (wchar_t*)g_plugin.wszApiKey);
return res;
}
static CMStringW build_url(MCONTACT hContact, const CMStringW &rsURL)
{
CMStringW sFrom = g_plugin.getMStringW(hContact, DB_STR_FROM_ID);
CMStringW sTo = g_plugin.getMStringW(hContact, DB_STR_TO_ID);
return build_url(rsURL, sFrom, sTo);
}
static bool parse_response(const CMStringW &rsJSON, double &dRate)
{
JSONNode root = JSONNode::parse(_T2A(rsJSON));
if (!root)
return false;
dRate = root.at(json_index_t(0)).as_float();
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////
// CCurrencyRatesProviderCurrencyConverter implementation
struct CCurrencyRatesProviderCurrencyConverter : public CCurrencyRatesProviderBase
{
CCurrencyRatesProviderCurrencyConverter()
{}
double Convert(double dAmount, const CCurrencyRate &from, const CCurrencyRate &to) const override
{
CMStringW sFullURL = build_url(GetURL(), from.GetID(), to.GetID());
CHTTPSession http;
if ((true == http.OpenURL(sFullURL))) {
CMStringW sHTML;
if ((true == http.ReadResponce(sHTML))) {
double dResult = 0.0;
if ((true == parse_response(sHTML, dResult)))
return dResult * dAmount;
throw std::runtime_error(Translate("Error occurred during HTML parsing."));
}
else throw std::runtime_error(Translate("Error occurred during site access."));
}
else throw std::runtime_error(Translate("Error occurred during site access."));
return 0.0;
}
private:
void RefreshCurrencyRates(TContacts &anContacts) override
{
CHTTPSession http;
CMStringW sURL = GetURL();
for (TContacts::const_iterator i = anContacts.begin(); i != anContacts.end(); ++i) {
MCONTACT hContact = *i;
CMStringW sFullURL = build_url(hContact, sURL);
if (true == http.OpenURL(sFullURL)) {
CMStringW sHTML;
if (true == http.ReadResponce(sHTML)) {
double dRate = 0.0;
if (true == parse_response(sHTML, dRate)) {
WriteContactRate(hContact, dRate);
continue;
}
}
}
SetContactStatus(hContact, ID_STATUS_NA);
}
}
wchar_t *GetXmlFilename() const override
{
return L"CC.xml";
}
};
/////////////////////////////////////////////////////////////////////////////////////////
// Module entry point
void InitCC()
{
g_apProviders.push(new CCurrencyRatesProviderCurrencyConverter());
}
|