2 * Sone - SoneMentionDetector.kt - Copyright © 2019 David ‘Bombe’ Roden
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package net.pterodactylus.sone.text
20 import com.google.common.eventbus.*
21 import net.pterodactylus.sone.core.event.*
22 import net.pterodactylus.sone.data.*
23 import net.pterodactylus.sone.database.*
24 import net.pterodactylus.sone.utils.*
28 * Listens to [NewPostFoundEvent]s and [NewPostReplyFoundEvent], parses the
29 * texts and emits a [MentionOfLocalSoneFoundEvent] if a [SoneTextParser]
30 * finds a [SonePart] that points to a local [Sone].
32 class SoneMentionDetector @Inject constructor(private val eventBus: EventBus, private val soneTextParser: SoneTextParser, private val postReplyProvider: PostReplyProvider) {
35 fun onNewPost(newPostFoundEvent: NewPostFoundEvent) {
36 newPostFoundEvent.post.let { post ->
37 post.sone.isLocal.onFalse {
38 if (post.text.hasLinksToLocalSones()) {
39 mentionedPosts += post
40 eventBus.post(MentionOfLocalSoneFoundEvent(post))
47 fun onNewPostReply(event: NewPostReplyFoundEvent) {
48 event.postReply.let { postReply ->
49 postReply.sone.isLocal.onFalse {
50 if (postReply.text.hasLinksToLocalSones()) {
52 .also { mentionedPosts += it }
53 .let(::MentionOfLocalSoneFoundEvent)
54 ?.also(eventBus::post)
61 fun onPostRemoved(event: PostRemovedEvent) {
62 unmentionPost(event.post)
66 fun onPostMarkedKnown(event: MarkPostKnownEvent) {
67 unmentionPost(event.post)
71 fun onReplyRemoved(event: PostReplyRemovedEvent) {
72 event.postReply.post.let {
73 if ((!it.text.hasLinksToLocalSones() || it.isKnown) && (it.replies.filterNot { it == event.postReply }.none { it.text.hasLinksToLocalSones() && !it.isKnown })) {
79 private fun unmentionPost(post: Post) {
80 if (post in mentionedPosts) {
81 eventBus.post(MentionOfLocalSoneRemovedEvent(post))
82 mentionedPosts -= post
86 private val mentionedPosts = mutableSetOf<Post>()
88 private fun String.hasLinksToLocalSones() = soneTextParser.parse(this, null)
89 .filterIsInstance<SonePart>()
90 .any { it.sone.isLocal }
92 private val Post.replies get() = postReplyProvider.getReplies(id)