Improvements for working with conversations
This commit is contained in:
parent
f1403bcd00
commit
81fc50ec37
@ -815,3 +815,14 @@ class Plaintext private constructor(
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class Conversation(val id: UUID, val subject: String, val messages: List<Plaintext>) {
|
||||||
|
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() }
|
||||||
|
}
|
||||||
|
@ -41,7 +41,7 @@ interface MessageRepository {
|
|||||||
* *
|
* *
|
||||||
* @return a distinct list of all conversations that have at least one message with the given label.
|
* @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>
|
fun findMessages(label: Label?): List<Plaintext>
|
||||||
|
|
||||||
|
@ -16,10 +16,11 @@
|
|||||||
|
|
||||||
package ch.dissem.bitmessage.utils
|
package ch.dissem.bitmessage.utils
|
||||||
|
|
||||||
|
import ch.dissem.bitmessage.entity.Conversation
|
||||||
import ch.dissem.bitmessage.entity.Plaintext
|
import ch.dissem.bitmessage.entity.Plaintext
|
||||||
import ch.dissem.bitmessage.entity.valueobject.InventoryVector
|
import ch.dissem.bitmessage.entity.valueobject.InventoryVector
|
||||||
|
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||||
import ch.dissem.bitmessage.ports.MessageRepository
|
import ch.dissem.bitmessage.ports.MessageRepository
|
||||||
import org.slf4j.LoggerFactory
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
@ -30,7 +31,10 @@ import java.util.regex.Pattern.CASE_INSENSITIVE
|
|||||||
*/
|
*/
|
||||||
class ConversationService(private val messageRepository: MessageRepository) {
|
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
|
* 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.
|
* @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)
|
return getConversation(message.conversationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +62,7 @@ class ConversationService(private val messageRepository: MessageRepository) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getConversation(conversationId: UUID): List<Plaintext> {
|
fun getConversation(conversationId: UUID): Conversation {
|
||||||
val messages = sorted(messageRepository.getConversation(conversationId))
|
val messages = sorted(messageRepository.getConversation(conversationId))
|
||||||
val map = HashMap<InventoryVector, Plaintext>(messages.size)
|
val map = HashMap<InventoryVector, Plaintext>(messages.size)
|
||||||
for (message in messages) {
|
for (message in messages) {
|
||||||
@ -74,7 +78,7 @@ class ConversationService(private val messageRepository: MessageRepository) {
|
|||||||
result.add(pos, last)
|
result.add(pos, last)
|
||||||
addAncestors(last, result, messages, map)
|
addAncestors(last, result, messages, map)
|
||||||
}
|
}
|
||||||
return result
|
return Conversation(conversationId, getSubject(result) ?: "", result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSubject(conversation: List<Plaintext>): String? {
|
fun getSubject(conversation: List<Plaintext>): String? {
|
||||||
@ -109,7 +113,12 @@ class ConversationService(private val messageRepository: MessageRepository) {
|
|||||||
return child.parents.firstOrNull { it == item.inventoryVector } != null
|
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) {
|
for (parentKey in message.parents) {
|
||||||
map.remove(parentKey)?.let {
|
map.remove(parentKey)?.let {
|
||||||
messages.remove(it)
|
messages.remove(it)
|
||||||
|
@ -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) {
|
val where = if (label == null) {
|
||||||
"id NOT IN (SELECT message_id FROM Message_Label)"
|
"id NOT IN (SELECT message_id FROM Message_Label)"
|
||||||
} else {
|
} else {
|
||||||
"id IN (SELECT message_id FROM Message_Label WHERE label_id=${label.id})"
|
"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>()
|
val result = LinkedList<UUID>()
|
||||||
try {
|
try {
|
||||||
config.getConnection().use { connection ->
|
config.getConnection().use { connection ->
|
||||||
connection.createStatement().use { stmt ->
|
connection.createStatement().use { stmt ->
|
||||||
stmt.executeQuery(
|
stmt.executeQuery(
|
||||||
"SELECT DISTINCT conversation FROM Message WHERE $where").use { rs ->
|
"SELECT DISTINCT conversation FROM Message WHERE $where $limit").use { rs ->
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
result.add(rs.getObject(1) as UUID)
|
result.add(rs.getObject(1) as UUID)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user