GnuCash  5.6-150-g038405b370+
Public Member Functions | Data Fields
GncPriceImport Class Reference

The actual PriceImport class It's intended to use in the following sequence of actions: More...

#include <gnc-import-price.hpp>

Public Member Functions

 GncPriceImport (GncImpFileFormat format=GncImpFileFormat::UNKNOWN)
 Constructor for GncPriceImport.
 
 ~GncPriceImport ()
 Destructor for GncPriceImport.
 
void file_format (GncImpFileFormat format)
 Sets the file format for the file to import, which may cause the file to be reloaded as well if the previously set file format was different and a filename was already set. More...
 
GncImpFileFormat file_format ()
 
void over_write (bool over)
 
bool over_write ()
 
void from_commodity (gnc_commodity *from_commodity)
 Sets a from commodity. More...
 
gnc_commodity * from_commodity ()
 
void to_currency (gnc_commodity *to_currency)
 Sets a to currency. More...
 
gnc_commodity * to_currency ()
 
void currency_format (int currency_format)
 
int currency_format ()
 
void date_format (int date_format)
 
int date_format ()
 
void encoding (const std::string &encoding)
 Converts raw file data using a new encoding. More...
 
std::string encoding ()
 
void update_skipped_lines (std::optional< uint32_t > start, std::optional< uint32_t > end, std::optional< bool > alt, std::optional< bool > errors)
 
uint32_t skip_start_lines ()
 
uint32_t skip_end_lines ()
 
bool skip_alt_lines ()
 
bool skip_err_lines ()
 
void separators (std::string separators)
 
std::string separators ()
 
void enable_escape (bool enable)
 
bool enable_escape ()
 
void settings (const CsvPriceImpSettings &settings)
 
bool save_settings ()
 
void settings_name (std::string name)
 
std::string settings_name ()
 
void load_file (const std::string &filename)
 Loads a file into a GncPriceImport. More...
 
void tokenize (bool guessColTypes)
 Splits a file into cells. More...
 
std::string verify ()
 
void create_prices ()
 This function will attempt to convert all tokenized lines into prices using the column types the user has set. More...
 
bool check_for_column_type (GncPricePropType type)
 
void set_column_type_price (uint32_t position, GncPricePropType type, bool force=false)
 
std::vector< GncPricePropType > column_types_price ()
 

Data Fields

std::unique_ptr< GncTokenizerm_tokenizer
 Will handle file loading/encoding conversion/splitting into fields.
 
std::vector< parse_line_tm_parsed_lines
 source file parsed into a two-dimensional array of strings. More...
 
int m_prices_added
 
int m_prices_duplicated
 
int m_prices_replaced
 

Detailed Description

The actual PriceImport class It's intended to use in the following sequence of actions:

Definition at line 82 of file gnc-import-price.hpp.

Member Function Documentation

◆ create_prices()

void GncPriceImport::create_prices ( )

This function will attempt to convert all tokenized lines into prices using the column types the user has set.

Creates a list of prices from parsed data.

The parsed data will first be validated. If any errors are found in lines that are marked for processing (ie not marked to skip) this function will throw an error.

Parameters
skip_errorstrue skip over lines with errors
Exceptions
throwsstd::invalid_argument if data validation or processing fails.

Definition at line 646 of file gnc-import-price.cpp.

647 {
648  /* Start with verifying the current data. */
649  auto verify_result = verify();
650  if (!verify_result.empty())
651  throw std::invalid_argument (verify_result);
652 
653  m_prices_added = 0;
654  m_prices_duplicated = 0;
655  m_prices_replaced = 0;
656 
657  /* Iterate over all parsed lines */
658  for (auto parsed_lines_it = m_parsed_lines.begin();
659  parsed_lines_it != m_parsed_lines.end();
660  ++parsed_lines_it)
661  {
662  /* Skip current line if the user specified so */
663  if ((std::get<PL_SKIP>(*parsed_lines_it)))
664  continue;
665 
666  /* Should not throw anymore, otherwise verify needs revision */
667  create_price (parsed_lines_it);
668  }
669  PINFO("Number of lines is %d, added %d, duplicated %d, replaced %d",
670  (int)m_parsed_lines.size(), m_prices_added, m_prices_duplicated, m_prices_replaced);
671 }
#define PINFO(format, args...)
Print an informational note.
Definition: qoflog.h:256
std::vector< parse_line_t > m_parsed_lines
source file parsed into a two-dimensional array of strings.

◆ encoding()

void GncPriceImport::encoding ( const std::string &  encoding)

Converts raw file data using a new encoding.

This function must be called after load_file only if load_file guessed the wrong encoding.

Parameters
encodingEncoding that data should be translated using

Definition at line 234 of file gnc-import-price.cpp.

235 {
236  // TODO investigate if we can catch conversion errors and report them
237  if (m_tokenizer)
238  {
239  m_tokenizer->encoding(encoding); // May throw
240  try
241  {
242  tokenize(false);
243  }
244  catch (...)
245  { };
246  }
247 
248  m_settings.m_encoding = encoding;
249 }
void tokenize(bool guessColTypes)
Splits a file into cells.
std::unique_ptr< GncTokenizer > m_tokenizer
Will handle file loading/encoding conversion/splitting into fields.
void encoding(const std::string &encoding)
Converts raw file data using a new encoding.

◆ file_format()

void GncPriceImport::file_format ( GncImpFileFormat  format)

Sets the file format for the file to import, which may cause the file to be reloaded as well if the previously set file format was different and a filename was already set.

Parameters
formatthe new format to set
Exceptions
std::ifstream::failureif file reloading fails

Definition at line 87 of file gnc-import-price.cpp.

88 {
89  if (m_tokenizer && m_settings.m_file_format == format)
90  return;
91 
92  auto new_encoding = std::string("UTF-8");
93  auto new_imp_file = std::string();
94 
95  // Recover common settings from old tokenizer
96  if (m_tokenizer)
97  {
98  new_encoding = m_tokenizer->encoding();
99  new_imp_file = m_tokenizer->current_file();
100  if (file_format() == GncImpFileFormat::FIXED_WIDTH)
101  {
102  auto fwtok = dynamic_cast<GncFwTokenizer*>(m_tokenizer.get());
103  if (!fwtok->get_columns().empty())
104  m_settings.m_column_widths = fwtok->get_columns();
105  }
106  }
107 
108  m_settings.m_file_format = format;
109  m_tokenizer = gnc_tokenizer_factory(m_settings.m_file_format);
110 
111  // Set up new tokenizer with common settings
112  // recovered from old tokenizer
113  m_tokenizer->encoding(new_encoding);
114  load_file(new_imp_file);
115 
116  // Restore potentially previously set separators or column_widths
117  if (file_format() == GncImpFileFormat::CSV)
118  {
119  if (!m_settings.m_separators.empty())
120  separators (m_settings.m_separators);
121  enable_escape (m_settings.m_enable_escape);
122  }
123  else if ((file_format() == GncImpFileFormat::FIXED_WIDTH)
124  && !m_settings.m_column_widths.empty())
125  {
126  auto fwtok = dynamic_cast<GncFwTokenizer*>(m_tokenizer.get());
127  fwtok->columns (m_settings.m_column_widths);
128  }
129 }
std::unique_ptr< GncTokenizer > m_tokenizer
Will handle file loading/encoding conversion/splitting into fields.
void file_format(GncImpFileFormat format)
Sets the file format for the file to import, which may cause the file to be reloaded as well if the p...
void load_file(const std::string &filename)
Loads a file into a GncPriceImport.

◆ from_commodity()

void GncPriceImport::from_commodity ( gnc_commodity *  from_commodity)

Sets a from commodity.

This is the commodity all import data relates to. When a from commodity is set, there can't be any from columns selected in the import data.

Parameters
from_commoditypointer to a commodity or NULL.

Definition at line 147 of file gnc-import-price.cpp.

148 {
149  m_settings.m_from_commodity = from_commodity;
150  if (m_settings.m_from_commodity)
151  {
152  auto col_type_sym = std::find (m_settings.m_column_types_price.begin(),
153  m_settings.m_column_types_price.end(), GncPricePropType::FROM_SYMBOL);
154 
155  if (col_type_sym != m_settings.m_column_types_price.end())
156  set_column_type_price (col_type_sym -m_settings.m_column_types_price.begin(),
157  GncPricePropType::NONE);
158 
159  auto col_type_name = std::find (m_settings.m_column_types_price.begin(),
160  m_settings.m_column_types_price.end(), GncPricePropType::FROM_NAMESPACE);
161 
162  if (col_type_name != m_settings.m_column_types_price.end())
163  set_column_type_price (col_type_name -m_settings.m_column_types_price.begin(),
164  GncPricePropType::NONE);
165 
166  // force a refresh of the to_currency if the from_commodity is changed
167  std::vector<GncPricePropType> commodities = { GncPricePropType::TO_CURRENCY };
168  reset_formatted_column (commodities);
169  }
170 }
void from_commodity(gnc_commodity *from_commodity)
Sets a from commodity.

◆ load_file()

void GncPriceImport::load_file ( const std::string &  filename)

Loads a file into a GncPriceImport.

This is the first function that must be called after creating a new GncPriceImport. As long as this function didn't run successfully, the importer can't proceed.

Parameters
filenameName of the file that should be opened
Exceptions
maythrow std::ifstream::failure on any io error

Definition at line 361 of file gnc-import-price.cpp.

362 {
363  /* Get the raw data first and handle an error if one occurs. */
364  try
365  {
366  m_tokenizer->load_file (filename);
367  return;
368  }
369  catch (std::ifstream::failure& ios_err)
370  {
371  // Just log the error and pass it on the call stack for proper handling
372  PWARN ("Error: %s", ios_err.what());
373  throw;
374  }
375 }
std::unique_ptr< GncTokenizer > m_tokenizer
Will handle file loading/encoding conversion/splitting into fields.
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250

◆ to_currency()

void GncPriceImport::to_currency ( gnc_commodity *  to_currency)

Sets a to currency.

This is the to currency all import data relates to. When a to currency is set, there can't be any to currency columns selected in the import data.

Parameters
to_currencypointer to a commodity or NULL.

Definition at line 178 of file gnc-import-price.cpp.

179 {
180  m_settings.m_to_currency = to_currency;
181  if (m_settings.m_to_currency)
182  {
183  auto col_type_currency = std::find (m_settings.m_column_types_price.begin(),
184  m_settings.m_column_types_price.end(), GncPricePropType::TO_CURRENCY);
185 
186  if (col_type_currency != m_settings.m_column_types_price.end())
187  set_column_type_price (col_type_currency -m_settings.m_column_types_price.begin(),
188  GncPricePropType::NONE);
189 
190  // force a refresh of the from_commodity if the to_currency is changed
191  // either namespace or symbol will be sufice
192  std::vector<GncPricePropType> commodities = { GncPricePropType::FROM_SYMBOL };
193  reset_formatted_column (commodities);
194  }
195 }
void to_currency(gnc_commodity *to_currency)
Sets a to currency.

◆ tokenize()

void GncPriceImport::tokenize ( bool  guessColTypes)

Splits a file into cells.

This requires having an encoding that works (see GncPriceImport::convert_encoding). Tokenizing related options should be set to the user's selections before calling this function. Notes: - this function must be called with guessColTypes set to true once before calling it with guessColTypes set to false.

  • if guessColTypes is true, all the column types will be set GncPricePropType::NONE right now as real guessing isn't implemented yet
    Parameters
    guessColTypestrue to guess what the types of columns are based on the cell contents
    Exceptions
    std::range_errorif tokenizing failed

Definition at line 388 of file gnc-import-price.cpp.

389 {
390  if (!m_tokenizer)
391  return;
392 
393  uint32_t max_cols = 0;
394  m_tokenizer->tokenize();
395  m_parsed_lines.clear();
396  for (auto tokenized_line : m_tokenizer->get_tokens())
397  {
398  auto length = tokenized_line.size();
399  if (length > 0)
400  m_parsed_lines.push_back (std::make_tuple (tokenized_line, std::string(),
401  std::make_shared<GncImportPrice>(date_format(), currency_format()),
402  false));
403  if (length > max_cols)
404  max_cols = length;
405  }
406 
407  /* If it failed, generate an error. */
408  if (m_parsed_lines.size() == 0)
409  {
410  throw (std::range_error ("Tokenizing failed."));
411  return;
412  }
413 
414  m_settings.m_column_types_price.resize(max_cols, GncPricePropType::NONE);
415 
416  /* Force reinterpretation of already set columns and/or base_account */
417  for (uint32_t i = 0; i < m_settings.m_column_types_price.size(); i++)
418  set_column_type_price (i, m_settings.m_column_types_price[i], true);
419 
420  if (guessColTypes)
421  {
422  /* Guess column_types based
423  * on the contents of each column. */
424  /* TODO Make it actually guess. */
425  }
426 }
std::unique_ptr< GncTokenizer > m_tokenizer
Will handle file loading/encoding conversion/splitting into fields.
std::vector< parse_line_t > m_parsed_lines
source file parsed into a two-dimensional array of strings.

Field Documentation

◆ m_parsed_lines

std::vector<parse_line_t> GncPriceImport::m_parsed_lines

source file parsed into a two-dimensional array of strings.

Per line also holds possible error messages and objects with extracted price properties.

Definition at line 145 of file gnc-import-price.hpp.


The documentation for this class was generated from the following files: