From 81fc50ec374f46ad62e909cae30673fa6ffeef97 Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Mon, 5 Mar 2018 10:12:21 +0100 Subject: [PATCH] Improvements for working with conversations --- .../ch/dissem/bitmessage/entity/Plaintext.kt | 11 ++++++++++ .../bitmessage/ports/MessageRepository.kt | 2 +- .../bitmessage/utils/ConversationService.kt | 21 +++++++++++++------ .../repository/JdbcMessageRepository.kt | 5 +++-- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/core/src/main/kotlin/ch/dissem/bitmessage/entity/Plaintext.kt b/core/src/main/kotlin/ch/dissem/bitmessage/entity/Plaintext.kt index 2069703..f7a2f24 100644 --- a/core/src/main/kotlin/ch/dissem/bitmessage/entity/Plaintext.kt +++ b/core/src/main/kotlin/ch/dissem/bitmessage/entity/Plaintext.kt @@ -815,3 +815,14 @@ class Plaintext private constructor( } } + +data class Conversation(val id: UUID, val subject: String, val messages: List) { + val participants = messages + .map { it.from } + .filter { it.privateKey == null || it.isChan } + .distinct() + + val extract: String by lazy { messages.lastOrNull()?.text ?: "" } + + fun hasUnread() = messages.any { it.isUnread() } +} diff --git a/core/src/main/kotlin/ch/dissem/bitmessage/ports/MessageRepository.kt b/core/src/main/kotlin/ch/dissem/bitmessage/ports/MessageRepository.kt index 272abae..95cd77e 100644 --- a/core/src/main/kotlin/ch/dissem/bitmessage/ports/MessageRepository.kt +++ b/core/src/main/kotlin/ch/dissem/bitmessage/ports/MessageRepository.kt @@ -41,7 +41,7 @@ interface MessageRepository { * * * @return a distinct list of all conversations that have at least one message with the given label. */ - fun findConversations(label: Label?): List<UUID> + fun findConversations(label: Label?, offset: Int = 0, limit: Int = 0): List<UUID> fun findMessages(label: Label?): List<Plaintext> diff --git a/core/src/main/kotlin/ch/dissem/bitmessage/utils/ConversationService.kt b/core/src/main/kotlin/ch/dissem/bitmessage/utils/ConversationService.kt index f06a6ed..5939c96 100644 --- a/core/src/main/kotlin/ch/dissem/bitmessage/utils/ConversationService.kt +++ b/core/src/main/kotlin/ch/dissem/bitmessage/utils/ConversationService.kt @@ -16,10 +16,11 @@ package ch.dissem.bitmessage.utils +import ch.dissem.bitmessage.entity.Conversation import ch.dissem.bitmessage.entity.Plaintext import ch.dissem.bitmessage.entity.valueobject.InventoryVector +import ch.dissem.bitmessage.entity.valueobject.Label import ch.dissem.bitmessage.ports.MessageRepository -import org.slf4j.LoggerFactory import java.util.* import java.util.Collections import java.util.regex.Pattern @@ -30,7 +31,10 @@ import java.util.regex.Pattern.CASE_INSENSITIVE */ class ConversationService(private val messageRepository: MessageRepository) { - private val SUBJECT_PREFIX = Pattern.compile("^(re|fwd?):", CASE_INSENSITIVE) + private val SUBJECT_PREFIX = Pattern.compile("^(re|fwd?):\\s*", CASE_INSENSITIVE) + + fun findConversations(label: Label?, offset: Int = 0, limit: Int = 0) = messageRepository.findConversations(label, offset, limit) + .map { getConversation(it) } /** * Retrieve the whole conversation from one single message. If the message isn't part @@ -41,7 +45,7 @@ class ConversationService(private val messageRepository: MessageRepository) { * * * @return a list of messages that belong to the same conversation. */ - fun getConversation(message: Plaintext): List<Plaintext> { + fun getConversation(message: Plaintext): Conversation { return getConversation(message.conversationId) } @@ -58,7 +62,7 @@ class ConversationService(private val messageRepository: MessageRepository) { return result } - fun getConversation(conversationId: UUID): List<Plaintext> { + fun getConversation(conversationId: UUID): Conversation { val messages = sorted(messageRepository.getConversation(conversationId)) val map = HashMap<InventoryVector, Plaintext>(messages.size) for (message in messages) { @@ -74,7 +78,7 @@ class ConversationService(private val messageRepository: MessageRepository) { result.add(pos, last) addAncestors(last, result, messages, map) } - return result + return Conversation(conversationId, getSubject(result) ?: "", result) } fun getSubject(conversation: List<Plaintext>): String? { @@ -109,7 +113,12 @@ class ConversationService(private val messageRepository: MessageRepository) { return child.parents.firstOrNull { it == item.inventoryVector } != null } - private fun addAncestors(message: Plaintext, result: LinkedList<Plaintext>, messages: LinkedList<Plaintext>, map: MutableMap<InventoryVector, Plaintext>) { + private fun addAncestors( + message: Plaintext, + result: LinkedList<Plaintext>, + messages: LinkedList<Plaintext>, + map: MutableMap<InventoryVector, Plaintext> + ) { for (parentKey in message.parents) { map.remove(parentKey)?.let { messages.remove(it) diff --git a/repositories/src/main/kotlin/ch/dissem/bitmessage/repository/JdbcMessageRepository.kt b/repositories/src/main/kotlin/ch/dissem/bitmessage/repository/JdbcMessageRepository.kt index c7f6d3a..744c085 100644 --- a/repositories/src/main/kotlin/ch/dissem/bitmessage/repository/JdbcMessageRepository.kt +++ b/repositories/src/main/kotlin/ch/dissem/bitmessage/repository/JdbcMessageRepository.kt @@ -257,18 +257,19 @@ class JdbcMessageRepository(private val config: JdbcConfig) : AbstractMessageRep } } - override fun findConversations(label: Label?): List<UUID> { + override fun findConversations(label: Label?, offset: Int, limit: Int): List<UUID> { val where = if (label == null) { "id NOT IN (SELECT message_id FROM Message_Label)" } else { "id IN (SELECT message_id FROM Message_Label WHERE label_id=${label.id})" } + val limit = if (limit == 0) "" else "LIMIT $limit OFFSET $offset" val result = LinkedList<UUID>() try { config.getConnection().use { connection -> connection.createStatement().use { stmt -> stmt.executeQuery( - "SELECT DISTINCT conversation FROM Message WHERE $where").use { rs -> + "SELECT DISTINCT conversation FROM Message WHERE $where $limit").use { rs -> while (rs.next()) { result.add(rs.getObject(1) as UUID) }