WIP
This commit is contained in:
parent
9084602be6
commit
5fbdbca3d2
13 changed files with 254 additions and 122 deletions
|
|
@ -82,6 +82,7 @@ engine/imap/message/imap-fetch-data-type.vala
|
|||
engine/imap/message/imap-fetched-data.vala
|
||||
engine/imap/message/imap-flag.vala
|
||||
engine/imap/message/imap-mailbox-information.vala
|
||||
engine/imap/message/imap-mailbox-specifier.vala
|
||||
engine/imap/message/imap-mailbox-parameter.vala
|
||||
engine/imap/message/imap-message-data.vala
|
||||
engine/imap/message/imap-message-set.vala
|
||||
|
|
|
|||
|
|
@ -391,7 +391,7 @@ class ImapConsole : Gtk.Window {
|
|||
|
||||
status("Listing...");
|
||||
cx.send_async.begin(new Geary.Imap.ListCommand.wildcarded(args[0],
|
||||
new Geary.Imap.MailboxParameter(args[1]), (cmd.down() == "xlist")), null, on_list);
|
||||
new Geary.Imap.MailboxSpecifier(args[1]), (cmd.down() == "xlist")), null, on_list);
|
||||
}
|
||||
|
||||
private void on_list(Object? source, AsyncResult result) {
|
||||
|
|
@ -407,7 +407,7 @@ class ImapConsole : Gtk.Window {
|
|||
check_connected(cmd, args, 1, "<mailbox>");
|
||||
|
||||
status("Opening %s read-only".printf(args[0]));
|
||||
cx.send_async.begin(new Geary.Imap.ExamineCommand(new Geary.Imap.MailboxParameter(args[0])),
|
||||
cx.send_async.begin(new Geary.Imap.ExamineCommand(new Geary.Imap.MailboxSpecifier(args[0])),
|
||||
null, on_examine);
|
||||
}
|
||||
|
||||
|
|
@ -488,7 +488,7 @@ class ImapConsole : Gtk.Window {
|
|||
for (int ctr = 1; ctr < args.length; ctr++)
|
||||
data_items += Geary.Imap.StatusDataType.decode(args[ctr]);
|
||||
|
||||
cx.send_async.begin(new Geary.Imap.StatusCommand(new Geary.Imap.MailboxParameter(args[0]),
|
||||
cx.send_async.begin(new Geary.Imap.StatusCommand(new Geary.Imap.MailboxSpecifier(args[0]),
|
||||
data_items), null, on_get_status);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ public class Geary.Engine : BaseObject {
|
|||
yield imap_session.initiate_session_async(account.imap_credentials, cancellable);
|
||||
|
||||
// Connected and initiated, still need to be sure connection authorized
|
||||
string current_mailbox;
|
||||
Imap.MailboxSpecifier current_mailbox;
|
||||
if (imap_session.get_context(out current_mailbox) != Imap.ClientSession.Context.AUTHORIZED)
|
||||
error_code |= ValidationResult.IMAP_CREDENTIALS_INVALID;
|
||||
} catch (Error err) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
* calling a fetch or list operation several times in a row will return separate Folder objects
|
||||
* each time. It is up to the higher layers of the stack to manage these objects.
|
||||
*/
|
||||
|
||||
private class Geary.Imap.Account : BaseObject {
|
||||
// all references to Inbox are converted to this string, purely for sanity sake when dealing
|
||||
// with Inbox's case issues
|
||||
|
|
@ -127,9 +128,9 @@ private class Geary.Imap.Account : BaseObject {
|
|||
if (!mailbox_info.attrs.contains(MailboxAttribute.NO_SELECT)) {
|
||||
StatusData status = yield fetch_status_async(path, cancellable);
|
||||
|
||||
return new Imap.Folder(session_mgr, path, status, mailbox_info);
|
||||
return new Imap.Folder(session_mgr, status, mailbox_info);
|
||||
} else {
|
||||
return new Imap.Folder.unselectable(session_mgr, path, mailbox_info);
|
||||
return new Imap.Folder.unselectable(session_mgr, mailbox_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -143,7 +144,7 @@ private class Geary.Imap.Account : BaseObject {
|
|||
|
||||
Gee.List<MailboxInformation> list_results = new Gee.ArrayList<MailboxInformation>();
|
||||
StatusResponse response = yield send_command_async(
|
||||
new ListCommand(new Imap.MailboxParameter(processed.get_fullpath()), can_xlist),
|
||||
new ListCommand(new MailboxSpecifier.from_folder_path(processed), can_xlist),
|
||||
list_results, null, cancellable);
|
||||
|
||||
throw_fetch_error(response, processed, list_results.size);
|
||||
|
|
@ -161,7 +162,7 @@ private class Geary.Imap.Account : BaseObject {
|
|||
|
||||
Gee.List<StatusData> status_results = new Gee.ArrayList<StatusData>();
|
||||
StatusResponse response = yield send_command_async(
|
||||
new StatusCommand(new MailboxParameter(processed.get_fullpath()), StatusDataType.all()),
|
||||
new StatusCommand(new MailboxSpecifier.from_folder_path(processed), StatusDataType.all()),
|
||||
null, status_results, cancellable);
|
||||
|
||||
throw_fetch_error(response, processed, status_results.size);
|
||||
|
|
@ -197,23 +198,20 @@ private class Geary.Imap.Account : BaseObject {
|
|||
|
||||
Gee.List<Imap.Folder> child_folders = new Gee.ArrayList<Imap.Folder>();
|
||||
|
||||
Gee.Map<FolderPath, MailboxInformation> info_map = new Gee.HashMap<FolderPath, MailboxInformation>();
|
||||
Gee.Map<StatusCommand, FolderPath> cmd_map = new Gee.HashMap<StatusCommand, FolderPath>();
|
||||
Gee.Map<MailboxSpecifier, MailboxInformation> info_map = new Gee.HashMap<
|
||||
MailboxSpecifier, MailboxInformation>();
|
||||
Gee.Map<StatusCommand, MailboxSpecifier> cmd_map = new Gee.HashMap<
|
||||
StatusCommand, MailboxSpecifier>();
|
||||
foreach (MailboxInformation mailbox_info in child_info) {
|
||||
FolderPath? child_path = process_path(processed, mailbox_info.get_basename(),
|
||||
mailbox_info.delim);
|
||||
if (child_path == null)
|
||||
continue;
|
||||
|
||||
if (mailbox_info.attrs.contains(MailboxAttribute.NO_SELECT)) {
|
||||
child_folders.add(new Imap.Folder.unselectable(session_mgr, child_path, mailbox_info));
|
||||
child_folders.add(new Imap.Folder.unselectable(session_mgr, mailbox_info));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
info_map.set(child_path, mailbox_info);
|
||||
cmd_map.set(new StatusCommand(new MailboxParameter(child_path.get_fullpath()),
|
||||
StatusDataType.all()), child_path);
|
||||
info_map.set(mailbox_info.mailbox, mailbox_info);
|
||||
cmd_map.set(new StatusCommand(mailbox_info.mailbox, StatusDataType.all()),
|
||||
mailbox_info.mailbox);
|
||||
}
|
||||
|
||||
Gee.List<StatusData> status_results = new Gee.ArrayList<StatusData>();
|
||||
|
|
@ -224,18 +222,18 @@ private class Geary.Imap.Account : BaseObject {
|
|||
StatusCommand status_cmd = (StatusCommand) cmd;
|
||||
StatusResponse response = responses.get(cmd);
|
||||
|
||||
FolderPath child_path = cmd_map.get(status_cmd);
|
||||
MailboxInformation mailbox_info = info_map.get(child_path);
|
||||
MailboxSpecifier mailbox = cmd_map.get(status_cmd);
|
||||
MailboxInformation mailbox_info = info_map.get(mailbox);
|
||||
|
||||
if (response.status != Status.OK) {
|
||||
message("Unable to get STATUS of %s: %s", child_path.to_string(), response.to_string());
|
||||
message("Unable to get STATUS of %s: %s", mailbox.to_string(), response.to_string());
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
StatusData? found_status = null;
|
||||
foreach (StatusData status_data in status_results) {
|
||||
if (status_data.mailbox == child_path.get_fullpath()) {
|
||||
if (status_data.mailbox.equal_to(mailbox)) {
|
||||
found_status = status_data;
|
||||
|
||||
break;
|
||||
|
|
@ -243,13 +241,13 @@ private class Geary.Imap.Account : BaseObject {
|
|||
}
|
||||
|
||||
if (found_status == null) {
|
||||
message("Unable to get STATUS of %s: not returned from server", child_path.to_string());
|
||||
message("Unable to get STATUS of %s: not returned from server", mailbox.to_string());
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
status_results.remove(found_status);
|
||||
child_folders.add(new Imap.Folder(session_mgr, child_path, found_status, mailbox_info));
|
||||
child_folders.add(new Imap.Folder(session_mgr, found_status, mailbox_info));
|
||||
}
|
||||
|
||||
if (status_results.size > 0)
|
||||
|
|
@ -267,14 +265,14 @@ private class Geary.Imap.Account : BaseObject {
|
|||
|
||||
ListCommand cmd;
|
||||
if (processed == null) {
|
||||
cmd = new ListCommand.wildcarded("", new MailboxParameter("%"), can_xlist);
|
||||
cmd = new ListCommand.wildcarded("", new MailboxSpecifier("%"), can_xlist);
|
||||
} else {
|
||||
string specifier = processed.get_fullpath();
|
||||
string delim = processed.get_root().default_separator;
|
||||
|
||||
specifier += specifier.has_suffix(delim) ? "%" : (delim + "%");
|
||||
|
||||
cmd = new ListCommand(new Imap.MailboxParameter(specifier), can_xlist);
|
||||
cmd = new ListCommand(new MailboxSpecifier(specifier), can_xlist);
|
||||
}
|
||||
|
||||
Gee.List<MailboxInformation> list_results = new Gee.ArrayList<MailboxInformation>();
|
||||
|
|
|
|||
|
|
@ -47,20 +47,20 @@ private class Geary.Imap.Folder : BaseObject {
|
|||
*/
|
||||
public signal void disconnected(ClientSession.DisconnectReason reason);
|
||||
|
||||
internal Folder(ClientSessionManager session_mgr, Geary.FolderPath path, StatusData status,
|
||||
MailboxInformation info) {
|
||||
internal Folder(ClientSessionManager session_mgr, StatusData status, MailboxInformation info) {
|
||||
assert(status.mailbox.equal_to(info.mailbox));
|
||||
|
||||
this.session_mgr = session_mgr;
|
||||
this.info = info;
|
||||
this.path = path;
|
||||
path = info.mailbox.to_folder_path(info.delim);
|
||||
|
||||
properties = new Imap.FolderProperties.status(status, info.attrs);
|
||||
}
|
||||
|
||||
internal Folder.unselectable(ClientSessionManager session_mgr, Geary.FolderPath path,
|
||||
MailboxInformation info) {
|
||||
internal Folder.unselectable(ClientSessionManager session_mgr, MailboxInformation info) {
|
||||
this.session_mgr = session_mgr;
|
||||
this.info = info;
|
||||
this.path = path;
|
||||
path = info.mailbox.to_folder_path(info.delim);
|
||||
|
||||
properties = new Imap.FolderProperties(0, 0, 0, null, null, info.attrs);
|
||||
}
|
||||
|
|
@ -81,8 +81,8 @@ private class Geary.Imap.Folder : BaseObject {
|
|||
session.status_response_received.connect(on_status_response);
|
||||
session.disconnected.connect(on_disconnected);
|
||||
|
||||
StatusResponse response = yield session.select_async(path.get_fullpath(info.delim),
|
||||
cancellable);
|
||||
StatusResponse response = yield session.select_async(
|
||||
new MailboxSpecifier.from_folder_path(path, info.delim), cancellable);
|
||||
if (response.status != Status.OK) {
|
||||
yield release_session_async(cancellable);
|
||||
|
||||
|
|
@ -436,7 +436,7 @@ private class Geary.Imap.Folder : BaseObject {
|
|||
Cancellable? cancellable) throws Error {
|
||||
check_open();
|
||||
|
||||
CopyCommand cmd = new CopyCommand(msg_set, new Imap.MailboxParameter(destination.get_fullpath()));
|
||||
CopyCommand cmd = new CopyCommand(msg_set, new MailboxSpecifier.from_folder_path(destination));
|
||||
Gee.Collection<Command> cmds = new Collection.SingleItem<Command>(cmd);
|
||||
|
||||
yield exec_commands_async(cmds, cancellable);
|
||||
|
|
@ -452,7 +452,7 @@ private class Geary.Imap.Folder : BaseObject {
|
|||
// Don't use copy_email_async followed by remove_email_async; this needs to be one
|
||||
// set of commands executed in order without releasing the cmd_mutex; this is especially
|
||||
// vital if positional addressing is used
|
||||
cmds.add(new CopyCommand(msg_set, new Imap.MailboxParameter(destination.get_fullpath())));
|
||||
cmds.add(new CopyCommand(msg_set, new MailboxSpecifier.from_folder_path(destination)));
|
||||
|
||||
Gee.List<MessageFlag> flags = new Gee.ArrayList<MessageFlag>();
|
||||
flags.add(MessageFlag.DELETED);
|
||||
|
|
|
|||
|
|
@ -74,8 +74,23 @@ public class Geary.Imap.Command : RootParameters {
|
|||
add(tag);
|
||||
add(new UnquotedStringParameter(name));
|
||||
if (args != null) {
|
||||
foreach (string arg in args)
|
||||
add(new StringParameter(arg));
|
||||
foreach (string arg in args) {
|
||||
switch (DataFormat.is_quoting_required(arg)) {
|
||||
case DataFormat.Quoting.REQUIRED:
|
||||
add(new QuotedStringParameter(arg));
|
||||
break;
|
||||
|
||||
case DataFormat.Quoting.OPTIONAL:
|
||||
add(new UnquotedStringParameter(arg));
|
||||
break;
|
||||
|
||||
case DataFormat.Quoting.UNALLOWED:
|
||||
error("Command continuations currently unsupported");
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,28 +62,36 @@ public class Geary.Imap.ListCommand : Command {
|
|||
public const string NAME = "list";
|
||||
public const string XLIST_NAME = "xlist";
|
||||
|
||||
public ListCommand(Geary.Imap.MailboxParameter mailbox, bool use_xlist) {
|
||||
base (use_xlist ? XLIST_NAME : NAME, { "", mailbox.value });
|
||||
public ListCommand(MailboxSpecifier mailbox, bool use_xlist) {
|
||||
base (use_xlist ? XLIST_NAME : NAME, { "" });
|
||||
|
||||
add(mailbox.to_parameter());
|
||||
}
|
||||
|
||||
public ListCommand.wildcarded(string reference, Geary.Imap.MailboxParameter mailbox, bool use_xlist) {
|
||||
base (use_xlist ? XLIST_NAME : NAME, { reference, mailbox.value });
|
||||
public ListCommand.wildcarded(string reference, MailboxSpecifier mailbox, bool use_xlist) {
|
||||
base (use_xlist ? XLIST_NAME : NAME, { reference });
|
||||
|
||||
add(mailbox.to_parameter());
|
||||
}
|
||||
}
|
||||
|
||||
public class Geary.Imap.ExamineCommand : Command {
|
||||
public const string NAME = "examine";
|
||||
|
||||
public ExamineCommand(Geary.Imap.MailboxParameter mailbox) {
|
||||
base (NAME, { mailbox.value });
|
||||
public ExamineCommand(MailboxSpecifier mailbox) {
|
||||
base (NAME);
|
||||
|
||||
add(mailbox.to_parameter());
|
||||
}
|
||||
}
|
||||
|
||||
public class Geary.Imap.SelectCommand : Command {
|
||||
public const string NAME = "select";
|
||||
|
||||
public SelectCommand(Geary.Imap.MailboxParameter mailbox) {
|
||||
base (NAME, { mailbox.value });
|
||||
public SelectCommand(MailboxSpecifier mailbox) {
|
||||
base (NAME);
|
||||
|
||||
add(mailbox.to_parameter());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -98,10 +106,10 @@ public class Geary.Imap.CloseCommand : Command {
|
|||
public class Geary.Imap.StatusCommand : Command {
|
||||
public const string NAME = "status";
|
||||
|
||||
public StatusCommand(Geary.Imap.MailboxParameter mailbox, StatusDataType[] data_items) {
|
||||
public StatusCommand(MailboxSpecifier mailbox, StatusDataType[] data_items) {
|
||||
base (NAME);
|
||||
|
||||
add(mailbox);
|
||||
add(mailbox.to_parameter());
|
||||
|
||||
assert(data_items.length > 0);
|
||||
ListParameter data_item_list = new ListParameter(this);
|
||||
|
|
@ -161,11 +169,11 @@ public class Geary.Imap.CopyCommand : Command {
|
|||
public const string NAME = "copy";
|
||||
public const string UID_NAME = "uid copy";
|
||||
|
||||
public CopyCommand(MessageSet message_set, Geary.Imap.MailboxParameter destination) {
|
||||
public CopyCommand(MessageSet message_set, MailboxSpecifier destination) {
|
||||
base (message_set.is_uid ? UID_NAME : NAME);
|
||||
|
||||
add(message_set.to_parameter());
|
||||
add(destination);
|
||||
add(destination.to_parameter());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,9 @@
|
|||
|
||||
public class Geary.Imap.MailboxInformation : Object {
|
||||
/**
|
||||
* The decoded mailbox name.
|
||||
*
|
||||
* See {@link MailboxParameter} for the encoded version of this string.
|
||||
* Name of the mailbox.
|
||||
*/
|
||||
public string name { get; private set; }
|
||||
public MailboxSpecifier mailbox { get; private set; }
|
||||
|
||||
/**
|
||||
* The (optional) delimiter specified by the server.
|
||||
|
|
@ -32,52 +30,12 @@ public class Geary.Imap.MailboxInformation : Object {
|
|||
*/
|
||||
public MailboxAttributes attrs { get; private set; }
|
||||
|
||||
public MailboxInformation(string name, string? delim, MailboxAttributes attrs) {
|
||||
this.name = name;
|
||||
public MailboxInformation(MailboxSpecifier mailbox, string? delim, MailboxAttributes attrs) {
|
||||
this.mailbox = mailbox;
|
||||
this.delim = delim;
|
||||
this.attrs = attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will always return a list with at least one element in it. If no delimiter is specified,
|
||||
* the name is returned as a single element.
|
||||
*/
|
||||
public Gee.List<string> get_path() {
|
||||
Gee.List<string> path = new Gee.ArrayList<string>();
|
||||
|
||||
if (!String.is_empty(delim)) {
|
||||
string[] split = name.split(delim);
|
||||
foreach (string str in split) {
|
||||
if (!String.is_empty(str))
|
||||
path.add(str);
|
||||
}
|
||||
}
|
||||
|
||||
if (path.size == 0)
|
||||
path.add(name);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* The mailbox's name without parent folders.
|
||||
*
|
||||
* If name is non-empty, will return a non-empty value which is the final folder name (i.e.
|
||||
* the parent components are stripped). If no delimiter is specified, the name is returned.
|
||||
*/
|
||||
public string get_basename() {
|
||||
if (String.is_empty(delim))
|
||||
return name;
|
||||
|
||||
int index = name.last_index_of(delim);
|
||||
if (index < 0)
|
||||
return name;
|
||||
|
||||
string basename = name.substring(index + 1);
|
||||
|
||||
return !String.is_empty(basename) ? basename : name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes {@link ServerData} into a MailboxInformation representation.
|
||||
*
|
||||
|
|
@ -114,10 +72,10 @@ public class Geary.Imap.MailboxInformation : Object {
|
|||
|
||||
// Set \Inbox to standard path
|
||||
if (Geary.Imap.MailboxAttribute.SPECIAL_FOLDER_INBOX in attributes) {
|
||||
return new MailboxInformation(Geary.Imap.Account.INBOX_NAME,
|
||||
return new MailboxInformation(MailboxSpecifier.inbox,
|
||||
(delim != null) ? delim.nullable_value : null, attributes);
|
||||
} else {
|
||||
return new MailboxInformation(mailbox.decode(),
|
||||
return new MailboxInformation(new MailboxSpecifier.from_parameter(mailbox),
|
||||
(delim != null) ? delim.nullable_value : null, attributes);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
143
src/engine/imap/message/imap-mailbox-specifier.vala
Normal file
143
src/engine/imap/message/imap-mailbox-specifier.vala
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/* Copyright 2013 Yorba Foundation
|
||||
*
|
||||
* This software is licensed under the GNU Lesser General Public License
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents an IMAP mailbox name or path (more commonly known as a folder).
|
||||
*
|
||||
* Can also be used to specify a wildcarded name for the {@link ListCommand}.
|
||||
*
|
||||
* See [[http://tools.ietf.org/html/rfc3501#section-5.1]]
|
||||
*/
|
||||
|
||||
public class Geary.Imap.MailboxSpecifier : BaseObject, Gee.Hashable<MailboxSpecifier>, Gee.Comparable<MailboxSpecifier> {
|
||||
/**
|
||||
* An instance of an Inbox MailboxSpecifier.
|
||||
*
|
||||
* This is a utility for creating the single IMAP Inbox. {@link compare_to}. {@link hash},
|
||||
* and {@link equal_to} do not rely on this instance for comparison.
|
||||
*/
|
||||
private static MailboxSpecifier? _inbox = null;
|
||||
public static MailboxSpecifier inbox {
|
||||
get {
|
||||
return (_inbox != null) ? _inbox : _inbox = new MailboxSpecifier("Inbox");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decoded mailbox path name.
|
||||
*/
|
||||
public string name { get; private set; }
|
||||
|
||||
/**
|
||||
* Indicates this is the {@link StatusData} for Inbox.
|
||||
*
|
||||
* IMAP guarantees only one mailbox in an account: Inbox.
|
||||
*
|
||||
* See [[http://tools.ietf.org/html/rfc3501#section-5.1]]
|
||||
*/
|
||||
public bool is_inbox { get; private set; }
|
||||
|
||||
public MailboxSpecifier(string name) {
|
||||
init(name);
|
||||
}
|
||||
|
||||
public MailboxSpecifier.from_parameter(MailboxParameter param) {
|
||||
init(param.decode());
|
||||
}
|
||||
|
||||
public MailboxSpecifier.from_folder_path(FolderPath path, string? delim = null) {
|
||||
init(path.get_fullpath(delim));
|
||||
}
|
||||
|
||||
private void init(string decoded) {
|
||||
name = decoded;
|
||||
is_inbox = name.down() == "inbox";
|
||||
}
|
||||
|
||||
/**
|
||||
* The mailbox's path as a list of strings.
|
||||
*
|
||||
* Will always return a list with at least one element in it. If no delimiter is specified,
|
||||
* the name is returned as a single element.
|
||||
*/
|
||||
public Gee.List<string> to_list(string? delim) {
|
||||
Gee.List<string> path = new Gee.ArrayList<string>();
|
||||
|
||||
if (!String.is_empty(delim)) {
|
||||
string[] split = name.split(delim);
|
||||
foreach (string str in split) {
|
||||
if (!String.is_empty(str))
|
||||
path.add(str);
|
||||
}
|
||||
}
|
||||
|
||||
if (path.size == 0)
|
||||
path.add(name);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public FolderPath to_folder_path(string? delim = null) {
|
||||
Gee.List<string> list = to_list(delim);
|
||||
FolderPath path = new FolderRoot(list[0], delim, !is_inbox);
|
||||
for (int ctr = 1; ctr < list.size; ctr++)
|
||||
path = path.get_child(list[ctr]);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* The mailbox's name without parent folders.
|
||||
*
|
||||
* If name is non-empty, will return a non-empty value which is the final folder name (i.e.
|
||||
* the parent components are stripped). If no delimiter is specified, the name is returned.
|
||||
*/
|
||||
public string get_basename(string? delim) {
|
||||
if (String.is_empty(delim))
|
||||
return name;
|
||||
|
||||
int index = name.last_index_of(delim);
|
||||
if (index < 0)
|
||||
return name;
|
||||
|
||||
string basename = name.substring(index + 1);
|
||||
|
||||
return !String.is_empty(basename) ? basename : name;
|
||||
}
|
||||
|
||||
public Parameter to_parameter() {
|
||||
return new MailboxParameter(name);
|
||||
}
|
||||
|
||||
public uint hash() {
|
||||
return is_inbox ? String.stri_hash(name) : name.hash();
|
||||
}
|
||||
|
||||
public bool equal_to(MailboxSpecifier other) {
|
||||
if (this == other)
|
||||
return true;
|
||||
|
||||
if (is_inbox)
|
||||
return String.stri_equal(name, other.name);
|
||||
|
||||
return name == other.name;
|
||||
}
|
||||
|
||||
public int compare_to(MailboxSpecifier other) {
|
||||
if (this == other)
|
||||
return 0;
|
||||
|
||||
if (is_inbox && other.is_inbox)
|
||||
return 0;
|
||||
|
||||
return strcmp(name, other.name);
|
||||
}
|
||||
|
||||
public string to_string() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,6 +101,10 @@ public class Geary.Imap.QuotedStringParameter : Geary.Imap.StringParameter {
|
|||
base (value);
|
||||
}
|
||||
|
||||
public override string to_string() {
|
||||
return "\"%s\"".printf(value);
|
||||
}
|
||||
|
||||
public override async void serialize(Serializer ser) throws Error {
|
||||
ser.push_quoted_string(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,9 @@ public class Geary.Imap.StatusData : Object {
|
|||
public const int UNSET = -1;
|
||||
|
||||
/**
|
||||
* Decoded mailbox path name.
|
||||
*
|
||||
* See {@link MailboxParameter} for the encoded version of this string.
|
||||
* Name of the mailbox.
|
||||
*/
|
||||
public string mailbox { get; private set; }
|
||||
public MailboxSpecifier mailbox { get; private set; }
|
||||
|
||||
/**
|
||||
* {@link UNSET} if not set.
|
||||
|
|
@ -53,7 +51,7 @@ public class Geary.Imap.StatusData : Object {
|
|||
*/
|
||||
public int unseen { get; private set; }
|
||||
|
||||
public StatusData(string mailbox, int messages, int recent, UID? uid_next,
|
||||
public StatusData(MailboxSpecifier mailbox, int messages, int recent, UID? uid_next,
|
||||
UIDValidity? uid_validity, int unseen) {
|
||||
this.mailbox = mailbox;
|
||||
this.messages = messages;
|
||||
|
|
@ -126,12 +124,12 @@ public class Geary.Imap.StatusData : Object {
|
|||
}
|
||||
}
|
||||
|
||||
return new StatusData(mailbox_param.decode(), messages, recent, uid_next, uid_validity,
|
||||
unseen);
|
||||
return new StatusData(new MailboxSpecifier.from_parameter(mailbox_param), messages, recent,
|
||||
uid_next, uid_validity, unseen);
|
||||
}
|
||||
|
||||
public string to_string() {
|
||||
return "%s/%d/UIDNEXT=%s/UIDVALIDITY=%s".printf(mailbox, messages,
|
||||
return "%s/%d/UIDNEXT=%s/UIDVALIDITY=%s".printf(mailbox.to_string(), messages,
|
||||
(uid_next != null) ? uid_next.to_string() : "(none)",
|
||||
(uid_validity != null) ? uid_validity.to_string() : "(none)");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ public class Geary.Imap.ClientSessionManager : BaseObject {
|
|||
|
||||
ClientSession? found_session = null;
|
||||
foreach (ClientSession session in sessions) {
|
||||
string? mailbox;
|
||||
MailboxSpecifier? mailbox;
|
||||
if (!reserved_sessions.contains(session) &&
|
||||
(session.get_context(out mailbox) == ClientSession.Context.AUTHORIZED)) {
|
||||
found_session = session;
|
||||
|
|
@ -253,7 +253,7 @@ public class Geary.Imap.ClientSessionManager : BaseObject {
|
|||
throws Error {
|
||||
check_open();
|
||||
|
||||
string? mailbox;
|
||||
MailboxSpecifier? mailbox;
|
||||
ClientSession.Context context = session.get_context(out mailbox);
|
||||
|
||||
switch (context) {
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ public class Geary.Imap.ClientSession : BaseObject {
|
|||
private Endpoint imap_endpoint;
|
||||
private Geary.State.Machine fsm;
|
||||
private ClientConnection? cx = null;
|
||||
private string? current_mailbox = null;
|
||||
private MailboxSpecifier? current_mailbox = null;
|
||||
private bool current_mailbox_readonly = false;
|
||||
private Gee.HashMap<Tag, StatusResponse> seen_completion_responses = new Gee.HashMap<
|
||||
Tag, StatusResponse>();
|
||||
|
|
@ -227,7 +227,8 @@ public class Geary.Imap.ClientSession : BaseObject {
|
|||
* (authorized -> selected/examined or vice-versa). If new_name is null readonly should be
|
||||
* ignored.
|
||||
*/
|
||||
public signal void current_mailbox_changed(string? old_name, string? new_name, bool readonly);
|
||||
public signal void current_mailbox_changed(MailboxSpecifier? old_name, MailboxSpecifier? new_name,
|
||||
bool readonly);
|
||||
|
||||
public ClientSession(Endpoint imap_endpoint) {
|
||||
this.imap_endpoint = imap_endpoint;
|
||||
|
|
@ -394,7 +395,7 @@ public class Geary.Imap.ClientSession : BaseObject {
|
|||
debug("DTOR: ClientSession");
|
||||
}
|
||||
|
||||
public string? get_current_mailbox() {
|
||||
public MailboxSpecifier? get_current_mailbox() {
|
||||
return current_mailbox;
|
||||
}
|
||||
|
||||
|
|
@ -402,7 +403,7 @@ public class Geary.Imap.ClientSession : BaseObject {
|
|||
return current_mailbox_readonly;
|
||||
}
|
||||
|
||||
public Context get_context(out string? current_mailbox) {
|
||||
public Context get_context(out MailboxSpecifier? current_mailbox) {
|
||||
current_mailbox = null;
|
||||
|
||||
switch (fsm.get_state()) {
|
||||
|
|
@ -464,7 +465,13 @@ public class Geary.Imap.ClientSession : BaseObject {
|
|||
assert(connect_waiter != null);
|
||||
|
||||
// connect and let ClientConnection's signals drive the show
|
||||
yield cx.connect_async(cancellable);
|
||||
try {
|
||||
yield cx.connect_async(cancellable);
|
||||
} catch (Error err) {
|
||||
fsm.issue(Event.SEND_ERROR, null, null, err);
|
||||
|
||||
throw err;
|
||||
}
|
||||
|
||||
// set up timer to wait for greeting from server
|
||||
Scheduler.Scheduled timeout = Scheduler.after_sec(GREETING_TIMEOUT_SEC, on_greeting_timeout);
|
||||
|
|
@ -970,26 +977,26 @@ public class Geary.Imap.ClientSession : BaseObject {
|
|||
// select/examine
|
||||
//
|
||||
|
||||
public async StatusResponse select_async(string mailbox, Cancellable? cancellable = null)
|
||||
public async StatusResponse select_async(MailboxSpecifier mailbox, Cancellable? cancellable = null)
|
||||
throws Error {
|
||||
return yield select_examine_async(mailbox, true, cancellable);
|
||||
}
|
||||
|
||||
public async StatusResponse examine_async(string mailbox, Cancellable? cancellable = null)
|
||||
public async StatusResponse examine_async(MailboxSpecifier mailbox, Cancellable? cancellable = null)
|
||||
throws Error {
|
||||
return yield select_examine_async(mailbox, false, cancellable);
|
||||
}
|
||||
|
||||
public async StatusResponse select_examine_async(string mailbox, bool is_select,
|
||||
public async StatusResponse select_examine_async(MailboxSpecifier mailbox, bool is_select,
|
||||
Cancellable? cancellable) throws Error {
|
||||
string? old_mailbox = current_mailbox;
|
||||
MailboxSpecifier? old_mailbox = current_mailbox;
|
||||
|
||||
// Ternary troubles
|
||||
Command cmd;
|
||||
if (is_select)
|
||||
cmd = new SelectCommand(new MailboxParameter(mailbox));
|
||||
cmd = new SelectCommand(mailbox);
|
||||
else
|
||||
cmd = new ExamineCommand(new MailboxParameter(mailbox));
|
||||
cmd = new ExamineCommand(mailbox);
|
||||
|
||||
MachineParams params = new MachineParams(cmd);
|
||||
fsm.issue(Event.SELECT, null, params);
|
||||
|
|
@ -1069,7 +1076,7 @@ public class Geary.Imap.ClientSession : BaseObject {
|
|||
//
|
||||
|
||||
public async StatusResponse close_mailbox_async(Cancellable? cancellable = null) throws Error {
|
||||
string? old_mailbox = current_mailbox;
|
||||
MailboxSpecifier? old_mailbox = current_mailbox;
|
||||
|
||||
CloseCommand cmd = new CloseCommand();
|
||||
|
||||
|
|
@ -1219,7 +1226,7 @@ public class Geary.Imap.ClientSession : BaseObject {
|
|||
private uint on_connecting_send_recv_error(uint state, uint event, void *user, Object? object, Error? err) {
|
||||
assert(err != null);
|
||||
|
||||
debug("[%s] Connecting send error, dropping client connection: %s", to_string(), err.message);
|
||||
debug("[%s] Connecting send/recv error, dropping client connection: %s", to_string(), err.message);
|
||||
|
||||
fsm.do_post_transition(() => { drop_connection(); });
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue