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).also(eventBus::post)
60 fun onPostRemoved(event: PostRemovedEvent) {
61 unmentionPost(event.post)
65 fun onPostMarkedKnown(event: MarkPostKnownEvent) {
66 unmentionPost(event.post)
70 fun onReplyRemoved(event: PostReplyRemovedEvent) {
71 event.postReply.post.let {
72 if ((!it.text.hasLinksToLocalSones() || it.isKnown) && (it.replies.filterNot { it == event.postReply }.none { it.text.hasLinksToLocalSones() && !it.isKnown })) {
78 private fun unmentionPost(post: Post) {
79 if (post in mentionedPosts) {
80 eventBus.post(MentionOfLocalSoneRemovedEvent(post))
81 mentionedPosts -= post
85 private val mentionedPosts = mutableSetOf<Post>()
87 private fun String.hasLinksToLocalSones() = soneTextParser.parse(this, null)
88 .filterIsInstance<SonePart>()
89 .any { it.sone.isLocal }
91 private val Post.replies get() = postReplyProvider.getReplies(id)