GnuCash c935c2f+
Loading...
Searching...
No Matches
gnucash-cli.cpp
1/*
2 * gnucash-cli.cpp -- The command line entry point for GnuCash
3 *
4 * Copyright (C) 2020 Geert Janssens <geert@kobaltwit.be>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, contact:
18 *
19 * Free Software Foundation Voice: +1-617-542-5942
20 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
21 * Boston, MA 02110-1301, USA gnu@gnu.org
22 */
23#include <config.h>
24
25#ifdef __MINGW32__
26#include <Windows.h>
27#include <fcntl.h>
28#endif
29
30#include "gnucash-commands.hpp"
31#include "gnucash-core-app.hpp"
32
33#include <glib/gi18n.h>
34#include <gnc-engine.h>
35#include <gnc-prefs.h>
36
37#include <boost/locale.hpp>
38#include <boost/optional.hpp>
39#ifdef __MINGW32__
40#include <boost/nowide/args.hpp>
41#endif
42#include <iostream>
43#include <gnc-quotes.hpp>
44
45namespace bl = boost::locale;
46
47/* This static indicates the debugging module that this .o belongs to. */
48[[maybe_unused]] static QofLogModule log_module = GNC_MOD_GUI;
49
50namespace Gnucash {
51
52 class GnucashCli : public CoreApp
53 {
54 public:
55 GnucashCli (const char* app_name);
56 void parse_command_line (int argc, char **argv);
57 int start (int argc, char **argv);
58 private:
59 void configure_program_options (void);
60
61 std::vector<std::string> m_quotes_cmd;
62 boost::optional <std::string> m_namespace;
63 bool m_verbose = false;
64
65 boost::optional <std::string> m_report_cmd;
66 boost::optional <std::string> m_report_name;
67 boost::optional <std::string> m_export_type;
68 boost::optional <std::string> m_output_file;
69 };
70
71}
72
73Gnucash::GnucashCli::GnucashCli (const char *app_name) : Gnucash::CoreApp (app_name)
74{
75 configure_program_options();
76}
77
78void
79Gnucash::GnucashCli::parse_command_line (int argc, char **argv)
80{
81 Gnucash::CoreApp::parse_command_line (argc, argv);
82
83 if (!m_log_to_filename || m_log_to_filename->empty())
84 m_log_to_filename = "stderr";
85
86 if (m_namespace)
87 gnc_prefs_set_namespace_regexp (m_namespace->c_str());
88}
89
90// Define command line options specific to gnucash-cli.
91void
92Gnucash::GnucashCli::configure_program_options (void)
93{
94 bpo::options_description quotes_options(_("Price Quotes Retrieval Options"));
95 quotes_options.add_options()
96 ("quotes,Q", bpo::value<std::vector<std::string>> (&m_quotes_cmd)->multitoken(),
97 _("Execute price quote related commands. The following commands are supported.\n\n"
98 " info: \tShow Finance::Quote version and exposed quote sources.\n"
99 " get: \tFetch current quotes for all foreign currencies and stocks in the given GnuCash datafile.\n"
100 " dump: \tFetch current quotes for specified currencies or stocks from a specified namespace and print the results to the console.\n"
101 " \tThis must be followed with a source and one or more symbols, unless the source is \"currency\" in which case it must be followed with two or more symbols, the first of which is the currency in which exchange rates for the rest will be quoted.\n"))
102 ("namespace", bpo::value (&m_namespace),
103 _("Regular expression determining which namespace commodities will be retrieved for when using the get command"))
104 ("verbose,V", bpo::bool_switch (&m_verbose),
105 _("When using the dump command list all of the parameters Finance::Quote returns for the symbol instead of the ones that Gnucash requires."));
106
107 m_opt_desc_display->add (quotes_options);
108 m_opt_desc_all.add (quotes_options);
109
110 bpo::options_description report_options(_("Report Generation Options"));
111 report_options.add_options()
112 ("report,R", bpo::value (&m_report_cmd),
113 _("Execute report related commands. The following commands are supported.\n\n"
114 " list: \tLists available reports.\n"
115 " show: \tDescribe the options modified in the named report. A datafile \
116may be specified to describe some saved options.\n"
117 " run: \tRun the named report in the given GnuCash datafile.\n"))
118 ("name", bpo::value (&m_report_name),
119 _("Name of the report to run\n"))
120 ("export-type", bpo::value (&m_export_type),
121 _("Specify export type\n"))
122 ("output-file", bpo::value (&m_output_file),
123 _("Output file for report\n"));
124 m_opt_desc_display->add (report_options);
125 m_opt_desc_all.add (report_options);
126
127}
128
129int
130Gnucash::GnucashCli::start ([[maybe_unused]] int argc, [[maybe_unused]] char **argv)
131{
132 Gnucash::CoreApp::start();
133
134 if (!m_quotes_cmd.empty())
135 {
136 if (m_quotes_cmd.front() == "info")
137 {
138 return Gnucash::check_finance_quote ();
139 }
140 else if (m_quotes_cmd.front() == "get")
141 {
142 if (!m_file_to_load && m_quotes_cmd.size() == 2)
143 m_file_to_load = m_quotes_cmd[1];
144
145 if (!m_file_to_load || m_file_to_load->empty())
146 {
147 std::cerr << bl::translate("Missing data file parameter") << "\n\n"
148 << *m_opt_desc_display.get() << std::endl;
149 return 1;
150 }
151 else
152 return Gnucash::add_quotes (m_file_to_load);
153 }
154 else if (m_quotes_cmd.front() == "dump")
155 {
156 if (m_quotes_cmd.size() < 3 ||
157 (m_quotes_cmd[1] == "currency" &&
158 m_quotes_cmd.size() < 4))
159 {
160 std::cerr << bl::translate("Not enough information for quotes dump") << std::endl;
161 return 1;
162 }
163 auto source = m_quotes_cmd[1];
164 m_quotes_cmd.erase(m_quotes_cmd.begin(), m_quotes_cmd.begin() + 2);
165 return Gnucash::report_quotes(source.c_str(), m_quotes_cmd,
166 m_verbose);
167 }
168 else
169 {
170 std::cerr << bl::format (bl::translate("Unknown quotes command '{1}'")) % m_quotes_cmd.front() << "\n\n"
171 << *m_opt_desc_display.get() << std::endl;
172 return 1;
173 }
174 }
175
176 if (m_report_cmd)
177 {
178 if (*m_report_cmd == "run")
179 {
180 if (!m_file_to_load || m_file_to_load->empty())
181 {
182 std::cerr << _("Missing data file parameter") << "\n\n"
183 << *m_opt_desc_display.get() << std::endl;
184 return 1;
185 }
186 else
187 return Gnucash::run_report(m_file_to_load, m_report_name,
188 m_export_type, m_output_file);
189 }
190
191 // The command "list" does *not* test&pass the m_file_to_load
192 // argument because the reports are global rather than
193 // per-file objects. In the future, saved reports may be saved
194 // into the datafile, therefore one will need to be specified
195 // for loading.
196 else if (*m_report_cmd == "list")
197 return Gnucash::report_list ();
198
199 // The command "show" does test&pass the m_file_to_load
200 // argument, and will attempt to load datafile prior to
201 // describing report. If loading fails, it will continue
202 // showing report options.
203 else if (*m_report_cmd == "show")
204 if (!m_report_name || m_report_name->empty())
205 {
206 std::cerr << _("Missing --name parameter") << "\n\n"
207 << *m_opt_desc_display.get() << std::endl;
208 return 1;
209 }
210 else
211 return Gnucash::report_show (m_file_to_load, m_report_name);
212 else
213 {
214 std::cerr << bl::format (std::string{_("Unknown report command '{1}'")}) % *m_report_cmd << "\n\n"
215 << *m_opt_desc_display.get();
216 return 1;
217 }
218 }
219
220 std::cerr << _("Missing command or option") << "\n\n"
221 << *m_opt_desc_display.get() << std::endl;
222
223 return 1;
224}
225
226int
227main(int argc, char **argv)
228{
229 const char *app_name = PROJECT_NAME "-cli";
230 Gnucash::GnucashCli application (app_name);
231#ifdef __MINGW32__
232 boost::nowide::args a(argc, argv); // Fix arguments - make them UTF-8
233#endif
234 application.parse_command_line (argc, argv);
235 return application.start (argc, argv);
236}
All type declarations for the whole Gnucash engine.
Generic api to store and retrieve preferences.