Merge pull request #3143 from vector-im/feature/bma/discovery_filtering
Filter some other words when navigating into the room directory
This commit is contained in:
commit
2d6fca9214
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* 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 im.vector.app.features.roomdirectory
|
||||
|
||||
import im.vector.app.InstrumentedTest
|
||||
import im.vector.app.core.utils.AssetReader
|
||||
import org.amshove.kluent.shouldBe
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import org.junit.runners.MethodSorters
|
||||
|
||||
@RunWith(JUnit4::class)
|
||||
@FixMethodOrder(MethodSorters.JVM)
|
||||
class ExplicitTermFilterTest : InstrumentedTest {
|
||||
|
||||
private val explicitTermFilter = ExplicitTermFilter(AssetReader(context()))
|
||||
|
||||
@Test
|
||||
fun isValidEmptyTrue() {
|
||||
explicitTermFilter.isValid("") shouldBe true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidTrue() {
|
||||
explicitTermFilter.isValid("Hello") shouldBe true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidFalse() {
|
||||
explicitTermFilter.isValid("nsfw") shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidUpCaseFalse() {
|
||||
explicitTermFilter.isValid("Nsfw") shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidMultilineTrue() {
|
||||
explicitTermFilter.isValid("Hello\nWorld") shouldBe true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidMultilineFalse() {
|
||||
explicitTermFilter.isValid("Hello\nnsfw") shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidMultilineFalse2() {
|
||||
explicitTermFilter.isValid("nsfw\nHello") shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidAnalFalse() {
|
||||
explicitTermFilter.isValid("anal") shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidAnal2False() {
|
||||
explicitTermFilter.isValid("There is some anal in this room") shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidAnalysisTrue() {
|
||||
explicitTermFilter.isValid("analysis") shouldBe true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidAnalysis2True() {
|
||||
explicitTermFilter.isValid("There is some analysis in the room") shouldBe true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidSpecialCharFalse() {
|
||||
explicitTermFilter.isValid("18+") shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidSpecialChar2False() {
|
||||
explicitTermFilter.isValid("This is a room with 18+ content") shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidOtherSpecialCharFalse() {
|
||||
explicitTermFilter.isValid("strap-on") shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidOtherSpecialChar2False() {
|
||||
explicitTermFilter.isValid("This is a room with strap-on content") shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValid18True() {
|
||||
explicitTermFilter.isValid("18") shouldBe true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValidLastFalse() {
|
||||
explicitTermFilter.isValid("zoo") shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canSearchForFalse() {
|
||||
explicitTermFilter.canSearchFor("zoo") shouldBe false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canSearchForTrue() {
|
||||
explicitTermFilter.canSearchFor("android") shouldBe true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
anal
|
||||
bbw
|
||||
bdsm
|
||||
beast
|
||||
bestiality
|
||||
blowjob
|
||||
bondage
|
||||
boobs
|
||||
clit
|
||||
cock
|
||||
cuck
|
||||
cum
|
||||
cunt
|
||||
daddy
|
||||
dick
|
||||
dildo
|
||||
erotic
|
||||
exhibitionism
|
||||
faggot
|
||||
femboy
|
||||
fisting
|
||||
flogging
|
||||
fmf
|
||||
foursome
|
||||
futa
|
||||
gangbang
|
||||
gore
|
||||
h3ntai
|
||||
handjob
|
||||
hentai
|
||||
incest
|
||||
jizz
|
||||
kink
|
||||
loli
|
||||
m4f
|
||||
masturbate
|
||||
masturbation
|
||||
mfm
|
||||
milf
|
||||
moresome
|
||||
naked
|
||||
neet
|
||||
nsfw
|
||||
nude
|
||||
nudity
|
||||
orgy
|
||||
pedo
|
||||
pegging
|
||||
penis
|
||||
petplay
|
||||
porn
|
||||
pussy
|
||||
rape
|
||||
rimming
|
||||
sadism
|
||||
sadomasochism
|
||||
sexy
|
||||
shota
|
||||
spank
|
||||
squirt
|
||||
strap-on
|
||||
threesome
|
||||
vagina
|
||||
vibrator
|
||||
voyeur
|
||||
watersports
|
||||
xxx
|
||||
zoo
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* 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 im.vector.app.features.roomdirectory
|
||||
|
||||
import im.vector.app.core.utils.AssetReader
|
||||
import javax.inject.Inject
|
||||
|
||||
class ExplicitTermFilter @Inject constructor(
|
||||
assetReader: AssetReader
|
||||
) {
|
||||
// List of forbidden terms is in file asset forbidden_terms.txt, in lower case
|
||||
private val explicitTerms = assetReader.readAssetFile("forbidden_terms.txt")
|
||||
.orEmpty()
|
||||
.split("\n")
|
||||
.map { it.trim() }
|
||||
.distinct()
|
||||
.filter { it.isNotEmpty() }
|
||||
|
||||
private val explicitContentRegex = explicitTerms
|
||||
.joinToString(prefix = ".*\\b(", separator = "|", postfix = ")\\b.*")
|
||||
.toRegex(RegexOption.IGNORE_CASE)
|
||||
|
||||
fun canSearchFor(term: String): Boolean {
|
||||
return term !in explicitTerms && term != "18+"
|
||||
}
|
||||
|
||||
fun isValid(str: String): Boolean {
|
||||
return explicitContentRegex.matches(str.replace("\n", " ")).not()
|
||||
// Special treatment for "18+" since word boundaries does not work here
|
||||
&& str.contains("18+").not()
|
||||
}
|
||||
}
|
|
@ -42,12 +42,12 @@ import org.matrix.android.sdk.api.session.room.model.thirdparty.RoomDirectoryDat
|
|||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import timber.log.Timber
|
||||
import java.util.Locale
|
||||
|
||||
class RoomDirectoryViewModel @AssistedInject constructor(
|
||||
@Assisted initialState: PublicRoomsViewState,
|
||||
vectorPreferences: VectorPreferences,
|
||||
private val session: Session
|
||||
private val session: Session,
|
||||
private val explicitTermFilter: ExplicitTermFilter
|
||||
) : VectorViewModel<PublicRoomsViewState, RoomDirectoryAction, RoomDirectoryViewEvents>(initialState) {
|
||||
|
||||
@AssistedFactory
|
||||
|
@ -58,11 +58,6 @@ class RoomDirectoryViewModel @AssistedInject constructor(
|
|||
companion object : MvRxViewModelFactory<RoomDirectoryViewModel, PublicRoomsViewState> {
|
||||
private const val PUBLIC_ROOMS_LIMIT = 20
|
||||
|
||||
// List of forbidden terms, in lower case
|
||||
private val explicitContentTerms = listOf(
|
||||
"nsfw"
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
override fun create(viewModelContext: ViewModelContext, state: PublicRoomsViewState): RoomDirectoryViewModel? {
|
||||
val activity: RoomDirectoryActivity = (viewModelContext as ActivityViewModelContext).activity()
|
||||
|
@ -166,6 +161,17 @@ class RoomDirectoryViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
private fun load(filter: String, roomDirectoryData: RoomDirectoryData) {
|
||||
if (!showAllRooms && !explicitTermFilter.canSearchFor(filter)) {
|
||||
setState {
|
||||
copy(
|
||||
asyncPublicRoomsRequest = Success(Unit),
|
||||
publicRooms = emptyList(),
|
||||
hasMore = false
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
currentJob = viewModelScope.launch {
|
||||
val data = try {
|
||||
session.getPublicRooms(roomDirectoryData.homeServer,
|
||||
|
@ -202,11 +208,7 @@ class RoomDirectoryViewModel @AssistedInject constructor(
|
|||
// Filter
|
||||
val newPublicRooms = data.chunk.orEmpty()
|
||||
.filter {
|
||||
showAllRooms
|
||||
|| "${it.name.orEmpty()} ${it.topic.orEmpty()} ${it.canonicalAlias.orEmpty()}".toLowerCase(Locale.ROOT)
|
||||
.let { str ->
|
||||
explicitContentTerms.all { term -> term !in str }
|
||||
}
|
||||
showAllRooms || explicitTermFilter.isValid("${it.name.orEmpty()} ${it.topic.orEmpty()}")
|
||||
}
|
||||
|
||||
setState {
|
||||
|
|
Loading…
Reference in New Issue