mirror of https://github.com/usbharu/Hideout.git
feat: ミュートの基本部分を実装
This commit is contained in:
parent
20c4d3f4e6
commit
827edb2d44
|
@ -0,0 +1,9 @@
|
||||||
|
package dev.usbharu.hideout.core.domain.model.filter
|
||||||
|
|
||||||
|
data class Filter(
|
||||||
|
val id: Long,
|
||||||
|
val userId: Long,
|
||||||
|
val name: String,
|
||||||
|
val context: List<FilterType>,
|
||||||
|
val filterAction: FilterAction,
|
||||||
|
)
|
|
@ -0,0 +1,6 @@
|
||||||
|
package dev.usbharu.hideout.core.domain.model.filter
|
||||||
|
|
||||||
|
enum class FilterAction {
|
||||||
|
warn,
|
||||||
|
hide
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package dev.usbharu.hideout.core.domain.model.filter
|
||||||
|
|
||||||
|
enum class FilterMode {
|
||||||
|
WHOLE_WORD,
|
||||||
|
REGEX,
|
||||||
|
NONE
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package dev.usbharu.hideout.core.domain.model.filter
|
||||||
|
|
||||||
|
interface FilterRepository {
|
||||||
|
|
||||||
|
suspend fun generateId(): Long
|
||||||
|
suspend fun save(filter: Filter): Filter
|
||||||
|
suspend fun findById(id: Long): Filter?
|
||||||
|
|
||||||
|
suspend fun findByUserIdAndType(userId: Long, types: List<FilterType>): List<Filter>
|
||||||
|
suspend fun deleteById(id: Long)
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package dev.usbharu.hideout.core.domain.model.filter
|
||||||
|
|
||||||
|
enum class FilterType {
|
||||||
|
home,
|
||||||
|
notifications,
|
||||||
|
public,
|
||||||
|
thread,
|
||||||
|
account
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package dev.usbharu.hideout.core.domain.model.filterkeyword
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterMode
|
||||||
|
|
||||||
|
data class FilterKeyword(
|
||||||
|
val id: Long,
|
||||||
|
val filterId: Long,
|
||||||
|
val keyword: String,
|
||||||
|
val mode: FilterMode
|
||||||
|
)
|
|
@ -0,0 +1,10 @@
|
||||||
|
package dev.usbharu.hideout.core.domain.model.filterkeyword
|
||||||
|
|
||||||
|
interface FilterKeywordRepository {
|
||||||
|
suspend fun generateId(): Long
|
||||||
|
suspend fun save(filterKeyword: FilterKeyword): FilterKeyword
|
||||||
|
suspend fun saveAll(filterKeywordList: List<FilterKeyword>)
|
||||||
|
suspend fun findById(id: Long): FilterKeyword?
|
||||||
|
suspend fun deleteById(id: Long)
|
||||||
|
suspend fun deleteByFilterId(filterId: Long)
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.application.service.id.IdGenerateService
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterMode
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filterkeyword.FilterKeyword
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filterkeyword.FilterKeywordRepository
|
||||||
|
import org.jetbrains.exposed.sql.*
|
||||||
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
|
import org.slf4j.Logger
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
class ExposedFilterKeywordRepository(private val idGenerateService: IdGenerateService) : FilterKeywordRepository,
|
||||||
|
AbstractRepository() {
|
||||||
|
override val logger: Logger
|
||||||
|
get() = Companion.logger
|
||||||
|
|
||||||
|
override suspend fun generateId(): Long = idGenerateService.generateId()
|
||||||
|
|
||||||
|
override suspend fun save(filterKeyword: FilterKeyword): FilterKeyword = query {
|
||||||
|
val empty = FilterKeywords.selectAll().where { FilterKeywords.id eq filterKeyword.id }.empty()
|
||||||
|
if (empty) {
|
||||||
|
FilterKeywords.insert {
|
||||||
|
it[id] = filterKeyword.id
|
||||||
|
it[filterId] = filterKeyword.filterId
|
||||||
|
it[keyword] = filterKeyword.keyword
|
||||||
|
it[mode] = filterKeyword.mode.name
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FilterKeywords.update({ FilterKeywords.id eq filterKeyword.id }) {
|
||||||
|
it[filterId] = filterKeyword.filterId
|
||||||
|
it[keyword] = filterKeyword.keyword
|
||||||
|
it[mode] = filterKeyword.mode.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filterKeyword
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun saveAll(filterKeywordList: List<FilterKeyword>): Unit = query {
|
||||||
|
FilterKeywords.batchInsert(filterKeywordList, ignore = true) {
|
||||||
|
this[FilterKeywords.id] = it.id
|
||||||
|
this[FilterKeywords.filterId] = it.filterId
|
||||||
|
this[FilterKeywords.keyword] = it.keyword
|
||||||
|
this[FilterKeywords.mode] = it.mode.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun findById(id: Long): FilterKeyword? = query {
|
||||||
|
return@query FilterKeywords.selectAll().where { FilterKeywords.id eq id }.singleOrNull()?.toFilterKeyword()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteById(id: Long): Unit = query {
|
||||||
|
FilterKeywords.deleteWhere { FilterKeywords.id eq id }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteByFilterId(filterId: Long): Unit = query {
|
||||||
|
FilterKeywords.deleteWhere { FilterKeywords.filterId eq filterId }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val logger = LoggerFactory.getLogger(ExposedFilterKeywordRepository::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ResultRow.toFilterKeyword(): FilterKeyword {
|
||||||
|
return FilterKeyword(
|
||||||
|
this[FilterKeywords.id],
|
||||||
|
this[FilterKeywords.filterId],
|
||||||
|
this[FilterKeywords.keyword],
|
||||||
|
this[FilterKeywords.mode].let { FilterMode.valueOf(it) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
object FilterKeywords : Table() {
|
||||||
|
val id = long("id")
|
||||||
|
val filterId = long("filter_id").references(Filters.id)
|
||||||
|
val keyword = varchar("keyword", 1000)
|
||||||
|
val mode = varchar("mode", 100)
|
||||||
|
|
||||||
|
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.application.service.id.IdGenerateService
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.Filter
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterAction
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterRepository
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterType
|
||||||
|
import org.jetbrains.exposed.sql.*
|
||||||
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
|
import org.slf4j.Logger
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
class ExposedFilterRepository(private val idGenerateService: IdGenerateService) : FilterRepository,
|
||||||
|
AbstractRepository() {
|
||||||
|
override val logger: Logger
|
||||||
|
get() = Companion.logger
|
||||||
|
|
||||||
|
override suspend fun generateId(): Long = idGenerateService.generateId()
|
||||||
|
|
||||||
|
override suspend fun save(filter: Filter): Filter = query {
|
||||||
|
val empty = Filters.selectAll().where {
|
||||||
|
Filters.id eq filter.id
|
||||||
|
}.forUpdate().empty()
|
||||||
|
if (empty) {
|
||||||
|
Filters.insert {
|
||||||
|
it[id] = filter.id
|
||||||
|
it[userId] = filter.userId
|
||||||
|
it[name] = filter.name
|
||||||
|
it[context] = filter.context.joinToString(",") { it.name }
|
||||||
|
it[filterAction] = filter.filterAction.name
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Filters.update({ Filters.id eq filter.id }) {
|
||||||
|
it[userId] = filter.userId
|
||||||
|
it[name] = filter.name
|
||||||
|
it[context] = filter.context.joinToString(",") { it.name }
|
||||||
|
it[filterAction] = filter.filterAction.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filter
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun findById(id: Long): Filter? = query {
|
||||||
|
return@query Filters.selectAll().where { Filters.id eq id }.singleOrNull()?.toFilter()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun findByUserIdAndType(userId: Long, types: List<FilterType>): List<Filter> = query {
|
||||||
|
return@query Filters.selectAll().where { Filters.userId eq userId }.map { it.toFilter() }
|
||||||
|
.filter { it.context.containsAll(types) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteById(id: Long): Unit = query {
|
||||||
|
Filters.deleteWhere { Filters.id eq id }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val logger = LoggerFactory.getLogger(ExposedFilterRepository::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ResultRow.toFilter(): Filter = Filter(
|
||||||
|
this[Filters.id],
|
||||||
|
this[Filters.userId],
|
||||||
|
this[Filters.name],
|
||||||
|
this[Filters.context].split(",").filterNot(String::isEmpty).map { FilterType.valueOf(it) },
|
||||||
|
this[Filters.filterAction].let { FilterAction.valueOf(it) }
|
||||||
|
)
|
||||||
|
|
||||||
|
object Filters : Table() {
|
||||||
|
val id = long("id")
|
||||||
|
val userId = long("user_id").references(Actors.id)
|
||||||
|
val name = varchar("name", 255)
|
||||||
|
val context = varchar("context", 500)
|
||||||
|
val filterAction = varchar("action", 255)
|
||||||
|
|
||||||
|
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package dev.usbharu.hideout.core.query.model
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterType
|
||||||
|
import dev.usbharu.hideout.core.infrastructure.exposedrepository.FilterKeywords
|
||||||
|
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Filters
|
||||||
|
import dev.usbharu.hideout.core.infrastructure.exposedrepository.toFilter
|
||||||
|
import dev.usbharu.hideout.core.infrastructure.exposedrepository.toFilterKeyword
|
||||||
|
import org.jetbrains.exposed.sql.Query
|
||||||
|
import org.jetbrains.exposed.sql.selectAll
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
class ExposedFilterQueryService : FilterQueryService {
|
||||||
|
override suspend fun findByUserIdAndType(userId: Long, types: List<FilterType>): List<FilterQueryModel> {
|
||||||
|
return Filters
|
||||||
|
.rightJoin(FilterKeywords)
|
||||||
|
.selectAll()
|
||||||
|
.where { Filters.userId eq userId }
|
||||||
|
.toFilterQueryModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Query.toFilterQueryModel(): List<FilterQueryModel> {
|
||||||
|
return this
|
||||||
|
.groupBy { it[Filters.id] }
|
||||||
|
.map { it.value }
|
||||||
|
.map {
|
||||||
|
FilterQueryModel.of(
|
||||||
|
it.first().toFilter(),
|
||||||
|
it.map { it.toFilterKeyword() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package dev.usbharu.hideout.core.query.model
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.Filter
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterAction
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterType
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filterkeyword.FilterKeyword
|
||||||
|
|
||||||
|
data class FilterQueryModel(
|
||||||
|
val id: Long,
|
||||||
|
val userId: Long,
|
||||||
|
val name: String,
|
||||||
|
val context: List<FilterType>,
|
||||||
|
val filterAction: FilterAction,
|
||||||
|
val keywords: List<FilterKeyword>
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun of(filter: Filter, keywords: List<FilterKeyword>): FilterQueryModel = FilterQueryModel(
|
||||||
|
filter.id,
|
||||||
|
filter.userId,
|
||||||
|
filter.name,
|
||||||
|
filter.context,
|
||||||
|
filter.filterAction,
|
||||||
|
keywords
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package dev.usbharu.hideout.core.query.model
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterType
|
||||||
|
|
||||||
|
interface FilterQueryService {
|
||||||
|
suspend fun findByUserIdAndType(userId: Long, types: List<FilterType>): List<FilterQueryModel>
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package dev.usbharu.hideout.core.service.filter
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterMode
|
||||||
|
|
||||||
|
data class FilterKeyword(
|
||||||
|
val keyword: String,
|
||||||
|
val mode: FilterMode
|
||||||
|
)
|
|
@ -0,0 +1,8 @@
|
||||||
|
package dev.usbharu.hideout.core.service.filter
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.query.model.FilterQueryModel
|
||||||
|
|
||||||
|
data class FilterResult(
|
||||||
|
val filter: FilterQueryModel,
|
||||||
|
val keyword: String,
|
||||||
|
)
|
|
@ -0,0 +1,14 @@
|
||||||
|
package dev.usbharu.hideout.core.service.filter
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterType
|
||||||
|
import dev.usbharu.hideout.core.domain.model.post.Post
|
||||||
|
import dev.usbharu.hideout.core.query.model.FilterQueryModel
|
||||||
|
|
||||||
|
interface MuteProcessService {
|
||||||
|
suspend fun processMute(post: Post, context: List<FilterType>, filters: List<FilterQueryModel>): FilterResult?
|
||||||
|
suspend fun processMutes(
|
||||||
|
posts: List<Post>,
|
||||||
|
context: List<FilterType>,
|
||||||
|
filters: List<FilterQueryModel>
|
||||||
|
): Map<Post, FilterResult>
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
package dev.usbharu.hideout.core.service.filter
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterMode.*
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterType
|
||||||
|
import dev.usbharu.hideout.core.domain.model.post.Post
|
||||||
|
import dev.usbharu.hideout.core.query.model.FilterQueryModel
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class MuteProcessServiceImpl : MuteProcessService {
|
||||||
|
override suspend fun processMute(
|
||||||
|
post: Post,
|
||||||
|
context: List<FilterType>,
|
||||||
|
filters: List<FilterQueryModel>
|
||||||
|
): FilterResult? {
|
||||||
|
val preprocess = preprocess(context, filters)
|
||||||
|
|
||||||
|
return processMute(post, preprocess)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun processMute(
|
||||||
|
post: Post,
|
||||||
|
preprocess: List<PreProcessedFilter>
|
||||||
|
): FilterResult? {
|
||||||
|
logger.trace("process mute post: {}", post)
|
||||||
|
if (post.overview != null) {
|
||||||
|
val processMute = processMute(post.overview, preprocess)
|
||||||
|
|
||||||
|
if (processMute != null) {
|
||||||
|
return processMute
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val processMute = processMute(post.text, preprocess)
|
||||||
|
|
||||||
|
if (processMute != null) {
|
||||||
|
return processMute
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun processMutes(
|
||||||
|
posts: List<Post>,
|
||||||
|
context: List<FilterType>,
|
||||||
|
filters: List<FilterQueryModel>
|
||||||
|
): Map<Post, FilterResult> {
|
||||||
|
val preprocess = preprocess(context, filters)
|
||||||
|
|
||||||
|
return posts.mapNotNull { it to (processMute(it, preprocess) ?: return@mapNotNull null) }.toMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun processMute(string: String, filters: List<PreProcessedFilter>): FilterResult? {
|
||||||
|
for (filter in filters) {
|
||||||
|
val matchEntire = filter.regex.find(string)
|
||||||
|
|
||||||
|
if (matchEntire != null) {
|
||||||
|
return FilterResult(filter.filter, matchEntire.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun preprocess(context: List<FilterType>, filters: List<FilterQueryModel>): List<PreProcessedFilter> {
|
||||||
|
val filterQueryModelList = filters
|
||||||
|
.filter { it.context.any(context::contains) }
|
||||||
|
.map {
|
||||||
|
PreProcessedFilter(
|
||||||
|
it,
|
||||||
|
precompileRegex(it)
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return filterQueryModelList
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun precompileRegex(filter: FilterQueryModel): Regex {
|
||||||
|
logger.trace("precompile regex. filter: {}", filter)
|
||||||
|
|
||||||
|
val regexList = mutableListOf<Regex>()
|
||||||
|
|
||||||
|
val noneRegexStrings = mutableListOf<String>()
|
||||||
|
val wholeRegexStrings = mutableListOf<String>()
|
||||||
|
|
||||||
|
for (keyword in filter.keywords) {
|
||||||
|
when (keyword.mode) {
|
||||||
|
WHOLE_WORD -> wholeRegexStrings.add(keyword.keyword)
|
||||||
|
REGEX -> regexList.add(Regex(keyword.keyword))
|
||||||
|
NONE -> noneRegexStrings.add(keyword.keyword)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val noneRegex = noneRegexStrings.joinToString("|", "(", ")")
|
||||||
|
val wholeRegex = wholeRegexStrings.joinToString("|", "\\b(", ")\\b")
|
||||||
|
|
||||||
|
|
||||||
|
val regex = if (noneRegexStrings.isNotEmpty() && wholeRegexStrings.isNotEmpty()) {
|
||||||
|
Regex("$noneRegex|$wholeRegex")
|
||||||
|
} else if (noneRegexStrings.isNotEmpty()) {
|
||||||
|
noneRegex.toRegex()
|
||||||
|
} else if (wholeRegexStrings.isNotEmpty()) {
|
||||||
|
wholeRegex.toRegex()
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regex != null) {
|
||||||
|
regexList.add(regex)
|
||||||
|
}
|
||||||
|
|
||||||
|
val pattern = regexList.joinToString(")|(", "(", ")")
|
||||||
|
logger.trace("precompiled regex {}", pattern)
|
||||||
|
|
||||||
|
return Regex(pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
data class PreProcessedFilter(val filter: FilterQueryModel, val regex: Regex)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val logger = LoggerFactory.getLogger(MuteProcessServiceImpl::class.java)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package dev.usbharu.hideout.core.service.filter
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.Filter
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterAction
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterType
|
||||||
|
import dev.usbharu.hideout.core.query.model.FilterQueryModel
|
||||||
|
|
||||||
|
interface MuteService {
|
||||||
|
suspend fun createFilter(
|
||||||
|
title: String,
|
||||||
|
name: String,
|
||||||
|
context: List<FilterType>,
|
||||||
|
action: FilterAction,
|
||||||
|
keywords: List<FilterKeyword>,
|
||||||
|
loginUser: Long
|
||||||
|
): Filter
|
||||||
|
|
||||||
|
suspend fun getFilters(userId: Long, types: List<FilterType> = emptyList()): List<FilterQueryModel>
|
||||||
|
|
||||||
|
suspend fun deleteFilter(filterId: Long)
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package dev.usbharu.hideout.core.service.filter
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.Filter
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterAction
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterRepository
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterType
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filterkeyword.FilterKeywordRepository
|
||||||
|
import dev.usbharu.hideout.core.query.model.FilterQueryModel
|
||||||
|
import dev.usbharu.hideout.core.query.model.FilterQueryService
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class MuteServiceImpl(
|
||||||
|
private val filterRepository: FilterRepository,
|
||||||
|
private val filterKeywordRepository: FilterKeywordRepository,
|
||||||
|
private val filterQueryService: FilterQueryService
|
||||||
|
) : MuteService {
|
||||||
|
override suspend fun createFilter(
|
||||||
|
title: String,
|
||||||
|
name: String,
|
||||||
|
context: List<FilterType>,
|
||||||
|
action: FilterAction,
|
||||||
|
keywords: List<FilterKeyword>,
|
||||||
|
loginUser: Long
|
||||||
|
): Filter {
|
||||||
|
val filter = Filter(
|
||||||
|
filterRepository.generateId(),
|
||||||
|
loginUser,
|
||||||
|
name,
|
||||||
|
context,
|
||||||
|
action
|
||||||
|
)
|
||||||
|
|
||||||
|
val filterKeywordList = keywords.map {
|
||||||
|
dev.usbharu.hideout.core.domain.model.filterkeyword.FilterKeyword(
|
||||||
|
filterRepository.generateId(),
|
||||||
|
filter.id,
|
||||||
|
it.keyword,
|
||||||
|
it.mode
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
filterKeywordRepository.saveAll(filterKeywordList)
|
||||||
|
|
||||||
|
return filterRepository.save(filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getFilters(userId: Long, types: List<FilterType>): List<FilterQueryModel> =
|
||||||
|
filterQueryService.findByUserIdAndType(userId, types)
|
||||||
|
|
||||||
|
override suspend fun deleteFilter(filterId: Long) {
|
||||||
|
filterKeywordRepository.deleteByFilterId(filterId)
|
||||||
|
filterRepository.deleteById(filterId)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,217 @@
|
||||||
|
package dev.usbharu.hideout.core.service.filter
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterAction
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterMode
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filter.FilterType
|
||||||
|
import dev.usbharu.hideout.core.domain.model.filterkeyword.FilterKeyword
|
||||||
|
import dev.usbharu.hideout.core.query.model.FilterQueryModel
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import utils.PostBuilder
|
||||||
|
|
||||||
|
class MuteProcessServiceImplTest {
|
||||||
|
@Test
|
||||||
|
fun 単純な文字列にマッチする() = runTest {
|
||||||
|
val muteProcessServiceImpl = MuteProcessServiceImpl()
|
||||||
|
|
||||||
|
val post = PostBuilder.of(text = "mute test")
|
||||||
|
|
||||||
|
val filterQueryModel = FilterQueryModel(
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
"mute test",
|
||||||
|
FilterType.entries,
|
||||||
|
FilterAction.warn,
|
||||||
|
listOf(
|
||||||
|
FilterKeyword(
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
"mute",
|
||||||
|
FilterMode.NONE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val actual = muteProcessServiceImpl.processMute(
|
||||||
|
post, FilterType.entries.toList(), listOf(
|
||||||
|
filterQueryModel
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(actual).isEqualTo(FilterResult(filterQueryModel, "mute"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun 複数の文字列でマッチする() = runTest {
|
||||||
|
val muteProcessServiceImpl = MuteProcessServiceImpl()
|
||||||
|
|
||||||
|
val post = PostBuilder.of(text = "mute test")
|
||||||
|
|
||||||
|
val filterQueryModel = FilterQueryModel(
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
"mute test",
|
||||||
|
FilterType.entries,
|
||||||
|
FilterAction.warn,
|
||||||
|
listOf(
|
||||||
|
FilterKeyword(
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
"mate",
|
||||||
|
FilterMode.NONE
|
||||||
|
),
|
||||||
|
FilterKeyword(
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
"mata",
|
||||||
|
FilterMode.NONE
|
||||||
|
),
|
||||||
|
FilterKeyword(
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
"mute",
|
||||||
|
FilterMode.NONE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val actual = muteProcessServiceImpl.processMute(
|
||||||
|
post, FilterType.entries.toList(), listOf(
|
||||||
|
filterQueryModel
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(actual).isEqualTo(FilterResult(filterQueryModel, "mute"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun 単語にマッチする() = runTest {
|
||||||
|
val muteProcessServiceImpl = MuteProcessServiceImpl()
|
||||||
|
|
||||||
|
val post = PostBuilder.of(text = "mute test")
|
||||||
|
|
||||||
|
val filterQueryModel = FilterQueryModel(
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
"mute test",
|
||||||
|
FilterType.entries,
|
||||||
|
FilterAction.warn,
|
||||||
|
listOf(
|
||||||
|
FilterKeyword(
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
"mute",
|
||||||
|
FilterMode.WHOLE_WORD
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val actual = muteProcessServiceImpl.processMute(
|
||||||
|
post, FilterType.entries.toList(), listOf(
|
||||||
|
filterQueryModel
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(actual).isEqualTo(FilterResult(filterQueryModel, "mute"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun 単語以外にはマッチしない() = runTest {
|
||||||
|
val muteProcessServiceImpl = MuteProcessServiceImpl()
|
||||||
|
|
||||||
|
val post = PostBuilder.of(text = "mutetest")
|
||||||
|
|
||||||
|
val filterQueryModel = FilterQueryModel(
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
"mute test",
|
||||||
|
FilterType.entries,
|
||||||
|
FilterAction.warn,
|
||||||
|
listOf(
|
||||||
|
FilterKeyword(
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
"mute",
|
||||||
|
FilterMode.WHOLE_WORD
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val actual = muteProcessServiceImpl.processMute(
|
||||||
|
post, FilterType.entries.toList(), listOf(
|
||||||
|
filterQueryModel
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(actual).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun 複数の単語にマッチする() = runTest {
|
||||||
|
val muteProcessServiceImpl = MuteProcessServiceImpl()
|
||||||
|
|
||||||
|
val post = PostBuilder.of(text = "mute test")
|
||||||
|
|
||||||
|
val filterQueryModel = FilterQueryModel(
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
"mute test",
|
||||||
|
FilterType.entries,
|
||||||
|
FilterAction.warn,
|
||||||
|
listOf(
|
||||||
|
FilterKeyword(
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
"mate",
|
||||||
|
FilterMode.WHOLE_WORD
|
||||||
|
),
|
||||||
|
FilterKeyword(
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
"mata",
|
||||||
|
FilterMode.WHOLE_WORD
|
||||||
|
),
|
||||||
|
FilterKeyword(
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
"mute",
|
||||||
|
FilterMode.WHOLE_WORD
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val actual = muteProcessServiceImpl.processMute(
|
||||||
|
post, FilterType.entries.toList(), listOf(
|
||||||
|
filterQueryModel
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(actual).isEqualTo(FilterResult(filterQueryModel, "mute"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun 正規表現も使える() = runTest {
|
||||||
|
val muteProcessServiceImpl = MuteProcessServiceImpl()
|
||||||
|
|
||||||
|
val post = PostBuilder.of(text = "mute test")
|
||||||
|
|
||||||
|
val filterQueryModel = FilterQueryModel(
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
"mute test",
|
||||||
|
FilterType.entries,
|
||||||
|
FilterAction.warn,
|
||||||
|
listOf(
|
||||||
|
FilterKeyword(
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
"e\\st",
|
||||||
|
FilterMode.REGEX
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val actual = muteProcessServiceImpl.processMute(
|
||||||
|
post, FilterType.entries.toList(), listOf(
|
||||||
|
filterQueryModel
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(actual).isEqualTo(FilterResult(filterQueryModel, "e t"))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue