Skip to content

Commit

Permalink
Add FolderType support to ImapStore + ImapBackend
Browse files Browse the repository at this point in the history
  • Loading branch information
cketti committed Nov 13, 2018
1 parent 4847c0f commit cea3c41
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.fsck.k9.backend.imap

import com.fsck.k9.backend.api.BackendStorage
import com.fsck.k9.backend.api.FolderInfo
import com.fsck.k9.mail.Folder.FolderType
import com.fsck.k9.mail.store.imap.ImapStore


Expand All @@ -17,11 +16,10 @@ internal class CommandRefreshFolderList(

val foldersToCreate = mutableListOf<FolderInfo>()
for (folder in foldersOnServer) {
//FIXME: Use correct folder type
if (folder.serverId !in oldFolderServerIds) {
foldersToCreate.add(FolderInfo(folder.serverId, folder.name, FolderType.REGULAR))
foldersToCreate.add(FolderInfo(folder.serverId, folder.name, folder.type))
} else {
backendStorage.changeFolder(folder.serverId, folder.name, FolderType.REGULAR)
backendStorage.changeFolder(folder.serverId, folder.name, folder.type)
}
}
backendStorage.createFolders(foldersToCreate)
Expand Down
3 changes: 3 additions & 0 deletions mail/protocols/imap/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
apply plugin: 'com.android.library'
apply plugin: 'org.jetbrains.kotlin.android'

apply from: "${rootProject.projectDir}/gradle/plugins/checkstyle-android.gradle"
apply from: "${rootProject.projectDir}/gradle/plugins/findbugs-android.gradle"
Expand All @@ -8,6 +9,8 @@ if (rootProject.testCoverage) {
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${versions.kotlin}"

api project(":mail:common")

implementation "com.jcraft:jzlib:1.0.7"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.fsck.k9.mail.store.imap

import com.fsck.k9.mail.Folder.FolderType

data class FolderListItem(val name: String, val type: FolderType)
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import java.io.IOException;
import java.nio.charset.CharacterCodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.EnumSet;
import java.util.HashMap;
Expand All @@ -20,6 +19,7 @@
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder.FolderType;
import com.fsck.k9.mail.K9MailLib;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.NetworkType;
Expand Down Expand Up @@ -125,17 +125,16 @@ public List<ImapFolder> getPersonalNamespaces() throws MessagingException {
ImapConnection connection = getConnection();

try {
Set<String> folderNames = listFolders(connection, false);
List<FolderListItem> folders = listFolders(connection, false);

if (!mStoreConfig.subscribedFoldersOnly()) {
return getFolders(folderNames);
return getFolders(folders);
}

Set<String> subscribedFolders = listFolders(connection, true);
List<FolderListItem> subscribedFolders = listFolders(connection, true);

folderNames.retainAll(subscribedFolders);

return getFolders(folderNames);
List<FolderListItem> filteredFolders = limitToSubscribedFolders(folders, subscribedFolders);
return getFolders(filteredFolders);
} catch (IOException | MessagingException ioe) {
connection.close();
throw new MessagingException("Unable to get folder list.", ioe);
Expand All @@ -144,26 +143,50 @@ public List<ImapFolder> getPersonalNamespaces() throws MessagingException {
}
}

private Set<String> listFolders(ImapConnection connection, boolean subscribedOnly) throws IOException,
private List<FolderListItem> limitToSubscribedFolders(List<FolderListItem> folders,
List<FolderListItem> subscribedFolders) {
Set<String> subscribedFolderNames = new HashSet<>(subscribedFolders.size());
for (FolderListItem subscribedFolder : subscribedFolders) {
subscribedFolderNames.add(subscribedFolder.getName());
}

List<FolderListItem> filteredFolders = new ArrayList<>();
for (FolderListItem folder : folders) {
if (subscribedFolderNames.contains(folder.getName())) {
filteredFolders.add(folder);
}
}

return filteredFolders;
}

private List<FolderListItem> listFolders(ImapConnection connection, boolean subscribedOnly) throws IOException,
MessagingException {
String commandResponse = subscribedOnly ? "LSUB" : "LIST";

List<ImapResponse> responses =
connection.executeSimpleCommand(String.format("%s \"\" %s", commandResponse,
ImapUtility.encodeString(getCombinedPrefix() + "*")));
String command;
if (subscribedOnly) {
command = "LSUB";
} else if (connection.hasCapability(Capabilities.SPECIAL_USE)) {
command = "LIST (SPECIAL-USE)";
} else {
command = "LIST";
}

List<ListResponse> listResponses = (subscribedOnly) ?
ListResponse.parseLsub(responses) : ListResponse.parseList(responses);
String encodedListPrefix = ImapUtility.encodeString(getCombinedPrefix() + "*");
List<ImapResponse> responses = connection.executeSimpleCommand(
String.format("%s \"\" %s", command, encodedListPrefix));

Set<String> folderNames = new HashSet<>(listResponses.size());
List<ListResponse> listResponses = (subscribedOnly) ?
ListResponse.parseLsub(responses) :
ListResponse.parseList(responses);

List<FolderListItem> folders = new ArrayList<>(listResponses.size());
for (ListResponse listResponse : listResponses) {
String decodedFolderName;
try {
decodedFolderName = folderNameCodec.decode(listResponse.getName());
} catch (CharacterCodingException e) {
Timber.w(e,
"Folder name not correctly encoded with the UTF-7 variant as defined by RFC 3501: %s",
Timber.w(e, "Folder name not correctly encoded with the UTF-7 variant as defined by RFC 3501: %s",
listResponse.getName());

//TODO: Use the raw name returned by the server for all commands that require
Expand Down Expand Up @@ -194,14 +217,31 @@ private Set<String> listFolders(ImapConnection connection, boolean subscribedOnl
}

folder = removePrefixFromFolderName(folder);
if (folder != null) {
folderNames.add(folder);
if (folder == null) {
continue;
}

FolderType type;
if (listResponse.hasAttribute("\\Archive") || listResponse.hasAttribute("\\All")) {
type = FolderType.ARCHIVE;
} else if (listResponse.hasAttribute("\\Drafts")) {
type = FolderType.DRAFTS;
} else if (listResponse.hasAttribute("\\Sent")) {
type = FolderType.SENT;
} else if (listResponse.hasAttribute("\\Junk")) {
type = FolderType.SPAM;
} else if (listResponse.hasAttribute("\\Trash")) {
type = FolderType.TRASH;
} else {
type = FolderType.REGULAR;
}

folders.add(new FolderListItem(folder, type));
}

folderNames.add(ImapFolder.INBOX);
folders.add(new FolderListItem(ImapFolder.INBOX, FolderType.INBOX));

return folderNames;
return folders;
}

void autoconfigureFolders(final ImapConnection connection) throws IOException, MessagingException {
Expand Down Expand Up @@ -347,15 +387,16 @@ FolderNameCodec getFolderNameCodec() {
return folderNameCodec;
}

private List<ImapFolder> getFolders(Collection<String> folderNames) {
List<ImapFolder> folders = new ArrayList<>(folderNames.size());
private List<ImapFolder> getFolders(List<FolderListItem> folders) {
List<ImapFolder> imapFolders = new ArrayList<>(folders.size());

for (String folderName : folderNames) {
ImapFolder imapFolder = getFolder(folderName);
folders.add(imapFolder);
for (FolderListItem folder : folders) {
ImapFolder imapFolder = getFolder(folder.getName());
imapFolder.setType(folder.getType());
imapFolders.add(imapFolder);
}

return folders;
return imapFolders;
}

@Override
Expand Down

0 comments on commit cea3c41

Please sign in to comment.