26 #include <guile-mappings.h> 32 #include "gnucash-commands.hpp" 33 #include "gnucash-core-app.hpp" 36 #include <gnc-engine-guile.h> 39 #include <gnc-session.h> 42 #include <boost/locale.hpp> 46 #include <gnc-report.h> 47 #include <gnc-quotes.hpp> 49 namespace bl = boost::locale;
51 static std::string empty_string{};
54 static QofLogModule log_module = GNC_MOD_GUI;
57 cleanup_and_exit_with_failure (QofSession *session)
62 if (error != ERR_BACKEND_NO_ERR)
65 PERR (
"File is locked, won't open.");
67 PERR (
"Session Error: %s\n",
68 qof_session_get_error_message (session));
70 qof_session_destroy (session);
76 static void gnc_shutdown_cli (
int exit_status)
78 gnc_hook_run (HOOK_SHUTDOWN, NULL);
85 scm_cleanup_and_exit_with_failure (QofSession *session)
87 cleanup_and_exit_with_failure (session);
92 report_session_percentage (
const char *message,
double percent)
94 static double previous = 0.0;
95 if ((percent - previous) < 5.0)
97 PINFO (
"\r%3.0f%% complete...", percent);
107 const std::string& file_to_load;
108 const std::string& run_report;
109 const std::string& export_type;
110 const std::string& output_file;
114 write_report_file (
const char *html,
const char* file)
116 if (!file || !html || !*html)
return;
117 auto ofs{gnc_open_filestream(file)};
120 std::cerr <<
"Failed to open file " << file <<
" for writing\n";
123 ofs << html << std::endl;
128 scm_run_report (
void *data,
129 [[maybe_unused]]
int argc, [[maybe_unused]]
char **argv)
133 scm_c_eval_string(
"(debug-set! stack 200000)");
134 scm_c_use_module (
"gnucash utilities");
135 scm_c_use_module (
"gnucash app-utils");
136 scm_c_use_module (
"gnucash reports");
139 Gnucash::gnc_load_scm_config ([](
const gchar *msg){
PINFO (
"%s", msg); });
143 auto datafile = args->file_to_load.c_str();
144 auto check_report_cmd = scm_c_eval_string (
"gnc:cmdline-check-report");
145 auto get_report_cmd = scm_c_eval_string (
"gnc:cmdline-get-report-id");
146 auto run_export_cmd = scm_c_eval_string (
"gnc:cmdline-template-export");
154 auto report = scm_from_locale_string (args->run_report.c_str());
155 auto type = !args->export_type.empty() ?
156 scm_from_locale_string (args->export_type.c_str()) : SCM_BOOL_F;
158 if (scm_is_false (scm_call_2 (check_report_cmd, report, type)))
159 scm_cleanup_and_exit_with_failure (
nullptr);
161 PINFO (
"Loading datafile %s...\n", datafile);
163 auto session = gnc_get_current_session ();
165 scm_cleanup_and_exit_with_failure (session);
169 scm_cleanup_and_exit_with_failure (session);
171 qof_session_load (session, report_session_percentage);
173 scm_cleanup_and_exit_with_failure (session);
175 if (!args->export_type.empty())
177 SCM retval = scm_call_2 (run_export_cmd, report, type);
178 SCM query_result = scm_c_eval_string (
"gnc:html-document?");
179 SCM get_export_string = scm_c_eval_string (
"gnc:html-document-export-string");
180 SCM get_export_error = scm_c_eval_string (
"gnc:html-document-export-error");
182 if (scm_is_false (scm_call_1 (query_result, retval)))
184 std::cerr << _(
"This report must be upgraded to \ 185 return a document object with export-string or export-error.") << std::endl;
186 scm_cleanup_and_exit_with_failure (
nullptr);
189 SCM export_string = scm_call_1 (get_export_string, retval);
190 SCM export_error = scm_call_1 (get_export_error, retval);
192 if (scm_is_string (export_string))
194 auto output = scm_to_utf8_string (export_string);
195 if (!args->output_file.empty())
197 write_report_file(output, args->output_file.c_str());
201 std::cout << output << std::endl;
205 else if (scm_is_string (export_error))
207 auto err = scm_to_utf8_string (export_error);
208 std::cerr << err << std::endl;
210 scm_cleanup_and_exit_with_failure (
nullptr);
214 std::cerr << _(
"This report must be upgraded to \ 215 return a document object with export-string or export-error.") << std::endl;
216 scm_cleanup_and_exit_with_failure (
nullptr);
221 SCM
id = scm_call_1(get_report_cmd, report);
223 if (scm_is_false (
id))
224 scm_cleanup_and_exit_with_failure (
nullptr);
227 if (gnc_run_report_with_error_handling (scm_to_int(
id), &html, &errmsg))
229 if (!args->output_file.empty())
231 write_report_file(html, args->output_file.c_str());
235 std::cout << html << std::endl;
241 std::cerr << errmsg << std::endl;
246 qof_session_destroy (session);
249 gnc_shutdown_cli (0);
255 const std::string& file_to_load;
256 const std::string& show_report;
260 scm_report_show (
void *data,
261 [[maybe_unused]]
int argc, [[maybe_unused]]
char **argv)
265 scm_c_eval_string(
"(debug-set! stack 200000)");
266 scm_c_use_module (
"gnucash utilities");
267 scm_c_use_module (
"gnucash app-utils");
268 scm_c_use_module (
"gnucash reports");
270 Gnucash::gnc_load_scm_config ([](
const gchar *msg){
PINFO (
"%s", msg); });
272 if (!args->file_to_load.empty())
274 auto datafile = args->file_to_load.c_str();
275 PINFO (
"Loading datafile %s...\n", datafile);
277 auto session = gnc_get_current_session ();
282 qof_session_load (session, report_session_percentage);
286 scm_call_2 (scm_c_eval_string (
"gnc:cmdline-report-show"),
287 scm_from_locale_string (args->show_report.c_str ()),
288 scm_current_output_port ());
289 gnc_shutdown_cli (0);
295 scm_report_list ([[maybe_unused]]
void *data,
296 [[maybe_unused]]
int argc, [[maybe_unused]]
char **argv)
298 scm_c_eval_string(
"(debug-set! stack 200000)");
299 scm_c_use_module (
"gnucash app-utils");
300 scm_c_use_module (
"gnucash reports");
302 Gnucash::gnc_load_scm_config ([](
const gchar *msg){
PINFO (
"%s", msg); });
304 scm_call_1 (scm_c_eval_string (
"gnc:cmdline-report-list"),
305 scm_current_output_port ());
306 gnc_shutdown_cli (0);
311 Gnucash::check_finance_quote (
void)
317 std::cout << bl::format (bl::translate (
"Found Finance::Quote version {1}.")) % quotes.
version() <<
"\n";
318 std::cout << bl::translate (
"Finance::Quote sources:\n");
320 const auto width{12};
321 for (
auto source : quotes.
sources())
323 auto mul{source.length() / width + 1};
330 std::cout << std::setw(mul * (width + 1)) << std::left << source;
332 std::cout << std::endl;
337 std::cout << err.what() << std::endl;
343 Gnucash::add_quotes (
const bo_str& uri)
348 auto session = gnc_get_current_session();
354 return cleanup_and_exit_with_failure (session);
356 qof_session_load(session, NULL);
358 return cleanup_and_exit_with_failure (session);
363 std::cout << bl::format (bl::translate (
"Found Finance::Quote version {1}.")) % quotes.
version() << std::endl;
364 auto quote_sources = quotes.
sources();
368 std::cerr << quotes.report_failures() << std::endl;
372 std::cerr << bl::translate(
"Price retrieval failed: ") << err.what() << std::endl;
376 return cleanup_and_exit_with_failure (session);
378 qof_session_destroy(session);
384 Gnucash::report_quotes (
const char* source,
const StrVec& commodities,
bool verbose)
390 quotes.
report(source, commodities, verbose);
392 std::cerr << quotes.report_failures() << std::endl;
396 std::cerr << bl::translate(
"Price retrieval failed: ") << err.what() << std::endl;
403 Gnucash::run_report (
const bo_str& file_to_load,
404 const bo_str& run_report,
405 const bo_str& export_type,
406 const bo_str& output_file)
408 auto args =
run_report_args { file_to_load ? *file_to_load : empty_string,
409 run_report ? *run_report : empty_string,
410 export_type ? *export_type : empty_string,
411 output_file ? *output_file : empty_string };
412 if (run_report && !run_report->empty())
413 scm_boot_guile (0,
nullptr, scm_run_report, &args);
419 Gnucash::report_show (
const bo_str& file_to_load,
420 const bo_str& show_report)
423 show_report ? *show_report : empty_string };
424 if (show_report && !show_report->empty())
425 scm_boot_guile (0,
nullptr, scm_report_show, &args);
431 Gnucash::report_list (
void)
433 scm_boot_guile (0,
nullptr, scm_report_list, NULL);
void qof_session_save(QofSession *session, QofPercentageFunc percentage_func)
The qof_session_save() method will commit all changes that have been made to the session.
#define PINFO(format, args...)
Print an informational note.
void gnc_engine_shutdown(void)
Called to shutdown the engine.
void qof_session_begin(QofSession *session, const char *uri, SessionOpenMode mode)
Begins a new session.
bool had_failures() noexcept
Report if there were quotes requested but not retrieved.
in use by another user (ETXTBSY)
#define PERR(format, args...)
Log a serious error.
Create a new store at the URI even if a store already exists there.
QofBook * qof_session_get_book(const QofSession *session)
Returns the QofBook of this session.
Preferences initialization function.
QofBackendError qof_session_get_error(QofSession *session)
The qof_session_get_error() routine can be used to obtain the reason for any failure.
void gnc_quote_source_set_fq_installed(const char *version_string, const std::vector< std::string > &sources_list)
Update gnucash internal tables based on what Finance::Quote sources are installed.
Generic api to store and retrieve preferences.
void gnc_prefs_init(void)
This function is called early in the load process to preload a number of preferences from the setting...
void qof_event_suspend(void)
Suspend all engine events.
void report(const char *source, const StrVec &commodities, bool verbose=false)
Report quote results from Finance::Quote to std::cout.
void fetch(QofBook *book)
Fetch quotes for all commodities in our db that have a quote source set.
void qof_event_resume(void)
Resume engine event generation.
File path resolution utility functions.
const std::string & version() noexcept
Get the installed Finance::Quote version.
const QuoteSources & sources() noexcept
Get the available Finance::Quote sources as a std::vector.