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 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 633 of file gnc-import-price.cpp.

634 {
635  /* Start with verifying the current data. */
636  auto verify_result = verify();
637  if (!verify_result.empty())
638  throw std::invalid_argument (verify_result);
639 
640  m_prices_added = 0;
641  m_prices_duplicated = 0;
642  m_prices_replaced = 0;
643 
644  /* Iterate over all parsed lines */
645  for (auto parsed_lines_it = m_parsed_lines.begin();
646  parsed_lines_it != m_parsed_lines.end();
647  ++parsed_lines_it)
648  {
649  /* Skip current line if the user specified so */
650  if ((std::get<PL_SKIP>(*parsed_lines_it)))
651  continue;
652 
653  /* Should not throw anymore, otherwise verify needs revision */
654  create_price (parsed_lines_it);
655  }
656  PINFO("Number of lines is %d, added %d, duplicated %d, replaced %d",
657  (int)m_parsed_lines.size(), m_prices_added, m_prices_duplicated, m_prices_replaced);
658 }
#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 231 of file gnc-import-price.cpp.

232 {
233  // TODO investigate if we can catch conversion errors and report them
234  if (m_tokenizer)
235  {
236  m_tokenizer->encoding(encoding); // May throw
237  try
238  {
239  tokenize(false);
240  }
241  catch (...)
242  { };
243  }
244 
245  m_settings.m_encoding = encoding;
246 }
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  && !m_settings.m_separators.empty())
119  separators (m_settings.m_separators);
120  else if ((file_format() == GncImpFileFormat::FIXED_WIDTH)
121  && !m_settings.m_column_widths.empty())
122  {
123  auto fwtok = dynamic_cast<GncFwTokenizer*>(m_tokenizer.get());
124  fwtok->columns (m_settings.m_column_widths);
125  }
126 }
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 144 of file gnc-import-price.cpp.

145 {
146  m_settings.m_from_commodity = from_commodity;
147  if (m_settings.m_from_commodity)
148  {
149  auto col_type_sym = std::find (m_settings.m_column_types_price.begin(),
150  m_settings.m_column_types_price.end(), GncPricePropType::FROM_SYMBOL);
151 
152  if (col_type_sym != m_settings.m_column_types_price.end())
153  set_column_type_price (col_type_sym -m_settings.m_column_types_price.begin(),
154  GncPricePropType::NONE);
155 
156  auto col_type_name = std::find (m_settings.m_column_types_price.begin(),
157  m_settings.m_column_types_price.end(), GncPricePropType::FROM_NAMESPACE);
158 
159  if (col_type_name != m_settings.m_column_types_price.end())
160  set_column_type_price (col_type_name -m_settings.m_column_types_price.begin(),
161  GncPricePropType::NONE);
162 
163  // force a refresh of the to_currency if the from_commodity is changed
164  std::vector<GncPricePropType> commodities = { GncPricePropType::TO_CURRENCY };
165  reset_formatted_column (commodities);
166  }
167 }
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 348 of file gnc-import-price.cpp.

349 {
350  /* Get the raw data first and handle an error if one occurs. */
351  try
352  {
353  m_tokenizer->load_file (filename);
354  return;
355  }
356  catch (std::ifstream::failure& ios_err)
357  {
358  // Just log the error and pass it on the call stack for proper handling
359  PWARN ("Error: %s", ios_err.what());
360  throw;
361  }
362 }
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 175 of file gnc-import-price.cpp.

176 {
177  m_settings.m_to_currency = to_currency;
178  if (m_settings.m_to_currency)
179  {
180  auto col_type_currency = std::find (m_settings.m_column_types_price.begin(),
181  m_settings.m_column_types_price.end(), GncPricePropType::TO_CURRENCY);
182 
183  if (col_type_currency != m_settings.m_column_types_price.end())
184  set_column_type_price (col_type_currency -m_settings.m_column_types_price.begin(),
185  GncPricePropType::NONE);
186 
187  // force a refresh of the from_commodity if the to_currency is changed
188  // either namespace or symbol will be sufice
189  std::vector<GncPricePropType> commodities = { GncPricePropType::FROM_SYMBOL };
190  reset_formatted_column (commodities);
191  }
192 }
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 375 of file gnc-import-price.cpp.

376 {
377  if (!m_tokenizer)
378  return;
379 
380  uint32_t max_cols = 0;
381  m_tokenizer->tokenize();
382  m_parsed_lines.clear();
383  for (auto tokenized_line : m_tokenizer->get_tokens())
384  {
385  auto length = tokenized_line.size();
386  if (length > 0)
387  m_parsed_lines.push_back (std::make_tuple (tokenized_line, std::string(),
388  std::make_shared<GncImportPrice>(date_format(), currency_format()),
389  false));
390  if (length > max_cols)
391  max_cols = length;
392  }
393 
394  /* If it failed, generate an error. */
395  if (m_parsed_lines.size() == 0)
396  {
397  throw (std::range_error ("Tokenizing failed."));
398  return;
399  }
400 
401  m_settings.m_column_types_price.resize(max_cols, GncPricePropType::NONE);
402 
403  /* Force reinterpretation of already set columns and/or base_account */
404  for (uint32_t i = 0; i < m_settings.m_column_types_price.size(); i++)
405  set_column_type_price (i, m_settings.m_column_types_price[i], true);
406 
407  if (guessColTypes)
408  {
409  /* Guess column_types based
410  * on the contents of each column. */
411  /* TODO Make it actually guess. */
412  }
413 }
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 142 of file gnc-import-price.hpp.


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