Restarting rewrite using Go instead of Ruby
This commit is contained in:
parent
bbcf381c6b
commit
ae73b4f374
|
@ -1,6 +1,9 @@
|
||||||
MumbleDJ Changelog
|
MumbleDJ Changelog
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
### December 8, 2014
|
||||||
|
* Switched from Ruby to Go, using `gumble` instead of `mumble-ruby` now.
|
||||||
|
|
||||||
### November 15, 2014
|
### November 15, 2014
|
||||||
* Created "v2" branch for Ruby rewrite.
|
* Created "v2" branch for Ruby rewrite.
|
||||||
|
|
||||||
|
|
6
Gemfile
6
Gemfile
|
@ -1,6 +0,0 @@
|
||||||
# MumbleDJ Gemfile
|
|
||||||
source "https://rubygems.org"
|
|
||||||
|
|
||||||
gem "mumble-ruby"
|
|
||||||
gem "spotify"
|
|
||||||
gem "mkfifo"
|
|
42
Gemfile.lock
42
Gemfile.lock
|
@ -1,42 +0,0 @@
|
||||||
GEM
|
|
||||||
remote: https://rubygems.org/
|
|
||||||
specs:
|
|
||||||
activesupport (4.1.8)
|
|
||||||
i18n (~> 0.6, >= 0.6.9)
|
|
||||||
json (~> 1.7, >= 1.7.7)
|
|
||||||
minitest (~> 5.1)
|
|
||||||
thread_safe (~> 0.1)
|
|
||||||
tzinfo (~> 1.1)
|
|
||||||
ffi (1.9.6)
|
|
||||||
hashie (3.3.1)
|
|
||||||
i18n (0.6.11)
|
|
||||||
json (1.8.1)
|
|
||||||
libspotify (12.1.51.4)
|
|
||||||
minitest (5.4.3)
|
|
||||||
mkfifo (0.0.1)
|
|
||||||
mumble-ruby (1.1.2)
|
|
||||||
activesupport
|
|
||||||
hashie
|
|
||||||
opus-ruby
|
|
||||||
ruby_protobuf
|
|
||||||
wavefile
|
|
||||||
opus-ruby (1.0.1)
|
|
||||||
ffi
|
|
||||||
performer (1.0.1)
|
|
||||||
ruby_protobuf (0.4.11)
|
|
||||||
spotify (12.6.0)
|
|
||||||
ffi (~> 1.0, >= 1.0.11)
|
|
||||||
libspotify (~> 12.1.51)
|
|
||||||
performer (~> 1.0)
|
|
||||||
thread_safe (0.3.4)
|
|
||||||
tzinfo (1.2.2)
|
|
||||||
thread_safe (~> 0.1)
|
|
||||||
wavefile (0.6.0)
|
|
||||||
|
|
||||||
PLATFORMS
|
|
||||||
ruby
|
|
||||||
|
|
||||||
DEPENDENCIES
|
|
||||||
mkfifo
|
|
||||||
mumble-ruby
|
|
||||||
spotify
|
|
|
@ -1,6 +1,8 @@
|
||||||
MumbleDJ
|
MumbleDJ
|
||||||
========
|
========
|
||||||
A Mumble bot that plays music fetched from YouTube videos. I have decided to experiment with rewriting the bot in Ruby using [mumble-ruby](https://github.com/perrym5/mumble-ruby). I am hoping this will cut down on the dependency list, make it easier to develop in the future, and allow for some extra functionality that wasn't previously possible.
|
A Mumble bot that plays music fetched from YouTube videos. I have decided to experiment with rewriting the bot in Go using [gumble](https://github.com/layeh/gumble). I am hoping this will cut down on the dependency list, make it easier to develop in the future, and allow for some extra functionality that wasn't previously possible.
|
||||||
|
|
||||||
|
And yes, I know that technically this is v3. The Ruby implementation had problems with high CPU usage and choppy audio which I couldn't seem to figure out.
|
||||||
|
|
||||||
## Author
|
## Author
|
||||||
[Matthieu Grieger](http://matthieugrieger.com)
|
[Matthieu Grieger](http://matthieugrieger.com)
|
||||||
|
@ -32,6 +34,5 @@ THE SOFTWARE.
|
||||||
|
|
||||||
## Thanks
|
## Thanks
|
||||||
* All those who contribute to [Mumble](https://github.com/mumble-voip/mumble).
|
* All those who contribute to [Mumble](https://github.com/mumble-voip/mumble).
|
||||||
* [perrym5](https://github.com/perrym5) for [mumble-ruby](https://github.com/perrym5/mumble-ruby).
|
* [Tim Cooper](https://github.com/bontibon) for [gumble](https://github.com/layeh/gumble).
|
||||||
* [Kim Burgestrand](https://github.com/Burgestrand) for [libspotify Ruby bindings](https://github.com/Burgestrand/spotify).
|
|
||||||
* [Ricardo Garcia](https://github.com/rg3) for [youtube-dl](https://github.com/rg3/youtube-dl).
|
* [Ricardo Garcia](https://github.com/rg3) for [youtube-dl](https://github.com/rg3/youtube-dl).
|
||||||
|
|
1
mumbledj/.gitignore
vendored
1
mumbledj/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
certs
|
|
|
@ -1,157 +0,0 @@
|
||||||
# MumbleDJ
|
|
||||||
# By Matthieu Grieger
|
|
||||||
# config.rb
|
|
||||||
|
|
||||||
|
|
||||||
# ------------------------
|
|
||||||
# CONNECTION CONFIGURATION
|
|
||||||
# ------------------------
|
|
||||||
|
|
||||||
# Bot username
|
|
||||||
# DEFAULT VALUE: "MumbleDJ"
|
|
||||||
BOT_USERNAME = "MumbleDJTest"
|
|
||||||
|
|
||||||
# Password to join Mumble server
|
|
||||||
# DEFAULT VALUE: "" (leave it as this value if no password is required)
|
|
||||||
MUMBLE_PASSWORD = ENV['MUMBLE_PW']
|
|
||||||
|
|
||||||
# Server address
|
|
||||||
# DEFAULT VALUE: "localhost"
|
|
||||||
MUMBLE_SERVER_ADDRESS = "matthieugrieger.com"
|
|
||||||
|
|
||||||
# Server port number
|
|
||||||
# DEFAULT VALUE: 64738
|
|
||||||
MUMBLE_SERVER_PORT = 64738
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------
|
|
||||||
# GENERAL CONFIGURATION
|
|
||||||
# ---------------------
|
|
||||||
|
|
||||||
# Default channel
|
|
||||||
# DEFAULT VALUE: "Music"
|
|
||||||
DEFAULT_CHANNEL = "Bot Testing"
|
|
||||||
|
|
||||||
# Command prefix
|
|
||||||
# DEFAULT VALUE: "!"
|
|
||||||
COMMAND_PREFIX = "!"
|
|
||||||
|
|
||||||
# Show status output in console?
|
|
||||||
# DEFAULT VALUE: true
|
|
||||||
OUTPUT_ENABLED = true
|
|
||||||
|
|
||||||
# Default volume
|
|
||||||
# DEFAULT VALUE: 0.2
|
|
||||||
VOLUME = 0.2
|
|
||||||
|
|
||||||
# Lowest volume allowed
|
|
||||||
# DEFAULT VALUE: 0.01
|
|
||||||
LOWEST_VOLUME = 0.01
|
|
||||||
|
|
||||||
# Highest volume allowed
|
|
||||||
# DEFAULT VALUE: 0.6
|
|
||||||
HIGHEST_VOLUME = 0.6
|
|
||||||
|
|
||||||
# Ratio that must be met or exceeded to trigger a song skip
|
|
||||||
# DEFAULT VALUE: 0.5
|
|
||||||
SKIP_RATIO = 0.5
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------
|
|
||||||
# COMMAND CONFIGURATION
|
|
||||||
# ---------------------
|
|
||||||
|
|
||||||
# Alias used for add command
|
|
||||||
# DEFAULT VALUE: "add"
|
|
||||||
ADD_ALIAS = "add"
|
|
||||||
|
|
||||||
# Alias used for skip command
|
|
||||||
# DEFAULT VALUE: "skip"
|
|
||||||
SKIP_ALIAS = "skip"
|
|
||||||
|
|
||||||
# Alias used for volume command
|
|
||||||
# DEFAULT VALUE: "volume"
|
|
||||||
VOLUME_ALIAS = "volume"
|
|
||||||
|
|
||||||
# Alias used for move command
|
|
||||||
# DEFAULT VALUE: "move"
|
|
||||||
MOVE_ALIAS = "move"
|
|
||||||
|
|
||||||
# Alias used for mute command
|
|
||||||
# DEFAULT VALUE: "mute"
|
|
||||||
MUTE_ALIAS = "mute"
|
|
||||||
|
|
||||||
# Alias used for unmute command
|
|
||||||
# DEFAULT VALUE: "unmute"
|
|
||||||
UNMUTE_ALIAS = "unmute"
|
|
||||||
|
|
||||||
|
|
||||||
# -------------------
|
|
||||||
# ADMIN CONFIGURATION
|
|
||||||
# -------------------
|
|
||||||
|
|
||||||
# Enable admins (true = on, false = off)
|
|
||||||
# DEFAULT VALUE: true
|
|
||||||
ENABLE_ADMINS = true
|
|
||||||
|
|
||||||
# List of admins
|
|
||||||
# NOTE: I recommend only giving users admin privileges if they are
|
|
||||||
# registered on the server. Otherwise people can just take their username
|
|
||||||
# and issue admin commands.
|
|
||||||
ADMINS = ["DrumZ"]
|
|
||||||
|
|
||||||
# Make add an admin command?
|
|
||||||
# DEFAULT VALUE: false
|
|
||||||
ADMIN_ADD = false
|
|
||||||
|
|
||||||
# Make skip an admin command?
|
|
||||||
# DEFAULT VALUE: false
|
|
||||||
ADMIN_SKIP = false
|
|
||||||
|
|
||||||
# Make volume an admin command?
|
|
||||||
# DEFAULT VALUE: true
|
|
||||||
ADMIN_VOLUME = true
|
|
||||||
|
|
||||||
# Make move an admin command?
|
|
||||||
# DEFAULT VALUE: true
|
|
||||||
ADMIN_MOVE = true
|
|
||||||
|
|
||||||
# Make mute an admin command?
|
|
||||||
# DEFAULT VALUE: true
|
|
||||||
ADMIN_MUTE = true
|
|
||||||
|
|
||||||
# Make unmute an admin command?
|
|
||||||
# DEFAULT VALUE: true
|
|
||||||
ADMIN_UNMUTE = true
|
|
||||||
|
|
||||||
|
|
||||||
#----------------------
|
|
||||||
# MESSAGE CONFIGURATION
|
|
||||||
#----------------------
|
|
||||||
|
|
||||||
# Message shown to users when they do not have permission to execute a command.
|
|
||||||
NO_PERMISSION_MSG = "You do not have permission to execute that command."
|
|
||||||
|
|
||||||
# Message shown to users when they try to move the bot to a non-existant channel.
|
|
||||||
CHANNEL_DOES_NOT_EXIST_MSG = "The channel you specified does not exist."
|
|
||||||
|
|
||||||
# Message shown to users when they attempt to add an invalid URL to the queue.
|
|
||||||
INVALID_URL_MSG = "The URL you submitted does not match the required format."
|
|
||||||
|
|
||||||
# Message shown to users when they attempt to use the stop command when no music is playing.
|
|
||||||
NO_MUSIC_PLAYING_MSG = "There is no music playing at the moment."
|
|
||||||
|
|
||||||
# Message shown to users when they issue a command that requires an argument and one was not supplied.
|
|
||||||
NO_ARGUMENT_MSG = "The command you issued requires an argument and you did not provide one. Make sure a space exists between the command and the argument."
|
|
||||||
|
|
||||||
# Message shown to users when they try to change the volume to a value outside the volume range.
|
|
||||||
NOT_IN_VOLUME_RANGE_MSG = "The volume you tried to supply is not in the allowed volume range. The value must be between #{LOWEST_VOLUME} and #{HIGHEST_VOLUME}."
|
|
||||||
|
|
||||||
# Message shown to users when they successfully change the volume.
|
|
||||||
VOLUME_SUCCESS_MSG = "You have successfully changed the volume to the following: %s."
|
|
||||||
|
|
||||||
# Message shown to users when they try to skip a song they have already skipped.
|
|
||||||
ALREADY_SKIPPED_MSG = "You have already voted to skip this song."
|
|
||||||
|
|
||||||
# Message shown to users when the required number of votes to trigger a skip has been met.
|
|
||||||
SKIP_SUCCESS_MSG = "Number of required skip votes has been met. Skipping song!"
|
|
|
@ -1,179 +0,0 @@
|
||||||
# MumbleDJ v2
|
|
||||||
# By Matthieu Grieger
|
|
||||||
# mumbledj.rb
|
|
||||||
|
|
||||||
require "mumble-ruby"
|
|
||||||
require "mkfifo"
|
|
||||||
require_relative "config"
|
|
||||||
require_relative "song_queue"
|
|
||||||
|
|
||||||
# Class that defines MumbleDJ behavior.
|
|
||||||
class MumbleDJ
|
|
||||||
|
|
||||||
attr_reader :username, :server_address, :server_port, :default_channel
|
|
||||||
|
|
||||||
# Initializes a new instance of MumbleDJ. The parameters are as follows:
|
|
||||||
# username: Desired username of the Mumble bot
|
|
||||||
# server_address: IP address/web address of Mumble server to connect to
|
|
||||||
# server_port: Port number of Mumble server (generally 64738)
|
|
||||||
# default_channel: The channel you would like the bot to connect to by
|
|
||||||
# default. If the channel does not exist, the bot will connect to
|
|
||||||
# the root channel of the server instead.
|
|
||||||
# password: Password to join a password-protected server
|
|
||||||
def initialize(username, server_address, server_port, default_channel, password)
|
|
||||||
@username = username
|
|
||||||
@password = password
|
|
||||||
@server_address = server_address
|
|
||||||
@server_port = server_port
|
|
||||||
@default_channel = default_channel
|
|
||||||
@song_queue = SongQueue.new
|
|
||||||
|
|
||||||
Mumble.configure do |conf|
|
|
||||||
conf.sample_rate = 48000
|
|
||||||
conf.bitrate = 32000
|
|
||||||
conf.ssl_cert_opts[:cert_dir] = File.expand_path("certs")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Connects to the Mumble server with the credentials specified in
|
|
||||||
# initialize.
|
|
||||||
def connect
|
|
||||||
@client = Mumble::Client.new(@server_address) do |conf|
|
|
||||||
conf.username = @username
|
|
||||||
if @password != ""
|
|
||||||
conf.password = @password
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
set_callbacks
|
|
||||||
|
|
||||||
@client.connect
|
|
||||||
@client.on_connected do
|
|
||||||
if @default_channel != ""
|
|
||||||
@client.join_channel(@default_channel)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Safely disconnects the bot from the server.
|
|
||||||
def disconnect
|
|
||||||
@client.disconnect
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# Parses messages looking for commands, and calls the appropriate
|
|
||||||
# methods to complete each requested command.
|
|
||||||
def parse_message(message)
|
|
||||||
@sender = @client.users[message.actor].name
|
|
||||||
if message.message[0] == COMMAND_PREFIX
|
|
||||||
if message.message.count(" ") != 0
|
|
||||||
@command = message.message[1..(message.message.index(" ") - 1)]
|
|
||||||
@argument = message.message[(message.message.index(" ") + 1)..-1]
|
|
||||||
else
|
|
||||||
@command = message.message[1..-1]
|
|
||||||
end
|
|
||||||
|
|
||||||
case @command
|
|
||||||
when ADD_ALIAS
|
|
||||||
if has_permission?(ADMIN_ADD, @sender)
|
|
||||||
add(@sender, @argument)
|
|
||||||
else
|
|
||||||
@client.text_user(@sender, NO_PERMISSION_MSG)
|
|
||||||
end
|
|
||||||
when SKIP_ALIAS
|
|
||||||
if has_permission?(ADMIN_SKIP, @sender)
|
|
||||||
skip(@sender)
|
|
||||||
else
|
|
||||||
@client.text_user(@sender, NO_PERMISSION_MSG)
|
|
||||||
end
|
|
||||||
when VOLUME_ALIAS
|
|
||||||
if has_permission?(ADMIN_VOLUME, @sender)
|
|
||||||
volume(@sender, @argument)
|
|
||||||
else
|
|
||||||
@client.text_user(@sender, NO_PERMISSION_MSG)
|
|
||||||
end
|
|
||||||
when MOVE_ALIAS
|
|
||||||
if has_permission?(ADMIN_MOVE, @sender)
|
|
||||||
move(@sender, @argument)
|
|
||||||
else
|
|
||||||
@client.text_user(@sender, NO_PERMISSION_MSG)
|
|
||||||
end
|
|
||||||
when MUTE_ALIAS
|
|
||||||
if has_permission?(ADMIN_MUTE, @sender)
|
|
||||||
@client.me.mute
|
|
||||||
else
|
|
||||||
@client.text_user(@sender, NO_PERMISSION_MSG)
|
|
||||||
end
|
|
||||||
when UNMUTE_ALIAS
|
|
||||||
if has_permission?(ADMIN_UNMUTE, @sender)
|
|
||||||
@client.me.mute(false)
|
|
||||||
else
|
|
||||||
@client.text_user(@sender, NO_PERMISSION_MSG)
|
|
||||||
end
|
|
||||||
when 'test'
|
|
||||||
File.mkfifo('/tmp/audio_stream.fifo')
|
|
||||||
`youtube-dl --output audio --write-info-json --quiet --format bestaudio https://www.youtube.com/watch?v=5xfEr2Oxdys`
|
|
||||||
spawn 'ffmpeg -y -i audio -f s16le -acodec pcm_s16le -ar 24000 -loglevel quiet /tmp/audio_stream.fifo'
|
|
||||||
@client.player.stream_named_pipe('/tmp/audio_stream.fifo')
|
|
||||||
else
|
|
||||||
@client.text_user(@sender, INVALID_COMMAND_MSG)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sets various callbacks that can be triggered during the connection.
|
|
||||||
def set_callbacks
|
|
||||||
@client.on_text_message do |message|
|
|
||||||
parse_message(message)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Checks message sender against ADMINS array to verify if they have
|
|
||||||
# permission to use a specific command.
|
|
||||||
def has_permission?(admin_command, sender)
|
|
||||||
if ENABLE_ADMINS and admin_command
|
|
||||||
return ADMINS.include?(sender)
|
|
||||||
else
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def add(sender, url)
|
|
||||||
if OUTPUT_ENABLED
|
|
||||||
puts("#{sender} has added a song to the queue.")
|
|
||||||
end
|
|
||||||
if @song_queue.add_song?(url, sender)
|
|
||||||
@client.text_channel(@client.me.current_channel.name, "<b>#{sender}</b> has added a song to the queue.")
|
|
||||||
else
|
|
||||||
@client.text_user(sender, INVALID_URL_MSG)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def skip(sender)
|
|
||||||
if OUTPUT_ENABLED
|
|
||||||
puts("#{sender} has voted to skip the current song.")
|
|
||||||
end
|
|
||||||
if @song_queue.get_current_song.add_skip?(sender)
|
|
||||||
@client.text_channel(@client.me.current_channel.name, "<b>#{sender}</b> has voted to skip the current song.")
|
|
||||||
if @song_queue.get_current_song.skip_now?(@client.me.current_channel.users.count - 1)
|
|
||||||
@client.text_channel(@client.me.current_channel.name, SKIP_SUCCESS_MSG)
|
|
||||||
@song_queue.get_current_song.skip
|
|
||||||
end
|
|
||||||
else
|
|
||||||
@client.text_user(sender, ALREADY_SKIPPED_MSG)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def volume(sender, vol)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def move(sender, channel)
|
|
||||||
begin
|
|
||||||
@client.join_channel(channel)
|
|
||||||
rescue Mumble::ChannelNotFound
|
|
||||||
@client.text_user(sender, CHANNEL_DOES_NOT_EXIST_MSG)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,20 +0,0 @@
|
||||||
# MumbleDJ
|
|
||||||
# By Matthieu Grieger
|
|
||||||
# run_bot.rb
|
|
||||||
|
|
||||||
require_relative "mumbledj"
|
|
||||||
require_relative "config"
|
|
||||||
require "thread"
|
|
||||||
|
|
||||||
bot = MumbleDJ.new(username=BOT_USERNAME, server_address=MUMBLE_SERVER_ADDRESS, port=MUMBLE_SERVER_PORT,
|
|
||||||
default_channel=DEFAULT_CHANNEL, password=MUMBLE_PASSWORD)
|
|
||||||
bot.connect
|
|
||||||
|
|
||||||
begin
|
|
||||||
t = Thread.new do
|
|
||||||
$stdin.gets
|
|
||||||
end
|
|
||||||
|
|
||||||
t.join
|
|
||||||
rescue Interrupt => e
|
|
||||||
end
|
|
|
@ -1,57 +0,0 @@
|
||||||
# MumbleDJ v2
|
|
||||||
# By Matthieu Grieger
|
|
||||||
# song.rb
|
|
||||||
|
|
||||||
require_relative "config"
|
|
||||||
|
|
||||||
# Base Song class that defines default behavior for any kind of song.
|
|
||||||
class Song
|
|
||||||
|
|
||||||
# Starts the song.
|
|
||||||
def start
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# Gets the name of the user who submitted the song.
|
|
||||||
def get_submitter
|
|
||||||
return @submitter
|
|
||||||
end
|
|
||||||
|
|
||||||
# Adds a skipper to the skips array for the current song.
|
|
||||||
def add_skip?(username)
|
|
||||||
if not @skips.include?(username)
|
|
||||||
@skips << username
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Determines if a skip should occur. Returns true if a skip is needed,
|
|
||||||
# false otherwise.
|
|
||||||
def skip_now?(total_users)
|
|
||||||
return (total_users / @skips.count) >= SKIP_RATIO
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class YouTubeSong < Song
|
|
||||||
|
|
||||||
attr_reader :url, :submitter, :song_title, :song_duration, :song_thumbnail_url
|
|
||||||
|
|
||||||
# Initializes the YouTubeSong object and retrieves the song title,
|
|
||||||
# duration, and thumbnail URL from the YouTube API.
|
|
||||||
def initialize(url, submitter)
|
|
||||||
@url = url
|
|
||||||
@submitter = submitter
|
|
||||||
@skips = []
|
|
||||||
# TODO: Retrieve YouTube information
|
|
||||||
@song_title = ""
|
|
||||||
@song_duration = ""
|
|
||||||
@song_thumbnail_url = ""
|
|
||||||
end
|
|
||||||
|
|
||||||
# Downloads the audio for the YouTube video and returns the filename.
|
|
||||||
def download_audio
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,80 +0,0 @@
|
||||||
# MumbleDJ v2
|
|
||||||
# By Matthieu Grieger
|
|
||||||
# song_queue.rb
|
|
||||||
|
|
||||||
require_relative "song"
|
|
||||||
|
|
||||||
# A specialized SongQueue class that handles queueing/unqueueing songs
|
|
||||||
# and other actions.
|
|
||||||
class SongQueue
|
|
||||||
|
|
||||||
attr_reader :queue
|
|
||||||
|
|
||||||
# Initializes a new song queue.
|
|
||||||
def initialize
|
|
||||||
@queue = []
|
|
||||||
end
|
|
||||||
|
|
||||||
# Checks if song already exists in the queue, and adds it if it doesn't
|
|
||||||
# already exist.
|
|
||||||
def add_song?(url, submitter)
|
|
||||||
youtube_regex = /(https?:\/\/www\.youtube\.com\/watch\?v=([\d\a_\-]+))
|
|
||||||
|(https?:\/\/youtube\.com\/watch\?v=([\d\a_\-]+))
|
|
||||||
|(https?:\/\/youtu\.be\/([\d\a_\-]+))
|
|
||||||
|(https?:\/\/youtube\.com\/v\/([\d\a_\-]+))
|
|
||||||
|(https?:\/\/www\.youtube\.com\/v\/([\d\a_\-]+))/x
|
|
||||||
|
|
||||||
if youtube_regex.match(url)
|
|
||||||
audio_type = "youtube"
|
|
||||||
end
|
|
||||||
|
|
||||||
if @queue.empty?
|
|
||||||
if audio_type == "youtube"
|
|
||||||
song = YouTubeSong.new(url, submitter)
|
|
||||||
end
|
|
||||||
@queue.push(song)
|
|
||||||
else
|
|
||||||
@queue.each do |song|
|
|
||||||
if song.url == url
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if audio_type == "youtube"
|
|
||||||
song = YouTubeSong.new(url, submitter)
|
|
||||||
end
|
|
||||||
@queue.push(song)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Processes a song delete request. Searches the queue for songs with
|
|
||||||
# titles containing the keyword. If found, the song is deleted if the
|
|
||||||
# username of the user who requested the deletion matches the
|
|
||||||
# username of who originally added the song.
|
|
||||||
def delete_song?(keyword, username)
|
|
||||||
if not @queue.empty?
|
|
||||||
@queue.each do |song|
|
|
||||||
if song.song_title.includes?(keyword)
|
|
||||||
if song.get_submitter == username
|
|
||||||
@queue.delete(song)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns a formatted string that contains information about the next
|
|
||||||
# song in the queue.
|
|
||||||
def peek_next
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns the current Song object from the queue.
|
|
||||||
def get_current_song
|
|
||||||
return @queue[0]
|
|
||||||
end
|
|
||||||
end
|
|
Reference in a new issue