Skip to content

Commit

Permalink
Add new scheduling features to queuing commands
Browse files Browse the repository at this point in the history
  • Loading branch information
DRSchlaubi committed May 22, 2024
1 parent dacde05 commit 2230604
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 52 deletions.
2 changes: 1 addition & 1 deletion .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[versions]
kotlin = "2.0.0-RC2"
kotlin = "2.0.0"
kordex = "1.8.0-SNAPSHOT"
kmongo = "4.11.0"
coroutines = "1.8.0"
coroutines = "1.8.1"
serialization = "1.6.3"
ktor = "2.3.10"
kord = "0.13.1"
api = "3.31.0"
ksp = "2.0.0-RC2-1.0.20"
ktor = "2.3.11"
kord = "0.14.0-SNAPSHOT"
api = "3.32.0"
ksp = "2.0.0-1.0.21"
lavakord = "6.2.0"

[libraries]
Expand Down
2 changes: 1 addition & 1 deletion music/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
subprojects {
version = "3.6.1-SNAPSHOT"
version = "3.7.0-SNAPSHOT"
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ class PlayMessageActionArguments(override val query: String) : QueueOptions {
override val force: Boolean = false
override val top: Boolean = false
override val searchProvider: QueueOptions.SearchProvider? = null
override val shuffle: Boolean? = null
override val loop: Boolean? = null
override val loopQueue: Boolean? = null

}

private suspend fun EphemeralMessageCommandContext<*>.queue(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class PlaylistAddArguments : PlaylistArguments(), QueueOptions {
}
override val top: Boolean = false
override val force: Boolean = false
override val shuffle: Boolean? = null
override val loop: Boolean? = null
override val loopQueue: Boolean? = null

}

fun PlaylistModule.addCommand() = ephemeralSubCommand(::PlaylistAddArguments) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,49 +21,57 @@ import org.litote.kmongo.eq
import org.litote.kmongo.or
import org.litote.kmongo.util.KMongoUtil

abstract class PlaylistArguments(val onlyMine:Boolean = true) : Arguments() {
val name by string {
name = "name"
description = "The name of the playlist"
interface PlaylistOptions {
val name: String
}

validate {
getPlaylistOrNull(context.getUser()!!, value) ?: context.notFound(value)
}
abstract class PlaylistArguments(onlyMine: Boolean = true) : Arguments(), PlaylistOptions {
override val name by playlistName(onlyMine)
}

autoComplete {
val genericFilter = if (onlyMine) {
Playlist::authorId eq user.id
} else {
or(Playlist::public eq true, Playlist::authorId eq user.id)
}
val input = focusedOption.value
val names = PlaylistDatabase.collection.find(
and(genericFilter,
KMongoUtil.toBson("{name: /$input/i}"))
).toFlow()
.take(25)
.toList()
suggestString {
names.forEach { choice(it.name, it.name) }
}
}
}
fun Arguments.playlistName(onlyMine: Boolean) = string {
name = "name"
description = "The name of the playlist"

private suspend fun CommandContext.notFound(value: String): Nothing {
throw DiscordRelayedException(translate("command.playlist.unknown_playlist", arrayOf(value)))
validate {
getPlaylistOrNull(context.getUser()!!, value) ?: context.notFound(value)
}

suspend fun getPlaylistOrNull(userBehavior: UserBehavior, name: String) =
PlaylistDatabase.collection.findOne(
autoComplete {
val genericFilter = if (onlyMine) {
Playlist::authorId eq user.id
} else {
or(Playlist::public eq true, Playlist::authorId eq user.id)
}
val input = focusedOption.value
val names = PlaylistDatabase.collection.find(
and(
Playlist::name eq name,
or(Playlist::public eq true, Playlist::authorId eq userBehavior.id)
genericFilter,
KMongoUtil.toBson("{name: /$input/i}")
)
)
).toFlow()
.take(25)
.toList()
suggestString {
names.forEach { choice(it.name, it.name) }
}
}
}

suspend fun EphemeralSlashCommandContext<out PlaylistArguments, *>.getPlaylist() =
arguments.getPlaylistOrNull(user, arguments.name) ?: error("Could not load playlist")
private suspend fun CommandContext.notFound(value: String): Nothing {
throw DiscordRelayedException(translate("command.playlist.unknown_playlist", arrayOf(value)))
}

private suspend fun getPlaylistOrNull(userBehavior: UserBehavior, name: String) =
PlaylistDatabase.collection.findOne(
and(
Playlist::name eq name,
or(Playlist::public eq true, Playlist::authorId eq userBehavior.id)
)
)
suspend fun <T> EphemeralSlashCommandContext<T, *>.getPlaylist()
where T : Arguments, T : PlaylistOptions =
getPlaylistOrNull(user, arguments.name) ?: error("Could not load playlist")

class PlaylistModule(context: PluginContext) : SubCommandModule(context) {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package dev.schlaubi.mikmusic.playlist.commands

import dev.schlaubi.mikmusic.checks.joinSameChannelCheck
import dev.schlaubi.mikmusic.player.queue.SchedulingArguments
import dev.schlaubi.mikmusic.playlist.PlaylistDatabase
import dev.schlaubi.mikmusic.util.mapToQueuedTrack

class LoadArguments : PlaylistArguments(onlyMine = false)
class LoadArguments : SchedulingArguments(), PlaylistOptions {
override val name by playlistName(onlyMine = false)
}

fun PlaylistModule.loadCommand() = ephemeralSubCommand(::LoadArguments) {
name = "load"
Expand All @@ -20,7 +23,8 @@ fun PlaylistModule.loadCommand() = ephemeralSubCommand(::LoadArguments) {

musicPlayer.queueTrack(
force = false, onTop = false,
tracks = playlist.getTracks(musicPlayer.node).mapToQueuedTrack(user)
tracks = playlist.getTracks(musicPlayer.node).mapToQueuedTrack(user),
schedulingOptions = arguments
)

respond {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class PlaylistSaveArguments : Arguments(), QueueOptions {
override val force: Boolean = false
override val top: Boolean = false
override val searchProvider: QueueOptions.SearchProvider? = null
override val shuffle: Boolean? = null
override val loop: Boolean? = null
override val loopQueue: Boolean? = null
}

fun PlaylistModule.saveCommand() = ephemeralSubCommand(::PlaylistSaveArguments) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import dev.schlaubi.lavakord.rest.getPlayer
import dev.schlaubi.lavakord.rest.updatePlayer
import dev.schlaubi.mikmusic.core.settings.MusicSettingsDatabase
import dev.schlaubi.mikmusic.musicchannel.updateMessage
import dev.schlaubi.mikmusic.player.queue.SchedulingOptions
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -147,11 +148,16 @@ class MusicPlayer(val link: Link, private val guild: GuildBehavior) : Link by li
onTop: Boolean,
tracks: Collection<QueuedTrack>,
position: Duration? = null,
schedulingOptions: SchedulingOptions? = null
) = lock.withLock {
val isFirst = nextSongIsFirst
require(isFirst || position == null) { "Can only specify position if nextSong is first" }
queue.addTracks(tracks, onTop || force)

queue.shuffle = schedulingOptions?.shuffle ?: queue.shuffle
loopQueue = schedulingOptions?.loopQueue ?: loopQueue
repeat = schedulingOptions?.loop ?: repeat

if ((force || isFirst) && !dontQueue) {
startNextSong(position = position)
waitForPlayerUpdate()
Expand Down Expand Up @@ -310,14 +316,14 @@ class MusicPlayer(val link: Link, private val guild: GuildBehavior) : Link by li
// called under lock
private suspend fun startNextSong(lastSong: Track? = null, position: Duration? = null) {
updateSponsorBlock()
val nextTrack: QueuedTrack? = when {
lastSong != null && repeat -> playingTrack!!
else -> queue.poll()
}
if (nextTrack == null) {
if (queue.isEmpty()) {
updateMusicChannelMessage()
return
}
val nextTrack: QueuedTrack = when {
lastSong != null && repeat -> playingTrack!!
else -> queue.poll()
}

playingTrack = nextTrack
link.player.playTrack(nextTrack.track) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.kotlindiscord.kord.extensions.commands.application.slash.EphemeralSla
import com.kotlindiscord.kord.extensions.commands.application.slash.converters.ChoiceEnum
import com.kotlindiscord.kord.extensions.commands.application.slash.converters.impl.optionalEnumChoice
import com.kotlindiscord.kord.extensions.commands.converters.impl.defaultingBoolean
import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalBoolean
import dev.arbjerg.lavalink.protocol.v4.Exception
import dev.arbjerg.lavalink.protocol.v4.LoadResult
import dev.kord.rest.builder.message.embed
Expand All @@ -22,7 +23,13 @@ private val LOG = KotlinLogging.logger { }

private val urlProtocol = "^https?://".toRegex()

interface QueueOptions {
interface SchedulingOptions {
val shuffle: Boolean?
val loop: Boolean?
val loopQueue: Boolean?
}

interface QueueOptions : SchedulingOptions {
val query: String
val force: Boolean
val top: Boolean
Expand All @@ -34,7 +41,24 @@ interface QueueOptions {
}
}

abstract class QueueArguments : Arguments(), QueueOptions {
abstract class SchedulingArguments : Arguments(), SchedulingOptions {
override val shuffle: Boolean? by optionalBoolean {
name = "shuffle"
description = "scheduler.options.shuffle.description"
}

override val loop: Boolean? by optionalBoolean {
name = "loop"
description = "scheduler.options.loop.description"
}

override val loopQueue: Boolean? by optionalBoolean {
name = "loop-queue"
description = "scheduler.options.loop_queue.description"
}
}

abstract class QueueArguments : SchedulingArguments(), QueueOptions {
override val query by autoCompletedYouTubeQuery("The query to play")
override val force by defaultingBoolean {
name = "force"
Expand Down Expand Up @@ -167,7 +191,8 @@ suspend fun CommandContext.queueTracks(
musicPlayer.queueTrack(
arguments.force,
arguments.top,
searchResult.tracks.map { SimpleQueuedTrack(it, getUser()!!.id) }
searchResult.tracks.map { SimpleQueuedTrack(it, getUser()!!.id) },
schedulingOptions = arguments
)
}
}
Expand Down

0 comments on commit 2230604

Please sign in to comment.