mirror of https://github.com/usbharu/Hideout.git
fix: ActivityPubのidが重複した際の処理を修正
This commit is contained in:
parent
cf6e66aa7d
commit
fd57578ad5
|
@ -20,4 +20,5 @@ interface IPostRepository {
|
|||
userId: Long?): List<Post>
|
||||
|
||||
suspend fun findByUserId(idOrNull: Long, since: Instant?, until: Instant?, minId: Long?, maxId: Long?, limit: Int?, userId: Long?): List<Post>
|
||||
suspend fun findByApId(id: String): Post?
|
||||
}
|
||||
|
|
|
@ -89,6 +89,12 @@ class PostRepositoryImpl(database: Database, private val idGenerateService: IdGe
|
|||
override suspend fun findByUserId(idOrNull: Long, since: Instant?, until: Instant?, minId: Long?, maxId: Long?, limit: Int?, userId: Long?): List<Post> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun findByApId(id: String): Post? {
|
||||
return query {
|
||||
Posts.select { Posts.apId eq id }.singleOrNull()?.toPost()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object Posts : Table() {
|
||||
|
|
|
@ -22,11 +22,11 @@ import java.time.Instant
|
|||
|
||||
@Single
|
||||
class ActivityPubNoteServiceImpl(
|
||||
private val httpClient: HttpClient,
|
||||
private val jobQueueParentService: JobQueueParentService,
|
||||
private val userService: IUserService,
|
||||
private val postRepository: IPostRepository,
|
||||
private val activityPubUserService: ActivityPubUserService
|
||||
private val httpClient: HttpClient,
|
||||
private val jobQueueParentService: JobQueueParentService,
|
||||
private val userService: IUserService,
|
||||
private val postRepository: IPostRepository,
|
||||
private val activityPubUserService: ActivityPubUserService
|
||||
) : ActivityPubNoteService {
|
||||
|
||||
private val logger = LoggerFactory.getLogger(this::class.java)
|
||||
|
@ -48,33 +48,44 @@ class ActivityPubNoteServiceImpl(
|
|||
val actor = props[DeliverPostJob.actor]
|
||||
val postEntity = Config.configData.objectMapper.readValue<Post>(props[DeliverPostJob.post])
|
||||
val note = Note(
|
||||
name = "Note",
|
||||
id = postEntity.url,
|
||||
attributedTo = actor,
|
||||
content = postEntity.text,
|
||||
published = Instant.ofEpochMilli(postEntity.createdAt).toString(),
|
||||
to = listOf(public, actor + "/follower")
|
||||
name = "Note",
|
||||
id = postEntity.url,
|
||||
attributedTo = actor,
|
||||
content = postEntity.text,
|
||||
published = Instant.ofEpochMilli(postEntity.createdAt).toString(),
|
||||
to = listOf(public, actor + "/follower")
|
||||
)
|
||||
val inbox = props[DeliverPostJob.inbox]
|
||||
logger.debug("createNoteJob: actor={}, note={}, inbox={}", actor, postEntity, inbox)
|
||||
httpClient.postAp(
|
||||
urlString = inbox,
|
||||
username = "$actor#pubkey",
|
||||
jsonLd = Create(
|
||||
name = "Create Note",
|
||||
`object` = note,
|
||||
actor = note.attributedTo,
|
||||
id = "${Config.configData.url}/create/note/${postEntity.id}"
|
||||
)
|
||||
urlString = inbox,
|
||||
username = "$actor#pubkey",
|
||||
jsonLd = Create(
|
||||
name = "Create Note",
|
||||
`object` = note,
|
||||
actor = note.attributedTo,
|
||||
id = "${Config.configData.url}/create/note/${postEntity.id}"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun fetchNote(url: String, targetActor: String?): Note {
|
||||
val post = postRepository.findByUrl(url)
|
||||
if (post != null) {
|
||||
val user = userService.findById(post.userId)
|
||||
val reply = post.replyId?.let { postRepository.findOneById(it) }
|
||||
return Note(
|
||||
return postToNote(post)
|
||||
}
|
||||
val response = httpClient.getAp(
|
||||
url,
|
||||
"$targetActor#pubkey"
|
||||
)
|
||||
val note = response.body<Note>()
|
||||
return note(note, targetActor, url)
|
||||
}
|
||||
|
||||
private suspend fun postToNote(post: Post): Note {
|
||||
val user = userService.findById(post.userId)
|
||||
val reply = post.replyId?.let { postRepository.findOneById(it) }
|
||||
return Note(
|
||||
name = "Post",
|
||||
id = post.apId,
|
||||
attributedTo = user.url,
|
||||
|
@ -84,38 +95,35 @@ class ActivityPubNoteServiceImpl(
|
|||
sensitive = post.sensitive,
|
||||
cc = listOf(public, user.url + "/follower"),
|
||||
inReplyTo = reply?.url
|
||||
)
|
||||
}
|
||||
val response = httpClient.getAp(
|
||||
url,
|
||||
"$targetActor#pubkey"
|
||||
)
|
||||
val note = response.body<Note>()
|
||||
return note(note, targetActor, url)
|
||||
}
|
||||
|
||||
private suspend fun ActivityPubNoteServiceImpl.note(
|
||||
note: Note,
|
||||
targetActor: String?,
|
||||
url: String
|
||||
note: Note,
|
||||
targetActor: String?,
|
||||
url: String
|
||||
): Note {
|
||||
val findByApId = postRepository.findByApId(url)
|
||||
if (findByApId != null) {
|
||||
return postToNote(findByApId)
|
||||
}
|
||||
val person = activityPubUserService.fetchPerson(
|
||||
note.attributedTo ?: throw IllegalActivityPubObjectException("note.attributedTo is null"),
|
||||
targetActor
|
||||
note.attributedTo ?: throw IllegalActivityPubObjectException("note.attributedTo is null"),
|
||||
targetActor
|
||||
)
|
||||
val user =
|
||||
userService.findByUrl(person.url ?: throw IllegalActivityPubObjectException("person.url is null"))
|
||||
userService.findByUrl(person.url ?: throw IllegalActivityPubObjectException("person.url is null"))
|
||||
|
||||
val visibility =
|
||||
if (note.to.contains(public) && note.cc.contains(public)) {
|
||||
Visibility.PUBLIC
|
||||
} else if (note.to.find { it.endsWith("/followers") } != null && note.cc.contains(public)) {
|
||||
Visibility.UNLISTED
|
||||
} else if (note.to.find { it.endsWith("/followers") } != null) {
|
||||
Visibility.FOLLOWERS
|
||||
} else {
|
||||
Visibility.DIRECT
|
||||
}
|
||||
if (note.to.contains(public) && note.cc.contains(public)) {
|
||||
Visibility.PUBLIC
|
||||
} else if (note.to.find { it.endsWith("/followers") } != null && note.cc.contains(public)) {
|
||||
Visibility.UNLISTED
|
||||
} else if (note.to.find { it.endsWith("/followers") } != null) {
|
||||
Visibility.FOLLOWERS
|
||||
} else {
|
||||
Visibility.DIRECT
|
||||
}
|
||||
|
||||
val reply = note.inReplyTo?.let {
|
||||
fetchNote(it, targetActor)
|
||||
|
@ -123,25 +131,25 @@ class ActivityPubNoteServiceImpl(
|
|||
}
|
||||
|
||||
postRepository.save(
|
||||
Post(
|
||||
id = postRepository.generateId(),
|
||||
userId = user.id,
|
||||
overview = null,
|
||||
text = note.content.orEmpty(),
|
||||
createdAt = Instant.parse(note.published).toEpochMilli(),
|
||||
visibility = visibility,
|
||||
url = note.id ?: url,
|
||||
repostId = null,
|
||||
replyId = reply?.id,
|
||||
sensitive = note.sensitive,
|
||||
apId = note.id ?: url,
|
||||
)
|
||||
Post(
|
||||
id = postRepository.generateId(),
|
||||
userId = user.id,
|
||||
overview = null,
|
||||
text = note.content.orEmpty(),
|
||||
createdAt = Instant.parse(note.published).toEpochMilli(),
|
||||
visibility = visibility,
|
||||
url = note.id ?: url,
|
||||
repostId = null,
|
||||
replyId = reply?.id,
|
||||
sensitive = note.sensitive,
|
||||
apId = note.id ?: url,
|
||||
)
|
||||
)
|
||||
return note
|
||||
}
|
||||
|
||||
override suspend fun fetchNote(note: Note, targetActor: String?): Note =
|
||||
note(note, targetActor, note.id ?: throw IllegalArgumentException("note.id is null"))
|
||||
note(note, targetActor, note.id ?: throw IllegalArgumentException("note.id is null"))
|
||||
|
||||
companion object {
|
||||
val public: String = "https://www.w3.org/ns/activitystreams#Public"
|
||||
|
|
Loading…
Reference in New Issue