message/flags: add flags_from_path
Borrow from mu-maildir, to which we cannot link.
This commit is contained in:
@ -39,6 +39,90 @@ Mu::flags_to_string(Flags flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The file-components, ie.
|
||||||
|
* 1631819685.fb7b279bbb0a7b66.evergrey:2,RS
|
||||||
|
* => {
|
||||||
|
* "1631819685.fb7b279bbb0a7b66.evergrey",
|
||||||
|
* ':',
|
||||||
|
* "2,",
|
||||||
|
* "RS"
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
struct FileParts {
|
||||||
|
std::string base;
|
||||||
|
char separator;
|
||||||
|
std::string flags_suffix;;
|
||||||
|
};
|
||||||
|
|
||||||
|
static FileParts
|
||||||
|
message_file_parts(const std::string& file)
|
||||||
|
{
|
||||||
|
const auto pos{file.find_last_of(":!;")};
|
||||||
|
|
||||||
|
/* no suffix at all? */
|
||||||
|
if (pos == std::string::npos ||
|
||||||
|
pos >= file.length() - 3 ||
|
||||||
|
file[pos + 1] != '2' ||
|
||||||
|
file[pos + 2] != ',')
|
||||||
|
return FileParts{ file, ':', {}};
|
||||||
|
|
||||||
|
return FileParts {
|
||||||
|
file.substr(0, pos),
|
||||||
|
file[pos],
|
||||||
|
file.substr(pos + 3)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct DirFile {
|
||||||
|
std::string dir;
|
||||||
|
std::string file;
|
||||||
|
bool is_new;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Option<DirFile>
|
||||||
|
base_message_dir_file(const std::string& path)
|
||||||
|
{
|
||||||
|
constexpr auto newdir{ G_DIR_SEPARATOR_S "new"};
|
||||||
|
|
||||||
|
if (path.empty())
|
||||||
|
return Nothing;
|
||||||
|
|
||||||
|
char *dirname{g_path_get_dirname(path.c_str())};
|
||||||
|
bool is_new{!!g_str_has_suffix(dirname, newdir)};
|
||||||
|
|
||||||
|
std::string mdir{dirname, ::strlen(dirname) - 4};
|
||||||
|
g_free(dirname);
|
||||||
|
|
||||||
|
char *basename{g_path_get_basename(path.c_str())};
|
||||||
|
std::string bname{basename};
|
||||||
|
g_free(basename);
|
||||||
|
|
||||||
|
return DirFile{std::move(mdir), std::move(bname), is_new};
|
||||||
|
}
|
||||||
|
|
||||||
|
Mu::Option<Mu::Flags>
|
||||||
|
Mu::flags_from_path(const std::string& path)
|
||||||
|
{ /*
|
||||||
|
* this gets us the source maildir filesystem path, the directory
|
||||||
|
* in which new/ & cur/ lives, and the source file
|
||||||
|
*/
|
||||||
|
auto dirfile{base_message_dir_file(path)};
|
||||||
|
if (!dirfile)
|
||||||
|
return Nothing;
|
||||||
|
|
||||||
|
/* a message under new/ is just.. New. Filename is not considered */
|
||||||
|
if (dirfile->is_new)
|
||||||
|
return Flags::New;
|
||||||
|
|
||||||
|
/* it's cur/ message, so parse the file name */
|
||||||
|
const auto parts{message_file_parts(dirfile->file)};
|
||||||
|
return flags_from_absolute_expr(parts.flags_suffix, true/*ignore invalid*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* flags & flag-info
|
* flags & flag-info
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -278,7 +278,7 @@ flags_from_delta_expr(std::string_view expr, Flags flags,
|
|||||||
* @return either messages flags or Nothing in case of error.
|
* @return either messages flags or Nothing in case of error.
|
||||||
*/
|
*/
|
||||||
constexpr Option<Flags>
|
constexpr Option<Flags>
|
||||||
flags_from_expr(std::string_view expr,
|
flags_from_expr(std::string_view expr,
|
||||||
Option<Flags> flags = Nothing)
|
Option<Flags> flags = Nothing)
|
||||||
{
|
{
|
||||||
if (expr.empty())
|
if (expr.empty())
|
||||||
@ -291,6 +291,19 @@ flags_from_expr(std::string_view expr,
|
|||||||
return flags_from_absolute_expr(expr, true);
|
return flags_from_absolute_expr(expr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Maildir flags from the full path of a mailfile. The flags are as
|
||||||
|
* specified in http://cr.yp.to/proto/maildir.html, plus MU_MSG_FLAG_NEW for new
|
||||||
|
* messages, ie the ones that live in new/. The flags are logically OR'ed. Note
|
||||||
|
* that the file does not have to exist; the flags are based on the path only.
|
||||||
|
*
|
||||||
|
* @param pathname of a mailfile; it does not have to refer to an existing
|
||||||
|
* file/message
|
||||||
|
*
|
||||||
|
* @return the message flags or Nothing
|
||||||
|
*/
|
||||||
|
Option<Flags> flags_from_path(const std::string& path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter out flags which are not in the given category
|
* Filter out flags which are not in the given category
|
||||||
*
|
*
|
||||||
|
|||||||
@ -305,8 +305,7 @@ base_message_dir_file(const std::string& path)
|
|||||||
return Ok(DirFile{std::move(mdir), std::move(bname), is_new});
|
return Ok(DirFile{std::move(mdir), std::move(bname), is_new});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// refactor: we have the same code in mu-flags.cc
|
||||||
|
|
||||||
|
|
||||||
Mu::Result<Mu::Flags>
|
Mu::Result<Mu::Flags>
|
||||||
Mu::mu_maildir_flags_from_path(const std::string& path)
|
Mu::mu_maildir_flags_from_path(const std::string& path)
|
||||||
|
|||||||
Reference in New Issue
Block a user