mirror of https://github.com/usbharu/Hideout.git
feat: フィルターの追加と削除を実装
This commit is contained in:
parent
ea666cf0f8
commit
078547d5ff
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.filter
|
||||
|
||||
data class DeleteFilter(val filterId: Long)
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.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.FilterContext
|
||||
|
||||
data class Filter(
|
||||
val filterId: Long,
|
||||
val userDetailId: Long,
|
||||
val name: String,
|
||||
val filterContext: Set<FilterContext>,
|
||||
val filterAction: FilterAction,
|
||||
val filterKeywords: Set<FilterKeyword>,
|
||||
) {
|
||||
companion object {
|
||||
fun of(filter: Filter): dev.usbharu.hideout.core.application.filter.Filter {
|
||||
return Filter(
|
||||
filterId = filter.id.id,
|
||||
userDetailId = filter.userDetailId.id,
|
||||
name = filter.name.name,
|
||||
filterContext = filter.filterContext,
|
||||
filterAction = filter.filterAction,
|
||||
filterKeywords = filter.filterKeywords.map {
|
||||
FilterKeyword(
|
||||
it.id.id,
|
||||
it.keyword.keyword,
|
||||
it.mode
|
||||
)
|
||||
}.toSet()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.filter
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterMode
|
||||
|
||||
data class FilterKeyword(
|
||||
val id: Long,
|
||||
val keyword: String,
|
||||
val filterMode: FilterMode,
|
||||
)
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.filter
|
||||
|
||||
data class GetFilter(val filterId: Long)
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.filter
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterAction
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterContext
|
||||
|
||||
data class RegisterFilter(
|
||||
val filterName: String,
|
||||
val filterContext: Set<FilterContext>,
|
||||
val filterAction: FilterAction,
|
||||
val filterKeywords: Set<RegisterFilterKeyword>,
|
||||
)
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.filter
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterMode
|
||||
|
||||
data class RegisterFilterKeyword(
|
||||
val keyword: String,
|
||||
val filterMode: FilterMode,
|
||||
)
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.filter
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterId
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterRepository
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class UserDeleteFilterApplicationService(private val filterRepository: FilterRepository, transaction: Transaction) :
|
||||
AbstractApplicationService<DeleteFilter, Unit>(
|
||||
transaction, logger
|
||||
) {
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(UserDeleteFilterApplicationService::class.java)
|
||||
}
|
||||
|
||||
override suspend fun internalExecute(command: DeleteFilter, executor: CommandExecutor) {
|
||||
val filter = filterRepository.findByFilterId(FilterId(command.filterId)) ?: throw Exception("not found")
|
||||
filterRepository.delete(filter)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.filter
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterId
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterRepository
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class UserGetFilterApplicationService(private val filterRepository: FilterRepository, transaction: Transaction) :
|
||||
AbstractApplicationService<GetFilter, Filter>(
|
||||
transaction, logger
|
||||
) {
|
||||
override suspend fun internalExecute(command: GetFilter, executor: CommandExecutor): Filter {
|
||||
val filter = filterRepository.findByFilterId(FilterId(command.filterId)) ?: throw Exception("Not Found")
|
||||
|
||||
return Filter.of(filter)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(UserGetFilterApplicationService::class.java)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.filter
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
|
||||
import dev.usbharu.hideout.core.domain.model.filter.*
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterKeyword
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
|
||||
import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class UserRegisterFilterApplicationService(
|
||||
private val idGenerateService: IdGenerateService,
|
||||
private val filterRepository: FilterRepository,
|
||||
transaction: Transaction,
|
||||
) :
|
||||
AbstractApplicationService<RegisterFilter, Filter>(
|
||||
transaction, logger
|
||||
) {
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(UserRegisterFilterApplicationService::class.java)
|
||||
}
|
||||
|
||||
override suspend fun internalExecute(command: RegisterFilter, executor: CommandExecutor): Filter {
|
||||
require(executor is UserDetailGettableCommandExecutor)
|
||||
|
||||
|
||||
val filter = dev.usbharu.hideout.core.domain.model.filter.Filter.create(
|
||||
FilterId(idGenerateService.generateId()),
|
||||
UserDetailId(executor.userDetailId),
|
||||
FilterName(command.filterName),
|
||||
command.filterContext,
|
||||
command.filterAction,
|
||||
command.filterKeywords
|
||||
.map {
|
||||
FilterKeyword(
|
||||
FilterKeywordId(idGenerateService.generateId()),
|
||||
FilterKeywordKeyword(it.keyword),
|
||||
it.filterMode
|
||||
)
|
||||
}.toSet()
|
||||
)
|
||||
|
||||
filterRepository.save(filter)
|
||||
return Filter.of(filter)
|
||||
}
|
||||
}
|
|
@ -9,9 +9,9 @@ class Filter(
|
|||
val id: FilterId,
|
||||
val userDetailId: UserDetailId,
|
||||
var name: FilterName,
|
||||
val filterContext: List<FilterContext>,
|
||||
val filterContext: Set<FilterContext>,
|
||||
val filterAction: FilterAction,
|
||||
filterKeywords: Set<FilterKeyword>
|
||||
filterKeywords: Set<FilterKeyword>,
|
||||
) {
|
||||
var filterKeywords = filterKeywords
|
||||
private set
|
||||
|
@ -39,6 +39,17 @@ class Filter(
|
|||
.toRegex()
|
||||
}
|
||||
|
||||
fun reconstructWith(filterKeywords: Set<FilterKeyword>): Filter {
|
||||
return Filter(
|
||||
this.id,
|
||||
this.userDetailId,
|
||||
this.name,
|
||||
this.filterContext,
|
||||
this.filterAction,
|
||||
filterKeywords
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun isAllow(user: UserDetail, action: Action, resource: Filter): Boolean {
|
||||
return when (action) {
|
||||
|
@ -49,5 +60,23 @@ class Filter(
|
|||
enum class Action {
|
||||
SET_KEYWORDS
|
||||
}
|
||||
|
||||
fun create(
|
||||
id: FilterId,
|
||||
userDetailId: UserDetailId,
|
||||
name: FilterName,
|
||||
filterContext: Set<FilterContext>,
|
||||
filterAction: FilterAction,
|
||||
filterKeywords: Set<FilterKeyword>,
|
||||
): Filter {
|
||||
return Filter(
|
||||
id,
|
||||
userDetailId,
|
||||
name,
|
||||
filterContext,
|
||||
filterAction,
|
||||
filterKeywords
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,4 +3,7 @@ package dev.usbharu.hideout.core.domain.model.filter
|
|||
interface FilterRepository {
|
||||
suspend fun save(filter: Filter): Filter
|
||||
suspend fun delete(filter: Filter)
|
||||
|
||||
suspend fun findByFilterKeywordId(filterKeywordId: FilterKeywordId): Filter?
|
||||
suspend fun findByFilterId(filterId: FilterId): Filter?
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposed
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.filter.*
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.FilterKeywords
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Filters
|
||||
import org.jetbrains.exposed.sql.Query
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class FilterQueryMapper(private val filterResultRowMapper: ResultRowMapper<Filter>) : QueryMapper<Filter> {
|
||||
override fun map(query: Query): List<Filter> {
|
||||
return query
|
||||
.groupBy { it[Filters.id] }
|
||||
.map { it.value }
|
||||
.map {
|
||||
it
|
||||
.first()
|
||||
.let(filterResultRowMapper::map)
|
||||
.apply {
|
||||
reconstructWith(it.mapNotNull { resultRow: ResultRow ->
|
||||
FilterKeyword(
|
||||
FilterKeywordId(resultRow.getOrNull(FilterKeywords.id) ?: return@mapNotNull null),
|
||||
FilterKeywordKeyword(
|
||||
resultRow.getOrNull(FilterKeywords.keyword) ?: return@mapNotNull null
|
||||
),
|
||||
FilterMode.valueOf(resultRow.getOrNull(FilterKeywords.mode) ?: return@mapNotNull null)
|
||||
)
|
||||
|
||||
}.toSet())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposed
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.filter.*
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Filters
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class FilterResultRowMapper : ResultRowMapper<Filter> {
|
||||
override fun map(resultRow: ResultRow): Filter = Filter(
|
||||
FilterId(resultRow[Filters.id]),
|
||||
UserDetailId(resultRow[Filters.userId]),
|
||||
FilterName(resultRow[Filters.name]),
|
||||
resultRow[Filters.context].split(",").filter { it.isNotEmpty() }.map { FilterContext.valueOf(it) }.toSet(),
|
||||
FilterAction.valueOf(resultRow[Filters.filterAction]),
|
||||
emptySet()
|
||||
)
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.filter.Filter
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterId
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterKeywordId
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterRepository
|
||||
import dev.usbharu.hideout.core.infrastructure.exposed.QueryMapper
|
||||
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 filterQueryMapper: QueryMapper<Filter>) : FilterRepository,
|
||||
AbstractRepository() {
|
||||
override suspend fun save(filter: Filter): Filter = query {
|
||||
Filters.upsert {
|
||||
it[id] = filter.id.id
|
||||
it[userId] = filter.userDetailId.id
|
||||
it[name] = filter.name.name
|
||||
it[context] = filter.filterContext.joinToString(",") { it.name }
|
||||
it[filterAction] = filter.filterAction.name
|
||||
}
|
||||
FilterKeywords.deleteWhere {
|
||||
filterId eq filter.id.id
|
||||
}
|
||||
FilterKeywords.batchUpsert(filter.filterKeywords) {
|
||||
this[FilterKeywords.id] = it.id.id
|
||||
this[FilterKeywords.filterId] = filter.id.id
|
||||
this[FilterKeywords.keyword] = it.keyword.keyword
|
||||
this[FilterKeywords.mode] = it.mode.name
|
||||
}
|
||||
filter
|
||||
}
|
||||
|
||||
override suspend fun delete(filter: Filter): Unit = query {
|
||||
FilterKeywords.deleteWhere { filterId eq filter.id.id }
|
||||
Filters.deleteWhere { id eq filter.id.id }
|
||||
}
|
||||
|
||||
override suspend fun findByFilterKeywordId(filterKeywordId: FilterKeywordId): Filter? {
|
||||
val filterId = FilterKeywords
|
||||
.selectAll()
|
||||
.where { FilterKeywords.id eq filterKeywordId.id }
|
||||
.firstOrNull()?.get(FilterKeywords.filterId) ?: return null
|
||||
val where = Filters.selectAll().where { Filters.id eq filterId }
|
||||
return filterQueryMapper.map(where).firstOrNull()
|
||||
}
|
||||
|
||||
override suspend fun findByFilterId(filterId: FilterId): Filter? {
|
||||
val where = Filters.selectAll().where { Filters.id eq filterId.id }
|
||||
return filterQueryMapper.map(where).firstOrNull()
|
||||
}
|
||||
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(ExposedFilterRepository::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
object Filters : Table("filters") {
|
||||
val id = long("id")
|
||||
val userId = long("user_id").references(UserDetails.id, ReferenceOption.CASCADE, ReferenceOption.CASCADE)
|
||||
val name = varchar("name", 255)
|
||||
val context = varchar("context", 500)
|
||||
val filterAction = varchar("action", 255)
|
||||
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||
}
|
||||
|
||||
object FilterKeywords : Table("filter_keywords") {
|
||||
val id = long("id")
|
||||
val filterId =
|
||||
long("filter_id").references(Filters.id, onDelete = ReferenceOption.CASCADE, onUpdate = ReferenceOption.CASCADE)
|
||||
val keyword = varchar("keyword", 1000)
|
||||
val mode = varchar("mode", 100)
|
||||
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.mastodon.application.filter
|
||||
|
||||
data class DeleteFilterV1(val filterKeywordId: Long)
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.mastodon.application.filter
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterKeywordId
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterRepository
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class DeleteFilterV1ApplicationService(private val filterRepository: FilterRepository, transaction: Transaction) :
|
||||
AbstractApplicationService<DeleteFilterV1, Unit>(
|
||||
transaction, logger
|
||||
) {
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(DeleteFilterV1ApplicationService::class.java)
|
||||
}
|
||||
|
||||
override suspend fun internalExecute(command: DeleteFilterV1, executor: CommandExecutor) {
|
||||
val filter = filterRepository.findByFilterKeywordId(FilterKeywordId(command.filterKeywordId))
|
||||
?: throw Exception("Not Found")
|
||||
filterRepository.delete(filter)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.mastodon.application.filter
|
||||
|
||||
data class GetFilterV1(val filterKeywordId: Long)
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.mastodon.application.filter
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterContext.*
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterKeywordId
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterMode
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterRepository
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.V1Filter
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
class GetFilterV1ApplicationService(private val filterRepository: FilterRepository, transaction: Transaction) :
|
||||
AbstractApplicationService<GetFilterV1, V1Filter>(
|
||||
transaction, logger
|
||||
) {
|
||||
override suspend fun internalExecute(command: GetFilterV1, executor: CommandExecutor): V1Filter {
|
||||
val filter = filterRepository.findByFilterKeywordId(FilterKeywordId(command.filterKeywordId))
|
||||
?: throw Exception("Not Found")
|
||||
|
||||
val filterKeyword = filter.filterKeywords.find { it.id.id == command.filterKeywordId }
|
||||
return V1Filter(
|
||||
id = filter.id.id.toString(),
|
||||
phrase = filterKeyword?.keyword?.keyword,
|
||||
context = filter.filterContext.map {
|
||||
when (it) {
|
||||
home -> V1Filter.Context.home
|
||||
notifications -> V1Filter.Context.notifications
|
||||
public -> V1Filter.Context.public
|
||||
thread -> V1Filter.Context.thread
|
||||
account -> V1Filter.Context.account
|
||||
}
|
||||
},
|
||||
expiresAt = null,
|
||||
irreversible = false,
|
||||
wholeWord = filterKeyword?.mode == FilterMode.WHOLE_WORD
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(GetFilterV1ApplicationService::class.java)
|
||||
}
|
||||
}
|
|
@ -16,21 +16,50 @@
|
|||
|
||||
package dev.usbharu.hideout.mastodon.interfaces.api
|
||||
|
||||
import dev.usbharu.hideout.core.application.filter.*
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterAction
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterContext
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterMode
|
||||
import dev.usbharu.hideout.core.infrastructure.springframework.oauth2.Oauth2CommandExecutorFactory
|
||||
import dev.usbharu.hideout.mastodon.application.filter.DeleteFilterV1
|
||||
import dev.usbharu.hideout.mastodon.application.filter.DeleteFilterV1ApplicationService
|
||||
import dev.usbharu.hideout.mastodon.application.filter.GetFilterV1
|
||||
import dev.usbharu.hideout.mastodon.application.filter.GetFilterV1ApplicationService
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.FilterApi
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Filter
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.FilterKeyword
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.FilterPostRequest.Context
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.V1FilterPostRequest.Context.*
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.stereotype.Controller
|
||||
|
||||
@Controller
|
||||
class SpringFilterApi : FilterApi {
|
||||
class SpringFilterApi(
|
||||
private val oauth2CommandExecutorFactory: Oauth2CommandExecutorFactory,
|
||||
private val userRegisterFilterApplicationService: UserRegisterFilterApplicationService,
|
||||
private val getFilterV1ApplicationService: GetFilterV1ApplicationService,
|
||||
private val deleteFilterV1ApplicationService: DeleteFilterV1ApplicationService,
|
||||
private val userDeleteFilterApplicationService: UserDeleteFilterApplicationService,
|
||||
private val userGetFilterApplicationService: UserGetFilterApplicationService,
|
||||
) : FilterApi {
|
||||
|
||||
override suspend fun apiV1FiltersIdDelete(id: String): ResponseEntity<Any> {
|
||||
return super.apiV1FiltersIdDelete(id)
|
||||
return ResponseEntity.ok(
|
||||
deleteFilterV1ApplicationService.execute(
|
||||
DeleteFilterV1(id.toLong()),
|
||||
oauth2CommandExecutorFactory.getCommandExecutor()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun apiV1FiltersIdGet(id: String): ResponseEntity<V1Filter> {
|
||||
return super.apiV1FiltersIdGet(id)
|
||||
return ResponseEntity.ok(
|
||||
getFilterV1ApplicationService.execute(
|
||||
GetFilterV1(id.toLong()),
|
||||
oauth2CommandExecutorFactory.getCommandExecutor()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun apiV1FiltersIdPut(
|
||||
|
@ -45,7 +74,33 @@ class SpringFilterApi : FilterApi {
|
|||
}
|
||||
|
||||
override suspend fun apiV1FiltersPost(v1FilterPostRequest: V1FilterPostRequest): ResponseEntity<V1Filter> {
|
||||
return super.apiV1FiltersPost(v1FilterPostRequest)
|
||||
val executor = oauth2CommandExecutorFactory.getCommandExecutor()
|
||||
val filterMode = if (v1FilterPostRequest.wholeWord == true) {
|
||||
FilterMode.WHOLE_WORD
|
||||
} else {
|
||||
FilterMode.NONE
|
||||
}
|
||||
val filterContext = v1FilterPostRequest.context.map {
|
||||
when (it) {
|
||||
home -> FilterContext.home
|
||||
notifications -> FilterContext.notifications
|
||||
public -> FilterContext.public
|
||||
thread -> FilterContext.thread
|
||||
account -> FilterContext.account
|
||||
}
|
||||
}.toSet()
|
||||
val filter = userRegisterFilterApplicationService.execute(
|
||||
RegisterFilter(
|
||||
v1FilterPostRequest.phrase, filterContext, FilterAction.warn,
|
||||
setOf(RegisterFilterKeyword(v1FilterPostRequest.phrase, filterMode))
|
||||
), executor
|
||||
)
|
||||
return ResponseEntity.ok(
|
||||
getFilterV1ApplicationService.execute(
|
||||
GetFilterV1(filter.filterKeywords.first().id),
|
||||
executor
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun apiV2FiltersFilterIdKeywordsPost(
|
||||
|
@ -63,13 +118,50 @@ class SpringFilterApi : FilterApi {
|
|||
}
|
||||
|
||||
override suspend fun apiV2FiltersIdDelete(id: String): ResponseEntity<Any> {
|
||||
return super.apiV2FiltersIdDelete(id)
|
||||
userDeleteFilterApplicationService.execute(
|
||||
DeleteFilter(id.toLong()),
|
||||
oauth2CommandExecutorFactory.getCommandExecutor()
|
||||
)
|
||||
return ResponseEntity.ok(Unit)
|
||||
}
|
||||
|
||||
override suspend fun apiV2FiltersIdGet(id: String): ResponseEntity<Filter> {
|
||||
return super.apiV2FiltersIdGet(id)
|
||||
val filter = userGetFilterApplicationService.execute(
|
||||
GetFilter(id.toLong()),
|
||||
oauth2CommandExecutorFactory.getCommandExecutor()
|
||||
)
|
||||
return ResponseEntity.ok(
|
||||
filter(filter)
|
||||
)
|
||||
}
|
||||
|
||||
private fun filter(filter: dev.usbharu.hideout.core.application.filter.Filter) = Filter(
|
||||
id = filter.filterId.toString(),
|
||||
title = filter.name,
|
||||
context = filter.filterContext.map {
|
||||
when (it) {
|
||||
FilterContext.home -> Filter.Context.home
|
||||
FilterContext.notifications -> Filter.Context.notifications
|
||||
FilterContext.public -> Filter.Context.public
|
||||
FilterContext.thread -> Filter.Context.thread
|
||||
FilterContext.account -> Filter.Context.account
|
||||
}
|
||||
},
|
||||
expiresAt = null,
|
||||
filterAction = when (filter.filterAction) {
|
||||
FilterAction.warn -> Filter.FilterAction.warn
|
||||
FilterAction.hide -> Filter.FilterAction.hide
|
||||
|
||||
},
|
||||
keywords = filter.filterKeywords.map {
|
||||
FilterKeyword(
|
||||
it.id.toString(),
|
||||
it.keyword,
|
||||
it.filterMode == FilterMode.WHOLE_WORD
|
||||
)
|
||||
}, statuses = null
|
||||
)
|
||||
|
||||
override suspend fun apiV2FiltersIdPut(
|
||||
id: String,
|
||||
title: String?,
|
||||
|
@ -99,14 +191,46 @@ class SpringFilterApi : FilterApi {
|
|||
}
|
||||
|
||||
override suspend fun apiV2FiltersPost(filterPostRequest: FilterPostRequest): ResponseEntity<Filter> {
|
||||
return super.apiV2FiltersPost(filterPostRequest)
|
||||
val executor = oauth2CommandExecutorFactory.getCommandExecutor()
|
||||
val filter = userRegisterFilterApplicationService.execute(
|
||||
RegisterFilter(
|
||||
filterName = filterPostRequest.title,
|
||||
filterContext = filterPostRequest.context.map {
|
||||
when (it) {
|
||||
Context.home -> FilterContext.home
|
||||
Context.notifications -> FilterContext.notifications
|
||||
Context.public -> FilterContext.public
|
||||
Context.thread -> FilterContext.thread
|
||||
Context.account -> FilterContext.account
|
||||
}
|
||||
}.toSet(),
|
||||
filterAction = when (filterPostRequest.filterAction) {
|
||||
FilterPostRequest.FilterAction.warn -> FilterAction.warn
|
||||
FilterPostRequest.FilterAction.hide -> FilterAction.hide
|
||||
null -> FilterAction.warn
|
||||
},
|
||||
filterKeywords = filterPostRequest.keywordsAttributes.orEmpty().map {
|
||||
RegisterFilterKeyword(
|
||||
it.keyword,
|
||||
if (it.regex == true) {
|
||||
FilterMode.REGEX
|
||||
} else if (it.wholeWord == true) {
|
||||
FilterMode.WHOLE_WORD
|
||||
} else {
|
||||
FilterMode.NONE
|
||||
}
|
||||
)
|
||||
}.toSet()
|
||||
), executor
|
||||
)
|
||||
return ResponseEntity.ok(filter(filter))
|
||||
}
|
||||
|
||||
override suspend fun apiV2FiltersStatusesIdDelete(id: String): ResponseEntity<Any> {
|
||||
return super.apiV2FiltersStatusesIdDelete(id)
|
||||
return ResponseEntity.notFound().build()
|
||||
}
|
||||
|
||||
override suspend fun apiV2FiltersStatusesIdGet(id: String): ResponseEntity<FilterStatus> {
|
||||
return super.apiV2FiltersStatusesIdGet(id)
|
||||
return ResponseEntity.notFound().build()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue