gnc-quotes.cpp (gnucash-5.0.tar.bz2) | : | gnc-quotes.cpp (gnucash-5.1.tar.bz2) | ||
---|---|---|---|---|
skipping to change at line 24 | skipping to change at line 24 | |||
* * | * * | |||
* You should have received a copy of the GNU General Public License* | * You should have received a copy of the GNU General Public License* | |||
* along with this program; if not, contact: * | * along with this program; if not, contact: * | |||
* * | * * | |||
* Free Software Foundation Voice: +1-617-542-5942 * | * Free Software Foundation Voice: +1-617-542-5942 * | |||
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * | * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * | |||
* Boston, MA 02110-1301, USA gnu@gnu.org * | * Boston, MA 02110-1301, USA gnu@gnu.org * | |||
\ *******************************************************************/ | \ *******************************************************************/ | |||
#include <config.h> | #include <config.h> | |||
#include <qoflog.h> | ||||
#include <algorithm> | #include <algorithm> | |||
#include <stdexcept> | #include <stdexcept> | |||
#include <vector> | #include <vector> | |||
#include <string> | #include <string> | |||
#include <iostream> | #include <iostream> | |||
#include <boost/version.hpp> | #include <boost/version.hpp> | |||
#if BOOST_VERSION < 107600 | #if BOOST_VERSION < 107600 | |||
// json_parser uses a deprecated version of bind.hpp | // json_parser uses a deprecated version of bind.hpp | |||
#define BOOST_BIND_GLOBAL_PLACEHOLDERS | #define BOOST_BIND_GLOBAL_PLACEHOLDERS | |||
skipping to change at line 124 | skipping to change at line 125 | |||
std::unique_ptr<GncQuoteSource> m_quotesource; | std::unique_ptr<GncQuoteSource> m_quotesource; | |||
QuoteSources m_sources; | QuoteSources m_sources; | |||
QFVec m_failures; | QFVec m_failures; | |||
QofBook *m_book; | QofBook *m_book; | |||
gnc_commodity *m_dflt_curr; | gnc_commodity *m_dflt_curr; | |||
}; | }; | |||
class GncFQQuoteSource final : public GncQuoteSource | class GncFQQuoteSource final : public GncQuoteSource | |||
{ | { | |||
const bfs::path c_cmd; | const bfs::path c_cmd; | |||
const std::string c_fq_wrapper; | std::string c_fq_wrapper; | |||
std::string m_version; | std::string m_version; | |||
StrVec m_sources; | StrVec m_sources; | |||
std::string m_api_key; | std::string m_api_key; | |||
public: | public: | |||
GncFQQuoteSource(); | GncFQQuoteSource(); | |||
~GncFQQuoteSource() = default; | ~GncFQQuoteSource() = default; | |||
const std::string& get_version() const noexcept override { return m_version; } | const std::string& get_version() const noexcept override { return m_version; } | |||
const StrVec& get_sources() const noexcept override { return m_sources; } | const StrVec& get_sources() const noexcept override { return m_sources; } | |||
QuoteResult get_quotes(const std::string&) const override; | QuoteResult get_quotes(const std::string&) const override; | |||
private: | private: | |||
skipping to change at line 147 | skipping to change at line 148 | |||
}; | }; | |||
static void show_quotes(const bpt::ptree& pt, const StrVec& commodities, bool ve rbose); | static void show_quotes(const bpt::ptree& pt, const StrVec& commodities, bool ve rbose); | |||
static void show_currency_quotes(const bpt::ptree& pt, const StrVec& commodities , bool verbose); | static void show_currency_quotes(const bpt::ptree& pt, const StrVec& commodities , bool verbose); | |||
static std::string parse_quotesource_error(const std::string& line); | static std::string parse_quotesource_error(const std::string& line); | |||
static const std::string empty_string{}; | static const std::string empty_string{}; | |||
GncFQQuoteSource::GncFQQuoteSource() : | GncFQQuoteSource::GncFQQuoteSource() : | |||
c_cmd{bp::search_path("perl")}, | c_cmd{bp::search_path("perl")}, | |||
c_fq_wrapper{std::string(gnc_path_get_bindir()) + "/finance-quote-wrapper"}, | ||||
m_version{}, m_sources{}, m_api_key{} | m_version{}, m_sources{}, m_api_key{} | |||
{ | { | |||
char *bindir = gnc_path_get_bindir(); | ||||
c_fq_wrapper = std::string(bindir) + "/finance-quote-wrapper"; | ||||
g_free(bindir); | ||||
StrVec args{"-w", c_fq_wrapper, "-v"}; | StrVec args{"-w", c_fq_wrapper, "-v"}; | |||
const std::string empty_string; | ||||
auto [rv, sources, errors] = run_cmd(args, empty_string); | auto [rv, sources, errors] = run_cmd(args, empty_string); | |||
if (rv) | if (rv) | |||
{ | { | |||
std::string err{bl::translate("Failed to initialize Finance::Quote: ")}; | std::string err{bl::translate("Failed to initialize Finance::Quote: ")}; | |||
for (const auto& err_line : errors) | for (const auto& err_line : errors) | |||
err += err_line.empty() ? "" : err_line + "\n"; | err += err_line.empty() ? "" : err_line + "\n"; | |||
throw(GncQuoteSourceError(err)); | throw(GncQuoteSourceError(err)); | |||
} | } | |||
if (!errors.empty()) | if (!errors.empty()) | |||
{ | { | |||
skipping to change at line 239 | skipping to change at line 241 | |||
process.wait(); | process.wait(); | |||
{ | { | |||
auto raw = out_buf.get(); | auto raw = out_buf.get(); | |||
std::vector<std::string> data; | std::vector<std::string> data; | |||
std::string line; | std::string line; | |||
bio::stream_buffer<bio::array_source> sb(raw.data(), raw.size()); | bio::stream_buffer<bio::array_source> sb(raw.data(), raw.size()); | |||
std::istream is(&sb); | std::istream is(&sb); | |||
while (std::getline(is, line) && !line.empty()) | while (std::getline(is, line) && !line.empty()) | |||
{ | ||||
#ifdef __WIN32 | ||||
if (line.back() == '\r') | ||||
line.pop_back(); | ||||
#endif | ||||
out_vec.push_back (std::move(line)); | out_vec.push_back (std::move(line)); | |||
} | ||||
raw = err_buf.get(); | raw = err_buf.get(); | |||
bio::stream_buffer<bio::array_source> eb(raw.data(), raw.size()); | bio::stream_buffer<bio::array_source> eb(raw.data(), raw.size()); | |||
std::istream es(&eb); | std::istream es(&eb); | |||
while (std::getline(es, line) && !line.empty()) | while (std::getline(es, line) && !line.empty()) | |||
err_vec.push_back (std::move(line)); | err_vec.push_back (std::move(line)); | |||
} | } | |||
cmd_result = process.exit_code(); | cmd_result = process.exit_code(); | |||
} | } | |||
catch (std::exception &e) | catch (std::exception &e) | |||
skipping to change at line 405 | skipping to change at line 412 | |||
{ | { | |||
auto [ns, sym, reason, err] = failure; | auto [ns, sym, reason, err] = failure; | |||
retval += "* " + ns + ":" + sym + " " + | retval += "* " + ns + ":" + sym + " " + | |||
explain(reason, err) + "\n"; | explain(reason, err) + "\n"; | |||
}); | }); | |||
return retval; | return retval; | |||
} | } | |||
/* **** Private function implementations ****/ | /* **** Private function implementations ****/ | |||
using Path = bpt::ptree::path_type; | ||||
static inline Path make_quote_path(const std::string &name_space, | ||||
const std::string &symbol) | ||||
{ | ||||
using Path = bpt::ptree::path_type; | ||||
Path key{name_space, '|'}; | ||||
key /= Path{symbol, '|'}; | ||||
return key; | ||||
}; | ||||
std::string | std::string | |||
GncQuotesImpl::comm_vec_to_json_string (const CommVec& comm_vec) const | GncQuotesImpl::comm_vec_to_json_string(const CommVec &comm_vec) const | |||
{ | { | |||
bpt::ptree pt, pt_child; | bpt::ptree pt, pt_child; | |||
pt.put ("defaultcurrency", gnc_commodity_get_mnemonic (m_dflt_curr)); | pt.put("defaultcurrency", gnc_commodity_get_mnemonic(m_dflt_curr)); | |||
std::for_each (comm_vec.cbegin(), comm_vec.cend(), | std::for_each (comm_vec.cbegin(), comm_vec.cend(), | |||
[this, &pt] (auto comm) | [this, &pt] (auto comm) | |||
{ | { | |||
auto comm_mnemonic = gnc_commodity_get_mnemonic (comm); | auto comm_mnemonic = gnc_commodity_get_mnemonic (comm); | |||
auto comm_ns = std::string("currency"); | auto comm_ns = std::string("currency"); | |||
if (gnc_commodity_is_currency (comm)) | if (gnc_commodity_is_currency (comm)) | |||
{ | { | |||
if (gnc_commodity_equiv(comm, m_dflt_curr) || | if (gnc_commodity_equiv(comm, m_dflt_curr) || | |||
(!comm_mnemonic || (strcmp (comm_mnemonic, "XXX") == 0))) | (!comm_mnemonic || (strcmp(comm_mnemonic, "XXX") == 0))) | |||
return; | return; | |||
} | } | |||
else | else | |||
comm_ns = gnc_quote_source_get_internal_name (gnc_com modity_get_quote_source (comm)); | comm_ns = gnc_quote_source_get_internal_name(gnc_comm odity_get_quote_source(comm)); | |||
auto key = comm_ns + "." + comm_mnemonic; | pt.put (make_quote_path(comm_ns, comm_mnemonic), ""); | |||
pt.put (key, ""); | ||||
} | } | |||
); | ); | |||
std::ostringstream result; | std::ostringstream result; | |||
bpt::write_json(result, pt); | bpt::write_json(result, pt); | |||
return result.str(); | return result.str(); | |||
} | } | |||
static inline std::string | static inline std::string | |||
get_quotes(const std::string& json_str, const std::unique_ptr<GncQuoteSource>& q s) | get_quotes(const std::string& json_str, const std::unique_ptr<GncQuoteSource>& q s) | |||
skipping to change at line 480 | skipping to change at line 496 | |||
if (is_currency) | if (is_currency) | |||
pt.put("defaultcurrency", commodities[0].c_str()); | pt.put("defaultcurrency", commodities[0].c_str()); | |||
else | else | |||
pt.put("defaultcurrency", gnc_commodity_get_mnemonic(m_dflt_curr)); | pt.put("defaultcurrency", gnc_commodity_get_mnemonic(m_dflt_curr)); | |||
std::for_each(is_currency ? ++commodities.cbegin() : commodities.cbegin(), | std::for_each(is_currency ? ++commodities.cbegin() : commodities.cbegin(), | |||
commodities.cend(), | commodities.cend(), | |||
[source, &pt](auto sym) | [source, &pt](auto sym) | |||
{ | { | |||
std::string key{source}; | pt.put(make_quote_path(source, sym), ""); | |||
key += "." + sym; | ||||
pt.put(key, ""); | ||||
}); | }); | |||
std::ostringstream result; | std::ostringstream result; | |||
bpt::write_json(result, pt); | bpt::write_json(result, pt); | |||
auto result_str{result.str()}; | ||||
PINFO("Query JSON: %s\n", result_str.c_str()); | ||||
return get_quotes(result.str(), m_quotesource); | return get_quotes(result.str(), m_quotesource); | |||
} | } | |||
std::string | std::string | |||
GncQuotesImpl::query_fq (const CommVec& comm_vec) | GncQuotesImpl::query_fq (const CommVec& comm_vec) | |||
{ | { | |||
auto json_str{comm_vec_to_json_string(comm_vec)}; | auto json_str{comm_vec_to_json_string(comm_vec)}; | |||
PINFO("Query JSON: %s\n", json_str.c_str()); | ||||
return get_quotes(json_str, m_quotesource); | return get_quotes(json_str, m_quotesource); | |||
} | } | |||
struct PriceParams | struct PriceParams | |||
{ | { | |||
const char* ns; | const char* ns; | |||
const char* mnemonic; | const char* mnemonic; | |||
bool success; | bool success; | |||
std::string type; | std::string type; | |||
boost::optional<std::string> price; | boost::optional<std::string> price; | |||
End of changes. 16 change blocks. | ||||
13 lines changed or deleted | 30 lines changed or added |