Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:56:56 +01:00
parent 75dc487a7a
commit 39c29d175b
6317 changed files with 388324 additions and 2 deletions

View file

@ -0,0 +1,15 @@
plugins {
id(ThunderbirdPlugins.Library.android)
}
android {
namespace = "app.k9mail.legacy.message"
}
dependencies {
implementation(projects.core.android.account)
implementation(projects.feature.search.implLegacy)
implementation(projects.mail.common)
implementation(projects.backend.api)
}

View file

@ -0,0 +1,16 @@
package app.k9mail.legacy.message.controller
import kotlinx.coroutines.flow.Flow
import net.thunderbird.core.android.account.LegacyAccount
import net.thunderbird.feature.search.legacy.LocalMessageSearch
import net.thunderbird.feature.search.legacy.SearchAccount
interface MessageCountsProvider {
fun getMessageCounts(account: LegacyAccount): MessageCounts
fun getMessageCounts(searchAccount: SearchAccount): MessageCounts
fun getMessageCounts(search: LocalMessageSearch): MessageCounts
fun getMessageCountsFlow(search: LocalMessageSearch): Flow<MessageCounts>
fun getUnreadMessageCount(account: LegacyAccount, folderId: Long): Int
}
data class MessageCounts(val unread: Int, val starred: Int)

View file

@ -0,0 +1,53 @@
package app.k9mail.legacy.message.controller
import com.fsck.k9.mail.filter.Base64
import java.util.StringTokenizer
data class MessageReference(
val accountUuid: String,
val folderId: Long,
val uid: String,
) {
fun toIdentityString(): String {
return buildString {
append(IDENTITY_VERSION_2)
append(IDENTITY_SEPARATOR)
append(Base64.encode(accountUuid))
append(IDENTITY_SEPARATOR)
append(Base64.encode(folderId.toString()))
append(IDENTITY_SEPARATOR)
append(Base64.encode(uid))
}
}
fun equals(accountUuid: String, folderId: Long, uid: String): Boolean {
return this.accountUuid == accountUuid && this.folderId == folderId && this.uid == uid
}
fun withModifiedUid(newUid: String): MessageReference {
return copy(uid = newUid)
}
companion object {
private const val IDENTITY_VERSION_2 = '#'
private const val IDENTITY_SEPARATOR = ":"
@Suppress("ReturnCount", "MagicNumber")
@JvmStatic
fun parse(identity: String?): MessageReference? {
if (identity == null || identity.isEmpty() || identity[0] != IDENTITY_VERSION_2) {
return null
}
val tokens = StringTokenizer(identity.substring(2), IDENTITY_SEPARATOR, false)
if (tokens.countTokens() < 3) {
return null
}
val accountUuid = Base64.decode(tokens.nextToken())
val folderId = Base64.decode(tokens.nextToken()).toLong()
val uid = Base64.decode(tokens.nextToken())
return MessageReference(accountUuid, folderId, uid)
}
}
}

View file

@ -0,0 +1,13 @@
package app.k9mail.legacy.message.controller
import net.thunderbird.core.android.account.LegacyAccount
interface MessagingControllerMailChecker {
fun checkMail(
account: LegacyAccount?,
ignoreLastCheckedTime: Boolean,
useManualWakeLock: Boolean,
notify: Boolean,
listener: MessagingListener?,
)
}

View file

@ -0,0 +1,8 @@
package app.k9mail.legacy.message.controller
interface MessagingControllerRegistry {
fun addListener(listener: MessagingListener)
fun removeListener(listener: MessagingListener)
}

View file

@ -0,0 +1,45 @@
package app.k9mail.legacy.message.controller;
import java.util.List;
import android.content.Context;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.Part;
import net.thunderbird.core.android.account.LegacyAccount;
public interface MessagingListener {
void synchronizeMailboxStarted(LegacyAccount account, long folderId);
void synchronizeMailboxHeadersStarted(LegacyAccount account, String folderServerId);
void synchronizeMailboxHeadersProgress(LegacyAccount account, String folderServerId, int completed, int total);
void synchronizeMailboxHeadersFinished(LegacyAccount account, String folderServerId, int totalMessagesInMailbox,
int numNewMessages);
void synchronizeMailboxProgress(LegacyAccount account, long folderId, int completed, int total);
void synchronizeMailboxNewMessage(LegacyAccount account, String folderServerId, Message message);
void synchronizeMailboxRemovedMessage(LegacyAccount account, String folderServerId, String messageServerId);
void synchronizeMailboxFinished(LegacyAccount account, long folderId);
void synchronizeMailboxFailed(LegacyAccount account, long folderId, String message);
void loadMessageRemoteFinished(LegacyAccount account, long folderId, String uid);
void loadMessageRemoteFailed(LegacyAccount account, long folderId, String uid, Throwable t);
void checkMailStarted(Context context, LegacyAccount account);
void checkMailFinished(Context context, LegacyAccount account);
void folderStatusChanged(LegacyAccount account, long folderId);
void messageUidChanged(LegacyAccount account, long folderId, String oldUid, String newUid);
void loadAttachmentFinished(LegacyAccount account, Message message, Part part);
void loadAttachmentFailed(LegacyAccount account, Message message, Part part, String reason);
void remoteSearchStarted(long folderId);
void remoteSearchServerQueryComplete(long folderId, int numResults, int maxResults);
void remoteSearchFinished(long folderId, int numResults, int maxResults, List<String> extraResults);
void remoteSearchFailed(String folderServerId, String err);
void enableProgressIndicator(boolean enable);
void updateProgress(int progress);
}

View file

@ -0,0 +1,107 @@
package app.k9mail.legacy.message.controller;
import java.util.List;
import android.content.Context;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.Part;
import net.thunderbird.core.android.account.LegacyAccount;
public abstract class SimpleMessagingListener implements MessagingListener {
@Override
public void synchronizeMailboxStarted(LegacyAccount account, long folderId) {
}
@Override
public void synchronizeMailboxHeadersStarted(LegacyAccount account, String folderServerId) {
}
@Override
public void synchronizeMailboxHeadersProgress(LegacyAccount account, String folderServerId, int completed, int total) {
}
@Override
public void synchronizeMailboxHeadersFinished(LegacyAccount account, String folderServerId, int totalMessagesInMailbox,
int numNewMessages) {
}
@Override
public void synchronizeMailboxProgress(LegacyAccount account, long folderId, int completed, int total) {
}
@Override
public void synchronizeMailboxNewMessage(LegacyAccount account, String folderServerId, Message message) {
}
@Override
public void synchronizeMailboxRemovedMessage(LegacyAccount account, String folderServerId, String messageServerId) {
}
@Override
public void synchronizeMailboxFinished(LegacyAccount account, long folderId) {
}
@Override
public void synchronizeMailboxFailed(LegacyAccount account, long folderId, String message) {
}
@Override
public void loadMessageRemoteFinished(LegacyAccount account, long folderId, String uid) {
}
@Override
public void loadMessageRemoteFailed(LegacyAccount account, long folderId, String uid, Throwable t) {
}
@Override
public void checkMailStarted(Context context, LegacyAccount account) {
}
@Override
public void checkMailFinished(Context context, LegacyAccount account) {
}
@Override
public void folderStatusChanged(LegacyAccount account, long folderId) {
}
@Override
public void messageUidChanged(LegacyAccount account, long folderId, String oldUid, String newUid) {
}
@Override
public void loadAttachmentFinished(LegacyAccount account, Message message, Part part) {
}
@Override
public void loadAttachmentFailed(LegacyAccount account, Message message, Part part, String reason) {
}
@Override
public void remoteSearchStarted(long folderId) {
}
@Override
public void remoteSearchServerQueryComplete(long folderId, int numResults, int maxResults) {
}
@Override
public void remoteSearchFinished(long folderId, int numResults, int maxResults, List<String> extraResults) {
}
@Override
public void remoteSearchFailed(String folderServerId, String err) {
}
@Override
public void enableProgressIndicator(boolean enable) {
}
@Override
public void updateProgress(int progress) {
}
}

View file

@ -0,0 +1,56 @@
package app.k9mail.legacy.message.extractors;
import androidx.annotation.NonNull;
public class PreviewResult {
private final PreviewType previewType;
private final String previewText;
private PreviewResult(PreviewType previewType, String previewText) {
this.previewType = previewType;
this.previewText = previewText;
}
public static PreviewResult text(@NonNull String previewText) {
return new PreviewResult(PreviewType.TEXT, previewText);
}
public static PreviewResult encrypted() {
return new PreviewResult(PreviewType.ENCRYPTED, null);
}
public static PreviewResult none() {
return new PreviewResult(PreviewType.NONE, null);
}
public static PreviewResult error() {
return new PreviewResult(PreviewType.ERROR, null);
}
public PreviewType getPreviewType() {
return previewType;
}
public boolean isPreviewTextAvailable() {
return previewType == PreviewType.TEXT;
}
public String getPreviewText() {
if (!isPreviewTextAvailable()) {
throw new IllegalStateException("Preview is not available");
}
return previewText;
}
public enum PreviewType {
NONE,
TEXT,
ENCRYPTED,
ERROR
}
}

View file

@ -0,0 +1,64 @@
package app.k9mail.legacy.message.controller
import assertk.assertThat
import assertk.assertions.isEqualTo
import assertk.assertions.isNull
import assertk.assertions.isTrue
import kotlin.test.assertNotNull
import org.junit.Test
class MessageReferenceTest {
@Test
fun checkIdentityStringFromMessageReference() {
val messageReference = MessageReference("o hai!", 2, "10101010")
val serialized = messageReference.toIdentityString()
assertThat(serialized).isEqualTo("#:byBoYWkh:Mg==:MTAxMDEwMTA=")
}
@Test
fun parseIdentityString() {
val result = MessageReference.parse("#:byBoYWkh:Mg==:MTAxMDEwMTA=")
assertNotNull(result) { messageReference ->
assertThat(messageReference.accountUuid).isEqualTo("o hai!")
assertThat(messageReference.folderId).isEqualTo(2)
assertThat(messageReference.uid).isEqualTo("10101010")
}
}
@Test
fun parseIdentityStringContainingBadVersionNumber() {
val messageReference = MessageReference.parse("@:byBoYWkh:MTAxMDEwMTA=")
assertThat(messageReference).isNull()
}
@Test
fun parseNullIdentityString() {
val messageReference = MessageReference.parse(null)
assertThat(messageReference).isNull()
}
@Test
fun checkMessageReferenceWithChangedUid() {
val messageReferenceOne = MessageReference("account", 1, "uid")
val messageReference = messageReferenceOne.withModifiedUid("---")
assertThat(messageReference.accountUuid).isEqualTo("account")
assertThat(messageReference.folderId).isEqualTo(1)
assertThat(messageReference.uid).isEqualTo("---")
}
@Test
fun alternativeEquals() {
val messageReference = MessageReference("account", 1, "uid")
val equalsResult = messageReference.equals("account", 1, "uid")
assertThat(equalsResult).isTrue()
}
}