message: refactor file handling, add ::mtime()

This commit is contained in:
Dirk-Jan C. Binnema 2022-04-22 08:11:19 +03:00
parent f0bfb38ff2
commit a548cac2d0
2 changed files with 47 additions and 10 deletions

View File

@ -39,7 +39,6 @@
#include "gmime/gmime-message.h" #include "gmime/gmime-message.h"
#include "mu-mime-object.hh" #include "mu-mime-object.hh"
#include "mu-msg-priv.hh"
using namespace Mu; using namespace Mu;
@ -56,6 +55,8 @@ struct Message::Private {
std::vector<std::string> references; std::vector<std::string> references;
std::vector<Part> parts; std::vector<Part> parts;
::time_t mtime{};
/* /*
* we only need to index these, so we don't * we only need to index these, so we don't
* really need these copy if we re-arrange things * really need these copy if we re-arrange things
@ -69,22 +70,38 @@ struct Message::Private {
static void fill_document(Message::Private& priv); static void fill_document(Message::Private& priv);
Message::Message(Message::Options opts, const std::string& path, const std::string& mdir): static Result<struct stat>
priv_{std::make_unique<Private>(opts)} get_statbuf(const std::string& path)
{ {
if (!g_path_is_absolute(path.c_str())) if (!g_path_is_absolute(path.c_str()))
throw Error(Error::Code::File, "path '%s' is not absolute", path.c_str()); return Err(Error::Code::File, "path '%s' is not absolute",
path.c_str());
if (::access(path.c_str(), R_OK) != 0) if (::access(path.c_str(), R_OK) != 0)
throw Error(Error::Code::File, "file @ '%s' is not readable", path.c_str()); return Err(Error::Code::File, "file @ '%s' is not readable",
path.c_str());
struct stat statbuf{}; struct stat statbuf{};
if (::stat(path.c_str(), &statbuf) < 0) if (::stat(path.c_str(), &statbuf) < 0)
throw Error(Error::Code::File, "cannot stat %s: %s", path.c_str(), return Err(Error::Code::File, "cannot stat %s: %s", path.c_str(),
g_strerror(errno)); g_strerror(errno));
if (!S_ISREG(statbuf.st_mode)) if (!S_ISREG(statbuf.st_mode))
throw Error(Error::Code::File, "not a regular file: %s", path.c_str()); return Err(Error::Code::File, "not a regular file: %s", path.c_str());
return Ok(std::move(statbuf));
}
Message::Message(Message::Options opts, const std::string& path,
const std::string& mdir):
priv_{std::make_unique<Private>(opts)}
{
const auto statbuf{get_statbuf(path)};
if (!statbuf)
throw statbuf.error();
priv_->mtime = statbuf->st_mtime;
init_gmime(); init_gmime();
if (auto msg{MimeMessage::make_from_file(path)}; !msg) if (auto msg{MimeMessage::make_from_file(path)}; !msg)
@ -99,7 +116,7 @@ Message::Message(Message::Options opts, const std::string& path, const std::stri
if (!mdir.empty()) if (!mdir.empty())
priv_->doc.add(Field::Id::Maildir, mdir); priv_->doc.add(Field::Id::Maildir, mdir);
priv_->doc.add(Field::Id::Size, static_cast<int64_t>(statbuf.st_size)); priv_->doc.add(Field::Id::Size, static_cast<int64_t>(statbuf->st_size));
// rest of the fields // rest of the fields
fill_document(*priv_); fill_document(*priv_);
@ -233,7 +250,8 @@ get_tags(const MimeMessage& mime_msg)
std::vector<std::string> tags; std::vector<std::string> tags;
seq_for_each(tag_headers, [&](auto&& item) { seq_for_each(tag_headers, [&](auto&& item) {
if (auto hdr{mime_msg.header(item.first)}; hdr) { if (auto&& hdr{mime_msg.header(item.first)}; hdr) {
auto lst = split(*hdr, item.second); auto lst = split(*hdr, item.second);
tags.reserve(tags.size() + lst.size()); tags.reserve(tags.size() + lst.size());
tags.insert(tags.end(), lst.begin(), lst.end()); tags.insert(tags.end(), lst.begin(), lst.end());
@ -658,3 +676,14 @@ Message::parts() const
return priv_->parts; return priv_->parts;
} }
::time_t
Message::mtime() const
{
if (!load_mime_message())
return 0;
return priv_->mtime;
}

View File

@ -309,6 +309,14 @@ public:
*/ */
Option<std::string> header(const std::string& header_field) const; Option<std::string> header(const std::string& header_field) const;
/**
* Get the mtime for the message file.
*
* @return the mtime
*/
::time_t mtime() const;
/** /**
* Get all contacts for this message. * Get all contacts for this message.
* *