feat: 引用リポストに対応

This commit is contained in:
usbharu 2024-02-03 16:06:56 +09:00
parent 09165783ae
commit 35d126703b
3 changed files with 83 additions and 30 deletions

View File

@ -1,5 +1,6 @@
package dev.usbharu.hideout.activitypub.domain.model package dev.usbharu.hideout.activitypub.domain.model
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.databind.annotation.JsonDeserialize import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import dev.usbharu.hideout.activitypub.domain.model.objects.Object import dev.usbharu.hideout.activitypub.domain.model.objects.Object
import dev.usbharu.hideout.activitypub.domain.model.objects.ObjectDeserializer import dev.usbharu.hideout.activitypub.domain.model.objects.ObjectDeserializer
@ -18,12 +19,15 @@ constructor(
val inReplyTo: String? = null, val inReplyTo: String? = null,
val attachment: List<Document> = emptyList(), val attachment: List<Document> = emptyList(),
@JsonDeserialize(contentUsing = ObjectDeserializer::class) @JsonDeserialize(contentUsing = ObjectDeserializer::class)
val tag: List<Object> = emptyList() val tag: List<Object> = emptyList(),
val quoteUri:String? = null,
val quoteUrl:String? = null,
@JsonProperty("_misskey_quote")
val misskeyQuote:String? = null
) : Object( ) : Object(
type = add(type, "Note") type = add(type, "Note")
), ),
HasId { HasId {
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (javaClass != other?.javaClass) return false
@ -41,6 +45,9 @@ constructor(
if (inReplyTo != other.inReplyTo) return false if (inReplyTo != other.inReplyTo) return false
if (attachment != other.attachment) return false if (attachment != other.attachment) return false
if (tag != other.tag) 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 return true
} }
@ -57,22 +64,28 @@ constructor(
result = 31 * result + (inReplyTo?.hashCode() ?: 0) result = 31 * result + (inReplyTo?.hashCode() ?: 0)
result = 31 * result + attachment.hashCode() result = 31 * result + attachment.hashCode()
result = 31 * result + tag.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 return result
} }
override fun toString(): String { override fun toString(): String {
return "Note(" + return "Note(" +
"id='$id', " + "id='$id', " +
"attributedTo='$attributedTo', " + "attributedTo='$attributedTo', " +
"content='$content', " + "content='$content', " +
"published='$published', " + "published='$published', " +
"to=$to, " + "to=$to, " +
"cc=$cc, " + "cc=$cc, " +
"sensitive=$sensitive, " + "sensitive=$sensitive, " +
"inReplyTo=$inReplyTo, " + "inReplyTo=$inReplyTo, " +
"attachment=$attachment, " + "attachment=$attachment, " +
"tag=$tag" + "tag=$tag, " +
")" + "quoteUri=$quoteUri, " +
" ${super.toString()}" "quoteUrl=$quoteUrl, " +
"misskeyQuote=$misskeyQuote" +
")" +
" ${super.toString()}"
} }
} }

View File

@ -59,6 +59,17 @@ class NoteQueryServiceImpl(private val postRepository: PostRepository, private v
null 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 = val visibility1 =
visibility( visibility(
Visibility.values().first { visibility -> visibility.ordinal == this[Posts.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, to = visibility1.first,
cc = visibility1.second, cc = visibility1.second,
inReplyTo = replyTo, inReplyTo = replyTo,
misskeyQuote = repost,
quoteUri = repost,
quoteUrl = repost,
sensitive = this[Posts.sensitive], sensitive = this[Posts.sensitive],
attachment = mediaList.map { Document(url = it.url, mediaType = "image/jpeg") } attachment = mediaList.map { Document(url = it.url, mediaType = "image/jpeg") }
) )

View File

@ -26,8 +26,8 @@ interface APNoteService {
suspend fun fetchNote(note: Note, targetActor: String? = null): Note suspend fun fetchNote(note: Note, targetActor: String? = null): Note
suspend fun fetchNoteWithEntity(url: String, targetActor: String? = null): Pair<Note, Post> suspend fun fetchNoteWithEntity(url: String, targetActor: String? = null): Pair<Note, Post>
suspend fun fetchAnnounce(url: String, signerId: Long? = null): Pair<Announce,Post> suspend fun fetchAnnounce(url: String, signerId: Long? = null): Pair<Announce, Post>
suspend fun fetchAnnounce(announce: Announce, signerId: Long? = null): Pair<Announce,Post> suspend fun fetchAnnounce(announce: Announce, signerId: Long? = null): Pair<Announce, Post>
} }
@Service @Service
@ -96,7 +96,7 @@ class APNoteServiceImpl(
throw FailedToGetActivityPubResourceException("Could not retrieve $url.", e) throw FailedToGetActivityPubResourceException("Could not retrieve $url.", e)
} }
return fetchAnnounce(announce,signerId) return fetchAnnounce(announce, signerId)
} }
override suspend fun fetchAnnounce(announce: Announce, signerId: Long?): Pair<Announce, Post> { override suspend fun fetchAnnounce(announce: Announce, signerId: Long?): Pair<Announce, Post> {
@ -172,6 +172,11 @@ class APNoteServiceImpl(
postRepository.findByUrl(it) postRepository.findByUrl(it)
} }
val quote = (note.misskeyQuote ?: note.quoteUri ?: note.quoteUrl)?.let {
fetchNote(it, targetActor)
postRepository.findByUrl(it)
}
val emojis = note.tag val emojis = note.tag
.filterIsInstance<Emoji>() .filterIsInstance<Emoji>()
.map { .map {
@ -192,20 +197,41 @@ class APNoteServiceImpl(
) )
}.map { it.id } }.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( val createRemote = postService.createRemote(
postBuilder.of( createPost
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
)
) )
return note to createRemote return note to createRemote
} }