Add support for creating special use mailboxes.
The IMAP CREATE-SPECIAL-USE extension allows specifying the use of a mailbox being created. We should use it if present. * src/engine/imap/api/imap-account.vala (Account::create_folder_async): Add optional SpecialFolderType param, if present use command variant that accepts it. * src/engine/imap/command/imap-create-command.vala (Command): Add additional ctor that accepts a SpecialFolderType param. If present, add a USE list to the command sent. * src/engine/imap/response/imap-capabilities.vala (Capabilities): Add CREATE-SPECIAL-USE to the list of known capabilities, sort the list.
This commit is contained in:
parent
bcca3f0332
commit
2015a72802
4 changed files with 94 additions and 25 deletions
|
|
@ -716,16 +716,15 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
|
|||
minimal_folder = folder_map.get(path);
|
||||
} else {
|
||||
debug("Creating %s to use as special folder %s", path.to_string(), special.to_string());
|
||||
|
||||
// TODO: ignore error due to already existing.
|
||||
yield remote.create_folder_async(path, cancellable);
|
||||
yield remote.create_folder_async(path, special, cancellable);
|
||||
minimal_folder = (MinimalFolder) yield fetch_folder_async(path, cancellable);
|
||||
}
|
||||
|
||||
|
||||
minimal_folder.set_special_folder_type(special);
|
||||
return minimal_folder;
|
||||
}
|
||||
|
||||
|
||||
public override async Geary.Folder get_required_special_folder_async(Geary.SpecialFolderType special,
|
||||
Cancellable? cancellable) throws Error {
|
||||
if (!(special in get_supported_special_folders())) {
|
||||
|
|
|
|||
|
|
@ -111,19 +111,36 @@ private class Geary.Imap.Account : BaseObject {
|
|||
return exists;
|
||||
}
|
||||
|
||||
public async void create_folder_async(FolderPath path, Cancellable? cancellable)
|
||||
/**
|
||||
* Creates a new special folder on the remote server.
|
||||
*
|
||||
* The given path must be a fully-qualified path, including
|
||||
* namespace prefix.
|
||||
*
|
||||
* If the optional special folder type is specified, and
|
||||
* CREATE-SPECIAL-USE is supported by the connection, that will be
|
||||
* used to specify the type of the new folder.
|
||||
*/
|
||||
public async void create_folder_async(FolderPath path,
|
||||
Geary.SpecialFolderType? type,
|
||||
Cancellable? cancellable)
|
||||
throws Error {
|
||||
ClientSession session = yield claim_session_async(cancellable);
|
||||
MailboxSpecifier mailbox = session.get_mailbox_for_path(path);
|
||||
bool can_create_special = session.capabilities.has_capability(Capabilities.CREATE_SPECIAL_USE);
|
||||
CreateCommand cmd = (type != null && can_create_special)
|
||||
? new CreateCommand.special_use(mailbox, type)
|
||||
: new CreateCommand(mailbox);
|
||||
|
||||
StatusResponse response = yield send_command_async(
|
||||
session,
|
||||
new CreateCommand(session.get_mailbox_for_path(path)),
|
||||
null, null,
|
||||
cancellable
|
||||
session, cmd, null, null, cancellable
|
||||
);
|
||||
|
||||
if (response.status != Status.OK) {
|
||||
throw new ImapError.SERVER_ERROR("Server reports error creating path %s: %s", path.to_string(),
|
||||
response.to_string());
|
||||
throw new ImapError.SERVER_ERROR(
|
||||
"Server reports error creating folder %s: %s",
|
||||
mailbox.to_string(), response.to_string()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
/* Copyright 2016 Software Freedom Conservancy Inc.
|
||||
/*
|
||||
* Copyright 2017 Michael Gratton <mike@vee.net>
|
||||
* Copyright 2016 Software Freedom Conservancy Inc.
|
||||
*
|
||||
* This software is licensed under the GNU Lesser General Public License
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
|
|
@ -10,14 +12,60 @@
|
|||
|
||||
public class Geary.Imap.CreateCommand : Command {
|
||||
public const string NAME = "create";
|
||||
|
||||
public const string USE = "use";
|
||||
|
||||
public MailboxSpecifier mailbox { get; private set; }
|
||||
|
||||
public Geary.SpecialFolderType? use { get; private set; default = null; }
|
||||
|
||||
|
||||
private static MailboxAttribute? get_special_folder_type(Geary.SpecialFolderType type) {
|
||||
switch (type) {
|
||||
case Geary.SpecialFolderType.TRASH:
|
||||
return MailboxAttribute.SPECIAL_FOLDER_TRASH;
|
||||
|
||||
case Geary.SpecialFolderType.DRAFTS:
|
||||
return MailboxAttribute.SPECIAL_FOLDER_DRAFTS;
|
||||
|
||||
case Geary.SpecialFolderType.SENT:
|
||||
return MailboxAttribute.SPECIAL_FOLDER_SENT;
|
||||
|
||||
case Geary.SpecialFolderType.ARCHIVE:
|
||||
return MailboxAttribute.SPECIAL_FOLDER_ARCHIVE;
|
||||
|
||||
case Geary.SpecialFolderType.SPAM:
|
||||
return MailboxAttribute.SPECIAL_FOLDER_JUNK;
|
||||
|
||||
case Geary.SpecialFolderType.FLAGGED:
|
||||
return MailboxAttribute.SPECIAL_FOLDER_STARRED;
|
||||
|
||||
case Geary.SpecialFolderType.ALL_MAIL:
|
||||
return MailboxAttribute.SPECIAL_FOLDER_ALL;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public CreateCommand(MailboxSpecifier mailbox) {
|
||||
base (NAME);
|
||||
|
||||
base(NAME);
|
||||
this.mailbox = mailbox;
|
||||
|
||||
add(mailbox.to_parameter());
|
||||
}
|
||||
|
||||
public CreateCommand.special_use(MailboxSpecifier mailbox, Geary.SpecialFolderType use) {
|
||||
this(mailbox);
|
||||
|
||||
MailboxAttribute? attr = get_special_folder_type(use);
|
||||
if (attr != null) {
|
||||
ListParameter use_types = new ListParameter();
|
||||
use_types.add(new AtomParameter(attr.to_string()));
|
||||
|
||||
ListParameter use_param = new ListParameter();
|
||||
use_param.add(new AtomParameter(USE));
|
||||
use_param.add(use_types);
|
||||
|
||||
add(use_param);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,20 +5,25 @@
|
|||
*/
|
||||
|
||||
public class Geary.Imap.Capabilities : Geary.GenericCapabilities {
|
||||
public const string IDLE = "IDLE";
|
||||
public const string STARTTLS = "STARTTLS";
|
||||
public const string XLIST = "XLIST";
|
||||
|
||||
|
||||
public const string CREATE_SPECIAL_USE = "CREATE-SPECIAL-USE";
|
||||
public const string COMPRESS = "COMPRESS";
|
||||
public const string DEFLATE_SETTING = "DEFLATE";
|
||||
public const string UIDPLUS = "UIDPLUS";
|
||||
public const string SPECIAL_USE = "SPECIAL-USE";
|
||||
public const string IDLE = "IDLE";
|
||||
public const string NAMESPACE = "NAMESPACE";
|
||||
public const string SPECIAL_USE = "SPECIAL-USE";
|
||||
public const string STARTTLS = "STARTTLS";
|
||||
public const string UIDPLUS = "UIDPLUS";
|
||||
public const string XLIST = "XLIST";
|
||||
|
||||
public const string NAME_SEPARATOR = "=";
|
||||
public const string? VALUE_SEPARATOR = null;
|
||||
|
||||
|
||||
|
||||
public int revision { get; private set; }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates an empty set of capabilities. revision represents the different variations of
|
||||
* capabilities that an IMAP session might offer (i.e. changes after login or STARTTLS, for
|
||||
|
|
@ -26,7 +31,7 @@ public class Geary.Imap.Capabilities : Geary.GenericCapabilities {
|
|||
*/
|
||||
public Capabilities(int revision) {
|
||||
base (NAME_SEPARATOR, VALUE_SEPARATOR);
|
||||
|
||||
|
||||
this.revision = revision;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue