mirror of https://github.com/djcb/mu.git
server: update (mu4e) server to use Mu::Message
This commit is contained in:
parent
9e9e16a7ec
commit
4a135e70fb
314
lib/mu-server.cc
314
lib/mu-server.cc
|
@ -20,7 +20,6 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "message/mu-message.hh"
|
#include "message/mu-message.hh"
|
||||||
#include "mu-msg.hh"
|
|
||||||
#include "mu-server.hh"
|
#include "mu-server.hh"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -40,7 +39,6 @@
|
||||||
#include "mu-query.hh"
|
#include "mu-query.hh"
|
||||||
#include "index/mu-indexer.hh"
|
#include "index/mu-indexer.hh"
|
||||||
#include "mu-store.hh"
|
#include "mu-store.hh"
|
||||||
#include "mu-msg-part.hh"
|
|
||||||
|
|
||||||
#include "utils/mu-str.h"
|
#include "utils/mu-str.h"
|
||||||
#include "utils/mu-utils.hh"
|
#include "utils/mu-utils.hh"
|
||||||
|
@ -115,23 +113,22 @@ struct Server::Private {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// helpers
|
// helpers
|
||||||
Sexp build_message_sexp(MuMsg* msg,
|
Sexp build_message_sexp(const Message& msg,
|
||||||
unsigned docid,
|
Store::Id docid,
|
||||||
const Option<QueryMatch&> qm,
|
const Option<QueryMatch&> qm) const;
|
||||||
MuMsgOptions opts) const;
|
|
||||||
|
|
||||||
Sexp::List move_docid(Store::Id docid, Option<std::string> flagstr,
|
Sexp::List move_docid(Store::Id docid, Option<std::string> flagstr,
|
||||||
bool new_name, bool no_view);
|
bool new_name, bool no_view);
|
||||||
|
|
||||||
Sexp::List perform_move(Store::Id docid,
|
Sexp::List perform_move(Store::Id docid,
|
||||||
MuMsg* 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 maybe_mark_as_read(MuMsg* msg, Store::Id docid, bool rename);
|
bool maybe_mark_as_read(Message& msg, Store::Id docid, bool rename);
|
||||||
bool maybe_mark_msgid_as_read(const char* msgid, bool rename);
|
bool maybe_mark_msgid_as_read(const std::string& msgid, bool rename);
|
||||||
|
|
||||||
Store& store_;
|
Store& store_;
|
||||||
Server::Output output_;
|
Server::Output output_;
|
||||||
|
@ -183,12 +180,11 @@ build_metadata(const QueryMatch& qmatch)
|
||||||
* optionally a :meta expression added.
|
* optionally a :meta expression added.
|
||||||
*/
|
*/
|
||||||
Sexp
|
Sexp
|
||||||
Server::Private::build_message_sexp(MuMsg* msg,
|
Server::Private::build_message_sexp(const Message& msg,
|
||||||
unsigned docid,
|
unsigned docid,
|
||||||
const Option<QueryMatch&> qm,
|
const Option<QueryMatch&> qm) const
|
||||||
MuMsgOptions opts) const
|
|
||||||
{
|
{
|
||||||
auto msgsexp{Mu::msg_to_sexp_list(msg, docid, opts)};
|
auto msgsexp{msg.to_sexp_list()};
|
||||||
if (qm)
|
if (qm)
|
||||||
msgsexp.add_prop(":meta", build_metadata(*qm));
|
msgsexp.add_prop(":meta", build_metadata(*qm));
|
||||||
|
|
||||||
|
@ -388,17 +384,15 @@ Server::Private::invoke(const std::string& expr) noexcept
|
||||||
return keep_going_;
|
return keep_going_;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MuMsgOptions
|
static Message::Options
|
||||||
message_options(const Parameters& params)
|
message_options(const Parameters& params)
|
||||||
{
|
{
|
||||||
const auto decrypt{get_bool_or(params, ":decrypt", false)};
|
Message::Options opts{};
|
||||||
|
|
||||||
int opts{MU_MSG_OPTION_NONE};
|
if (get_bool_or(params, ":decrypt", false))
|
||||||
|
opts |= Message::Options::Decrypt;
|
||||||
|
|
||||||
if (decrypt)
|
return opts;
|
||||||
opts |= MU_MSG_OPTION_DECRYPT | MU_MSG_OPTION_USE_AGENT;
|
|
||||||
|
|
||||||
return (MuMsgOptions)opts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 'add' adds a message to the database, and takes two parameters: 'path', which
|
/* 'add' adds a message to the database, and takes two parameters: 'path', which
|
||||||
|
@ -410,7 +404,12 @@ void
|
||||||
Server::Private::add_handler(const Parameters& params)
|
Server::Private::add_handler(const Parameters& params)
|
||||||
{
|
{
|
||||||
auto path{get_string_or(params, ":path")};
|
auto path{get_string_or(params, ":path")};
|
||||||
const auto docid{store().add_message(path)};
|
const auto docid_res{store().add_message(path)};
|
||||||
|
|
||||||
|
if (!docid_res)
|
||||||
|
throw Error(Error::Code::Store, "failed to add message to store");
|
||||||
|
|
||||||
|
const auto docid{docid_res.value()};
|
||||||
|
|
||||||
Sexp::List expr;
|
Sexp::List expr;
|
||||||
expr.add_prop(":info", Sexp::make_symbol("add"));
|
expr.add_prop(":info", Sexp::make_symbol("add"));
|
||||||
|
@ -419,46 +418,44 @@ Server::Private::add_handler(const Parameters& params)
|
||||||
|
|
||||||
output_sexp(Sexp::make_list(std::move(expr)));
|
output_sexp(Sexp::make_list(std::move(expr)));
|
||||||
|
|
||||||
auto msg{store().find_message(docid)};
|
auto msg_res{store().find_message(docid)};
|
||||||
if (!msg)
|
if (!msg_res)
|
||||||
throw Error(Error::Code::Store,
|
throw Error(Error::Code::Store,
|
||||||
"failed to get message at %s (docid=%u)",
|
"failed to get message at %s (docid=%u)",
|
||||||
path.c_str(),
|
path.c_str(), docid);
|
||||||
docid);
|
|
||||||
|
|
||||||
Sexp::List update;
|
Sexp::List update;
|
||||||
update.add_prop(":update", build_message_sexp(msg, docid, {}, MU_MSG_OPTION_VERIFY));
|
update.add_prop(":update", build_message_sexp(msg_res.value(), docid, {}));
|
||||||
output_sexp(Sexp::make_list(std::move(update)));
|
output_sexp(Sexp::make_list(std::move(update)));
|
||||||
mu_msg_unref(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PartInfo {
|
// struct PartInfo {
|
||||||
Sexp::List attseq;
|
// Sexp::List attseq;
|
||||||
MuMsgOptions opts;
|
// MuMsgOptions opts;
|
||||||
};
|
// };
|
||||||
|
|
||||||
static void
|
// static void
|
||||||
each_part(MuMsg* msg, MuMsgPart* part, PartInfo* pinfo)
|
// each_part(const Message& msg, MuMsgPart* part, PartInfo* pinfo)
|
||||||
{
|
// {
|
||||||
/* exclude things that don't look like proper attachments, unless they're images */
|
// /* exclude things that don't look like proper attachments, unless they're images */
|
||||||
if (!mu_msg_part_maybe_attachment(part))
|
// if (!mu_msg_part_maybe_attachment(part))
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
GError* gerr{};
|
// GError* gerr{};
|
||||||
char* cachefile =
|
// char* cachefile =
|
||||||
mu_msg_part_save_temp(msg,
|
// mu_msg_part_save_temp(msg,
|
||||||
(MuMsgOptions)(pinfo->opts | MU_MSG_OPTION_OVERWRITE),
|
// (MuMsgOptions)(pinfo->opts | MU_MSG_OPTION_OVERWRITE),
|
||||||
part->index,
|
// part->index,
|
||||||
&gerr);
|
// &gerr);
|
||||||
if (!cachefile)
|
// if (!cachefile)
|
||||||
throw Error(Error::Code::File, &gerr, "failed to save part");
|
// throw Error(Error::Code::File, &gerr, "failed to save part");
|
||||||
|
|
||||||
Sexp::List pi;
|
// Sexp::List pi;
|
||||||
pi.add_prop(":file-name", Sexp::make_string(cachefile));
|
// pi.add_prop(":file-name", Sexp::make_string(cachefile));
|
||||||
pi.add_prop(":mime-type", Sexp::make_string(format("%s/%s", part->type, part->subtype)));
|
// pi.add_prop(":mime-type", Sexp::make_string(format("%s/%s", part->type, part->subtype)));
|
||||||
pinfo->attseq.add(Sexp::make_list(std::move(pi)));
|
// pinfo->attseq.add(Sexp::make_list(std::move(pi)));
|
||||||
g_free(cachefile);
|
// g_free(cachefile);
|
||||||
}
|
// }
|
||||||
|
|
||||||
/* 'compose' produces the un-changed *original* message sexp (ie., the message
|
/* 'compose' produces the un-changed *original* message sexp (ie., the message
|
||||||
* to reply to, forward or edit) for a new message to compose). It takes two
|
* to reply to, forward or edit) for a new message to compose). It takes two
|
||||||
|
@ -479,29 +476,33 @@ Server::Private::compose_handler(const Parameters& params)
|
||||||
Sexp::List comp_lst;
|
Sexp::List comp_lst;
|
||||||
comp_lst.add_prop(":compose", Sexp::make_symbol(std::string(ctype)));
|
comp_lst.add_prop(":compose", Sexp::make_symbol(std::string(ctype)));
|
||||||
|
|
||||||
if (ctype == "reply" || ctype == "forward" || ctype == "edit" || ctype == "resend") {
|
|
||||||
GError* gerr{};
|
|
||||||
const unsigned docid{(unsigned)get_int_or(params, ":docid")};
|
|
||||||
auto msg{store().find_message(docid)};
|
|
||||||
if (!msg)
|
|
||||||
throw Error{Error::Code::Store, &gerr, "failed to get message %u", docid};
|
|
||||||
|
|
||||||
const auto opts{message_options(params)};
|
if (ctype == "reply" || ctype == "forward" || ctype == "edit" || ctype == "resend") {
|
||||||
comp_lst.add_prop(":original", build_message_sexp(msg, docid, {}, opts));
|
const unsigned docid{(unsigned)get_int_or(params, ":docid")};
|
||||||
|
auto msg{store().find_message(docid)};
|
||||||
|
if (!msg)
|
||||||
|
throw Error{Error::Code::Store, "failed to get message %u", docid};
|
||||||
|
|
||||||
|
comp_lst.add_prop(":original", build_message_sexp(msg.value(), docid, {}));
|
||||||
|
|
||||||
if (ctype == "forward") {
|
if (ctype == "forward") {
|
||||||
PartInfo pinfo{};
|
// for (auto&& part: msg->parts()) {
|
||||||
pinfo.opts = opts;
|
// if (!part.is_attachment())
|
||||||
mu_msg_part_foreach(msg, opts, (MuMsgPartForeachFunc)each_part, &pinfo);
|
// continue;
|
||||||
if (!pinfo.attseq.empty())
|
|
||||||
comp_lst.add_prop(":include",
|
|
||||||
Sexp::make_list(std::move(pinfo.attseq)));
|
|
||||||
|
|
||||||
|
// PartInfo pinfo{};
|
||||||
|
// pinfo.opts = opts;
|
||||||
|
// mu_msg_part_foreach(msg, opts, (MuMsgPartForeachFunc)each_part, &pinfo);
|
||||||
|
// if (!pinfo.attseq.empty())
|
||||||
|
// comp_lst.add_prop(":include",
|
||||||
|
// Sexp::make_list(std::move(pinfo.attseq)));
|
||||||
}
|
}
|
||||||
mu_msg_unref(msg);
|
|
||||||
|
|
||||||
} else if (ctype != "new")
|
} else if (ctype != "new")
|
||||||
throw Error(Error::Code::InvalidArgument,
|
throw Error(Error::Code::InvalidArgument, "invalid compose type '%s'",
|
||||||
"invalid compose type '%s'",
|
|
||||||
ctype.c_str());
|
ctype.c_str());
|
||||||
|
|
||||||
output_sexp(std::move(comp_lst));
|
output_sexp(std::move(comp_lst));
|
||||||
|
@ -588,22 +589,17 @@ docids_for_msgid(const Store& store, const std::string& msgid, size_t max = 100)
|
||||||
* mu_store_get_path could be added if this turns out to be a problem
|
* mu_store_get_path could be added if this turns out to be a problem
|
||||||
*/
|
*/
|
||||||
static std::string
|
static std::string
|
||||||
path_from_docid(const Store& store, unsigned docid)
|
path_from_docid(const Store& store, Store::Id docid)
|
||||||
{
|
{
|
||||||
auto msg{store.find_message(docid)};
|
auto msg{store.find_message(docid)};
|
||||||
if (!msg)
|
if (!msg)
|
||||||
throw Error(Error::Code::Store, "could not get message from store");
|
throw Error(Error::Code::Store, "could not get message from store");
|
||||||
|
|
||||||
auto p{mu_msg_get_path(msg)};
|
if (auto path{msg->path()}; path.empty())
|
||||||
if (!p) {
|
throw Error(Error::Code::Store, "could not get path for message %u",
|
||||||
mu_msg_unref(msg);
|
docid);
|
||||||
throw Error(Error::Code::Store, "could not get path for message %u", docid);
|
else
|
||||||
}
|
return path;
|
||||||
|
|
||||||
std::string msgpath{p};
|
|
||||||
mu_msg_unref(msg);
|
|
||||||
|
|
||||||
return msgpath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<Store::Id>
|
static std::vector<Store::Id>
|
||||||
|
@ -635,14 +631,14 @@ Server::Private::output_results(const QueryResults& qres, size_t batch_size) con
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto&& mi : qres) {
|
for (auto&& mi : qres) {
|
||||||
auto msg{mi.floating_msg()};
|
auto msg{mi.message()};
|
||||||
if (!msg)
|
if (!msg)
|
||||||
continue;
|
continue;
|
||||||
++n;
|
++n;
|
||||||
|
|
||||||
// construct sexp for a single header.
|
// construct sexp for a single header.
|
||||||
auto qm{mi.query_match()};
|
auto qm{mi.query_match()};
|
||||||
headers.add(build_message_sexp(msg, mi.doc_id(), qm, MU_MSG_OPTION_HEADERS_ONLY));
|
headers.add(build_message_sexp(*msg, mi.doc_id(), qm));
|
||||||
// we output up-to-batch-size lists of messages. It's much
|
// we output up-to-batch-size lists of messages. It's much
|
||||||
// faster (on the emacs side) to handle such batches than single
|
// faster (on the emacs side) to handle such batches than single
|
||||||
// headers.
|
// headers.
|
||||||
|
@ -817,7 +813,7 @@ Server::Private::mkdir_handler(const Parameters& params)
|
||||||
|
|
||||||
Sexp::List
|
Sexp::List
|
||||||
Server::Private::perform_move(Store::Id docid,
|
Server::Private::perform_move(Store::Id docid,
|
||||||
MuMsg* msg,
|
const Message& msg,
|
||||||
const std::string& maildirarg,
|
const std::string& maildirarg,
|
||||||
Flags flags,
|
Flags flags,
|
||||||
bool new_name,
|
bool new_name,
|
||||||
|
@ -826,17 +822,16 @@ Server::Private::perform_move(Store::Id docid,
|
||||||
bool different_mdir{};
|
bool different_mdir{};
|
||||||
auto maildir{maildirarg};
|
auto maildir{maildirarg};
|
||||||
if (maildir.empty()) {
|
if (maildir.empty()) {
|
||||||
maildir = mu_msg_get_maildir(msg);
|
maildir = msg.maildir();
|
||||||
different_mdir = false;
|
different_mdir = false;
|
||||||
} 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 != mu_msg_get_maildir(msg);
|
different_mdir = maildir != msg.maildir();
|
||||||
|
|
||||||
GError* gerr{};
|
#warning implement me
|
||||||
|
// if (!mu_msg_move_to_maildir(msg,
|
||||||
if (!mu_msg_move_to_maildir(msg,
|
// store().properties().root_maildir,
|
||||||
store().properties().root_maildir,
|
// maildir, flags, true, new_name, &gerr))
|
||||||
maildir, flags, true, new_name, &gerr))
|
// throw Error{Error::Code::File, &gerr, "failed to move message"};
|
||||||
throw Error{Error::Code::File, &gerr, "failed to move message"};
|
|
||||||
|
|
||||||
/* after mu_msg_move_to_maildir, path will be the *new* path, and flags and maildir
|
/* after mu_msg_move_to_maildir, path will be the *new* path, and flags and maildir
|
||||||
* fields will be updated as wel */
|
* fields will be updated as wel */
|
||||||
|
@ -844,7 +839,7 @@ Server::Private::perform_move(Store::Id docid,
|
||||||
throw Error{Error::Code::Store, "failed to store updated message"};
|
throw Error{Error::Code::Store, "failed to store updated message"};
|
||||||
|
|
||||||
Sexp::List seq;
|
Sexp::List seq;
|
||||||
seq.add_prop(":update", build_message_sexp(msg, docid, {}, MU_MSG_OPTION_VERIFY));
|
seq.add_prop(":update", build_message_sexp(msg, docid, {}));
|
||||||
/* 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)
|
||||||
|
@ -857,14 +852,13 @@ Server::Private::perform_move(Store::Id docid,
|
||||||
|
|
||||||
|
|
||||||
static Flags
|
static Flags
|
||||||
calculate_message_flags(MuMsg* msg, Option<std::string> flagopt)
|
calculate_message_flags(const Message& msg, Option<std::string> flagopt)
|
||||||
{
|
{
|
||||||
const auto flags = std::invoke([&]()->Option<Flags>{
|
const auto flags = std::invoke([&]()->Option<Flags>{
|
||||||
auto msgflags{mu_msg_get_flags(msg)};
|
|
||||||
if (!flagopt)
|
if (!flagopt)
|
||||||
return mu_msg_get_flags(msg);
|
return msg.flags();
|
||||||
else
|
else
|
||||||
return flags_from_expr(*flagopt, msgflags);
|
return flags_from_expr(*flagopt, msg.flags());
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!flags)
|
if (!flags)
|
||||||
|
@ -884,20 +878,12 @@ Server::Private::move_docid(Store::Id docid,
|
||||||
throw Error{Error::Code::InvalidArgument, "invalid docid"};
|
throw Error{Error::Code::InvalidArgument, "invalid docid"};
|
||||||
|
|
||||||
auto msg{store_.find_message(docid)};
|
auto msg{store_.find_message(docid)};
|
||||||
try {
|
if (!msg)
|
||||||
if (!msg)
|
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, flagopt);
|
const auto flags = calculate_message_flags(msg.value(), flagopt);
|
||||||
auto lst = perform_move(docid, msg, "", flags, new_name, no_view);
|
auto lst = perform_move(docid, *msg, "", flags, new_name, no_view);
|
||||||
mu_msg_unref(msg);
|
return lst;
|
||||||
return lst;
|
|
||||||
|
|
||||||
} catch (...) {
|
|
||||||
if (msg)
|
|
||||||
mu_msg_unref(msg);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -929,28 +915,19 @@ Server::Private::move_handler(const Parameters& params)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto docid{docids.at(0)};
|
auto docid{docids.at(0)};
|
||||||
|
auto msg = store().find_message(docid)
|
||||||
GError* gerr{};
|
.or_else([]{throw Error{Error::Code::InvalidArgument,
|
||||||
auto msg{store().find_message(docid)};
|
"could not create message"};}).value();
|
||||||
if (!msg)
|
|
||||||
throw Error{Error::Code::InvalidArgument, &gerr, "could not create message"};
|
|
||||||
|
|
||||||
/* if maildir was not specified, take the current one */
|
/* if maildir was not specified, take the current one */
|
||||||
if (maildir.empty())
|
if (maildir.empty())
|
||||||
maildir = mu_msg_get_maildir(msg);
|
maildir = msg.maildir();
|
||||||
|
|
||||||
/* determine the real target flags, which come from the flags-parameter
|
/* determine the real target flags, which come from the flags-parameter
|
||||||
* 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);
|
||||||
try {
|
output_sexp(perform_move(docid, msg, maildir, flags, rename, no_view));
|
||||||
output_sexp(perform_move(docid, msg, maildir, flags, rename, no_view));
|
|
||||||
} catch (...) {
|
|
||||||
mu_msg_unref(msg);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
mu_msg_unref(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1027,76 +1004,66 @@ void
|
||||||
Server::Private::sent_handler(const Parameters& params)
|
Server::Private::sent_handler(const Parameters& params)
|
||||||
{
|
{
|
||||||
const auto path{get_string_or(params, ":path")};
|
const auto path{get_string_or(params, ":path")};
|
||||||
const auto docid{store().add_message(path)};
|
const auto docid = store().add_message(path);
|
||||||
if (docid == Store::InvalidId)
|
if (!docid)
|
||||||
throw Error{Error::Code::Store, "failed to add path"};
|
throw Error{Error::Code::Store, "failed to add path"};
|
||||||
|
|
||||||
|
|
||||||
Sexp::List lst;
|
Sexp::List lst;
|
||||||
lst.add_prop(":sent", Sexp::make_symbol("t"));
|
lst.add_prop(":sent", Sexp::make_symbol("t"));
|
||||||
lst.add_prop(":path", Sexp::make_string(path));
|
lst.add_prop(":path", Sexp::make_string(path));
|
||||||
lst.add_prop(":docid", Sexp::make_number(docid));
|
lst.add_prop(":docid", Sexp::make_number(docid.value()));
|
||||||
|
|
||||||
output_sexp(std::move(lst));
|
output_sexp(std::move(lst));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Server::Private::maybe_mark_as_read(MuMsg* msg, Store::Id docid, bool rename)
|
Server::Private::maybe_mark_as_read(Message& msg, Store::Id docid, bool rename)
|
||||||
{
|
{
|
||||||
if (!msg)
|
// const auto oldflags{msg.flags()};
|
||||||
throw Error{Error::Code::Store, "missing message"};
|
// const auto newflags{flags_from_delta_expr("+S-u-N", oldflags)};
|
||||||
|
// if (!newflags || oldflags == *newflags)
|
||||||
|
// return false; // nothing to do.
|
||||||
|
|
||||||
const auto oldflags{mu_msg_get_flags(msg)};
|
// GError* gerr{};
|
||||||
const auto newflags{flags_from_delta_expr("+S-u-N", oldflags)};
|
// if (!mu_msg_move_to_maildir(msg,
|
||||||
if (!newflags || oldflags == *newflags)
|
// store().properties().root_maildir,
|
||||||
return false; // nothing to do.
|
// mu_msg_get_maildir(msg),
|
||||||
|
// *newflags,
|
||||||
|
// true,
|
||||||
|
// rename,
|
||||||
|
// &gerr))
|
||||||
|
// throw Error{Error::Code::File, &gerr, "failed to move message"};
|
||||||
|
|
||||||
GError* gerr{};
|
// /* after mu_msg_move_to_maildir, path will be the *new* path, and flags and maildir
|
||||||
if (!mu_msg_move_to_maildir(msg,
|
// * fields will be updated as wel */
|
||||||
store().properties().root_maildir,
|
// if (!store().update_message(msg, docid))
|
||||||
mu_msg_get_maildir(msg),
|
// throw Error{Error::Code::Store, "failed to store updated message"};
|
||||||
*newflags,
|
|
||||||
true,
|
|
||||||
rename,
|
|
||||||
&gerr))
|
|
||||||
throw Error{Error::Code::File, &gerr, "failed to move message"};
|
|
||||||
|
|
||||||
/* after mu_msg_move_to_maildir, path will be the *new* path, and flags and maildir
|
// /* send an update */
|
||||||
* fields will be updated as wel */
|
// Sexp::List update;
|
||||||
if (!store().update_message(msg, docid))
|
// update.add_prop(":update", build_message_sexp(msg, docid, {}, MU_MSG_OPTION_NONE));
|
||||||
throw Error{Error::Code::Store, "failed to store updated message"};
|
// output_sexp(Sexp::make_list(std::move(update)));
|
||||||
|
|
||||||
/* send an update */
|
// g_debug("marked message %d as read => %s", docid, mu_msg_get_path(msg));
|
||||||
Sexp::List update;
|
|
||||||
update.add_prop(":update", build_message_sexp(msg, docid, {}, MU_MSG_OPTION_NONE));
|
|
||||||
output_sexp(Sexp::make_list(std::move(update)));
|
|
||||||
|
|
||||||
g_debug("marked message %d as read => %s", docid, mu_msg_get_path(msg));
|
|
||||||
|
|
||||||
|
#warning implement me
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Server::Private::maybe_mark_msgid_as_read(const char* msgid, bool rename) try {
|
Server::Private::maybe_mark_msgid_as_read(const std::string& msgid,
|
||||||
|
bool rename) try {
|
||||||
if (!msgid)
|
if (!msgid.empty())
|
||||||
return false; // nothing to do.
|
return false; // nothing to do.
|
||||||
|
|
||||||
const auto docids{docids_for_msgid(store_, std::string{msgid})};
|
for (auto&& docid: docids_for_msgid(store_, msgid))
|
||||||
for (auto&& docid : docids) {
|
if (auto msg{store().find_message(docid)}; msg)
|
||||||
MuMsg* msg = store().find_message(docid);
|
maybe_mark_as_read(msg.value(), docid, rename);
|
||||||
if (!msg)
|
|
||||||
continue;
|
|
||||||
try {
|
|
||||||
maybe_mark_as_read(msg, docid, rename);
|
|
||||||
} catch (...) {
|
|
||||||
mu_msg_unref(msg);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (...) { /* not fatal */
|
} catch (...) { /* not fatal */
|
||||||
g_warning("failed to mark <%s> as read", msgid);
|
g_warning("failed to mark <%s> as read", msgid.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1114,20 +1081,19 @@ Server::Private::view_handler(const Parameters& params)
|
||||||
throw Error{Error::Code::Store, "failed to find message for view"};
|
throw Error{Error::Code::Store, "failed to find message for view"};
|
||||||
|
|
||||||
const auto docid{docids.at(0)};
|
const auto docid{docids.at(0)};
|
||||||
MuMsg* msg{store().find_message(docid)};
|
auto msg = store().find_message(docid)
|
||||||
if (!msg)
|
.or_else([]{throw Error{Error::Code::Store,
|
||||||
throw Error{Error::Code::Store, "failed to find message for view"};
|
"failed to find message for view"};}).value();
|
||||||
|
|
||||||
if (mark_as_read) {
|
if (mark_as_read) {
|
||||||
// maybe mark the main message as read.
|
// maybe mark the main message as read.
|
||||||
maybe_mark_as_read(msg, docid, rename);
|
maybe_mark_as_read(msg, docid, rename);
|
||||||
/* maybe mark _all_ messsage with same message-id as read */
|
/* maybe mark _all_ messsage with same message-id as read */
|
||||||
maybe_mark_msgid_as_read(mu_msg_get_msgid(msg), rename);
|
maybe_mark_msgid_as_read(msg.message_id(), rename);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sexp::List seq;
|
Sexp::List seq;
|
||||||
seq.add_prop(":view", build_message_sexp(msg, docid, {}, MU_MSG_OPTION_NONE));
|
seq.add_prop(":view", build_message_sexp(msg, docid, {}));
|
||||||
mu_msg_unref(msg);
|
|
||||||
output_sexp(std::move(seq));
|
output_sexp(std::move(seq));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue