mu-message: various small tweaks
- Remove possible cache-dir - Retain Personal flag - Handle some corner cases
This commit is contained in:
@ -27,6 +27,7 @@
|
||||
#include <string>
|
||||
#include <regex>
|
||||
#include <utils/mu-utils.hh>
|
||||
#include <utils/mu-utils-file.hh>
|
||||
#include <utils/mu-error.hh>
|
||||
#include <utils/mu-option.hh>
|
||||
#include <utils/mu-lang-detector.hh>
|
||||
@ -50,6 +51,14 @@ struct Message::Private {
|
||||
Private(Message::Options options, Xapian::Document&& xdoc):
|
||||
opts{options}, doc{std::move(xdoc), doc_opts(opts)} {}
|
||||
|
||||
~Private() { /* clean up the cache dir, if any */
|
||||
if (cache_path.empty())
|
||||
return;
|
||||
if (auto&& res{remove_directory(cache_path)}; !res)
|
||||
mu_warning("failed to remove cache dir '{}': {}",
|
||||
cache_path, res.error().what());
|
||||
}
|
||||
|
||||
Message::Options opts;
|
||||
Document doc;
|
||||
mutable Option<MimeMessage> mime_msg;
|
||||
@ -78,7 +87,7 @@ struct Message::Private {
|
||||
|
||||
private:
|
||||
Document::Options doc_opts(Message::Options mopts) {
|
||||
return any_of(opts & Message::Options::NgramsEnabled) ?
|
||||
return any_of(mopts & Message::Options::NgramsEnabled) ?
|
||||
Document::Options::NgramsEnabled :
|
||||
Document::Options::None;
|
||||
}
|
||||
@ -326,7 +335,8 @@ extract_tags(const MimeMessage& mime_msg)
|
||||
for (auto&& tagval : split(*hdr, item.second)) {
|
||||
tagval.erase(0, tagval.find_first_not_of(' '));
|
||||
tagval.erase(tagval.find_last_not_of(' ')+1);
|
||||
tags.emplace_back(std::move(tagval));
|
||||
if (!tagval.empty())
|
||||
tags.emplace_back(std::move(tagval));
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -493,6 +503,9 @@ handle_encrypted(const MimeMultipartEncrypted& part, Message::Private& info)
|
||||
}
|
||||
|
||||
if (res->first.is_multipart()) {
|
||||
/* handle the multipart itself too, so e.g. a decrypted
|
||||
* multipart/signed sets the Signed flag */
|
||||
handle_object(part, res->first, info);
|
||||
MimeMultipart{res->first}.for_each(
|
||||
[&](auto&& parent, auto&& child_obj) {
|
||||
handle_object(parent, child_obj, info);
|
||||
@ -538,8 +551,7 @@ handle_object(const MimeObject& parent,
|
||||
handle_encrypted(MimeMultipartEncrypted{obj}, info);
|
||||
else if (obj.is_part() ||
|
||||
obj.is_message_part() ||
|
||||
obj.is_multipart_signed() ||
|
||||
obj.is_multipart_encrypted())
|
||||
obj.is_multipart_signed())
|
||||
info.parts.emplace_back(obj);
|
||||
|
||||
if (obj.is_part())
|
||||
@ -662,13 +674,14 @@ doc_add_list_post(Document& doc, const MimeMessage& mime_msg)
|
||||
* those cases, check the List-Post address and use that instead */
|
||||
|
||||
GMatchInfo* minfo{};
|
||||
GRegex* rx{};
|
||||
const auto list_post{mime_msg.header("List-Post")};
|
||||
if (!list_post)
|
||||
return;
|
||||
|
||||
rx = g_regex_new("<?mailto:([a-z0-9!@#$%&'*+-/=?^_`{|}~]+)>?",
|
||||
G_REGEX_CASELESS, (GRegexMatchFlags)0, {});
|
||||
/* compile the regex only once */
|
||||
static GRegex *rx = g_regex_new(
|
||||
"<?mailto:([a-z0-9!@#$%&'*+-/=?^_`{|}~]+)>?",
|
||||
G_REGEX_CASELESS, (GRegexMatchFlags)0, {});
|
||||
g_return_if_fail(rx);
|
||||
|
||||
Contacts contacts;
|
||||
@ -681,8 +694,6 @@ doc_add_list_post(Document& doc, const MimeMessage& mime_msg)
|
||||
if (minfo)
|
||||
g_match_info_free(minfo);
|
||||
|
||||
g_regex_unref(rx);
|
||||
|
||||
doc.add_extra_contacts(":list-post", contacts);
|
||||
}
|
||||
|
||||
@ -732,7 +743,10 @@ fill_document(Message::Private& priv)
|
||||
doc.add(field.id, mime_msg.contacts(Contact::Type::Cc));
|
||||
break;
|
||||
case Field::Id::Changed:
|
||||
doc.add(field.id, priv.ctime);
|
||||
/* when lazily re-filling a store-backed message, we
|
||||
* never stat'ed the file; keep the stored value */
|
||||
if (priv.ctime != 0)
|
||||
doc.add(field.id, priv.ctime);
|
||||
break;
|
||||
case Field::Id::Date:
|
||||
doc.add(field.id, mime_msg.date());
|
||||
@ -745,7 +759,12 @@ fill_document(Message::Private& priv)
|
||||
doc.add(field.id, part.raw_filename());
|
||||
break;
|
||||
case Field::Id::Flags:
|
||||
doc.add(priv.flags);
|
||||
/* the stored flags may include Flags::Personal, which
|
||||
* is determined with the contacts-cache (mu-store.cc)
|
||||
* and cannot be recomputed here; don't lose it when
|
||||
* lazily re-filling a store-backed message */
|
||||
doc.add(flags_keep_unmutable(doc.flags_value(), priv.flags,
|
||||
Flags::Personal));
|
||||
break;
|
||||
case Field::Id::From:
|
||||
doc.add(field.id, mime_msg.contacts(Contact::Type::From));
|
||||
@ -806,7 +825,9 @@ fill_document(Message::Private& priv)
|
||||
Option<std::string>
|
||||
Message::header(const std::string& header_field) const
|
||||
{
|
||||
load_mime_message();
|
||||
if (!load_mime_message())
|
||||
return Nothing;
|
||||
|
||||
return priv_->mime_msg->header(header_field);
|
||||
}
|
||||
|
||||
@ -860,11 +881,11 @@ Message::cache_path(Option<size_t> index) const
|
||||
}
|
||||
|
||||
if (index) {
|
||||
GError *err{};
|
||||
auto tpath = mu_format("{}/{}", priv_->cache_path, *index);
|
||||
if (g_mkdir(tpath.c_str(), 0700) != 0)
|
||||
return Err(Error::Code::File, &err,
|
||||
"failed to create cache dir '{}'; err={}", tpath, errno);
|
||||
if (g_mkdir(tpath.c_str(), 0700) != 0 && errno != EEXIST)
|
||||
return Err(Error::Code::File,
|
||||
"failed to create cache dir '{}': {}", tpath,
|
||||
g_strerror(errno));
|
||||
return Ok(std::move(tpath));
|
||||
} else
|
||||
|
||||
|
||||
Reference in New Issue
Block a user