cli: support --ignored-address for init command

Allow for skipping unwanted addresses (such as 'noreply') from the
contacts cache.
This commit is contained in:
Dirk-Jan C. Binnema 2023-07-01 19:03:51 +03:00
parent 5dc41ed811
commit c4b5795328
7 changed files with 44 additions and 14 deletions

View File

@ -8,6 +8,14 @@
- ~mu~ commands ~extract~, ~verify~ and ~view~ can now read the message from - ~mu~ commands ~extract~, ~verify~ and ~view~ can now read the message from
standard input; see their man-pages for details standard input; see their man-pages for details
- ~mu init~ gained the ~--ignored-address~ option for email-addresses / regexps
that should _not_ be included in the contacts-cache (i.e., for ~mu cfind~ and
Mu4e address completion). See the ~mu-init~ manpage for details.
It's not unusual for 'noreply`-type e-mail addresses to be the majority in
an e-mail corpus, so it useful to get rid of those, with
'=--ignored-address=/.*noreply*/'=
- experimental: if you build ~mu~ with [[https://github.com/CLD2Owners/cld2][CLD2]] support (available in many Linux - experimental: if you build ~mu~ with [[https://github.com/CLD2Owners/cld2][CLD2]] support (available in many Linux
distros), ~mu~ will try to detect the language of the body of e-mail distros), ~mu~ will try to detect the language of the body of e-mail
messages; you can then search by their ISO-639-1 code, e.g. ~mu find messages; you can then search by their ISO-639-1 code, e.g. ~mu find

View File

@ -188,8 +188,6 @@ ContactsCache::Private::serialize() const
dirty_ = 0; dirty_ = 0;
} }
ContactsCache::ContactsCache(Config& config_db) ContactsCache::ContactsCache(Config& config_db)
: priv_{std::make_unique<Private>(config_db)} : priv_{std::make_unique<Private>(config_db)}
{} {}
@ -381,9 +379,6 @@ ContactsCache::is_ignored(const std::string& addr) const
return address_matches(addr, priv_->ignored_plain_, priv_->ignored_rx_); return address_matches(addr, priv_->ignored_plain_, priv_->ignored_rx_);
} }
#ifdef BUILD_TESTS #ifdef BUILD_TESTS
/* /*
* Tests. * Tests.

View File

@ -21,24 +21,38 @@ starts searching at =<maildir>=. By default, *mu* uses whatever the *MAILDIR*
environment variable is set to; if it is not set, it tries =~/Maildir= if it environment variable is set to; if it is not set, it tries =~/Maildir= if it
already exists. already exists.
** --my-address=<my-email-address> ** --my-address=<email-address-or-regex>
specifies that some e-mail addresses are 'my-address' (the option can be used specifies that some e-mail address is 'my-address' (the option can be used
multiple times). Any message in which at least one of the contact fields multiple times). Any message in which at least one of the contact fields
contains such an address is considered a 'personal' messages; this can then be contains such an address is considered a 'personal' messages; this can then be
used for filtering in *mu-find(1)*, *mu-cfind(1)* and *mu4e*, e.g. to filter-out used for filtering in *mu-find(1)*, *mu-cfind(1)* and *mu4e*, e.g. to filter-out
mailing list messages. mailing list messages.
=<my-email-address>= can be either a plain e-mail address (such as =<email-address-or-regex>= can be either a plain e-mail address (such as
*foo@example.com*), or a basic PCRE regular-expression (see *pcre(3)* for details), *foo@example.com*), or a basic PCRE regular-expression (see *pcre(3)* for details),
wrapped in */* (such as =/foo-.*@example\\.com/=). Depending on your shell, the wrapped in */* (such as =/foo-.*@example\\.com/=). Depending on your shell, the
argument may need to be quoted. argument may need to be quoted.
** --ignored-address=<email-address-or-regex>
specifies that some e-mail address is to be ignored from the contacts-cache
(the option can be used multiple times). Such address then cannot be found with
*mu-cfind(1)* or in the Mu4e contacts cache.
=<my-email-address>= can be either a plain e-mail address or a regexp, just like
for the =--my-address= option.
** --reinit ** --reinit
reinitialize the database from an earlier version; that is, create a new reinitialize the database from an earlier version; that is, create a new empty
empty database witht the existing settings. This cannot be combined database with the existing settings. This cannot be combined with the other ~init~
with the other ~init~ options. options.
* EXAMPLE
#+begin_example
$ mu init --maildir=~/Maildir --my-address=alice@example.com --my-address=bob@example.com --ignored-address='/.*reply.*/'
#+end_example
#+include: "exit-code.inc" :minlevel 1 #+include: "exit-code.inc" :minlevel 1

View File

@ -49,7 +49,6 @@ Mu::mu_cmd_info(const Mu::Store& store, const Options& opts)
return "never"; return "never";
else else
return time_to_string("%c", t); return time_to_string("%c", t);
}; };
Table info; Table info;
@ -61,8 +60,11 @@ Mu::mu_cmd_info(const Mu::Store& store, const Options& opts)
info.add_row({"max-message-size", format("%zu", conf.get<Config::Id::MaxMessageSize>())}); info.add_row({"max-message-size", format("%zu", conf.get<Config::Id::MaxMessageSize>())});
info.add_row({"batch-size", format("%zu", conf.get<Config::Id::BatchSize>())}); info.add_row({"batch-size", format("%zu", conf.get<Config::Id::BatchSize>())});
info.add_row({"created", tstamp(conf.get<Config::Id::Created>())}); info.add_row({"created", tstamp(conf.get<Config::Id::Created>())});
for (auto&& c : conf.get<Config::Id::PersonalAddresses>()) for (auto&& c : conf.get<Config::Id::PersonalAddresses>())
info.add_row({"personal-address", c}); info.add_row({"personal-address", c});
for (auto&& c : conf.get<Config::Id::IgnoredAddresses>())
info.add_row({"ignored-address", c});
info.add_row({"messages in store", format("%zu", store.size())}); info.add_row({"messages in store", format("%zu", store.size())});
info.add_row({"last-change", tstamp(store.statistics().last_change)}); info.add_row({"last-change", tstamp(store.statistics().last_change)});

View File

@ -46,10 +46,15 @@ Mu::mu_cmd_init(const Options& opts)
MemDb mdb; MemDb mdb;
Config conf{mdb}; Config conf{mdb};
if (opts.init.max_msg_size) if (opts.init.max_msg_size)
conf.set<Config::Id::MaxMessageSize>(*opts.init.max_msg_size); conf.set<Config::Id::MaxMessageSize>(*opts.init.max_msg_size);
if (opts.init.batch_size) if (opts.init.batch_size)
conf.set<Config::Id::MaxMessageSize>(*opts.init.batch_size); conf.set<Config::Id::MaxMessageSize>(*opts.init.batch_size);
if (!opts.init.my_addresses.empty())
conf.set<Config::Id::PersonalAddresses>(opts.init.my_addresses);
if (!opts.init.ignored_addresses.empty())
conf.set<Config::Id::IgnoredAddresses>(opts.init.ignored_addresses);
return Store::make_new(opts.runtime_path(RuntimePath::XapianDb), return Store::make_new(opts.runtime_path(RuntimePath::XapianDb),
opts.init.maildir, conf); opts.init.maildir, conf);
@ -67,4 +72,3 @@ Mu::mu_cmd_init(const Options& opts)
return Ok(); return Ok();
} }

View File

@ -383,8 +383,12 @@ sub_init(CLI::App& sub, Options& opts)
"Top of the maildir") "Top of the maildir")
->type_name("<maildir>"); ->type_name("<maildir>");
sub.add_option("--my-address", opts.init.my_addresses, sub.add_option("--my-address", opts.init.my_addresses,
"Personal e-mail addresses") "Personal e-mail address or regexp")
->type_name("<address>"); ->type_name("<address>");
sub.add_option("--ignored-address", opts.init.ignored_addresses,
"Ignored e-mail address or regexp")
->type_name("<address>");
sub.add_option("--max-message-size", opts.init.max_msg_size, sub.add_option("--max-message-size", opts.init.max_msg_size,
"Maximum allowed message size in bytes"); "Maximum allowed message size in bytes");
sub.add_option("--batch-size", opts.init.batch_size, sub.add_option("--batch-size", opts.init.batch_size,
@ -393,6 +397,7 @@ sub_init(CLI::App& sub, Options& opts)
"Re-initialize database with current settings") "Re-initialize database with current settings")
->excludes("--maildir") ->excludes("--maildir")
->excludes("--my-address") ->excludes("--my-address")
->excludes("--ignored-address")
->excludes("--max-message-size") ->excludes("--max-message-size")
->excludes("--batch-size"); ->excludes("--batch-size");
} }

View File

@ -184,6 +184,8 @@ struct Options {
struct Init { struct Init {
std::string maildir; /**< where the mails are */ std::string maildir; /**< where the mails are */
StringVec my_addresses; /**< personal e-mail addresses */ StringVec my_addresses; /**< personal e-mail addresses */
StringVec ignored_addresses; /**< addresses to be ignored for
* the contacts-cache */
OptSize max_msg_size; /**< max size for message files */ OptSize max_msg_size; /**< max size for message files */
OptSize batch_size; /**< db transaction batch size */ OptSize batch_size; /**< db transaction batch size */
bool reinit; /**< re-initialize */ bool reinit; /**< re-initialize */