mirror of https://github.com/djcb/mu.git
message: allow extracting message parts to file
And add unit-test. Fixes #2467
This commit is contained in:
parent
cd23e6015d
commit
026a19bcfa
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** Copyright (C) 2022 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
** Copyright (C) 2023 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||||
**
|
**
|
||||||
** This program is free software; you can redistribute it and/or modify it
|
** This program is free software; you can redistribute it and/or modify it
|
||||||
** under the terms of the GNU General Public License as published by the
|
** under the terms of the GNU General Public License as published by the
|
||||||
|
@ -156,16 +156,18 @@ MessagePart::to_string() const noexcept
|
||||||
return mime_object().to_string_opt();
|
return mime_object().to_string_opt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Result<size_t>
|
Result<size_t>
|
||||||
MessagePart::to_file(const std::string& path, bool overwrite) const noexcept
|
MessagePart::to_file(const std::string& path, bool overwrite) const noexcept
|
||||||
{
|
{
|
||||||
if (!mime_object().is_part())
|
if (mime_object().is_part())
|
||||||
return Err(Error::Code::InvalidArgument,
|
|
||||||
"not a part");
|
|
||||||
else
|
|
||||||
return MimePart{mime_object()}.to_file(path, overwrite);
|
return MimePart{mime_object()}.to_file(path, overwrite);
|
||||||
|
else if (mime_object().is_message_part()) {
|
||||||
|
if (auto&& msg{MimeMessagePart{mime_object()}.get_message()}; !msg)
|
||||||
|
return Err(Error::Code::Message, "failed to get message-part");
|
||||||
|
else
|
||||||
|
return msg->to_file(path, overwrite);
|
||||||
|
} else
|
||||||
|
return mime_object().to_file(path, overwrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** Copyright (C) 2022 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
** Copyright (C) 2023 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||||
**
|
**
|
||||||
** This program is free software; you can redistribute it and/or modify it
|
** This program is free software; you can redistribute it and/or modify it
|
||||||
** under the terms of the GNU General Public License as published by the
|
** under the terms of the GNU General Public License as published by the
|
||||||
|
@ -53,7 +53,6 @@ public:
|
||||||
*/
|
*/
|
||||||
~MessagePart();
|
~MessagePart();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the underlying MimeObject; you need to include mu-mime-object.hh
|
* Get the underlying MimeObject; you need to include mu-mime-object.hh
|
||||||
* to do anything useful with it.
|
* to do anything useful with it.
|
||||||
|
|
|
@ -125,8 +125,6 @@ MimeObject::headers() const noexcept
|
||||||
return hdrs;
|
return hdrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Result<size_t>
|
Result<size_t>
|
||||||
MimeObject::write_to_stream(const MimeFormatOptions& f_opts,
|
MimeObject::write_to_stream(const MimeFormatOptions& f_opts,
|
||||||
MimeStream& stream) const
|
MimeStream& stream) const
|
||||||
|
@ -139,6 +137,22 @@ MimeObject::write_to_stream(const MimeFormatOptions& f_opts,
|
||||||
return Ok(static_cast<size_t>(written));
|
return Ok(static_cast<size_t>(written));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<size_t>
|
||||||
|
MimeObject::to_file(const std::string& path, bool overwrite) const noexcept
|
||||||
|
{
|
||||||
|
GError *err{};
|
||||||
|
auto strm{g_mime_stream_fs_open(path.c_str(),
|
||||||
|
O_WRONLY | O_CREAT | O_TRUNC |(overwrite ? 0 : O_EXCL),
|
||||||
|
S_IRUSR|S_IWUSR,
|
||||||
|
&err)};
|
||||||
|
if (!strm)
|
||||||
|
return Err(Error::Code::File, &err, "failed to open '%s'", path.c_str());
|
||||||
|
|
||||||
|
MimeStream stream{MimeStream::make_from_stream(strm)};
|
||||||
|
return write_to_stream({}, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Option<std::string>
|
Option<std::string>
|
||||||
MimeObject::to_string_opt() const noexcept
|
MimeObject::to_string_opt() const noexcept
|
||||||
{
|
{
|
||||||
|
@ -525,11 +539,8 @@ MimePart::to_string() const noexcept
|
||||||
buffer.resize(buflen);
|
buffer.resize(buflen);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Result<size_t>
|
Result<size_t>
|
||||||
MimePart::to_file(const std::string& path, bool overwrite) const noexcept
|
MimePart::to_file(const std::string& path, bool overwrite) const noexcept
|
||||||
{
|
{
|
||||||
|
@ -558,9 +569,6 @@ MimePart::to_file(const std::string& path, bool overwrite) const noexcept
|
||||||
return Ok(static_cast<size_t>(written));
|
return Ok(static_cast<size_t>(written));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MimeMultipart::for_each(const ForEachFunc& func) const noexcept
|
MimeMultipart::for_each(const ForEachFunc& func) const noexcept
|
||||||
{
|
{
|
||||||
|
|
|
@ -829,6 +829,16 @@ public:
|
||||||
*/
|
*/
|
||||||
Option<std::string> to_string_opt() const noexcept;
|
Option<std::string> to_string_opt() const noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write object to a file
|
||||||
|
*
|
||||||
|
* @param path path to file
|
||||||
|
* @param overwrite if true, overwrite existing file, if it bqexists
|
||||||
|
*
|
||||||
|
* @return size of the wrtten file, or an error.
|
||||||
|
*/
|
||||||
|
Result<size_t> to_file(const std::string& path, bool overwrite) const noexcept;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* subtypes.
|
* subtypes.
|
||||||
*/
|
*/
|
||||||
|
@ -1101,7 +1111,6 @@ public:
|
||||||
*/
|
*/
|
||||||
Option<std::string> to_string() const noexcept;
|
Option<std::string> to_string() const noexcept;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write part to a file
|
* Write part to a file
|
||||||
*
|
*
|
||||||
|
@ -1113,7 +1122,6 @@ public:
|
||||||
Result<size_t> to_file(const std::string& path, bool overwrite)
|
Result<size_t> to_file(const std::string& path, bool overwrite)
|
||||||
const noexcept;
|
const noexcept;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Types of Content Encoding.
|
* Types of Content Encoding.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** Copyright (C) 2022 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
** Copyright (C) 2023 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||||
**
|
**
|
||||||
** This program is free software; you can redistribute it and/or modify it
|
** This program is free software; you can redistribute it and/or modify it
|
||||||
** under the terms of the GNU General Public License as published by the
|
** under the terms of the GNU General Public License as published by the
|
||||||
|
@ -249,6 +249,10 @@ World!
|
||||||
{
|
{
|
||||||
auto&& part{message->parts().at(3)};
|
auto&& part{message->parts().at(3)};
|
||||||
g_assert_true(part.mime_type() == "message/rfc822");
|
g_assert_true(part.mime_type() == "message/rfc822");
|
||||||
|
|
||||||
|
const auto fname{*cache_path + "/msgpart"};
|
||||||
|
g_assert_cmpuint(part.to_file(fname, true).value_or(123), ==, 139);
|
||||||
|
g_assert_true(::access(fname.c_str(), F_OK) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue