mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Merge Christian Gruber's 'fix_bug_797587' into maint.
This commit is contained in:
commit
95857a8b99
@ -387,8 +387,24 @@ tokenize_string(GList* existing_tokens, const char *string)
|
|||||||
/* add each token to the token GList */
|
/* add each token to the token GList */
|
||||||
while (stringpos && *stringpos)
|
while (stringpos && *stringpos)
|
||||||
{
|
{
|
||||||
/* prepend the char* to the token GList */
|
if (strlen(*stringpos) > 0)
|
||||||
existing_tokens = g_list_prepend(existing_tokens, g_strdup(*stringpos));
|
{
|
||||||
|
/* check for duplicated tokens */
|
||||||
|
gboolean duplicated = FALSE;
|
||||||
|
for (GList* token = existing_tokens; token != NULL; token = token->next)
|
||||||
|
{
|
||||||
|
if (g_strcmp0(token->data, *stringpos) == 0)
|
||||||
|
{
|
||||||
|
duplicated = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (duplicated == FALSE)
|
||||||
|
{
|
||||||
|
/* prepend the char* to the token GList */
|
||||||
|
existing_tokens = g_list_prepend(existing_tokens, g_strdup(*stringpos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* then move to the next string */
|
/* then move to the next string */
|
||||||
stringpos++;
|
stringpos++;
|
||||||
|
@ -5279,15 +5279,14 @@ struct AccountInfo
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
build_token_info(char const * key, KvpValue * value, TokenAccountsInfo & tokenInfo)
|
build_token_info(char const * suffix, KvpValue * value, TokenAccountsInfo & tokenInfo)
|
||||||
{
|
{
|
||||||
tokenInfo.total_count += value->get<int64_t>();
|
if (strlen(suffix) == GUID_ENCODING_LENGTH)
|
||||||
AccountTokenCount this_account;
|
{
|
||||||
std::string account_guid {key};
|
tokenInfo.total_count += value->get<int64_t>();
|
||||||
/*By convention, the key ends with the account GUID.*/
|
/*By convention, the key ends with the account GUID.*/
|
||||||
this_account.account_guid = account_guid.substr(account_guid.size() - GUID_ENCODING_LENGTH);
|
tokenInfo.accounts.emplace_back(AccountTokenCount{std::string{suffix}, value->get<int64_t>()});
|
||||||
this_account.token_count = value->get<int64_t>();
|
}
|
||||||
tokenInfo.accounts.push_back(this_account);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** We scale the probability values by probability_factor.
|
/** We scale the probability values by probability_factor.
|
||||||
@ -5332,7 +5331,7 @@ get_first_pass_probabilities(GncImportMatchMap * imap, GList * tokens)
|
|||||||
for (auto current_token = tokens; current_token; current_token = current_token->next)
|
for (auto current_token = tokens; current_token; current_token = current_token->next)
|
||||||
{
|
{
|
||||||
TokenAccountsInfo tokenInfo{};
|
TokenAccountsInfo tokenInfo{};
|
||||||
auto path = std::string{IMAP_FRAME_BAYES "/"} + static_cast <char const *> (current_token->data);
|
auto path = std::string{IMAP_FRAME_BAYES "/"} + static_cast <char const *> (current_token->data) + "/";
|
||||||
qof_instance_foreach_slot_prefix (QOF_INSTANCE (imap->acc), path, &build_token_info, tokenInfo);
|
qof_instance_foreach_slot_prefix (QOF_INSTANCE (imap->acc), path, &build_token_info, tokenInfo);
|
||||||
for (auto const & current_account_token : tokenInfo.accounts)
|
for (auto const & current_account_token : tokenInfo.accounts)
|
||||||
{
|
{
|
||||||
@ -5665,38 +5664,27 @@ build_non_bayes (const char *key, const GValue *value, gpointer user_data)
|
|||||||
g_free (guid_string);
|
g_free (guid_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::tuple<std::string, std::string, std::string>
|
|
||||||
parse_bayes_imap_info (std::string const & imap_bayes_entry)
|
|
||||||
{
|
|
||||||
auto header_length = strlen (IMAP_FRAME_BAYES);
|
|
||||||
std::string header {imap_bayes_entry.substr (0, header_length)};
|
|
||||||
auto guid_start = imap_bayes_entry.size() - GUID_ENCODING_LENGTH;
|
|
||||||
std::string keyword {imap_bayes_entry.substr (header_length + 1, guid_start - header_length - 2)};
|
|
||||||
std::string account_guid {imap_bayes_entry.substr (guid_start)};
|
|
||||||
return std::tuple <std::string, std::string, std::string> {header, keyword, account_guid};
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
build_bayes (const char *key, KvpValue * value, GncImapInfo & imapInfo)
|
build_bayes (const char *suffix, KvpValue * value, GncImapInfo & imapInfo)
|
||||||
{
|
{
|
||||||
auto parsed_key = parse_bayes_imap_info (key);
|
size_t guid_start = strlen(suffix) - GUID_ENCODING_LENGTH;
|
||||||
|
std::string account_guid {&suffix[guid_start]};
|
||||||
GncGUID guid;
|
GncGUID guid;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto temp_guid = gnc::GUID::from_string (std::get <2> (parsed_key));
|
guid = gnc::GUID::from_string (account_guid);
|
||||||
guid = temp_guid;
|
|
||||||
}
|
}
|
||||||
catch (const gnc::guid_syntax_exception& err)
|
catch (const gnc::guid_syntax_exception& err)
|
||||||
{
|
{
|
||||||
PWARN("Invalid GUID string from %s", key);
|
PWARN("Invalid GUID string from %s%s", IMAP_FRAME_BAYES, suffix);
|
||||||
}
|
}
|
||||||
auto map_account = xaccAccountLookup (&guid, gnc_account_get_book (imapInfo.source_account));
|
auto map_account = xaccAccountLookup (&guid, gnc_account_get_book (imapInfo.source_account));
|
||||||
auto imap_node = static_cast <GncImapInfo*> (g_malloc (sizeof (GncImapInfo)));
|
auto imap_node = static_cast <GncImapInfo*> (g_malloc (sizeof (GncImapInfo)));
|
||||||
auto count = value->get <int64_t> ();
|
auto count = value->get <int64_t> ();
|
||||||
imap_node->source_account = imapInfo.source_account;
|
imap_node->source_account = imapInfo.source_account;
|
||||||
imap_node->map_account = map_account;
|
imap_node->map_account = map_account;
|
||||||
imap_node->head = g_strdup (key);
|
imap_node->head = g_strdup_printf ("%s%s", IMAP_FRAME_BAYES, suffix);
|
||||||
imap_node->match_string = g_strdup (std::get <1> (parsed_key).c_str ());
|
imap_node->match_string = g_strndup (&suffix[1], guid_start - 2);
|
||||||
imap_node->category = g_strdup(" ");
|
imap_node->category = g_strdup(" ");
|
||||||
imap_node->count = g_strdup_printf ("%" G_GINT64_FORMAT, count);
|
imap_node->count = g_strdup_printf ("%" G_GINT64_FORMAT, count);
|
||||||
imapInfo.list = g_list_prepend (imapInfo.list, imap_node);
|
imapInfo.list = g_list_prepend (imapInfo.list, imap_node);
|
||||||
|
@ -235,23 +235,6 @@ struct KvpFrameImpl
|
|||||||
KvpValue * set_impl (std::string const &, KvpValue *) noexcept;
|
KvpValue * set_impl (std::string const &, KvpValue *) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename func_type>
|
|
||||||
void KvpFrame::for_each_slot_prefix(std::string const & prefix,
|
|
||||||
func_type const & func) const noexcept
|
|
||||||
{
|
|
||||||
std::for_each (m_valuemap.begin(), m_valuemap.end(),
|
|
||||||
[&prefix,&func](const KvpFrameImpl::map_type::value_type & a)
|
|
||||||
{
|
|
||||||
std::string temp_key {a.first};
|
|
||||||
if (temp_key.size() < prefix.size())
|
|
||||||
return;
|
|
||||||
/* Testing for prefix matching */
|
|
||||||
if (std::mismatch(prefix.begin(), prefix.end(), temp_key.begin()).first == prefix.end())
|
|
||||||
func (a.first, a.second);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename func_type, typename data_type>
|
template<typename func_type, typename data_type>
|
||||||
void KvpFrame::for_each_slot_prefix(std::string const & prefix,
|
void KvpFrame::for_each_slot_prefix(std::string const & prefix,
|
||||||
func_type const & func, data_type & data) const noexcept
|
func_type const & func, data_type & data) const noexcept
|
||||||
@ -259,12 +242,9 @@ void KvpFrame::for_each_slot_prefix(std::string const & prefix,
|
|||||||
std::for_each (m_valuemap.begin(), m_valuemap.end(),
|
std::for_each (m_valuemap.begin(), m_valuemap.end(),
|
||||||
[&prefix,&func,&data](const KvpFrameImpl::map_type::value_type & a)
|
[&prefix,&func,&data](const KvpFrameImpl::map_type::value_type & a)
|
||||||
{
|
{
|
||||||
std::string temp_key {a.first};
|
|
||||||
if (temp_key.size() < prefix.size())
|
|
||||||
return;
|
|
||||||
/* Testing for prefix matching */
|
/* Testing for prefix matching */
|
||||||
if (std::mismatch(prefix.begin(), prefix.end(), temp_key.begin()).first == prefix.end())
|
if (strncmp(a.first, prefix.c_str(), prefix.size()) == 0)
|
||||||
func (a.first, a.second, data);
|
func (&a.first[prefix.size()], a.second, data);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -271,6 +271,14 @@ TEST_F(ImapBayesTest, FindAccountBayes)
|
|||||||
EXPECT_EQ(t_expense_account2, account);
|
EXPECT_EQ(t_expense_account2, account);
|
||||||
account = gnc_account_imap_find_account_bayes(t_imap, t_list5);
|
account = gnc_account_imap_find_account_bayes(t_imap, t_list5);
|
||||||
EXPECT_EQ(nullptr, account);
|
EXPECT_EQ(nullptr, account);
|
||||||
|
|
||||||
|
// only imap entries with exact token matching should be considered
|
||||||
|
root->set_path({std::string{IMAP_FRAME_BAYES} + "/" + pepper + waldo + "/" + acct2_guid}, new KvpValue{*value});
|
||||||
|
account = gnc_account_imap_find_account_bayes(t_imap, t_list3);
|
||||||
|
EXPECT_EQ(t_expense_account1, account);
|
||||||
|
root->set_path({std::string{IMAP_FRAME_BAYES} + "/" + pepper + "/" + waldo + "/" + acct2_guid}, new KvpValue{*value});
|
||||||
|
account = gnc_account_imap_find_account_bayes(t_imap, t_list3);
|
||||||
|
EXPECT_EQ(t_expense_account1, account);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ImapBayesTest, AddAccountBayes)
|
TEST_F(ImapBayesTest, AddAccountBayes)
|
||||||
|
Loading…
Reference in New Issue
Block a user