Merge pull request #30 from dalbodeule/develop

add /user/{uid} endoints.
This commit is contained in:
JinU Choi 2024-08-04 18:55:25 +09:00 committed by GitHub
commit 13ce148fc5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 128 additions and 0 deletions

View File

@ -1,7 +1,19 @@
package space.mori.chzzk_bot.chatbot.chzzk
import io.github.cdimascio.dotenv.dotenv
import jdk.internal.net.http.common.Pair
import jdk.internal.net.http.common.Pair.pair
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.koin.java.KoinJavaComponent.inject
import org.slf4j.LoggerFactory
import space.mori.chzzk_bot.common.events.CoroutinesEventBus
import space.mori.chzzk_bot.common.events.GetUserEvents
import space.mori.chzzk_bot.common.events.GetUserType
import space.mori.chzzk_bot.common.models.User
import space.mori.chzzk_bot.common.services.LiveStatusService
import space.mori.chzzk_bot.common.services.UserService
import xyz.r2turntrue.chzzk4j.Chzzk
import xyz.r2turntrue.chzzk4j.ChzzkBuilder
import xyz.r2turntrue.chzzk4j.types.channel.ChzzkChannel
@ -15,10 +27,34 @@ object Connector {
.withAuthorization(dotenv["NID_AUT"], dotenv["NID_SES"])
.build()
private val logger = LoggerFactory.getLogger(this::class.java)
private val dispatcher: CoroutinesEventBus by inject(CoroutinesEventBus::class.java)
fun getChannel(channelId: String): ChzzkChannel? = chzzk.getChannel(channelId)
init {
logger.info("chzzk logged: ${chzzk.isLoggedIn} / ${chzzk.loggedUser?.nickname ?: "----"}")
dispatcher.subscribe(GetUserEvents::class) {
if (it.type == GetUserType.REQUEST) {
CoroutineScope(Dispatchers.Default).launch {
val channel = getChannel(it.uid ?: "")
if(channel == null) dispatcher.post(GetUserEvents(
GetUserType.NOTFOUND, null, null, null, null
))
else {
val user = UserService.getUser(channel.channelId)
dispatcher.post(
GetUserEvents(
GetUserType.RESPONSE,
channel.channelId,
channel.channelName,
LiveStatusService.getLiveStatus(user!!)?.status ?: false,
channel.channelImageUrl
)
)
}
}
}
}
}
}

View File

@ -0,0 +1,17 @@
package space.mori.chzzk_bot.common.events
enum class GetUserType(var value: Int) {
REQUEST(0),
RESPONSE(1),
NOTFOUND(2)
}
class GetUserEvents(
val type: GetUserType,
val uid: String?,
val nickname: String?,
val isStreamOn: Boolean?,
val avatarUrl: String?,
): Event {
var TAG = javaClass.simpleName
}

View File

@ -4,8 +4,49 @@ import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
import org.koin.java.KoinJavaComponent.inject
import space.mori.chzzk_bot.common.events.CoroutinesEventBus
import space.mori.chzzk_bot.common.events.GetUserEvents
import space.mori.chzzk_bot.common.events.GetUserType
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentLinkedQueue
@Serializable
data class GetUserDTO(
val uid: String,
val nickname: String,
val isStreamOn: Boolean,
val avatarUrl: String,
)
fun GetUserEvents.toDTO(): GetUserDTO {
return GetUserDTO(
this.uid!!,
this.nickname!!,
this.isStreamOn!!,
this.avatarUrl!!
)
}
fun Routing.apiRoutes() {
val dispatcher: CoroutinesEventBus by inject(CoroutinesEventBus::class.java)
val callMap = ConcurrentHashMap<String, ConcurrentLinkedQueue<ApplicationCall>>()
fun addCall(uid: String, call: ApplicationCall) {
callMap.computeIfAbsent(uid) { ConcurrentLinkedQueue() }.add(call)
}
fun removeCall(uid: String, call: ApplicationCall) {
callMap[uid]?.remove(call)
if(callMap[uid]?.isEmpty() == true) {
callMap.remove(uid)
}
}
route("/") {
get {
call.respondText("Hello World!", status = HttpStatusCode.OK)
@ -16,4 +57,38 @@ fun Routing.apiRoutes() {
call.respondText("OK", status= HttpStatusCode.OK)
}
}
route("/user") {
get {
call.respondText("Require UID", status = HttpStatusCode.NotFound)
}
get("{uid}") {
val uid = call.parameters["uid"]
if(uid != null) {
addCall(uid, call)
if(!callMap.containsKey(uid)) {
CoroutineScope(Dispatchers.Default).launch {
dispatcher.post(GetUserEvents(GetUserType.REQUEST, null, null, null, null))
}
}
}
}
}
dispatcher.subscribe(GetUserEvents::class) {
if(it.type == GetUserType.REQUEST) return@subscribe
CoroutineScope(Dispatchers.Default). launch {
if (it.type == GetUserType.NOTFOUND) {
callMap[it.uid]?.forEach { call ->
call.respondText("User not found", status = HttpStatusCode.NotFound)
removeCall(it.uid ?: "", call)
}
return@launch
}
callMap[it.uid]?.forEach { call ->
call.respond(HttpStatusCode.OK, it.toDTO())
removeCall(it.uid ?: "", call)
}
}
}
}