Merge pull request #117 from dalbodeule/develop

Manager function to web
This commit is contained in:
JinU Choi 2024-08-28 16:01:40 +09:00 committed by GitHub
commit 7784130be3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 74 additions and 276 deletions

View File

@ -8,7 +8,6 @@ import net.dv8tion.jda.api.entities.Activity
import net.dv8tion.jda.api.entities.Guild import net.dv8tion.jda.api.entities.Guild
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel import net.dv8tion.jda.api.entities.channel.concrete.TextChannel
import net.dv8tion.jda.api.events.guild.GuildJoinEvent import net.dv8tion.jda.api.events.guild.GuildJoinEvent
import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent
import net.dv8tion.jda.api.hooks.ListenerAdapter import net.dv8tion.jda.api.hooks.ListenerAdapter
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder
@ -17,7 +16,6 @@ import space.mori.chzzk_bot.common.utils.IData
import space.mori.chzzk_bot.common.utils.IStreamInfo import space.mori.chzzk_bot.common.utils.IStreamInfo
import space.mori.chzzk_bot.chatbot.discord.commands.* import space.mori.chzzk_bot.chatbot.discord.commands.*
import space.mori.chzzk_bot.common.models.User import space.mori.chzzk_bot.common.models.User
import space.mori.chzzk_bot.common.services.ManagerService
import java.time.Instant import java.time.Instant
val dotenv = dotenv { val dotenv = dotenv {
@ -62,9 +60,6 @@ class Discord: ListenerAdapter() {
private val commands = listOf( private val commands = listOf(
PingCommand, PingCommand,
AddManagerCommand,
ListManagerCommand,
RemoveManagerCommand,
) )
override fun onSlashCommandInteraction(event: SlashCommandInteractionEvent) { override fun onSlashCommandInteraction(event: SlashCommandInteractionEvent) {
@ -74,10 +69,6 @@ class Discord: ListenerAdapter() {
handler?.run(event, bot) handler?.run(event, bot)
} }
override fun onGuildMemberRemove(event: GuildMemberRemoveEvent) {
event.member?.let { ManagerService.deleteManager(event.guild.idLong, it.idLong) }
}
override fun onGuildJoin(event: GuildJoinEvent) { override fun onGuildJoin(event: GuildJoinEvent) {
commandUpdate(event.guild) commandUpdate(event.guild)
} }

View File

@ -1,47 +0,0 @@
package space.mori.chzzk_bot.chatbot.discord.commands
import net.dv8tion.jda.api.JDA
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent
import net.dv8tion.jda.api.interactions.commands.OptionType
import net.dv8tion.jda.api.interactions.commands.build.Commands
import net.dv8tion.jda.api.interactions.commands.build.OptionData
import org.slf4j.LoggerFactory
import space.mori.chzzk_bot.chatbot.discord.CommandInterface
import space.mori.chzzk_bot.common.services.ManagerService
import space.mori.chzzk_bot.common.services.UserService
object AddManagerCommand : CommandInterface {
private val logger = LoggerFactory.getLogger(this::class.java)
override val name: String = "addmanager"
override val command = Commands.slash(name, "매니저를 추가합니다.")
.addOptions(OptionData(OptionType.USER, "user", "추가할 유저를 선택하세요.", true))
override fun run(event: SlashCommandInteractionEvent, bot: JDA) {
val manager = event.getOption("user")?.asUser
if(manager == null) {
event.hook.sendMessage("유저는 필수사항입니다.").queue()
return
}
if(manager.idLong == event.user.idLong) {
event.hook.sendMessage("자신은 매니저로 설정할 수 없습니다.").queue()
return
}
val user = UserService.getUser(event.user.idLong)
if(user == null) {
event.hook.sendMessage("치지직 계정을 찾을 수 없습니다.").queue()
return
}
try {
ManagerService.saveManager(user, manager.idLong, manager.effectiveName)
if(user.liveAlertGuild == null)
UserService.updateLiveAlert(user, event.guild!!.idLong, event.channelIdLong, "")
event.hook.sendMessage("등록이 완료되었습니다. ${manager.effectiveName}").queue()
} catch (e: Exception) {
event.hook.sendMessage("에러가 발생했습니다.").queue()
logger.debug(e.stackTraceToString())
}
}
}

View File

@ -1,44 +0,0 @@
package space.mori.chzzk_bot.chatbot.discord.commands
import net.dv8tion.jda.api.EmbedBuilder
import net.dv8tion.jda.api.JDA
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent
import net.dv8tion.jda.api.interactions.commands.build.Commands
import org.slf4j.LoggerFactory
import space.mori.chzzk_bot.chatbot.discord.CommandInterface
import space.mori.chzzk_bot.common.services.ManagerService
import space.mori.chzzk_bot.common.services.UserService
object ListManagerCommand : CommandInterface {
private val logger = LoggerFactory.getLogger(this::class.java)
override val name: String = "listmanager"
override val command = Commands.slash(name, "매니저 목록을 확인합니다.")
override fun run(event: SlashCommandInteractionEvent, bot: JDA) {
try {
val managers = event.guild?.idLong?.let { ManagerService.getAllUsers(it) }
if(managers == null) {
event.channel.sendMessage("여기에서는 사용할 수 없습니다.")
return
}
val user = UserService.getUserWithGuildId(event.guild!!.idLong)
val embed = EmbedBuilder()
embed.setTitle("${user!!.username} 매니저 목록")
embed.setDescription("매니저 목록입니다.")
var idx = 1
managers.forEach {
embed.addField("${idx++}", it.lastUserName ?: it.managerId.toString(), true)
}
event.channel.sendMessageEmbeds(embed.build()).queue()
} catch (e: Exception) {
event.hook.sendMessage("에러가 발생했습니다.").queue()
logger.debug(e.stackTraceToString())
}
}
}

View File

@ -1,49 +0,0 @@
package space.mori.chzzk_bot.chatbot.discord.commands
import net.dv8tion.jda.api.JDA
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent
import net.dv8tion.jda.api.interactions.commands.OptionType
import net.dv8tion.jda.api.interactions.commands.build.Commands
import net.dv8tion.jda.api.interactions.commands.build.OptionData
import org.slf4j.LoggerFactory
import space.mori.chzzk_bot.chatbot.discord.CommandInterface
import space.mori.chzzk_bot.common.services.ManagerService
import space.mori.chzzk_bot.common.services.UserService
object RemoveManagerCommand : CommandInterface {
private val logger = LoggerFactory.getLogger(this::class.java)
override val name: String = "removemanager"
override val command = Commands.slash(name, "매니저를 삭제합니다.")
.addOptions(OptionData(OptionType.USER, "user", "삭제할 유저를 선택하세요.", true))
override fun run(event: SlashCommandInteractionEvent, bot: JDA) {
val manager = event.getOption("user")?.asUser
if(manager == null) {
event.hook.sendMessage("유저는 필수사항입니다.").queue()
return
}
if(manager.idLong == event.user.idLong) {
event.hook.sendMessage("자신은 매니저로 설정할 수 없습니다.").queue()
return
}
val user = UserService.getUser(event.user.idLong)
if(user == null) {
event.hook.sendMessage("치지직 계정을 찾을 수 없습니다.").queue()
return
}
if(ManagerService.getUser(user.liveAlertGuild ?: 0L, manager.idLong) == null) {
event.hook.sendMessage("${manager.name}은 매니저가 아닙니다.")
}
try {
ManagerService.deleteManager(user, manager.idLong)
event.hook.sendMessage("삭제가 완료되었습니다. ${manager.effectiveName}").queue()
} catch (e: Exception) {
event.hook.sendMessage("에러가 발생했습니다.").queue()
logger.debug(e.stackTraceToString())
}
}
}

View File

@ -26,11 +26,11 @@ object Connector {
Database.connect(dataSource) Database.connect(dataSource)
val tables = listOf( val tables = listOf(
Users, Users,
UserManagers,
Commands, Commands,
Counters, Counters,
DailyCounters, DailyCounters,
PersonalCounters, PersonalCounters,
Managers,
TimerConfigs, TimerConfigs,
LiveStatuses, LiveStatuses,
SongLists, SongLists,

View File

@ -1,22 +0,0 @@
package space.mori.chzzk_bot.common.models
import org.jetbrains.exposed.dao.IntEntity
import org.jetbrains.exposed.dao.IntEntityClass
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.IntIdTable
object Managers: IntIdTable("manager") {
val user = reference("user", Users)
val managerId = long("manager_id")
val discordGuildId = long("discord_guild_id")
var lastUserName = varchar("last_user_name", 255).nullable()
}
class Manager(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<Manager>(Managers)
var user by User referencedOn Managers.user
var managerId by Managers.managerId
var discordGuildId by Managers.discordGuildId
var lastUserName by Managers.lastUserName
}

View File

@ -26,4 +26,7 @@ class User(id: EntityID<Int>) : IntEntity(id) {
var liveAlertGuild by Users.liveAlertGuild var liveAlertGuild by Users.liveAlertGuild
var liveAlertChannel by Users.liveAlertChannel var liveAlertChannel by Users.liveAlertChannel
var liveAlertMessage by Users.liveAlertMessage var liveAlertMessage by Users.liveAlertMessage
val managers by User via UserManagers
val suborinates by User via UserManagers
} }

View File

@ -0,0 +1,8 @@
package space.mori.chzzk_bot.common.models
import org.jetbrains.exposed.sql.Table
object UserManagers: Table("user_managers") {
val user = reference("user_id", Users)
val manager = reference("manager_id", Users)
}

View File

@ -1,79 +0,0 @@
package space.mori.chzzk_bot.common.services
import org.jetbrains.exposed.dao.load
import org.jetbrains.exposed.dao.with
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.transactions.transaction
import space.mori.chzzk_bot.common.models.Manager
import space.mori.chzzk_bot.common.models.Managers
import space.mori.chzzk_bot.common.models.User
object ManagerService {
fun saveManager(user: User, discordId: Long, name: String): Manager {
if (user.liveAlertGuild == null)
throw RuntimeException("${user.username} has no liveAlertGuild")
return transaction {
Manager.new {
this.user = user
this.discordGuildId = user.liveAlertGuild!!
this.managerId = discordId
this.lastUserName = name
}
}
}
fun updateManager(user: User, discordId: Long, name: String): Manager {
return transaction {
if (user.liveAlertGuild == null)
throw RuntimeException("${user.username} has no liveAlertGuild")
val manager = getUser(user.liveAlertGuild!!, discordId) ?: throw RuntimeException("$name isn't manager.")
manager.lastUserName = name
manager
}
}
fun getUser(guildId: Long, discordId: Long): Manager? {
return transaction {
val manager = Manager.find(
(Managers.discordGuildId eq guildId) and (Managers.managerId eq discordId),
)
.with(Manager::user)
.firstOrNull()
manager
}
}
fun getAllUsers(guildId: Long): List<Manager> {
return transaction {
val result = Manager.find(Managers.discordGuildId eq guildId)
.with(Manager::user)
.toList()
result.forEach { it.load(Manager::user) }
result
}
}
fun deleteManager(user: User, discordId: Long): Manager {
if (user.liveAlertGuild == null)
throw RuntimeException("${user.username} has no liveAlertGuild")
return deleteManager(user.liveAlertGuild!!, discordId)
}
fun deleteManager(guildId: Long, discordId: Long): Manager {
return transaction {
val managerRow = Manager.find((Managers.discordGuildId eq guildId) and (Managers.managerId eq discordId)).firstOrNull()
managerRow ?: throw RuntimeException("Manager not found! $discordId")
managerRow.delete()
managerRow
}
}
}

View File

@ -28,7 +28,7 @@ fun Routing.apiCommandRoutes() {
return@get return@get
} }
val user = UserService.getUser(uid) val user = UserService.getUser(uid)
if(user == null ) { if(user == null) {
call.respond(HttpStatusCode.BadRequest, "User does not exist") call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@get return@get
} }
@ -49,7 +49,12 @@ fun Routing.apiCommandRoutes() {
return@put return@put
} }
val user = UserService.getUser(uid) val user = UserService.getUser(uid)
if(user == null || user.naverId != session?.id) { if(user == null) {
call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@put
}
if(!user.managers.any { it.naverId == session?.id } && user.naverId != session?.id) {
call.respond(HttpStatusCode.BadRequest, "User does not exist") call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@put return@put
} }
@ -74,7 +79,12 @@ fun Routing.apiCommandRoutes() {
return@post return@post
} }
val user = UserService.getUser(uid) val user = UserService.getUser(uid)
if(user == null || user.naverId != session?.id) { if(user == null) {
call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@post
}
if(!user.managers.any { it.naverId == session?.id } && user.naverId != session?.id) {
call.respond(HttpStatusCode.BadRequest, "User does not exist") call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@post return@post
} }
@ -104,7 +114,12 @@ fun Routing.apiCommandRoutes() {
return@delete return@delete
} }
val user = UserService.getUser(uid) val user = UserService.getUser(uid)
if(user == null || user.naverId != session?.id) { if(user == null) {
call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@delete
}
if(!user.managers.any { it.naverId == session?.id } && user.naverId != session?.id) {
call.respond(HttpStatusCode.BadRequest, "User does not exist") call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@delete return@delete
} }

View File

@ -25,7 +25,11 @@ fun Route.apiDiscordRoutes() {
return@get return@get
} }
val user = UserService.getUser(uid) val user = UserService.getUser(uid)
if(user == null || user.naverId != session?.id || user.token == null) { if(user?.token == null) {
call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@get
}
if(!user.managers.any { it.naverId == session?.id } && user.naverId != session?.id) {
call.respond(HttpStatusCode.BadRequest, "User does not exist") call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@get return@get
} }
@ -50,10 +54,15 @@ fun Route.apiDiscordRoutes() {
return@post return@post
} }
val user = UserService.getUser(uid) val user = UserService.getUser(uid)
if(user == null || user.naverId != session?.id || user.token == null) { if(user?.token == null) {
call.respond(HttpStatusCode.BadRequest, "User does not exist") call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@post return@post
} }
if(!user.managers.any { it.naverId == session?.id } && user.naverId != session?.id) {
call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@post
}
UserService.updateLiveAlert(user, body.guildId?.toLong() ?: 0L, body.channelId?.toLong() ?: 0L, body.message) UserService.updateLiveAlert(user, body.guildId?.toLong() ?: 0L, body.channelId?.toLong() ?: 0L, body.message)
call.respond(HttpStatusCode.OK) call.respond(HttpStatusCode.OK)
} }
@ -82,21 +91,6 @@ fun Route.apiDiscordRoutes() {
call.respond(HttpStatusCode.OK, guild) call.respond(HttpStatusCode.OK, guild)
return@get return@get
} }
get {
val session = call.sessions.get<UserSession>()
if(session == null) {
call.respond(HttpStatusCode.BadRequest, "Session is required")
return@get
}
val user = UserService.getUserWithNaverId(session.id)
if(user == null) {
call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@get
}
call.respond(HttpStatusCode.OK, DiscordGuildCache.getCachedGuilds(session.discordGuildList))
return@get
}
} }
} }

View File

@ -89,13 +89,13 @@ fun Routing.apiRoutes() {
call.respondText("No session found", status = HttpStatusCode.Unauthorized) call.respondText("No session found", status = HttpStatusCode.Unauthorized)
return@get return@get
} }
println(session)
var user = UserService.getUserWithNaverId(session.id) var user = UserService.getUserWithNaverId(session.id)
if(user == null) { if(user == null) {
user = UserService.saveUser("임시닉네임", session.id) user = UserService.saveUser("임시닉네임", session.id)
} }
val songConfig = SongConfigService.getConfig(user) val songConfig = SongConfigService.getConfig(user)
val status = user.token?.let { it1 -> getStreamInfo(it1) } val status = user.token?.let { it1 -> getStreamInfo(it1) }
val returnUsers = mutableListOf<GetSessionDTO>()
if (user.username == "임시닉네임") { if (user.username == "임시닉네임") {
status?.content?.channel?.let { it1 -> UserService.updateUser(user, it1.channelId, it1.channelName) } status?.content?.channel?.let { it1 -> UserService.updateUser(user, it1.channelId, it1.channelName) }
@ -106,7 +106,7 @@ fun Routing.apiRoutes() {
return@get return@get
} }
call.respond(HttpStatusCode.OK, GetSessionDTO( returnUsers.add(GetSessionDTO(
status.content!!.channel.channelId, status.content!!.channel.channelId,
status.content!!.channel.channelName, status.content!!.channel.channelName,
status.content!!.status == "OPEN", status.content!!.status == "OPEN",
@ -116,6 +116,24 @@ fun Routing.apiRoutes() {
songConfig.streamerOnly, songConfig.streamerOnly,
songConfig.disabled songConfig.disabled
)) ))
user.suborinates.forEach {
val subStatus = user.token?.let { it1 -> getStreamInfo(it1) }
if(it.token == null) return@forEach
if(subStatus?.content == null) return@forEach
returnUsers.add(GetSessionDTO(
subStatus.content!!.channel.channelId,
subStatus.content!!.channel.channelName,
subStatus.content!!.status == "OPEN",
subStatus.content!!.channel.channelImageUrl,
0,
0,
false,
false
))
}
call.respond(HttpStatusCode.OK, returnUsers)
} }
post { post {
val session = call.sessions.get<UserSession>() val session = call.sessions.get<UserSession>()

View File

@ -22,7 +22,12 @@ fun Routing.apiTimerRoutes() {
return@get return@get
} }
val user = UserService.getUser(uid) val user = UserService.getUser(uid)
if(user == null || user.naverId != session?.id) { if(user == null) {
call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@get
}
if(!user.managers.any { it.naverId == session?.id } && user.naverId != session?.id) {
call.respond(HttpStatusCode.BadRequest, "User does not exist") call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@get return@get
} }
@ -41,7 +46,12 @@ fun Routing.apiTimerRoutes() {
return@put return@put
} }
val user = UserService.getUser(uid) val user = UserService.getUser(uid)
if(user == null || user.naverId != session?.id) { if(user == null) {
call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@put
}
if(!user.managers.any { it.naverId == session?.id } && user.naverId != session?.id) {
call.respond(HttpStatusCode.BadRequest, "User does not exist") call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@put return@put
} }