diff --git a/libgnucash/app-utils/gnc-quotes.cpp b/libgnucash/app-utils/gnc-quotes.cpp index 83c4ab785ad..2812297e347 100644 --- a/libgnucash/app-utils/gnc-quotes.cpp +++ b/libgnucash/app-utils/gnc-quotes.cpp @@ -63,7 +63,9 @@ static const QofLogModule log_module = "gnc.price-quotes"; static const char* av_api_env = "ALPHAVANTAGE_API_KEY"; +static const char* av_api_key = "alphavantage-api-key"; static const char* yh_api_env = "FINANCEAPI_API_KEY"; +static const char* yh_api_key = "yhfinance-api-key"; namespace bl = boost::locale; namespace bp = boost::process; @@ -131,8 +133,7 @@ class GncFQQuoteSource final : public GncQuoteSource std::string c_fq_wrapper; std::string m_version; StrVec m_sources; - std::string m_av_api_key; - std::string m_yh_api_key; + bp::environment m_env; public: GncFQQuoteSource(); ~GncFQQuoteSource() = default; @@ -141,7 +142,7 @@ class GncFQQuoteSource final : public GncQuoteSource QuoteResult get_quotes(const std::string&) const override; private: QuoteResult run_cmd (const StrVec& args, const std::string& json_string) const; - + void set_api_key(const char* api_pref, const char* api_env); }; static void show_quotes(const bpt::ptree& pt, const StrVec& commodities, bool verbose); @@ -150,28 +151,9 @@ static std::string parse_quotesource_error(const std::string& line); static const std::string empty_string{}; -static inline std::string -get_api_key(const char* prefskey, const char* envvar) -{ - std::string keyval{}; - auto key = gnc_prefs_get_string ("general.finance-quote", prefskey); - if (!(key && *key)) - { - g_free (key); - key = g_strdup(getenv(envvar)); - } - - if (key) - { - keyval = std::string(key); - g_free (key); - } - return keyval; -} - GncFQQuoteSource::GncFQQuoteSource() : c_cmd{bp::search_path("perl")}, -m_version{}, m_sources{}, m_av_api_key{}, m_yh_api_key{} +m_version{}, m_sources{}, m_env{boost::this_process::environment()} { char *bindir = gnc_path_get_bindir(); c_fq_wrapper = std::string(bindir) + "/finance-quote-wrapper"; @@ -203,10 +185,8 @@ m_version{}, m_sources{}, m_av_api_key{}, m_yh_api_key{} m_sources = std::move(sources); std::sort (m_sources.begin(), m_sources.end()); - m_av_api_key = get_api_key("alphavantage-api-key", av_api_env); - if (m_av_api_key.empty()) - PWARN("No Alpha Vantage API key set, currency quotes and other AlphaVantage based quotes won't work."); - m_yh_api_key = get_api_key("yhfinance-api-key", yh_api_env); + set_api_key(av_api_key, av_api_env); + set_api_key(yh_api_key, yh_api_env); } QuoteResult @@ -228,13 +208,7 @@ GncFQQuoteSource::run_cmd (const StrVec& args, const std::string& json_string) c boost::asio::io_service svc; auto input_buf = bp::buffer (json_string); - auto curr_env{boost::this_process::environment()}; - bp::environment new_env{curr_env}; bp::child process; - if (!m_av_api_key.empty()) - new_env[av_api_env] = m_av_api_key; - if (!m_yh_api_key.empty()) - new_env[yh_api_env] = m_yh_api_key; process = bp::child(c_cmd, args, bp::std_out > out_buf, bp::std_err > err_buf, @@ -242,7 +216,7 @@ GncFQQuoteSource::run_cmd (const StrVec& args, const std::string& json_string) c #ifdef BOOST_WINDOWS_API bp::windows::create_no_window, #endif - new_env, + m_env, svc); svc.run(); @@ -281,6 +255,27 @@ GncFQQuoteSource::run_cmd (const StrVec& args, const std::string& json_string) c return QuoteResult (cmd_result, std::move(out_vec), std::move(err_vec)); } +void +GncFQQuoteSource::set_api_key(const char* api_key, const char* api_env) +{ + if (m_env.find(api_env) == m_env.end()) + { + auto key = gnc_prefs_get_string("general.finance-quote", api_key); + if (key && *key) + { + m_env[api_env] = key; + g_free(key); + } + else + { + if (api_key == av_api_key) + PWARN("No Alpha Vantage API key set, currency quotes and other " + "AlphaVantage based quotes won't work."); + g_free(key); + } + } +} + /* GncQuotes implementation */ GncQuotesImpl::GncQuotesImpl() : m_quotesource{new GncFQQuoteSource}, m_sources{}, m_failures{}, @@ -1040,9 +1035,7 @@ GncQuotes::GncQuotes () try { m_impl = std::make_unique(); - } - catch (const GncQuoteSourceError& err) - { + } catch (const GncQuoteSourceError &err) { throw(GncQuoteException(err.what())); } }