Completely rebased project. Now in Lua instead of Python
This commit is contained in:
parent
b9ecf125d2
commit
4af3a6c987
|
@ -1,5 +1,11 @@
|
||||||
MumbleDJ Changelog
|
MumbleDJ Changelog
|
||||||
==================
|
==================
|
||||||
|
### September 14, 2014
|
||||||
|
* Changed the base for the project from pymumble to piepan.
|
||||||
|
* Entire codebase is now written in Lua instead of Python.
|
||||||
|
* Re-implemented some of the config in config.lua.
|
||||||
|
* Implemented code to connect the bot to the server and move it into the Bot Testing channel.
|
||||||
|
|
||||||
### September 13, 2014
|
### September 13, 2014
|
||||||
* Added song.py, a file that houses the Song class.
|
* Added song.py, a file that houses the Song class.
|
||||||
* Added command & storage options to config.py.
|
* Added command & storage options to config.py.
|
||||||
|
|
1
mumbledj/.gitignore
vendored
Normal file
1
mumbledj/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
piepan
|
|
@ -1,8 +0,0 @@
|
||||||
#----------------------#
|
|
||||||
# MumbleDJ #
|
|
||||||
# By Matthieu Grieger #
|
|
||||||
#----------------------#-------------#
|
|
||||||
# __init__.py #
|
|
||||||
# Currently empty, and will probably #
|
|
||||||
# stay that way. :) #
|
|
||||||
#------------------------------------#
|
|
24
mumbledj/config.lua
Normal file
24
mumbledj/config.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
-------------------------
|
||||||
|
-- MumbleDJ --
|
||||||
|
-- By Matthieu Grieger --
|
||||||
|
-------------------------------------------------
|
||||||
|
-- config.lua --
|
||||||
|
-- This is where all the configuration options --
|
||||||
|
-- for the bot can be set. --
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
-- GENERAL CONFIGURATION
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
-- Bot username
|
||||||
|
-- DEFAULT VALUE: "MumbleDJ"
|
||||||
|
BOT_USERNAME = "MumbleDJ"
|
||||||
|
|
||||||
|
-- Default channel
|
||||||
|
-- DEFAULT VALUE: "Bot Testing"
|
||||||
|
DEFAULT_CHANNEL = "Bot Testing"
|
||||||
|
|
||||||
|
-- Command prefix
|
||||||
|
-- DEFAULT VALUE: "!"
|
||||||
|
COMMAND_PREFIX = "!"
|
|
@ -1,125 +0,0 @@
|
||||||
#----------------------#
|
|
||||||
# MumbleDJ #
|
|
||||||
# By Matthieu Grieger #
|
|
||||||
#----------------------#-------------#
|
|
||||||
# config.py #
|
|
||||||
# Configuration options for the bot. #
|
|
||||||
#------------------------------------#
|
|
||||||
|
|
||||||
# ------------------------
|
|
||||||
# CONNECTION CONFIGURATION
|
|
||||||
# ------------------------
|
|
||||||
|
|
||||||
# Server address
|
|
||||||
# DEFAULT VALUE: 'localhost'
|
|
||||||
SERVER_ADDRESS = 'matthieugrieger.com'
|
|
||||||
|
|
||||||
# Server port
|
|
||||||
# DEFAULT VALUE: 64738
|
|
||||||
SERVER_PORT = 64738
|
|
||||||
|
|
||||||
# Username (this will be the username of the bot as well)
|
|
||||||
# DEFAULT VALUE: 'MumbleDJ'
|
|
||||||
SERVER_USERNAME = 'MumbleDJ'
|
|
||||||
|
|
||||||
# Server password (leave blank if no password exists)
|
|
||||||
# DEFAULT VALUE: ''
|
|
||||||
SERVER_PASSWORD = ''
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------
|
|
||||||
# GENERAL CONFIGURATION
|
|
||||||
# ---------------------
|
|
||||||
|
|
||||||
# Default channel
|
|
||||||
# DEFAULT VALUE: 'MumbleDJ'
|
|
||||||
DEFAULT_CHANNEL = 'Bot Testing'
|
|
||||||
|
|
||||||
# Debugging mode (True = on, False = off)
|
|
||||||
# DEFAULT VALUE: False
|
|
||||||
DEBUG = False
|
|
||||||
|
|
||||||
# Command prefix (this is the character that designates a command)
|
|
||||||
# NOTE: This must be one character!
|
|
||||||
# DEFAULT VALUE: '!'
|
|
||||||
COMMAND_PREFIX = '!'
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------
|
|
||||||
# COMMAND CONFIGURATION
|
|
||||||
# ---------------------
|
|
||||||
|
|
||||||
# Allow users to start music queue
|
|
||||||
# DEFAULT VALUE: True
|
|
||||||
ALLOW_START = True
|
|
||||||
|
|
||||||
# Allow users to start music playback
|
|
||||||
# DEFAULT VALUE: True
|
|
||||||
ALLOW_PLAY = True
|
|
||||||
|
|
||||||
# Allow users to pause music playback
|
|
||||||
# DEFAULT VALUE: True
|
|
||||||
ALLOW_PAUSE = True
|
|
||||||
|
|
||||||
# Allow users to add music to queue
|
|
||||||
# DEFAULT VALUE: True
|
|
||||||
ALLOW_ADD = True
|
|
||||||
|
|
||||||
# Allow users to vote to skip tracks
|
|
||||||
# DEFAULT VALUE: True
|
|
||||||
ALLOW_SKIPS = True
|
|
||||||
|
|
||||||
# Allow users to raise volume
|
|
||||||
# DEFAULT VALUE: False
|
|
||||||
ALLOW_VOLUMEUP = False
|
|
||||||
|
|
||||||
# Allow users to lower volume
|
|
||||||
# DEFAULT VALUE: False
|
|
||||||
ALLOW_VOLUMEDOWN = False
|
|
||||||
|
|
||||||
# Allow users to move bot to another channel
|
|
||||||
# DEFAULT VALUE: False
|
|
||||||
ALLOW_MOVE = False
|
|
||||||
|
|
||||||
# Allow users to kill bot (this should rarely be used)
|
|
||||||
# DEFAULT VALUE: False
|
|
||||||
ALLOW_KILL = False
|
|
||||||
|
|
||||||
# ---------------------
|
|
||||||
# STORAGE CONFIGURATION
|
|
||||||
# ---------------------
|
|
||||||
|
|
||||||
# Delete audio files after they have been played.
|
|
||||||
# DEFAULT VALUE: True
|
|
||||||
DELETE_AUDIO = True
|
|
||||||
|
|
||||||
# Delete thumbnails after they have been used.
|
|
||||||
# DEFAULT VALUE: True
|
|
||||||
DELETE_THUMBNAILS = True
|
|
||||||
|
|
||||||
|
|
||||||
# ------------------
|
|
||||||
# CHAT CONFIGURATION
|
|
||||||
# ------------------
|
|
||||||
|
|
||||||
# Enable/disable chat notifications
|
|
||||||
# DEFAULT VALUE: True
|
|
||||||
SHOW_CHAT_NOTIFICATIONS = True
|
|
||||||
|
|
||||||
# Enable/disable YouTube thumbnails (only has an effect if SHOW_CHAT_NOTIFICATIONS is True)
|
|
||||||
# DEFAULT VALUE: True
|
|
||||||
SHOW_YT_THUMBNAILS = True
|
|
||||||
|
|
||||||
|
|
||||||
# -------------------
|
|
||||||
# AUDIO CONFIGURATION
|
|
||||||
# -------------------
|
|
||||||
|
|
||||||
# Bitrate
|
|
||||||
# DEFAULT VALUE: 48000
|
|
||||||
BITRATE = 48000
|
|
||||||
|
|
||||||
# Number of users that, if reached, will pause the music until it is started again by a user.
|
|
||||||
# This is to prevent against YouTube audio downloads when nobody is listening.
|
|
||||||
# DEFAULT VALUE: 1
|
|
||||||
USER_SOUND_PAUSE_TARGET = 1
|
|
25
mumbledj/mumbledj.lua
Normal file
25
mumbledj/mumbledj.lua
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
-------------------------
|
||||||
|
-- MumbleDJ --
|
||||||
|
-- By Matthieu Grieger --
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
function piepan.onConnect()
|
||||||
|
print("MumbleDJ has connected to the server!")
|
||||||
|
local user = piepan.users["MumbleDJ"]
|
||||||
|
local channel = user.channel("Bot Testing")
|
||||||
|
piepan.me:moveTo(channel)
|
||||||
|
end
|
||||||
|
|
||||||
|
function piepan.onMessage(message)
|
||||||
|
if message.user == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local patterns = {
|
||||||
|
"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_%-]+)"
|
||||||
|
}
|
||||||
|
end
|
|
@ -1,110 +0,0 @@
|
||||||
#----------------------#
|
|
||||||
# MumbleDJ #
|
|
||||||
# By Matthieu Grieger #
|
|
||||||
#----------------------#---------------------------#
|
|
||||||
# mumbledj.py #
|
|
||||||
# Contains definitions of MumbleDJ class & methods #
|
|
||||||
#--------------------------------------------------#
|
|
||||||
|
|
||||||
import pymumble
|
|
||||||
from pymumble.constants import *
|
|
||||||
from config import *
|
|
||||||
from time import sleep
|
|
||||||
|
|
||||||
class MumbleDJ:
|
|
||||||
# Since all the configuration is set in config.py, we don't really need to do anything here.
|
|
||||||
def __init__(self):
|
|
||||||
print('Starting up ' + SERVER_USERNAME + '...')
|
|
||||||
|
|
||||||
# Connects to the Mumble server with the credentials specified upon object creation.
|
|
||||||
def connect_to_server(self):
|
|
||||||
self.mumble = pymumble.Mumble(SERVER_ADDRESS, SERVER_PORT, SERVER_USERNAME, SERVER_PASSWORD, debug = DEBUG)
|
|
||||||
self.mumble.callbacks.set_callback(PYMUMBLE_CLBK_TEXTMESSAGERECEIVED, self.parse_message)
|
|
||||||
self.mumble.start()
|
|
||||||
self.mumble.is_ready()
|
|
||||||
self.mumble.channels.find_by_name(DEFAULT_CHANNEL).move_in()
|
|
||||||
self.mumble.users.myself.mute()
|
|
||||||
self.kill_bot = False
|
|
||||||
|
|
||||||
self.listen()
|
|
||||||
|
|
||||||
# Starts to play the first song in the queue when called. If no songs exist in the queue, it will wait until
|
|
||||||
# a song is added.
|
|
||||||
def start_music(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Resumes music when called.
|
|
||||||
def play_music(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Pauses music until told to resume.
|
|
||||||
def pause_music(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Adds a YouTube link to the queue along with its metadata.
|
|
||||||
def add_to_queue(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Sends a message to the chat when a new song starts playing.
|
|
||||||
def announce_new_song(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Skips the current song if more than 50% of the users in the channel vote to skip.
|
|
||||||
# The vote tracking will be handled elsewhere.
|
|
||||||
def skip_song(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Raises the volume by the increment decided by the user.
|
|
||||||
def raise_volume(self, increment):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Lowers the volume by the increment decided by the user.
|
|
||||||
def lower_volume(self, increment):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Moves bot from the current channel to the specified channel.
|
|
||||||
def move_bot(self, channel):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Completely stops the bot if a person on the approved list of admins
|
|
||||||
# issues the stop command.
|
|
||||||
def kill_bot(self):
|
|
||||||
self.kill_bot = True
|
|
||||||
|
|
||||||
# Parses a new message and checks for a command. If one exists, it will
|
|
||||||
# parse the command and its arguments (if they exist) and pass them along
|
|
||||||
# to the appropriate function.
|
|
||||||
def parse_message(self, message):
|
|
||||||
if message[0] == COMMAND_PREFIX:
|
|
||||||
if ' ' in message:
|
|
||||||
command = message[1:message.find(' ')]
|
|
||||||
else:
|
|
||||||
command = message[1:]
|
|
||||||
|
|
||||||
if command == 'start' and ALLOW_START:
|
|
||||||
pass
|
|
||||||
elif command == 'play' and ALLOW_PLAY:
|
|
||||||
pass
|
|
||||||
elif command == 'pause' and ALLOW_PAUSE:
|
|
||||||
pass
|
|
||||||
elif command == 'add' and ALLOW_ADD:
|
|
||||||
pass
|
|
||||||
elif command == 'skip' and ALLOW_SKIPS:
|
|
||||||
pass
|
|
||||||
elif command == 'volumeup' and ALLOW_VOLUMEUP:
|
|
||||||
pass
|
|
||||||
elif command == 'volumedown' and ALLOW_VOLUMEDOWN:
|
|
||||||
pass
|
|
||||||
elif command == 'move' and ALLOW_MOVE:
|
|
||||||
pass
|
|
||||||
elif command == 'kill' and ALLOW_KILL:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# This is the main loop for the bot. It will listen for commands periodically and
|
|
||||||
# call the appropriate functions to deal with them.
|
|
||||||
def listen(self):
|
|
||||||
while self.mumble.is_alive() and not self.kill_bot:
|
|
||||||
sleep(0.5)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
63
mumbledj/pymumble/.gitignore
vendored
63
mumbledj/pymumble/.gitignore
vendored
|
@ -1,63 +0,0 @@
|
||||||
# Byte-compiled / optimized / DLL files
|
|
||||||
__pycache__/
|
|
||||||
*.py[cod]
|
|
||||||
|
|
||||||
# C extensions
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Distribution / packaging
|
|
||||||
.Python
|
|
||||||
env/
|
|
||||||
build/
|
|
||||||
develop-eggs/
|
|
||||||
dist/
|
|
||||||
downloads/
|
|
||||||
eggs/
|
|
||||||
lib/
|
|
||||||
lib64/
|
|
||||||
parts/
|
|
||||||
sdist/
|
|
||||||
var/
|
|
||||||
*.egg-info/
|
|
||||||
.installed.cfg
|
|
||||||
*.egg
|
|
||||||
|
|
||||||
# PyInstaller
|
|
||||||
# Usually these files are written by a python script from a template
|
|
||||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
||||||
*.manifest
|
|
||||||
*.spec
|
|
||||||
|
|
||||||
# Installer logs
|
|
||||||
pip-log.txt
|
|
||||||
pip-delete-this-directory.txt
|
|
||||||
|
|
||||||
# Unit test / coverage reports
|
|
||||||
htmlcov/
|
|
||||||
.tox/
|
|
||||||
.coverage
|
|
||||||
.cache
|
|
||||||
nosetests.xml
|
|
||||||
coverage.xml
|
|
||||||
|
|
||||||
# Translations
|
|
||||||
*.mo
|
|
||||||
*.pot
|
|
||||||
|
|
||||||
# Django stuff:
|
|
||||||
*.log
|
|
||||||
|
|
||||||
# Sphinx documentation
|
|
||||||
docs/_build/
|
|
||||||
|
|
||||||
# PyBuilder
|
|
||||||
target/
|
|
||||||
|
|
||||||
# pymumble files
|
|
||||||
pycelt/
|
|
||||||
pyopus/
|
|
||||||
*.py
|
|
||||||
mumble.proto
|
|
||||||
TODO
|
|
||||||
LICENSE
|
|
||||||
API.md
|
|
|
@ -1,4 +0,0 @@
|
||||||
pymumble
|
|
||||||
=======================
|
|
||||||
|
|
||||||
In this directory you need to setup [pymumble](https://github.com/Robert904/pymumble). I chose not to directly distribute this project with mine, as a bit of setup needs to be performed anyway. Instructions on setup can be found on the pymumble README, but I will summarize here for clarity once I get the project in a somewhat finished state.
|
|
|
@ -1,59 +0,0 @@
|
||||||
#----------------------#
|
|
||||||
# MumbleDJ #
|
|
||||||
# By Matthieu Grieger #
|
|
||||||
#----------------------#---------------------------#
|
|
||||||
# song.py #
|
|
||||||
# Contains definitions of Song class & methods #
|
|
||||||
#--------------------------------------------------#
|
|
||||||
|
|
||||||
import pafy
|
|
||||||
from config import *
|
|
||||||
|
|
||||||
class Song:
|
|
||||||
# Constructs a new Song object with all of the necessary attributes
|
|
||||||
# for the given YouTube url. No downloading of audio or thumbnails
|
|
||||||
# is done at this stage.
|
|
||||||
def __init__(self, youtube_url):
|
|
||||||
song = pafy.new(youtube_url)
|
|
||||||
self.song_title = song.title
|
|
||||||
self.song_duration = song.duration
|
|
||||||
self.song_thumbnail = song.thumb
|
|
||||||
self.song_audio = song.getbestaudio(preftype = 'ogg')
|
|
||||||
self.audio_ready = False
|
|
||||||
self.song_skips = 0
|
|
||||||
|
|
||||||
# Downloads the audio file that was found in __init__. Download progress
|
|
||||||
# callbacks are passed to check_download_status.
|
|
||||||
def download_song(self):
|
|
||||||
self.song_audio.download(quiet = True, callback = self._check_download_status)
|
|
||||||
|
|
||||||
# A callback function that checks the download status of an audio file. Simply
|
|
||||||
# sets audio_ready to True when the ratio is 1 (download is completed).
|
|
||||||
def _check_download_status(total, recvd, ratio, rate, eta):
|
|
||||||
if ratio == 1:
|
|
||||||
self.audio_ready = True
|
|
||||||
|
|
||||||
# Returns the status of a song download.
|
|
||||||
def audio_ready(self):
|
|
||||||
return self.audio_ready
|
|
||||||
|
|
||||||
# Called after a song is done playing. Audio files have no use to us after the song
|
|
||||||
# has finished, so they should just be deleted.
|
|
||||||
def delete_song(self):
|
|
||||||
if DELETE_AUDIO:
|
|
||||||
pass # Delete audio
|
|
||||||
|
|
||||||
# Downloads thumnail from location specified by song_thumbnail.
|
|
||||||
def download_thumbnail(self):
|
|
||||||
if SHOW_CHAT_NOTIFICATIONS and SHOW_YT_THUMBNAILS:
|
|
||||||
pass # Download thumbnail
|
|
||||||
|
|
||||||
# Called after a song is done playing. Much like audio files, thumbnails are of no
|
|
||||||
# use to us after the song has finished.
|
|
||||||
def delete_thumbnail(self):
|
|
||||||
if DELETE_THUMBNAILS and SHOW_CHAT_NOTIFICATIONS and SHOW_YT_THUMBNAILS:
|
|
||||||
pass # Delete thumbnail
|
|
||||||
|
|
||||||
# Increments the skip count when a user uses the skip command.
|
|
||||||
def increment_skip_count(self):
|
|
||||||
self.song_skips = self.song_skips + 1
|
|
13
run_bot.py
13
run_bot.py
|
@ -1,13 +0,0 @@
|
||||||
#----------------------#
|
|
||||||
# MumbleDJ #
|
|
||||||
# By Matthieu Grieger #
|
|
||||||
#----------------------#-------------------------------#
|
|
||||||
# run_bot.py #
|
|
||||||
# Starts and runs the bot. This is the file you should #
|
|
||||||
# execute with Python to start the bot. #
|
|
||||||
#------------------------------------------------------#
|
|
||||||
|
|
||||||
from mumbledj.mumbledj import MumbleDJ
|
|
||||||
|
|
||||||
bot = MumbleDJ()
|
|
||||||
bot.connect_to_server()
|
|
Reference in a new issue