109 lines
4.0 KiB
Kotlin
109 lines
4.0 KiB
Kotlin
package be.simplenotes.domain
|
|
|
|
import arrow.core.raise.either
|
|
import be.simplenotes.domain.security.HtmlSanitizer
|
|
import be.simplenotes.domain.utils.parseSearchTerms
|
|
import be.simplenotes.persistence.repositories.NoteRepository
|
|
import be.simplenotes.persistence.repositories.UserRepository
|
|
import be.simplenotes.search.NoteSearcher
|
|
import be.simplenotes.types.LoggedInUser
|
|
import be.simplenotes.types.Note
|
|
import be.simplenotes.types.PersistedNoteMetadata
|
|
import jakarta.annotation.PostConstruct
|
|
import jakarta.annotation.PreDestroy
|
|
import jakarta.inject.Singleton
|
|
import java.util.*
|
|
|
|
@Singleton
|
|
class NoteService(
|
|
private val markdownService: MarkdownService,
|
|
private val noteRepository: NoteRepository,
|
|
private val userRepository: UserRepository,
|
|
private val searcher: NoteSearcher,
|
|
private val htmlSanitizer: HtmlSanitizer,
|
|
) {
|
|
|
|
fun create(user: LoggedInUser, markdownText: String) = either {
|
|
markdownService.renderDocument(markdownText)
|
|
.map { it.copy(html = htmlSanitizer.sanitize(user, it.html)) }
|
|
.map { Note(title = it.metadata.title, tags = it.metadata.tags, markdown = markdownText, html = it.html) }
|
|
.map { noteRepository.create(user.userId, it) }
|
|
.bind()
|
|
.also { searcher.indexNote(user.userId, it) }
|
|
}
|
|
|
|
fun update(user: LoggedInUser, uuid: UUID, markdownText: String) =
|
|
either {
|
|
markdownService.renderDocument(markdownText)
|
|
.map { it.copy(html = htmlSanitizer.sanitize(user, it.html)) }
|
|
.map {
|
|
Note(
|
|
title = it.metadata.title,
|
|
tags = it.metadata.tags,
|
|
markdown = markdownText,
|
|
html = it.html,
|
|
)
|
|
}
|
|
.map { noteRepository.update(user.userId, uuid, it) }
|
|
.bind()
|
|
?.also { searcher.updateIndex(user.userId, it) }
|
|
}
|
|
|
|
fun paginatedNotes(
|
|
userId: Int,
|
|
page: Int,
|
|
itemsPerPage: Int = 20,
|
|
tag: String? = null,
|
|
deleted: Boolean = false,
|
|
): PaginatedNotes {
|
|
val count = noteRepository.count(userId, tag, deleted)
|
|
val offset = (page - 1) * itemsPerPage
|
|
val numberOfPages = (count / itemsPerPage) + 1
|
|
val notes = if (count == 0) emptyList() else noteRepository.findAll(userId, itemsPerPage, offset, tag, deleted)
|
|
return PaginatedNotes(numberOfPages, notes)
|
|
}
|
|
|
|
fun find(userId: Int, uuid: UUID) = noteRepository.find(userId, uuid)
|
|
|
|
fun trash(userId: Int, uuid: UUID): Boolean {
|
|
val res = noteRepository.delete(userId, uuid, permanent = false)
|
|
if (res) searcher.deleteIndex(userId, uuid)
|
|
return res
|
|
}
|
|
|
|
fun restore(userId: Int, uuid: UUID): Boolean {
|
|
val res = noteRepository.restore(userId, uuid)
|
|
if (res) find(userId, uuid)?.let { note -> searcher.indexNote(userId, note) }
|
|
return res
|
|
}
|
|
|
|
fun delete(userId: Int, uuid: UUID): Boolean {
|
|
val res = noteRepository.delete(userId, uuid, permanent = true)
|
|
if (res) searcher.deleteIndex(userId, uuid)
|
|
return res
|
|
}
|
|
|
|
fun countDeleted(userId: Int) = noteRepository.count(userId, deleted = true)
|
|
|
|
@PostConstruct
|
|
fun indexAll() {
|
|
dropAllIndexes()
|
|
val userIds = userRepository.findAll()
|
|
userIds.forEach { id ->
|
|
val notes = noteRepository.findAllDetails(id)
|
|
searcher.indexNotes(id, notes)
|
|
}
|
|
}
|
|
|
|
fun search(userId: Int, searchInput: String) = searcher.search(userId, parseSearchTerms(searchInput))
|
|
|
|
@PreDestroy
|
|
fun dropAllIndexes() = searcher.dropAll()
|
|
|
|
fun makePublic(userId: Int, uuid: UUID) = noteRepository.makePublic(userId, uuid)
|
|
fun makePrivate(userId: Int, uuid: UUID) = noteRepository.makePrivate(userId, uuid)
|
|
fun findPublic(uuid: UUID) = noteRepository.findPublic(uuid)
|
|
}
|
|
|
|
data class PaginatedNotes(val pages: Int, val notes: List<PersistedNoteMetadata>)
|