mirror of https://github.com/djcb/mu.git
mu: add "modified" fields
Add a new "modified" field for checking the last modification time of the message.
This commit is contained in:
parent
9e0173f387
commit
a864616110
|
@ -39,39 +39,28 @@ struct Field {
|
|||
*
|
||||
*/
|
||||
enum struct Id {
|
||||
/*
|
||||
* first all the string-based ones
|
||||
*/
|
||||
Bcc = 0, /**< Blind Carbon-Copy */
|
||||
BodyHtml, /**< HTML Body */
|
||||
BodyText, /**< Text body */
|
||||
Cc, /**< Carbon-Copy */
|
||||
EmbeddedText, /**< Embedded text in message */
|
||||
File, /**< Filename */
|
||||
From, /**< Message sender */
|
||||
Maildir, /**< Maildir path */
|
||||
Mime, /**< MIME-Type */
|
||||
MessageId, /**< Message Id */
|
||||
Path, /**< File-system Path */
|
||||
Subject, /**< Message subject */
|
||||
To, /**< To: recipient */
|
||||
/*
|
||||
* string list items...
|
||||
*/
|
||||
References, /**< All references (incl. Reply-To:) */
|
||||
Tags, /**< Message Tags */
|
||||
/*
|
||||
* then the numerical ones
|
||||
*/
|
||||
Date, /**< Message date */
|
||||
Flags, /**< Message flags */
|
||||
Priority, /**< Message priority */
|
||||
Size, /**< Message size (in bytes) */
|
||||
|
||||
/* add new ones here... */
|
||||
MailingList, /**< Mailing list */
|
||||
ThreadId, /**< Thread Id */
|
||||
|
||||
Bcc = 0, /**< Blind Carbon-Copy */
|
||||
BodyHtml, /**< HTML Body */
|
||||
BodyText, /**< Text body */
|
||||
Cc, /**< Carbon-Copy */
|
||||
Date, /**< Message date */
|
||||
EmbeddedText, /**< Embedded text in message */
|
||||
File, /**< Filename */
|
||||
Flags, /**< Message flags */
|
||||
From, /**< Message sender */
|
||||
Maildir, /**< Maildir path */
|
||||
MailingList, /**< Mailing list */
|
||||
MessageId, /**< Message Id */
|
||||
Mime, /**< MIME-Type */
|
||||
Modified, /**< Last modification time */
|
||||
Path, /**< File-system Path */
|
||||
Priority, /**< Message priority */
|
||||
References, /**< All references (incl. Reply-To:) */
|
||||
Size, /**< Message size (in bytes) */
|
||||
Subject, /**< Message subject */
|
||||
Tags, /**< Message Tags */
|
||||
ThreadId, /**< Thread Id */
|
||||
To, /**< To: recipient */
|
||||
/*
|
||||
* <private>
|
||||
*/
|
||||
|
@ -146,10 +135,9 @@ struct Field {
|
|||
Value = 1 << 11,
|
||||
/**< Field value is stored (so the literal value can be retrieved) */
|
||||
|
||||
DoNotCache = 1 << 20,
|
||||
/**< don't cache this field in * the MuMsg cache */
|
||||
Range = 1 << 21
|
||||
Range = 1 << 21,
|
||||
/**< whether this is a range field (e.g., date, size)*/
|
||||
Internal = 1 << 26
|
||||
};
|
||||
|
||||
constexpr bool any_of(Flag some_flag) const{
|
||||
|
@ -164,6 +152,7 @@ struct Field {
|
|||
is_normal_term(); }
|
||||
|
||||
constexpr bool is_value() const { return any_of(Flag::Value); }
|
||||
constexpr bool is_internal() const { return any_of(Flag::Internal); }
|
||||
|
||||
constexpr bool is_contact() const { return any_of(Flag::Contact); }
|
||||
constexpr bool is_range() const { return any_of(Flag::Range); }
|
||||
|
@ -215,7 +204,6 @@ MU_ENABLE_BITOPS(Field::Flag);
|
|||
static constexpr std::array<Field, Field::id_size()>
|
||||
Fields = {
|
||||
{
|
||||
// Bcc
|
||||
{
|
||||
Field::Id::Bcc,
|
||||
Field::Type::ContactList,
|
||||
|
@ -226,7 +214,6 @@ static constexpr std::array<Field, Field::id_size()>
|
|||
Field::Flag::Contact |
|
||||
Field::Flag::Value
|
||||
},
|
||||
// HTML Body
|
||||
{
|
||||
Field::Id::BodyHtml,
|
||||
Field::Type::String,
|
||||
|
@ -234,19 +221,17 @@ static constexpr std::array<Field, Field::id_size()>
|
|||
"Message html body",
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
Field::Flag::Internal
|
||||
},
|
||||
// Body
|
||||
{
|
||||
Field::Id::BodyText,
|
||||
Field::Type::String,
|
||||
"body",
|
||||
"Message plain-text body",
|
||||
"body:capybara", // example
|
||||
"body:capybara",
|
||||
'b',
|
||||
Field::Flag::IndexableTerm,
|
||||
},
|
||||
// Cc
|
||||
{
|
||||
Field::Id::Cc,
|
||||
Field::Type::ContactList,
|
||||
|
@ -257,124 +242,6 @@ static constexpr std::array<Field, Field::id_size()>
|
|||
Field::Flag::Contact |
|
||||
Field::Flag::Value
|
||||
},
|
||||
// Embed
|
||||
{
|
||||
Field::Id::EmbeddedText,
|
||||
Field::Type::String,
|
||||
"embed",
|
||||
"Embedded text",
|
||||
"embed:war OR embed:peace",
|
||||
'e',
|
||||
Field::Flag::IndexableTerm
|
||||
},
|
||||
// File
|
||||
{
|
||||
Field::Id::File,
|
||||
Field::Type::String,
|
||||
"file",
|
||||
"Attachment file name",
|
||||
"file:/image\\.*.jpg/",
|
||||
'j',
|
||||
Field::Flag::NormalTerm
|
||||
},
|
||||
// From
|
||||
{
|
||||
Field::Id::From,
|
||||
Field::Type::ContactList,
|
||||
"from",
|
||||
"Message sender",
|
||||
"from:jimbo",
|
||||
'f',
|
||||
Field::Flag::Contact |
|
||||
Field::Flag::Value
|
||||
},
|
||||
// Maildir
|
||||
{
|
||||
Field::Id::Maildir,
|
||||
Field::Type::String,
|
||||
"maildir",
|
||||
"Maildir path for message",
|
||||
"maildir:/private/archive",
|
||||
'm',
|
||||
Field::Flag::BooleanTerm |
|
||||
Field::Flag::Value
|
||||
},
|
||||
// MIME
|
||||
{
|
||||
Field::Id::Mime,
|
||||
Field::Type::String,
|
||||
"mime",
|
||||
"Attachment MIME-type",
|
||||
"mime:image/jpeg",
|
||||
'y',
|
||||
Field::Flag::NormalTerm
|
||||
},
|
||||
// Message-ID
|
||||
{
|
||||
Field::Id::MessageId,
|
||||
Field::Type::String,
|
||||
"msgid",
|
||||
"Attachment MIME-type",
|
||||
"msgid:abc@123",
|
||||
'i',
|
||||
Field::Flag::BooleanTerm |
|
||||
Field::Flag::Value
|
||||
},
|
||||
// Path
|
||||
{
|
||||
Field::Id::Path,
|
||||
Field::Type::String,
|
||||
"path",
|
||||
"File system path to message",
|
||||
{},
|
||||
'l',
|
||||
Field::Flag::BooleanTerm |
|
||||
Field::Flag::Value
|
||||
},
|
||||
// Subject
|
||||
{
|
||||
Field::Id::Subject,
|
||||
Field::Type::String,
|
||||
"subject",
|
||||
"Message subject",
|
||||
"subject:wombat",
|
||||
's',
|
||||
Field::Flag::Value |
|
||||
Field::Flag::IndexableTerm
|
||||
},
|
||||
// To
|
||||
{
|
||||
Field::Id::To,
|
||||
Field::Type::ContactList,
|
||||
"to",
|
||||
"Message recipient",
|
||||
"to:flimflam@example.com",
|
||||
't',
|
||||
Field::Flag::Contact |
|
||||
Field::Flag::Value
|
||||
},
|
||||
// References
|
||||
{
|
||||
Field::Id::References,
|
||||
Field::Type::StringList,
|
||||
"refs",
|
||||
"Message references to other messages",
|
||||
{},
|
||||
'r',
|
||||
Field::Flag::Value
|
||||
},
|
||||
// Tags
|
||||
{
|
||||
Field::Id::Tags,
|
||||
Field::Type::StringList,
|
||||
"tag",
|
||||
"Message tags",
|
||||
"tag:projectx",
|
||||
'x',
|
||||
Field::Flag::NormalTerm |
|
||||
Field::Flag::Value
|
||||
},
|
||||
// Date
|
||||
{
|
||||
Field::Id::Date,
|
||||
Field::Type::TimeT,
|
||||
|
@ -385,7 +252,24 @@ static constexpr std::array<Field, Field::id_size()>
|
|||
Field::Flag::Value |
|
||||
Field::Flag::Range
|
||||
},
|
||||
// Flags
|
||||
{
|
||||
Field::Id::EmbeddedText,
|
||||
Field::Type::String,
|
||||
"embed",
|
||||
"Embedded text",
|
||||
"embed:war OR embed:peace",
|
||||
'e',
|
||||
Field::Flag::IndexableTerm
|
||||
},
|
||||
{
|
||||
Field::Id::File,
|
||||
Field::Type::String,
|
||||
"file",
|
||||
"Attachment file name",
|
||||
"file:/image\\.*.jpg/",
|
||||
'j',
|
||||
Field::Flag::NormalTerm
|
||||
},
|
||||
{
|
||||
Field::Id::Flags,
|
||||
Field::Type::Integer,
|
||||
|
@ -396,7 +280,75 @@ static constexpr std::array<Field, Field::id_size()>
|
|||
Field::Flag::NormalTerm |
|
||||
Field::Flag::Value
|
||||
},
|
||||
// Priority
|
||||
{
|
||||
Field::Id::From,
|
||||
Field::Type::ContactList,
|
||||
"from",
|
||||
"Message sender",
|
||||
"from:jimbo",
|
||||
'f',
|
||||
Field::Flag::Contact |
|
||||
Field::Flag::Value
|
||||
},
|
||||
{
|
||||
Field::Id::Maildir,
|
||||
Field::Type::String,
|
||||
"maildir",
|
||||
"Maildir path for message",
|
||||
"maildir:/private/archive",
|
||||
'm',
|
||||
Field::Flag::BooleanTerm |
|
||||
Field::Flag::Value
|
||||
},
|
||||
{
|
||||
Field::Id::MailingList,
|
||||
Field::Type::String,
|
||||
"list",
|
||||
"Mailing list (List-Id:)",
|
||||
"list:mu-discuss.example.com",
|
||||
'v',
|
||||
Field::Flag::BooleanTerm |
|
||||
Field::Flag::Value
|
||||
},
|
||||
{
|
||||
Field::Id::MessageId,
|
||||
Field::Type::String,
|
||||
"msgid",
|
||||
"Attachment MIME-type",
|
||||
"msgid:abc@123",
|
||||
'i',
|
||||
Field::Flag::BooleanTerm |
|
||||
Field::Flag::Value
|
||||
},
|
||||
{
|
||||
Field::Id::Mime,
|
||||
Field::Type::String,
|
||||
"mime",
|
||||
"Attachment MIME-type",
|
||||
"mime:image/jpeg",
|
||||
'y',
|
||||
Field::Flag::NormalTerm
|
||||
},
|
||||
{
|
||||
Field::Id::Modified,
|
||||
Field::Type::TimeT,
|
||||
"modified",
|
||||
"Last modification time",
|
||||
"modified:30m..now",
|
||||
'k',
|
||||
Field::Flag::Value |
|
||||
Field::Flag::Range
|
||||
},
|
||||
{
|
||||
Field::Id::Path,
|
||||
Field::Type::String,
|
||||
"path",
|
||||
"File system path to message",
|
||||
"path:/a/b/Maildir/cur/msg:2,S",
|
||||
'l',
|
||||
Field::Flag::BooleanTerm |
|
||||
Field::Flag::Value
|
||||
},
|
||||
{
|
||||
Field::Id::Priority,
|
||||
Field::Type::Integer,
|
||||
|
@ -407,7 +359,15 @@ static constexpr std::array<Field, Field::id_size()>
|
|||
Field::Flag::BooleanTerm |
|
||||
Field::Flag::Value
|
||||
},
|
||||
// Size
|
||||
{
|
||||
Field::Id::References,
|
||||
Field::Type::StringList,
|
||||
"refs",
|
||||
"References to related messages",
|
||||
{},
|
||||
'r',
|
||||
Field::Flag::Value
|
||||
},
|
||||
{
|
||||
Field::Id::Size,
|
||||
Field::Type::ByteSize,
|
||||
|
@ -418,18 +378,26 @@ static constexpr std::array<Field, Field::id_size()>
|
|||
Field::Flag::Value |
|
||||
Field::Flag::Range
|
||||
},
|
||||
// Mailing List
|
||||
{
|
||||
Field::Id::MailingList,
|
||||
Field::Id::Subject,
|
||||
Field::Type::String,
|
||||
"list",
|
||||
"Mailing list (List-Id:)",
|
||||
"list:mu-discuss.googlegroups.com",
|
||||
'v',
|
||||
Field::Flag::BooleanTerm |
|
||||
"subject",
|
||||
"Message subject",
|
||||
"subject:wombat",
|
||||
's',
|
||||
Field::Flag::Value |
|
||||
Field::Flag::IndexableTerm
|
||||
},
|
||||
{
|
||||
Field::Id::Tags,
|
||||
Field::Type::StringList,
|
||||
"tag",
|
||||
"Message tags",
|
||||
"tag:projectx",
|
||||
'x',
|
||||
Field::Flag::NormalTerm |
|
||||
Field::Flag::Value
|
||||
},
|
||||
// ThreadId
|
||||
{
|
||||
Field::Id::ThreadId,
|
||||
Field::Type::String,
|
||||
|
@ -440,6 +408,16 @@ static constexpr std::array<Field, Field::id_size()>
|
|||
Field::Flag::BooleanTerm |
|
||||
Field::Flag::Value
|
||||
},
|
||||
{
|
||||
Field::Id::To,
|
||||
Field::Type::ContactList,
|
||||
"to",
|
||||
"Message recipient",
|
||||
"to:flimflam@example.com",
|
||||
't',
|
||||
Field::Flag::Contact |
|
||||
Field::Flag::Value
|
||||
},
|
||||
}};
|
||||
|
||||
/*
|
||||
|
|
|
@ -596,6 +596,9 @@ fill_document(Message::Private& priv)
|
|||
for (auto&& part: priv.parts)
|
||||
doc.add(field.id, part.mime_type());
|
||||
break;
|
||||
case Field::Id::Modified:
|
||||
doc.add(field.id, priv.mtime);
|
||||
break;
|
||||
case Field::Id::Path: /* already */
|
||||
break;
|
||||
case Field::Id::Priority:
|
||||
|
@ -708,8 +711,10 @@ Message::update_after_move(const std::string& new_path,
|
|||
return Err(statbuf.error());
|
||||
|
||||
priv_->doc.add(Field::Id::Path, new_path);
|
||||
priv_->doc.add(Field::Id::Modified, statbuf->st_mtime);
|
||||
priv_->doc.add(new_flags);
|
||||
|
||||
|
||||
if (const auto res = set_maildir(new_maildir); !res)
|
||||
return res;
|
||||
|
||||
|
|
|
@ -84,18 +84,29 @@ public:
|
|||
/**
|
||||
* Construct a message based on a Message::Document
|
||||
*
|
||||
* @param doc
|
||||
* @param doc a Mu Document
|
||||
*
|
||||
* @return a message or an error
|
||||
*/
|
||||
static Result<Message> make_from_document(Xapian::Document&& doc) try {
|
||||
return Ok(Message{Mu::Document{std::move(doc)}});
|
||||
static Result<Message> make_from_document(Mu::Document&& doc) try {
|
||||
return Ok(Message{std::move(doc)});
|
||||
} catch (Error& err) {
|
||||
return Err(err);
|
||||
} catch (...) {
|
||||
return Err(Mu::Error(Error::Code::Message, "failed to create message"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a message based on a Xapian::Document
|
||||
*
|
||||
* @param doc a xapian document
|
||||
*
|
||||
* @return a message or an error
|
||||
*/
|
||||
static Result<Message> make_from_document(Xapian::Document&& doc) noexcept {
|
||||
return make_from_document(Mu::Document{std::move(doc)});
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a message from a string. This is mostly useful for testing.
|
||||
|
||||
|
@ -216,12 +227,24 @@ public:
|
|||
std::string mailing_list() const { return document().string_value(Field::Id::MailingList);}
|
||||
|
||||
/**
|
||||
* get the message date/time (the Date: field) as time_t, using UTC
|
||||
* get the message date/time (the Date: field) as time_t
|
||||
*
|
||||
* @return message date/time or 0 in case of error or if there
|
||||
* is no such header.
|
||||
*/
|
||||
::time_t date() const { return static_cast<time_t>(document().integer_value(Field::Id::Date)); }
|
||||
::time_t date() const {
|
||||
return static_cast<::time_t>(document().integer_value(Field::Id::Date));
|
||||
}
|
||||
|
||||
/**
|
||||
* get the last modification or creation time for this message
|
||||
*
|
||||
* @return message date/time or 0 if unknown
|
||||
*/
|
||||
::time_t modified() const {
|
||||
return static_cast<::time_t>(document().integer_value(Field::Id::Modified));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the flags for this message.
|
||||
|
|
|
@ -177,7 +177,7 @@ process_range(const std::string& field_str,
|
|||
std::string u2 = upper;
|
||||
constexpr auto upper_limit = std::numeric_limits<int64_t>::max();
|
||||
|
||||
if (field_opt->id == Field::Id::Date) {
|
||||
if (field_opt->id == Field::Id::Date || field_opt->id == Field::Id::Modified) {
|
||||
l2 = to_lexnum(parse_date_time(lower, true).value_or(0));
|
||||
u2 = to_lexnum(parse_date_time(upper, false).value_or(upper_limit));
|
||||
} else if (field_opt->id == Field::Id::Size) {
|
||||
|
@ -420,7 +420,8 @@ Parser::Private::factor_2(Mu::Tokens& tokens, Node::Type& op, WarningVec& warnin
|
|||
op = Node::Type::OpAnd; // implicit AND
|
||||
break;
|
||||
|
||||
default: return empty();
|
||||
default:
|
||||
return empty();
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
|
Loading…
Reference in New Issue