mu-server: update for move_message API update
This commit is contained in:
111
lib/mu-server.cc
111
lib/mu-server.cc
@ -109,17 +109,17 @@ private:
|
|||||||
Store::Id docid,
|
Store::Id docid,
|
||||||
const Option<QueryMatch&> qm) const;
|
const Option<QueryMatch&> qm) const;
|
||||||
|
|
||||||
Sexp move_docid(Store::Id docid, Option<std::string> flagstr,
|
void move_docid(Store::Id docid, Option<std::string> flagstr,
|
||||||
bool new_name, bool no_view);
|
bool new_name, bool no_view);
|
||||||
|
|
||||||
Sexp perform_move(Store::Id docid,
|
void perform_move(Store::Id docid,
|
||||||
const Message& msg,
|
const Message& msg,
|
||||||
const std::string& maildirarg,
|
const std::string& maildirarg,
|
||||||
Flags flags,
|
Flags flags,
|
||||||
bool new_name,
|
bool new_name,
|
||||||
bool no_view);
|
bool no_view);
|
||||||
|
|
||||||
bool view_mark_as_read(Store::Id docid, const Message& msg, bool rename);
|
void view_mark_as_read(Store::Id docid, Message&& msg, bool rename);
|
||||||
|
|
||||||
Store& store_;
|
Store& store_;
|
||||||
Server::Output output_;
|
Server::Output output_;
|
||||||
@ -797,7 +797,7 @@ Server::Private::mkdir_handler(const Command& cmd)
|
|||||||
":message", format("%s has been created", path.c_str())));
|
":message", format("%s has been created", path.c_str())));
|
||||||
}
|
}
|
||||||
|
|
||||||
Sexp
|
void
|
||||||
Server::Private::perform_move(Store::Id docid,
|
Server::Private::perform_move(Store::Id docid,
|
||||||
const Message& msg,
|
const Message& msg,
|
||||||
const std::string& maildirarg,
|
const std::string& maildirarg,
|
||||||
@ -813,20 +813,26 @@ Server::Private::perform_move(Store::Id docid,
|
|||||||
} else /* are we moving to a different mdir, or is it just flags? */
|
} else /* are we moving to a different mdir, or is it just flags? */
|
||||||
different_mdir = maildir != msg.maildir();
|
different_mdir = maildir != msg.maildir();
|
||||||
|
|
||||||
const auto new_msg = store().move_message(docid, maildir, flags, new_name);
|
Store::MoveOptions move_opts{Store::MoveOptions::DupFlags};
|
||||||
if (!new_msg)
|
if (new_name)
|
||||||
throw new_msg.error();
|
move_opts |= Store::MoveOptions::ChangeName;
|
||||||
|
|
||||||
Sexp seq;
|
/* note: we get back _all_ the messages that changed; the first is the
|
||||||
seq.put_props(":update", build_message_sexp(new_msg.value(), docid, {}));
|
* primary mover; the rest (if present) are any dups affected */
|
||||||
|
const auto idmsgvec{store().move_message(docid, maildir, flags, move_opts)};
|
||||||
|
if (!idmsgvec)
|
||||||
|
throw idmsgvec.error();
|
||||||
|
|
||||||
|
for (auto&&[id, msg]: *idmsgvec) {
|
||||||
|
Sexp sexp{":update"_sym, build_message_sexp(idmsgvec->at(0).second, id, {})};
|
||||||
/* note, the :move t thing is a hint to the frontend that it
|
/* note, the :move t thing is a hint to the frontend that it
|
||||||
* could remove the particular header */
|
* could remove the particular header */
|
||||||
if (different_mdir)
|
if (different_mdir)
|
||||||
seq.put_props(":move", Sexp::t());
|
sexp.put_props(":move", Sexp::t());
|
||||||
if (!no_view)
|
if (!no_view && id == docid)
|
||||||
seq.put_props(":maybe-view", Sexp::t());
|
sexp.put_props(":maybe-view", Sexp::t());
|
||||||
|
output_sexp(std::move(sexp));
|
||||||
return seq;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -847,7 +853,7 @@ calculate_message_flags(const Message& msg, Option<std::string> flagopt)
|
|||||||
return flags.value();
|
return flags.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
Sexp
|
void
|
||||||
Server::Private::move_docid(Store::Id docid,
|
Server::Private::move_docid(Store::Id docid,
|
||||||
Option<std::string> flagopt,
|
Option<std::string> flagopt,
|
||||||
bool new_name,
|
bool new_name,
|
||||||
@ -861,9 +867,7 @@ Server::Private::move_docid(Store::Id docid,
|
|||||||
throw Error{Error::Code::Store, "failed to get message from store"};
|
throw Error{Error::Code::Store, "failed to get message from store"};
|
||||||
|
|
||||||
const auto flags = calculate_message_flags(msg.value(), flagopt);
|
const auto flags = calculate_message_flags(msg.value(), flagopt);
|
||||||
auto lst = perform_move(docid, *msg, "", flags, new_name, no_view);
|
perform_move(docid, *msg, "", flags, new_name, no_view);
|
||||||
|
|
||||||
return lst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -871,9 +875,6 @@ Server::Private::move_docid(Store::Id docid,
|
|||||||
* flags. parameters are *either* a 'docid:' or 'msgid:' pointing to
|
* flags. parameters are *either* a 'docid:' or 'msgid:' pointing to
|
||||||
* the message, a 'maildir:' for the target maildir, and a 'flags:'
|
* the message, a 'maildir:' for the target maildir, and a 'flags:'
|
||||||
* parameter for the new flags.
|
* parameter for the new flags.
|
||||||
*
|
|
||||||
* returns an (:update <new-msg-sexp>)
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
Server::Private::move_handler(const Command& cmd)
|
Server::Private::move_handler(const Command& cmd)
|
||||||
@ -890,8 +891,7 @@ Server::Private::move_handler(const Command& cmd)
|
|||||||
"can't move multiple messages at the same time"};
|
"can't move multiple messages at the same time"};
|
||||||
// multi.
|
// multi.
|
||||||
for (auto&& docid : docids)
|
for (auto&& docid : docids)
|
||||||
output_sexp(move_docid(docid, flagopt,
|
move_docid(docid, flagopt, rename, no_view);
|
||||||
rename, no_view));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto docid{docids.at(0)};
|
auto docid{docids.at(0)};
|
||||||
@ -907,7 +907,7 @@ Server::Private::move_handler(const Command& cmd)
|
|||||||
* we received (ie., flagstr), if any, plus the existing message
|
* we received (ie., flagstr), if any, plus the existing message
|
||||||
* flags. */
|
* flags. */
|
||||||
const auto flags = calculate_message_flags(msg, flagopt);
|
const auto flags = calculate_message_flags(msg, flagopt);
|
||||||
output_sexp(perform_move(docid, msg, maildir, flags, rename, no_view));
|
perform_move(docid, msg, maildir, flags, rename, no_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -982,43 +982,32 @@ Server::Private::sent_handler(const Command& cmd)
|
|||||||
":docid", docid.value()));
|
":docid", docid.value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
Server::Private::view_mark_as_read(Store::Id docid, const Message& msg, bool rename)
|
Server::Private::view_mark_as_read(Store::Id docid, Message&& msg, bool rename)
|
||||||
{
|
{
|
||||||
/* move some message if the flags changes; and send either a :view (main message
|
|
||||||
* or :update (the rest))*/
|
|
||||||
auto maybe_move = [&](Store::Id msg_docid, Flags old_flags,
|
|
||||||
bool do_rename, bool do_view)->bool {
|
|
||||||
|
|
||||||
const auto newflags{flags_from_delta_expr("+S-u-N", old_flags)};
|
auto move_res = std::invoke([&]()->Result<Store::IdMessageVec> {
|
||||||
if (!newflags || old_flags == *newflags)
|
const auto newflags{flags_from_delta_expr("+S-u-N", msg.flags())};
|
||||||
return false;
|
if (!newflags || msg.flags() == *newflags) {
|
||||||
|
/* case 1: message was already read; do nothing */
|
||||||
auto updated_msg = store().move_message(msg_docid, {}, newflags, do_rename);
|
Store::IdMessageVec idmvec;
|
||||||
if (!updated_msg)
|
idmvec.emplace_back(docid, std::move(msg));
|
||||||
throw updated_msg.error();
|
return idmvec;
|
||||||
|
} else {
|
||||||
output_sexp(Sexp().put_props(do_view ? ":view" : ":update",
|
/* case 2: move message (and possibly dups) */
|
||||||
build_message_sexp(*updated_msg, docid, {})));
|
Store::MoveOptions move_opts{Store::MoveOptions::DupFlags};
|
||||||
return true;
|
if (rename)
|
||||||
};
|
move_opts |= Store::MoveOptions::ChangeName;
|
||||||
|
return store().move_message(docid, {}, newflags, move_opts);
|
||||||
/* now get _al_ the message-ids for the given message-id,
|
|
||||||
* since, we want to apply the read-status to _all_. */
|
|
||||||
|
|
||||||
/* first the main message */
|
|
||||||
bool moved = maybe_move(docid, msg.flags(), rename, true/*:view*/);
|
|
||||||
|
|
||||||
/* now any other message with the same message-id */
|
|
||||||
for (auto&& rel_docid: docids_for_msgid(store_, msg.message_id())) {
|
|
||||||
/* ignore main one since we already handled it. */
|
|
||||||
if (rel_docid == docid)
|
|
||||||
continue;
|
|
||||||
if (auto msg{store().find_message(docid)}; msg)
|
|
||||||
maybe_move(rel_docid, msg->flags(), rename, false/*:update*/);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return moved;
|
if (!move_res)
|
||||||
|
throw move_res.error();
|
||||||
|
|
||||||
|
for (auto&& [id, msg]: move_res.value())
|
||||||
|
output_sexp(Sexp{id == docid ? ":view"_sym : ":update"_sym,
|
||||||
|
build_message_sexp(msg, id, {})});
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1038,10 +1027,12 @@ Server::Private::view_handler(const Command& cmd)
|
|||||||
.or_else([]{throw Error{Error::Code::Store,
|
.or_else([]{throw Error{Error::Code::Store,
|
||||||
"failed to find message for view"};}).value();
|
"failed to find message for view"};}).value();
|
||||||
|
|
||||||
/* if the message is marked-as-read, the response is handled there;
|
/* if the message should not be marked-as-read, we're done. */
|
||||||
* otherwise, we do so here. */
|
if (!mark_as_read)
|
||||||
if (!mark_as_read || !view_mark_as_read(docid, msg, rename))
|
|
||||||
output_sexp(Sexp().put_props(":view", build_message_sexp(msg, docid, {})));
|
output_sexp(Sexp().put_props(":view", build_message_sexp(msg, docid, {})));
|
||||||
|
else
|
||||||
|
view_mark_as_read(docid, std::move(msg), rename);
|
||||||
|
/* otherwise, mark message and and possible dups as read */
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::Server(Store& store, Server::Output output)
|
Server::Server(Store& store, Server::Output output)
|
||||||
|
|||||||
Reference in New Issue
Block a user