diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Note.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Note.kt index 60e7858c..ba888274 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Note.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Note.kt @@ -1,5 +1,6 @@ package dev.usbharu.hideout.activitypub.domain.model +import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.databind.annotation.JsonDeserialize import dev.usbharu.hideout.activitypub.domain.model.objects.Object import dev.usbharu.hideout.activitypub.domain.model.objects.ObjectDeserializer @@ -18,12 +19,15 @@ constructor( val inReplyTo: String? = null, val attachment: List = emptyList(), @JsonDeserialize(contentUsing = ObjectDeserializer::class) - val tag: List = emptyList() + val tag: List = emptyList(), + val quoteUri:String? = null, + val quoteUrl:String? = null, + @JsonProperty("_misskey_quote") + val misskeyQuote:String? = null ) : Object( type = add(type, "Note") ), HasId { - override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -41,6 +45,9 @@ constructor( if (inReplyTo != other.inReplyTo) return false if (attachment != other.attachment) return false if (tag != other.tag) return false + if (quoteUri != other.quoteUri) return false + if (quoteUrl != other.quoteUrl) return false + if (misskeyQuote != other.misskeyQuote) return false return true } @@ -57,22 +64,28 @@ constructor( result = 31 * result + (inReplyTo?.hashCode() ?: 0) result = 31 * result + attachment.hashCode() result = 31 * result + tag.hashCode() + result = 31 * result + (quoteUri?.hashCode() ?: 0) + result = 31 * result + (quoteUrl?.hashCode() ?: 0) + result = 31 * result + (misskeyQuote?.hashCode() ?: 0) return result } override fun toString(): String { return "Note(" + - "id='$id', " + - "attributedTo='$attributedTo', " + - "content='$content', " + - "published='$published', " + - "to=$to, " + - "cc=$cc, " + - "sensitive=$sensitive, " + - "inReplyTo=$inReplyTo, " + - "attachment=$attachment, " + - "tag=$tag" + - ")" + - " ${super.toString()}" + "id='$id', " + + "attributedTo='$attributedTo', " + + "content='$content', " + + "published='$published', " + + "to=$to, " + + "cc=$cc, " + + "sensitive=$sensitive, " + + "inReplyTo=$inReplyTo, " + + "attachment=$attachment, " + + "tag=$tag, " + + "quoteUri=$quoteUri, " + + "quoteUrl=$quoteUrl, " + + "misskeyQuote=$misskeyQuote" + + ")" + + " ${super.toString()}" } } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt index 1ebc9511..00dd9167 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt @@ -59,6 +59,17 @@ class NoteQueryServiceImpl(private val postRepository: PostRepository, private v null } + val repostId = this[Posts.repostId] + val repost = if (repostId != null) { + val url = postRepository.findById(repostId)?.url + if (url == null){ + logger.warn("Failed to get repostId: $repostId") + } + url + }else{ + null + } + val visibility1 = visibility( Visibility.values().first { visibility -> visibility.ordinal == this[Posts.visibility] }, @@ -72,6 +83,9 @@ class NoteQueryServiceImpl(private val postRepository: PostRepository, private v to = visibility1.first, cc = visibility1.second, inReplyTo = replyTo, + misskeyQuote = repost, + quoteUri = repost, + quoteUrl = repost, sensitive = this[Posts.sensitive], attachment = mediaList.map { Document(url = it.url, mediaType = "image/jpeg") } ) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt index 94f21c36..fb2b22ba 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt @@ -26,8 +26,8 @@ interface APNoteService { suspend fun fetchNote(note: Note, targetActor: String? = null): Note suspend fun fetchNoteWithEntity(url: String, targetActor: String? = null): Pair - suspend fun fetchAnnounce(url: String, signerId: Long? = null): Pair - suspend fun fetchAnnounce(announce: Announce, signerId: Long? = null): Pair + suspend fun fetchAnnounce(url: String, signerId: Long? = null): Pair + suspend fun fetchAnnounce(announce: Announce, signerId: Long? = null): Pair } @Service @@ -96,7 +96,7 @@ class APNoteServiceImpl( throw FailedToGetActivityPubResourceException("Could not retrieve $url.", e) } - return fetchAnnounce(announce,signerId) + return fetchAnnounce(announce, signerId) } override suspend fun fetchAnnounce(announce: Announce, signerId: Long?): Pair { @@ -172,6 +172,11 @@ class APNoteServiceImpl( postRepository.findByUrl(it) } + val quote = (note.misskeyQuote ?: note.quoteUri ?: note.quoteUrl)?.let { + fetchNote(it, targetActor) + postRepository.findByUrl(it) + } + val emojis = note.tag .filterIsInstance() .map { @@ -192,20 +197,41 @@ class APNoteServiceImpl( ) }.map { it.id } + val createPost = + if (quote != null) { + postBuilder.quoteRepostOf( + id = postRepository.generateId(), + actorId = person.second.id, + content = note.content, + createdAt = Instant.parse(note.published), + visibility = visibility, + url = note.id, + replyId = reply?.id, + sensitive = note.sensitive, + apId = note.id, + mediaIds = mediaList, + emojiIds = emojis, + repost = quote + ) + } else { + postBuilder.of( + id = postRepository.generateId(), + actorId = person.second.id, + content = note.content, + createdAt = Instant.parse(note.published).toEpochMilli(), + visibility = visibility, + url = note.id, + replyId = reply?.id, + sensitive = note.sensitive, + apId = note.id, + mediaIds = mediaList, + emojiIds = emojis + ) + + } + val createRemote = postService.createRemote( - postBuilder.of( - id = postRepository.generateId(), - actorId = person.second.id, - content = note.content, - createdAt = Instant.parse(note.published).toEpochMilli(), - visibility = visibility, - url = note.id, - replyId = reply?.id, - sensitive = note.sensitive, - apId = note.id, - mediaIds = mediaList, - emojiIds = emojis - ) + createPost ) return note to createRemote }