Support playback of local files
- Recursive listing of available files - Protected against path traversal attacks - Does not follow symlinks - Possibility to ignore directories or files with specific names - If no exact match for the requested track can be found, the bot plays the track with the best match - If multiple tracks match the user gets a message listing all candidates
This commit is contained in:
parent
4ae9c1cdb7
commit
7910f23d0d
@ -4,6 +4,8 @@ volume = 0.1
|
||||
admin = BafTac
|
||||
music_folder = /home/fabian/music/mumblebot/
|
||||
tmp_folder = /tmp/
|
||||
ignored_folders = tmp
|
||||
ignored_files = Thumbs.db
|
||||
is_proxified = True
|
||||
|
||||
[debug]
|
||||
@ -35,6 +37,7 @@ not_playing = Aucun stream en lecture
|
||||
bad_file = Bad file asked
|
||||
no_file = Not file here
|
||||
bad_url = Bad URL asked
|
||||
multiple_matches = Track not found! Possible candidates:
|
||||
|
||||
help = Command available:
|
||||
<br />!play_file <path>
|
||||
|
47
mumbleBot.py
47
mumbleBot.py
@ -110,9 +110,20 @@ class MumbleBot:
|
||||
|
||||
if command == self.config.get('command', 'play_file') and parameter:
|
||||
music_folder = self.config.get('bot', 'music_folder')
|
||||
# sanitize "../" and so on
|
||||
path = os.path.abspath(os.path.join(music_folder, parameter))
|
||||
if path.startswith(music_folder) and os.path.isfile(path):
|
||||
if path.startswith(music_folder):
|
||||
if os.path.isfile(path):
|
||||
self.launch_play_file(path)
|
||||
else:
|
||||
# try to do a partial match
|
||||
matches = [file for file in self.__get_recursive_filelist_sorted(music_folder) if parameter in file]
|
||||
if len(matches) == 1:
|
||||
self.launch_play_file(music_folder + matches[0])
|
||||
else:
|
||||
msg = self.config.get('strings', 'multiple_matches') + '<br />'
|
||||
msg += '<br />'.join(matches)
|
||||
self.mumble.users[text.actor].send_message(msg)
|
||||
else:
|
||||
self.mumble.users[text.actor].send_message(self.config.get('strings', 'bad_file'))
|
||||
|
||||
@ -164,9 +175,27 @@ class MumbleBot:
|
||||
var.current_music = var.playlist[0]
|
||||
var.playlist.pop(0)
|
||||
self.launch_next()
|
||||
elif command == self.config.get('command', 'list'):
|
||||
folder_path = self.config.get('bot', 'music_folder')
|
||||
|
||||
files = self.__get_recursive_filelist_sorted(folder_path)
|
||||
if files :
|
||||
self.mumble.users[text.actor].send_message('<br>'.join(files))
|
||||
else :
|
||||
self.mumble.users[text.actor].send_message(self.config.get('strings', 'no_file'))
|
||||
else:
|
||||
self.mumble.users[text.actor].send_message(self.config.get('strings', 'bad_command'))
|
||||
|
||||
def launch_play_file(self, path):
|
||||
self.stop()
|
||||
if self.config.getboolean('debug', 'ffmpeg'):
|
||||
ffmpeg_debug = "debug"
|
||||
else:
|
||||
ffmpeg_debug = "warning"
|
||||
command = ["ffmpeg", '-v', ffmpeg_debug, '-nostdin', '-i', path, '-ac', '1', '-f', 's16le', '-ar', '48000', '-']
|
||||
self.thread = sp.Popen(command, stdout=sp.PIPE, bufsize=480)
|
||||
self.playing = True
|
||||
|
||||
def is_admin(self, user):
|
||||
username = self.mumble.users[user]['name']
|
||||
list_admin = self.config.get('bot', 'admin').split(';')
|
||||
@ -272,6 +301,22 @@ class MumbleBot:
|
||||
channel = self.mumble.channels[self.mumble.users.myself['channel_id']]
|
||||
channel.send_text_message(msg)
|
||||
|
||||
def __get_recursive_filelist_sorted(self, path):
|
||||
filelist = []
|
||||
for root, dirs, files in os.walk(path):
|
||||
relroot = root.replace(path, '')
|
||||
if relroot in self.config.get('bot', 'ignored_folders'):
|
||||
continue
|
||||
if len(relroot):
|
||||
relroot += '/'
|
||||
for file in files:
|
||||
if file in self.config.get('bot', 'ignored_files'):
|
||||
continue
|
||||
filelist.append(relroot + file)
|
||||
|
||||
filelist.sort()
|
||||
return filelist
|
||||
|
||||
|
||||
def start_web_interface():
|
||||
interface.web.run(port=8181, host="127.0.0.1")
|
||||
|
Loading…
x
Reference in New Issue
Block a user