diff --git a/configuration.ini b/configuration.ini
index 4917f06..894a72f 100644
--- a/configuration.ini
+++ b/configuration.ini
@@ -1,8 +1,9 @@
[bot]
-comment = Coucou, Je suis née du savoir du Azlux, accès au https://azlux.fr/bot
+comment = Coucou, Je suis née du savoir du Azlux, accès au https://azlux.fr/bot
volume = 0.1
admin = Azlux;AzMobile
music_folder = /home/dmichel/botamusique/music/
+tmp_folder = /tmp/
is_proxified = True
[debug]
@@ -10,14 +11,20 @@ ffmpeg = False
mumbleConnection = False
[command]
-play_file = play
+play_file = file
+play_url = url
+play_radio = radio
+
+help = help
stop = stop
+list = list
+next = next
current_music = np
volume = v
kill = kill
stop_and_getout = oust
joinme = joinme
-list = list
+
[strings]
current_volume = volume : %d%%
@@ -27,3 +34,14 @@ not_admin = T'es pas admin, patate !
not_playing = Aucun stream en lecture
bad_file = Bad file asked
no_file = Not file here
+bad_url = Bad URL asked
+
+help = Command available:
+
!play_file
+
!play_url - youtube or soundcloud
+
!play_radio - url of a stream
+
!next - jump to the next music of the playlist
+
!stop - stop and clear the playlist
+
!play_file - stop + Go to default channel
+
!v - get or change the volume (in %)
+
!joinme
diff --git a/interface.py b/interface.py
index 1fcd62f..8307595 100644
--- a/interface.py
+++ b/interface.py
@@ -64,14 +64,14 @@ def index():
files[director] = [f for f in listdir(folder_path + director) if os.path.isfile(os.path.join(folder_path + director, f))]
if request.method == 'POST':
- if 'add_music' in request.form and ".." not in request.form['add_music']:
- var.playlist.append(request.form['add_music'])
+ if 'add_file' in request.form and ".." not in request.form['add_music']:
+ var.playlist.append((request.form['type'], request.form['add_music']))
if 'add_folder' in request.form and ".." not in request.form['add_folder']:
- dir_files = [request.form['add_folder'] + '/' + i for i in files[request.form['add_folder']]]
+ dir_files = [("file", request.form['add_folder'] + '/' + i) for i in files[request.form['add_folder']]]
var.playlist.extend(dir_files)
elif 'delete_music' in request.form:
try:
- var.playlist.remove(request.form['delete_music'])
+ var.playlist.remove("file", request.form['delete_music'])
except ValueError:
pass
elif 'action' in request.form:
diff --git a/media.py b/media.py
new file mode 100644
index 0000000..64af452
--- /dev/null
+++ b/media.py
@@ -0,0 +1,67 @@
+import re
+import urllib
+import logging
+import json
+import http.client
+import struct
+
+
+def get_radio_server_description(url):
+ p = re.compile('(https?\:\/\/[^\/]*)', re.IGNORECASE)
+ res = re.search(p, url)
+ base_url = res.group(1)
+ url_icecast = base_url + '/status-json.xsl'
+ url_shoutcast = base_url + '/stats?json=1'
+ title_server = None
+ try:
+ request = urllib.request.Request(url_shoutcast)
+ response = urllib.request.urlopen(request)
+ data = json.loads(response.read().decode("utf-8"))
+ title_server = data['servertitle']
+ logging.debug("TITLE FOUND SHOUTCAST: " + title_server)
+ except urllib.error.HTTPError:
+ pass
+ except http.client.BadStatusLine:
+ pass
+ except ValueError:
+ return False
+
+ if not title_server:
+ try:
+ request = urllib.request.Request(url_icecast)
+ response = urllib.request.urlopen(request)
+ data = json.loads(response.read().decode('utf-8',errors='ignore'),strict=False)
+ title_server = data['icestats']['source'][0]['server_name'] + ' - ' + data['icestats']['source'][0]['server_description']
+ logging.debug("TITLE FOUND ICECAST: " + title_server)
+ if not title_server:
+ title_server = url
+ except urllib.error.URLError:
+ title_server = url
+ except urllib.error.HTTPError:
+ return False
+ except http.client.BadStatusLine:
+ pass
+ return title_server
+
+
+def get_radio_title(url):
+ request = urllib.request.Request(url, headers={'Icy-MetaData': 1})
+ try:
+
+ response = urllib.request.urlopen(request)
+ icy_metaint_header = int(response.headers['icy-metaint'])
+ if icy_metaint_header is not None:
+ response.read(icy_metaint_header)
+
+ metadata_length = struct.unpack('B', response.read(1))[0] * 16 # length byte
+ metadata = response.read(metadata_length).rstrip(b'\0')
+ logging.debug(metadata)
+ # extract title from the metadata
+ m = re.search(br"StreamTitle='([^']*)';", metadata)
+ if m:
+ title = m.group(1)
+ if title:
+ return title.decode()
+ except (urllib.error.URLError, urllib.error.HTTPError):
+ pass
+ return 'Impossible to get the music title'
diff --git a/mumbleBot.py b/mumbleBot.py
index a9b60d7..66f7637 100644
--- a/mumbleBot.py
+++ b/mumbleBot.py
@@ -1,6 +1,8 @@
#!/usr/bin/python3
-import threading
+from __future__ import unicode_literals
+import re
+import threading
import time
import sys
import signal
@@ -13,6 +15,9 @@ from os import listdir
import pymumble.pymumble_py3 as pymumble
import interface
import variables as var
+import hashlib
+import youtube_dl
+import media
class MumbleBot:
@@ -34,7 +39,24 @@ class MumbleBot:
self.channel = args.channel
var.current_music = None
+
+ ######
+ ## Format of the Playlist :
+ ## [("","")]
+ ## [("",""), ("","")]
+ ## types : file, radio, url
+ ######
+
+ ######
+ ## Format of the current_music variable
+ # len(var.current_music) = 4
+ # var.current_music[0] =
+ # var.current_music[1] = if url of radio
+ # var.current_music[2] =
+ # var.current_music[3] = if url or file
+
var.playlist = []
+
var.user = args.user
var.music_folder = self.config.get('bot', 'music_folder')
var.is_proxified = self.config.getboolean("bot", "is_proxified")
@@ -44,9 +66,9 @@ class MumbleBot:
interface.init_proxy()
- t = threading.Thread(target=start_web_interface)
- t.daemon = True
- t.start()
+ # t = threading.Thread(target=start_web_interface)
+ # t.daemon = True
+ # t.start()
self.mumble = pymumble.Mumble(args.host, user=args.user, port=args.port, password=args.password,
debug=self.config.getboolean('debug', 'mumbleConnection'))
@@ -91,10 +113,19 @@ class MumbleBot:
if "/" in parameter:
self.mumble.users[text.actor].send_message(self.config.get('strings', 'bad_file'))
elif os.path.isfile(path):
- self.launch_play_file(path)
+ var.playlist.append(["file", path])
else:
self.mumble.users[text.actor].send_message(self.config.get('strings', 'bad_file'))
+ elif command == self.config.get('command', 'play_url') and parameter:
+ var.playlist.append(["url", parameter])
+
+ elif command == self.config.get('command', 'play_radio') and parameter:
+ var.playlist.append(["radio", parameter])
+
+ elif command == self.config.get('command', 'help'):
+ self.send_msg_channel(self.config.get('strings', 'help'))
+
elif command == self.config.get('command', 'stop'):
self.stop()
@@ -123,17 +154,17 @@ class MumbleBot:
elif command == self.config.get('command', 'current_music'):
if var.current_music is not None:
- self.send_msg_channel(var.current_music)
+ if var.current_music[0] == "radio":
+ self.send_msg_channel(media.get_radio_title(var.current_music[1]) + " sur " + var.current_music[2])
+ else:
+ self.send_msg_channel(var.current_music[2] + "
" + var.current_music[1])
else:
self.mumble.users[text.actor].send_message(self.config.get('strings', 'not_playing'))
- elif command == self.config.get('command', 'list'):
- folder_path = self.config.get('bot', 'music_folder')
- files = [f for f in listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]
- if files:
- self.mumble.users[text.actor].send_message('
'.join(files))
- else:
- self.mumble.users[text.actor].send_message(self.config.get('strings', 'no_file'))
+ elif command == self.config.get('command', 'next'):
+ var.current_music = var.playlist[0]
+ var.playlist.pop(0)
+ self.launch_next()
else:
self.mumble.users[text.actor].send_message(self.config.get('strings', 'bad_command'))
@@ -145,21 +176,69 @@ class MumbleBot:
else:
return False
- def launch_play_file(self, path=None):
- if not path:
- path = self.config.get('bot', 'music_folder') + var.current_music
+ def launch_next(self):
+ path = ""
+ title = ""
+ if var.current_music[0] == "url":
+ regex = re.compile(" 0.5:
+ while self.mumble.sound_output.get_buffer_size() > 0.5 and not self.exit:
time.sleep(0.01)
if self.thread:
raw_music = self.thread.stdout.read(480)
@@ -173,7 +252,7 @@ class MumbleBot:
if (self.thread is None or not raw_music) and len(var.playlist) != 0:
var.current_music = var.playlist[0]
var.playlist.pop(0)
- self.launch_play_file()
+ self.launch_next()
while self.mumble.sound_output.get_buffer_size() > 0:
time.sleep(0.01)
diff --git a/variables.py b/variables.py
index f0396d3..f7eb8ce 100644
--- a/variables.py
+++ b/variables.py
@@ -1,5 +1,5 @@
-current_music = ""
+current_music = ("", "")
playlist = []
user = ""
music_folder = ""
-is_proxified = False
\ No newline at end of file
+is_proxified = False