diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/header/AudioHeaderEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/header/AudioHeaderEvent.kt index 46d1199305..acc168f39d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/header/AudioHeaderEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/header/AudioHeaderEvent.kt @@ -29,6 +29,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,7 +40,10 @@ class AudioHeaderEvent( tags: Array>, content: String, sig: HexKey, -) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { +) : Event(id, pubKey, createdAt, KIND, tags, content, sig), + SearchableEvent { + override fun indexableContent() = content + fun download() = tags.firstNotNullOfOrNull(DownloadUrlTag::parse) fun stream() = tags.firstNotNullOfOrNull(StreamUrlTag::parse) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/track/AudioTrackEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/track/AudioTrackEvent.kt index 1726dd0b27..56c45a3920 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/track/AudioTrackEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/track/AudioTrackEvent.kt @@ -31,7 +31,9 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag +import com.vitorpamplona.quartz.nip14Subject.SubjectTag import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.uuid.ExperimentalUuidApi import kotlin.uuid.Uuid @@ -44,7 +46,13 @@ class AudioTrackEvent( tags: Array>, content: String, sig: HexKey, -) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) { +) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig), + SearchableEvent { + // content is empty for audio tracks; the only free-text is the subject tag. + override fun indexableContent() = listOfNotNull(subject()).joinToString("\n") + + fun subject() = tags.firstNotNullOfOrNull(SubjectTag::parse) + fun participants() = tags.mapNotNull(ParticipantTag::parse) fun type() = tags.firstNotNullOfOrNull(TypeTag::parse) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/release/SoftwareReleaseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/release/SoftwareReleaseEvent.kt index 7e802fd248..1927c70c97 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/release/SoftwareReleaseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/release/SoftwareReleaseEvent.kt @@ -31,6 +31,7 @@ import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils /** @@ -55,7 +56,13 @@ class SoftwareReleaseEvent( content: String, sig: HexKey, ) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig), - EventHintProvider { + EventHintProvider, + SearchableEvent { + // content carries the release notes (free-text). NOTE: kind 30063 collides + // with NIP-51 ReleaseArtifactSetEvent, which is what EventFactory builds for + // stored events — so in practice this override is not exercised at runtime. + override fun indexableContent() = content + override fun eventHints() = tags.mapNotNull(AssetTag::parseAsHint) override fun linkedEventIds() = tags.mapNotNull(AssetTag::parseId) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/reply/GitReplyEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/reply/GitReplyEvent.kt index a738bccec8..464a1d238e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/reply/GitReplyEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/reply/GitReplyEvent.kt @@ -47,6 +47,7 @@ import com.vitorpamplona.quartz.nip19Bech32.pubKeyHints import com.vitorpamplona.quartz.nip19Bech32.pubKeys import com.vitorpamplona.quartz.nip34Git.issue.GitIssueEvent import com.vitorpamplona.quartz.nip34Git.patch.GitPatchEvent +import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.lastNotNullOfOrNull @@ -62,7 +63,10 @@ class GitReplyEvent( ) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig), PubKeyHintProvider, EventHintProvider, - AddressHintProvider { + AddressHintProvider, + SearchableEvent { + override fun indexableContent() = content + override fun eventHints(): List { val eHints = tags.mapNotNull(ETag::parseAsHint) val qHints = tags.mapNotNull(QTag::parseEventAsHint) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip35Torrents/TorrentCommentEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip35Torrents/TorrentCommentEvent.kt index 8b0f8b15b9..699e64911d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip35Torrents/TorrentCommentEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip35Torrents/TorrentCommentEvent.kt @@ -48,6 +48,7 @@ import com.vitorpamplona.quartz.nip19Bech32.eventIds import com.vitorpamplona.quartz.nip19Bech32.pubKeyHints import com.vitorpamplona.quartz.nip19Bech32.pubKeys import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -62,7 +63,10 @@ class TorrentCommentEvent( ) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig), EventHintProvider, PubKeyHintProvider, - AddressHintProvider { + AddressHintProvider, + SearchableEvent { + override fun indexableContent() = content + override fun eventHints(): List { val eHints = tags.mapNotNull(MarkedETag::parseAsHint) val qHints = tags.mapNotNull(QTag::parseEventAsHint) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/interestSet/InterestSetEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/interestSet/InterestSetEvent.kt index 3b8c956ffd..12072ab335 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/interestSet/InterestSetEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/interestSet/InterestSetEvent.kt @@ -33,10 +33,13 @@ import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.HashtagTag import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.removeAny import com.vitorpamplona.quartz.nip51Lists.removeIgnoreCase +import com.vitorpamplona.quartz.nip51Lists.tags.DescriptionTag +import com.vitorpamplona.quartz.nip51Lists.tags.TitleTag import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.uuid.ExperimentalUuidApi import kotlin.uuid.Uuid @@ -49,7 +52,16 @@ class InterestSetEvent( tags: Array>, content: String, sig: HexKey, -) : PrivateTagArrayEvent(id, pubKey, createdAt, KIND, tags, content, sig) { +) : PrivateTagArrayEvent(id, pubKey, createdAt, KIND, tags, content, sig), + SearchableEvent { + // Public title/description plus the public-interest hashtags. Private + // hashtags live in NIP-44 encrypted content and are never indexed. + override fun indexableContent() = (listOfNotNull(title(), description()) + publicHashtags()).joinToString("\n") + + fun title() = tags.firstNotNullOfOrNull(TitleTag::parse) + + fun description() = tags.firstNotNullOfOrNull(DescriptionTag::parse) + fun publicHashtags() = tags.mapNotNull(HashtagTag::parse) suspend fun privateHashtags(signer: NostrSigner) = privateTags(signer)?.mapNotNull(HashtagTag::parse) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip88Polls/poll/PollEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip88Polls/poll/PollEvent.kt index 63647352ec..e6f0976082 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip88Polls/poll/PollEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip88Polls/poll/PollEvent.kt @@ -28,6 +28,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip22Comments.RootScope import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip88Polls.poll.tags.OptionTag import com.vitorpamplona.quartz.nip88Polls.poll.tags.PollType import com.vitorpamplona.quartz.utils.TimeUtils @@ -41,7 +42,14 @@ class PollEvent( content: String, sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig), - RootScope { + RootScope, + SearchableEvent { + override fun indexableContent() = + buildString { + append(content) + options().forEach { append('\n').append(it.label) } + } + fun options() = tags.options() fun relays() = tags.relays() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipC0CodeSnippets/CodeSnippetEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipC0CodeSnippets/CodeSnippetEvent.kt index 42008395f7..9c07eeb531 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipC0CodeSnippets/CodeSnippetEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipC0CodeSnippets/CodeSnippetEvent.kt @@ -27,6 +27,7 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip22Comments.RootScope import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils /** @@ -43,7 +44,10 @@ class CodeSnippetEvent( content: String, sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig), - RootScope { + RootScope, + SearchableEvent { + override fun indexableContent() = listOfNotNull(snippetName(), snippetDescription(), content).joinToString("\n") + /** Programming language, lowercase (e.g. "python"). */ fun language() = tags.language()