Correctly handle creating special folders when they do not exist
This commit is contained in:
parent
c39b1e5457
commit
7449e10b3e
2 changed files with 62 additions and 23 deletions
|
|
@ -670,7 +670,6 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
|
|||
Geary.SpecialFolderType special,
|
||||
Cancellable? cancellable)
|
||||
throws Error {
|
||||
MinimalFolder? minimal_folder = null;
|
||||
Geary.FolderPath? path = information.get_special_folder_path(special);
|
||||
if (path != null) {
|
||||
debug("Previously used %s for special folder %s", path.to_string(), special.to_string());
|
||||
|
|
@ -698,22 +697,49 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
|
|||
information.set_special_folder_path(special, path);
|
||||
}
|
||||
|
||||
if (path in folder_map.keys) {
|
||||
debug("Promoting %s to special folder %s", path.to_string(), special.to_string());
|
||||
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, special, cancellable);
|
||||
minimal_folder = (MinimalFolder) yield fetch_folder_async(path, cancellable);
|
||||
if (!this.folder_map.has_key(path)) {
|
||||
debug("Creating \"%s\" to use as special folder %s",
|
||||
path.to_string(), special.to_string());
|
||||
|
||||
GLib.Error? created_err = null;
|
||||
try {
|
||||
yield remote.create_folder_async(path, special, cancellable);
|
||||
} catch (GLib.Error err) {
|
||||
// Hang on to the error since the folder might exist
|
||||
// on the remote, so try fetching it anyway.
|
||||
created_err = err;
|
||||
}
|
||||
|
||||
Imap.Folder? remote_folder = null;
|
||||
try {
|
||||
remote_folder = yield remote.fetch_folder_async(
|
||||
path, cancellable
|
||||
);
|
||||
} catch (GLib.Error err) {
|
||||
// If we couldn't fetch it after also failing to
|
||||
// create it, it's probably due to the problem
|
||||
// creating it, so throw that error instead.
|
||||
if (created_err != null) {
|
||||
throw created_err;
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
ImapDB.Folder local_folder = yield this.local.clone_folder_async(
|
||||
remote_folder, cancellable
|
||||
);
|
||||
add_folders(Collection.single(local_folder), created_err != null);
|
||||
}
|
||||
|
||||
Gee.Map<Geary.SpecialFolderType,Geary.Folder> specials =
|
||||
new Gee.HashMap<Geary.SpecialFolderType,Geary.Folder>();
|
||||
specials.set(special, minimal_folder);
|
||||
promote_folders(specials);
|
||||
Geary.Folder special_folder = this.folder_map.get(path);
|
||||
promote_folders(
|
||||
Collection.single_map<Geary.SpecialFolderType,Geary.Folder>(
|
||||
special, special_folder
|
||||
)
|
||||
);
|
||||
|
||||
return minimal_folder;
|
||||
return special_folder;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1222,10 +1248,11 @@ internal class Geary.ImapEngine.UpdateRemoteFolders : AccountOperation {
|
|||
remote_folder.path.to_string(), update_error.message);
|
||||
}
|
||||
|
||||
// set the engine folder's special type
|
||||
// (but only promote, not demote, since getting the special folder type via its
|
||||
// properties relies on the optional XLIST extension)
|
||||
// use this iteration to add discovered properties to map
|
||||
// set the engine folder's special type (but only promote,
|
||||
// not demote, since getting the special folder type via
|
||||
// its properties relies on the optional SPECIAL-USE or
|
||||
// XLIST extensions) use this iteration to add discovered
|
||||
// properties to map
|
||||
if (minimal_folder.special_folder_type == SpecialFolderType.NONE)
|
||||
minimal_folder.set_special_folder_type(remote_folder.properties.attrs.get_special_folder_type());
|
||||
}
|
||||
|
|
@ -1298,11 +1325,9 @@ internal class Geary.ImapEngine.UpdateRemoteFolders : AccountOperation {
|
|||
// Ensure each of the important special folders we need already exist
|
||||
foreach (Geary.SpecialFolderType special in this.specials) {
|
||||
try {
|
||||
if (this.generic_account.get_special_folder(special) == null) {
|
||||
yield this.generic_account.ensure_special_folder_async(
|
||||
remote, special, cancellable
|
||||
);
|
||||
}
|
||||
yield this.generic_account.ensure_special_folder_async(
|
||||
remote, special, cancellable
|
||||
);
|
||||
} catch (Error e) {
|
||||
warning("Unable to ensure special folder %s: %s", special.to_string(), e.message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,20 @@ public inline bool is_empty(Gee.Collection? c) {
|
|||
return c == null || c.size == 0;
|
||||
}
|
||||
|
||||
/** Returns a modifiable collection containing a single element. */
|
||||
public Gee.Collection<T> single<T>(T element) {
|
||||
Gee.Collection<T> single = new Gee.LinkedList<T>();
|
||||
single.add(element);
|
||||
return single;
|
||||
}
|
||||
|
||||
/** Returns a modifiable map containing a single entry. */
|
||||
public Gee.Map<K,V> single_map<K,V>(K key, V value) {
|
||||
Gee.Map<K,V> single = new Gee.HashMap<K,V>();
|
||||
single.set(key, value);
|
||||
return single;
|
||||
}
|
||||
|
||||
// A substitute for ArrayList<G>.wrap() for compatibility with older versions of Gee.
|
||||
public Gee.ArrayList<G> array_list_wrap<G>(G[] a, owned Gee.EqualDataFunc<G>? equal_func = null) {
|
||||
Gee.ArrayList<G> list = new Gee.ArrayList<G>((owned) equal_func);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue