Compare commits

..

2 Commits

7 changed files with 105 additions and 19 deletions

View File

@@ -9,14 +9,22 @@ The bot does not yet clone the events from iCal to Discord, rather it only curre
## Built With
- [sksamuel/hoplite](https://github.com/sksamuel/hoplite)
- Config Library
- [ical4j/ical4j](https://github.com/ical4j/ical4j)
- Parsing the iCal file
- [DV8FromTheWorld/JDA](https://github.com/DV8FromTheWorld/JDA)
- Discord API Wrapper
- [Litote/kmongo](https://github.com/Litote/kmongo)
- Toolkit for Mongo in Kotlin
- [junodevs/kriess](https://github.com/junodevs/kriess)
- Command handler with some extra features
- [qos-ch/logback](https://github.com/qos-ch/logback)
- Logging framework
- [square/okhttp](https://github.com/square/okhttp)
- Downloading iCal file
- [ronmamo/reflections](https://github.com/ronmamo/reflections)
- [snakeyaml/snakeyaml](https://github.com/snakeyaml/snakeyaml)
- Querying of classpath metadata at runtime
- Allows for commands and services to be dynamically registered
## Usage
### Build it!

View File

@@ -51,14 +51,12 @@ dependencies {
// Utilities
implementation("ch.qos.logback:logback-classic:1.4.4")
implementation("org.reflections:reflections:0.10.2")
implementation("com.squareup.okhttp3:okhttp:4.10.0")
// Calendar
implementation("org.mnode.ical4j:ical4j:3.2.6")
implementation("com.squareup.okhttp3:okhttp:4.10.0")
// Data
implementation("org.yaml:snakeyaml:1.31")
implementation("org.litote.kmongo:kmongo:4.7.2")
implementation("com.sksamuel.hoplite:hoplite-core:1.4.16")
implementation("com.sksamuel.hoplite:hoplite-yaml:1.4.16")

View File

@@ -1,5 +1,5 @@
major=0
minor=4
minor=5
patch=0
kotlin.code.style=official

View File

@@ -2,6 +2,8 @@ package xyz.brettb.discord.ieeevents
import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import com.mongodb.client.MongoClient
import com.mongodb.client.MongoDatabase
import com.sksamuel.hoplite.ConfigLoader
import net.dv8tion.jda.api.JDA
import net.dv8tion.jda.api.JDABuilder
@@ -20,6 +22,7 @@ import net.fortuna.ical4j.model.Date
import net.fortuna.ical4j.model.DateTime
import net.fortuna.ical4j.model.Period
import net.fortuna.ical4j.model.component.VEvent
import org.litote.kmongo.KMongo
import org.reflections.Reflections
import org.slf4j.LoggerFactory
import tech.junodevs.discord.kriess.impl.managers.CommandManager
@@ -95,10 +98,20 @@ object IEEEventsBot : EventListener {
lateinit var commandManager: CommandManager<IEEEventsGuildSettings>
/**
* The bot [config]uration
* The bot [config]
*/
lateinit var config: BotConfig
/**
* The [MongoClient] used by the bot
*/
lateinit var dbClient: MongoClient
/**
* The [MongoDatabase] used by the bot
*/
lateinit var database: MongoDatabase
/**
* The iCal [Calendar] object gotten from the [BotConfig.calendarUrl].
*/
@@ -176,9 +189,14 @@ object IEEEventsBot : EventListener {
config = ConfigLoader().loadConfigOrThrow(configFile)
// Loger
val level = Level.toLevel(config.logLevel, Level.INFO)
(LoggerFactory.getLogger("ROOT") as Logger).level = level
// Database
dbClient = KMongo.createClient(config.database.url)
database = dbClient.getDatabase(config.database.name)
// Managers
IEEEventsGuildSettingsManager.start()
commandManager = CommandManager(IEEEventsGuildSettingsManager, config.prefix) { cEvent, t ->

View File

@@ -0,0 +1,42 @@
package xyz.brettb.discord.ieeevents.commands.settings
import net.dv8tion.jda.api.Permission
import tech.junodevs.discord.kriess.command.CommandEvent
import xyz.brettb.discord.ieeevents.commands.CommandBase
import xyz.brettb.discord.ieeevents.commands.CommandCategories
import xyz.brettb.discord.ieeevents.data.settings.IEEEventsGuildSettingsManager
/**
* The [SetEventChannelCommand] allows you to change the bots' prefix in a given server.
*/
@Suppress("unused")
object SetEventChannelCommand : CommandBase(
"seteventchannel",
"Set the channel for events to be posted to",
CommandCategories.SETTINGS,
listOf("sec"),
"[new_channel:channel]",
true,
false,
listOf(Permission.MANAGE_SERVER)
) {
override fun handle(event: CommandEvent) {
val newChannel = if (event.arguments.channel("new_channel") == null) {
event.textChannel
} else {
event.arguments.channel("new_channel")!!
}
if (newChannel.guild.idLong != event.guild.idLong) {
event.replyError("Can't set the event channel to a channel in another guild!")
return
}
IEEEventsGuildSettingsManager.editSettings(event.guild) {
eventChannelID = newChannel.idLong
event.reply(":white_check_mark: Updated event channel to ${newChannel.asMention}")
}
}
}

View File

@@ -18,7 +18,7 @@ class IEEEventsGuildSettings(
/**
* The ID of the channel where the events should be sent.
*/
@Suppress("MemberVisibilityCanBePrivate") val eventChannelID: Long? = null,
var eventChannelID: Long? = null,
/**
* Should we mirror events to this guild from the calendar?
*/
@@ -33,7 +33,7 @@ class IEEEventsGuildSettings(
*/
@Suppress("unused")
val eventChannel: TextChannel?
get() = if (eventChannelID != null) IEEEventsBot.JDA.getTextChannelById(eventChannelID) else null
get() = if (eventChannelID != null) IEEEventsBot.JDA.getTextChannelById(eventChannelID!!) else null
override fun toMap(): Map<String, Any?> {
return mapOf(

View File

@@ -1,20 +1,40 @@
package xyz.brettb.discord.ieeevents.data.settings
import tech.junodevs.discord.kriess.impl.managers.GuildSettingsManager
import com.mongodb.client.MongoCollection
import net.dv8tion.jda.api.entities.Guild
import org.litote.kmongo.eq
import org.litote.kmongo.findOne
import org.litote.kmongo.getCollection
import org.litote.kmongo.updateOne
import tech.junodevs.discord.kriess.managers.GuildSettingsManager
import xyz.brettb.discord.ieeevents.IEEEventsBot
import java.util.concurrent.CompletableFuture
object IEEEventsGuildSettingsManager : GuildSettingsManager<IEEEventsGuildSettings>() {
object IEEEventsGuildSettingsManager : GuildSettingsManager<IEEEventsGuildSettings> {
override fun createAbsentInstance(guildId: Long): IEEEventsGuildSettings {
return IEEEventsGuildSettings(guildId)
private lateinit var settings: MongoCollection<IEEEventsGuildSettings>
override fun start() {
settings = IEEEventsBot.database.getCollection()
}
override fun createInstance(guildId: Long, properties: Map<String, Any?>): IEEEventsGuildSettings {
return IEEEventsGuildSettings(
guildId,
properties["prefix"] as String?,
properties["eventChannelID"] as Long?,
properties["mirrorEvents"] as Boolean? ?: false
)
override fun editSettings(guild: Guild, action: IEEEventsGuildSettings.() -> Unit) {
getSettingsFor(guild).thenAccept {
action.invoke(it)
settings.updateOne(IEEEventsGuildSettings::guildid eq guild.idLong, it)
}
}
override fun getSettingsFor(guild: Guild): CompletableFuture<IEEEventsGuildSettings> {
val future = CompletableFuture<IEEEventsGuildSettings>()
settings.findOne(IEEEventsGuildSettings::guildid eq guild.idLong)
?: settings.insertOne(IEEEventsGuildSettings(guildid = guild.idLong))
future.complete(settings.findOne(IEEEventsGuildSettings::guildid eq guild.idLong)!!)
return future
}
}