Make it easier to obtain folders from path objects from Geary.Account
Replace async folder accessors with sync versions, add a means of obtaining a folder path from its serialised form.
This commit is contained in:
parent
01a154bc5f
commit
f7488453d0
7 changed files with 115 additions and 93 deletions
|
|
@ -320,6 +320,48 @@ public abstract class Geary.Account : BaseObject {
|
|||
public abstract EmailIdentifier to_email_identifier(GLib.Variant serialised)
|
||||
throws EngineError.BAD_PARAMETERS;
|
||||
|
||||
/**
|
||||
* Returns the folder path from its serialised form.
|
||||
*
|
||||
* This is useful for converting a string representation of a
|
||||
* folder path back into an actual instance of a path. This does
|
||||
* not guarantee that the folder represented by the path will
|
||||
* exist.
|
||||
*
|
||||
* @see FolderPath.to_variant
|
||||
* @throws EngineError.BAD_PARAMETERS when the variant is not the
|
||||
* have the correct type or if no folder root with an appropriate
|
||||
* label exists.
|
||||
*/
|
||||
public abstract FolderPath to_folder_path(GLib.Variant serialised)
|
||||
throws EngineError.BAD_PARAMETERS;
|
||||
|
||||
/**
|
||||
* Determines if a folder is known to the engine.
|
||||
*
|
||||
* This method only considers currently known folders, it does not
|
||||
* check the remote to see if a previously folder exists.
|
||||
*/
|
||||
public virtual bool has_folder(FolderPath path) {
|
||||
try {
|
||||
get_folder(path);
|
||||
return true;
|
||||
} catch (EngineError.NOT_FOUND err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the folder represented by a specific path.
|
||||
*
|
||||
* This method only considers currently known folders, it does not
|
||||
* check the remote to see if a previously folder exists.
|
||||
*
|
||||
* @throws EngineError.NOT_FOUND if the folder does not exist.
|
||||
*/
|
||||
public abstract Folder get_folder(FolderPath path)
|
||||
throws EngineError.NOT_FOUND;
|
||||
|
||||
/**
|
||||
* Lists all the currently-available folders found under the parent path
|
||||
* unless it's null, in which case it lists all the root folders. If the
|
||||
|
|
@ -347,26 +389,6 @@ public abstract class Geary.Account : BaseObject {
|
|||
*/
|
||||
public abstract Geary.ContactStore get_contact_store();
|
||||
|
||||
/**
|
||||
* Returns true if the folder exists.
|
||||
*
|
||||
* This method never throws EngineError.NOT_FOUND.
|
||||
*/
|
||||
public abstract async bool folder_exists_async(Geary.FolderPath path, Cancellable? cancellable = null)
|
||||
throws Error;
|
||||
|
||||
/**
|
||||
* Fetches a Folder object corresponding to the supplied path. If the backing medium does
|
||||
* not have a record of a folder at the path, EngineError.NOT_FOUND will be thrown.
|
||||
*
|
||||
* The same Geary.Folder object (instance) will be returned if the same path is submitted
|
||||
* multiple times. This means that multiple callers may be holding references to the same
|
||||
* Folders. This is important when thinking of opening and closing folders and signal
|
||||
* notifications.
|
||||
*/
|
||||
public abstract async Geary.Folder fetch_folder_async(Geary.FolderPath path,
|
||||
Cancellable? cancellable = null) throws Error;
|
||||
|
||||
/**
|
||||
* Returns the folder representing the given special folder type. If no such folder exists,
|
||||
* null is returned.
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public class Geary.App.EmailStore : BaseObject {
|
|||
foreach (Geary.FolderPath path in folders.get(email)) {
|
||||
Geary.Folder folder;
|
||||
try {
|
||||
folder = yield account.fetch_folder_async(path, cancellable);
|
||||
folder = account.get_folder(path);
|
||||
} catch (Error e) {
|
||||
debug("Error getting a folder from path %s: %s", path.to_string(), e.message);
|
||||
continue;
|
||||
|
|
@ -108,33 +108,23 @@ public class Geary.App.EmailStore : BaseObject {
|
|||
emails, cancellable);
|
||||
}
|
||||
|
||||
private async Gee.HashMap<Geary.FolderPath, Geary.Folder> get_folder_instances_async(
|
||||
Gee.Collection<Geary.FolderPath> paths, Cancellable? cancellable) throws Error {
|
||||
Gee.HashMap<Geary.FolderPath, Geary.Folder> folders
|
||||
= new Gee.HashMap<Geary.FolderPath, Geary.Folder>();
|
||||
foreach (Geary.FolderPath path in paths) {
|
||||
Geary.Folder folder = yield account.fetch_folder_async(path, cancellable);
|
||||
folders.set(path, folder);
|
||||
}
|
||||
return folders;
|
||||
}
|
||||
|
||||
private Geary.FolderPath? next_folder_for_operation(AsyncFolderOperation operation,
|
||||
Gee.MultiMap<Geary.FolderPath, Geary.EmailIdentifier> folders_to_ids,
|
||||
Gee.Map<Geary.FolderPath, Geary.Folder> folders) throws Error {
|
||||
private FolderPath?
|
||||
next_folder_for_operation(AsyncFolderOperation operation,
|
||||
Gee.MultiMap<FolderPath,EmailIdentifier> folders_to_ids)
|
||||
throws GLib.Error {
|
||||
bool best_is_open = false;
|
||||
int best_count = 0;
|
||||
Geary.FolderPath? best = null;
|
||||
foreach (Geary.FolderPath path in folders_to_ids.get_keys()) {
|
||||
assert(folders.has_key(path));
|
||||
if (!folders.get(path).get_type().is_a(operation.folder_type))
|
||||
Folder folder = this.account.get_folder(path);
|
||||
if (!folder.get_type().is_a(operation.folder_type))
|
||||
continue;
|
||||
|
||||
int count = folders_to_ids.get(path).size;
|
||||
if (count == 0)
|
||||
continue;
|
||||
|
||||
if (folders.get(path).get_open_state() == Geary.Folder.OpenState.REMOTE) {
|
||||
if (folder.get_open_state() == Geary.Folder.OpenState.REMOTE) {
|
||||
if (!best_is_open) {
|
||||
best_is_open = true;
|
||||
best_count = 0;
|
||||
|
|
@ -167,12 +157,9 @@ public class Geary.App.EmailStore : BaseObject {
|
|||
|
||||
Gee.MultiMap<Geary.FolderPath, Geary.EmailIdentifier> folders_to_ids
|
||||
= Geary.Collection.reverse_multi_map<Geary.EmailIdentifier, Geary.FolderPath>(ids_to_folders);
|
||||
Gee.HashMap<Geary.FolderPath, Geary.Folder> folders
|
||||
= yield get_folder_instances_async(folders_to_ids.get_keys(), cancellable);
|
||||
|
||||
Geary.FolderPath? path;
|
||||
while ((path = next_folder_for_operation(operation, folders_to_ids, folders)) != null) {
|
||||
Geary.Folder folder = folders.get(path);
|
||||
while ((path = next_folder_for_operation(operation, folders_to_ids)) != null) {
|
||||
Geary.Folder folder = this.account.get_folder(path);
|
||||
Gee.Collection<Geary.EmailIdentifier> ids = folders_to_ids.get(path);
|
||||
assert(ids.size > 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -336,7 +336,7 @@ private class Geary.ImapDB.SearchFolder : Geary.SearchFolder, Geary.FolderSuppor
|
|||
= Geary.Collection.reverse_multi_map<Geary.EmailIdentifier, Geary.FolderPath>(ids_to_folders);
|
||||
|
||||
foreach (Geary.FolderPath path in folders_to_ids.get_keys()) {
|
||||
Geary.Folder folder = yield account.fetch_folder_async(path, cancellable);
|
||||
Geary.Folder folder = account.get_folder(path);
|
||||
Geary.FolderSupport.Remove? remove = folder as Geary.FolderSupport.Remove;
|
||||
if (remove == null)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -434,6 +434,34 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
|
|||
throw new EngineError.BAD_PARAMETERS("Unknown serialised type: %c", type);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public override FolderPath to_folder_path(GLib.Variant serialised)
|
||||
throws EngineError.BAD_PARAMETERS {
|
||||
FolderPath? path = null;
|
||||
try {
|
||||
path = this.local.imap_folder_root.from_variant(serialised);
|
||||
} catch (EngineError.BAD_PARAMETERS err) {
|
||||
path = this.local_folder_root.from_variant(serialised);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public override Folder get_folder(FolderPath path)
|
||||
throws EngineError.NOT_FOUND {
|
||||
Folder? folder = this.folder_map.get(path);
|
||||
if (folder == null) {
|
||||
folder = this.local_only.get(path);
|
||||
if (folder == null) {
|
||||
throw new EngineError.NOT_FOUND(
|
||||
"Folder not found: %s", path.to_string()
|
||||
);
|
||||
}
|
||||
}
|
||||
return folder;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public override Gee.Collection<Geary.Folder> list_matching_folders(Geary.FolderPath? parent)
|
||||
throws Error {
|
||||
check_open();
|
||||
|
|
@ -461,33 +489,6 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
|
|||
return local.contact_store;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public override async bool folder_exists_async(Geary.FolderPath path,
|
||||
Cancellable? cancellable = null)
|
||||
throws Error {
|
||||
check_open();
|
||||
return this.local_only.has_key(path) || this.folder_map.has_key(path);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public override async Geary.Folder fetch_folder_async(Geary.FolderPath path,
|
||||
Cancellable? cancellable = null)
|
||||
throws Error {
|
||||
check_open();
|
||||
|
||||
Geary.Folder? folder = this.local_only.get(path);
|
||||
if (folder == null) {
|
||||
folder = this.folder_map.get(path);
|
||||
|
||||
if (folder == null) {
|
||||
throw new EngineError.NOT_FOUND(
|
||||
"Folder not found: %s", path.to_string()
|
||||
);
|
||||
}
|
||||
}
|
||||
return 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())) {
|
||||
|
|
@ -1125,9 +1126,7 @@ internal class Geary.ImapEngine.LoadFolders : AccountOperation {
|
|||
path = this.local.imap_folder_root.copy(path);
|
||||
if (path != null) {
|
||||
try {
|
||||
Geary.Folder target = yield generic.fetch_folder_async(
|
||||
path, cancellable
|
||||
);
|
||||
Geary.Folder target = generic.get_folder(path);
|
||||
added_specials.set(type, target);
|
||||
} catch (Error err) {
|
||||
debug(
|
||||
|
|
|
|||
|
|
@ -1272,7 +1272,7 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
|
|||
Geary.FolderPath destination,
|
||||
GLib.Cancellable? cancellable = null)
|
||||
throws GLib.Error {
|
||||
Geary.Folder target = yield this._account.fetch_folder_async(destination);
|
||||
Geary.Folder target = this._account.get_folder(destination);
|
||||
yield copy_email_uids_async(to_copy, destination, cancellable);
|
||||
this._account.update_folder(target);
|
||||
}
|
||||
|
|
@ -1321,7 +1321,7 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
|
|||
if (prepare.prepared_for_move == null || prepare.prepared_for_move.size == 0)
|
||||
return null;
|
||||
|
||||
Geary.Folder target = yield this._account.fetch_folder_async(destination);
|
||||
Geary.Folder target = this._account.get_folder(destination);
|
||||
return new RevokableMove(
|
||||
_account, this, target, prepare.prepared_for_move
|
||||
);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ private class Geary.ImapEngine.RevokableCommittedMove : Revokable {
|
|||
|
||||
notify_revoked();
|
||||
|
||||
Geary.Folder target = yield this.account.fetch_folder_async(this.destination);
|
||||
Geary.Folder target = this.account.get_folder(this.destination);
|
||||
this.account.update_folder(target);
|
||||
} finally {
|
||||
if (session != null) {
|
||||
|
|
|
|||
|
|
@ -135,6 +135,36 @@ public class Geary.MockAccount : Account, MockObject {
|
|||
}
|
||||
}
|
||||
|
||||
public override FolderPath to_folder_path(GLib.Variant serialised)
|
||||
throws EngineError.BAD_PARAMETERS {
|
||||
try {
|
||||
return object_or_throw_call(
|
||||
"to_folder_path",
|
||||
{ box_arg(serialised) },
|
||||
new EngineError.BAD_PARAMETERS("Mock error")
|
||||
);
|
||||
} catch (EngineError.BAD_PARAMETERS err) {
|
||||
throw err;
|
||||
} catch (GLib.Error err) {
|
||||
return new FolderRoot("#mock", false);
|
||||
}
|
||||
}
|
||||
|
||||
public override Folder get_folder(FolderPath path)
|
||||
throws EngineError.NOT_FOUND {
|
||||
try {
|
||||
return object_or_throw_call(
|
||||
"get_folder",
|
||||
{ path },
|
||||
new EngineError.NOT_FOUND("Mock error")
|
||||
);
|
||||
} catch (EngineError.NOT_FOUND err) {
|
||||
throw err;
|
||||
} catch (GLib.Error err) {
|
||||
return new MockFolder(null, null, null, SpecialFolderType.NONE, null);
|
||||
}
|
||||
}
|
||||
|
||||
public override Gee.Collection<Folder> list_folders() throws Error {
|
||||
return object_call<Gee.Collection<Folder>>(
|
||||
"list_folders", {}, Gee.List.empty<Folder>()
|
||||
|
|
@ -145,22 +175,6 @@ public class Geary.MockAccount : Account, MockObject {
|
|||
return new MockContactStore();
|
||||
}
|
||||
|
||||
public override async bool folder_exists_async(FolderPath path,
|
||||
Cancellable? cancellable = null)
|
||||
throws Error {
|
||||
return boolean_call("folder_exists_async", {path, cancellable}, false);
|
||||
}
|
||||
|
||||
public override async Folder fetch_folder_async(FolderPath path,
|
||||
Cancellable? cancellable = null)
|
||||
throws Error {
|
||||
return object_or_throw_call<Folder>(
|
||||
"fetch_folder_async",
|
||||
{path, cancellable},
|
||||
new EngineError.NOT_FOUND("Mock call")
|
||||
);
|
||||
}
|
||||
|
||||
public override Folder? get_special_folder(SpecialFolderType special)
|
||||
throws Error {
|
||||
return object_call<Folder?>(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue