chore: optimize logging. separate bot log and web log.

This commit is contained in:
Terry Geng 2020-02-28 14:08:36 +08:00
parent dc5a30b384
commit cf1feea870
10 changed files with 222 additions and 115 deletions

View File

@ -15,6 +15,7 @@ import variables as var
from librb import radiobrowser from librb import radiobrowser
from database import Database from database import Database
log = logging.getLogger("bot")
def register_all_commands(bot): def register_all_commands(bot):
bot.register_command(constants.commands('joinme'), cmd_joinme) bot.register_command(constants.commands('joinme'), cmd_joinme)
@ -52,6 +53,8 @@ def register_all_commands(bot):
bot.register_command(constants.commands('drop_database'), cmd_drop_database) bot.register_command(constants.commands('drop_database'), cmd_drop_database)
def send_multi_lines(bot, lines, text): def send_multi_lines(bot, lines, text):
global log
msg = "" msg = ""
br = "" br = ""
for newline in lines: for newline in lines:
@ -68,11 +71,15 @@ def send_multi_lines(bot, lines, text):
def cmd_joinme(bot, user, text, command, parameter): def cmd_joinme(bot, user, text, command, parameter):
global log
bot.mumble.users.myself.move_in( bot.mumble.users.myself.move_in(
bot.mumble.users[text.actor]['channel_id'], token=parameter) bot.mumble.users[text.actor]['channel_id'], token=parameter)
def cmd_user_ban(bot, user, text, command, parameter): def cmd_user_ban(bot, user, text, command, parameter):
global log
if bot.is_admin(user): if bot.is_admin(user):
if parameter: if parameter:
bot.mumble.users[text.actor].send_text_message(util.user_ban(parameter)) bot.mumble.users[text.actor].send_text_message(util.user_ban(parameter))
@ -84,6 +91,8 @@ def cmd_user_ban(bot, user, text, command, parameter):
def cmd_user_unban(bot, user, text, command, parameter): def cmd_user_unban(bot, user, text, command, parameter):
global log
if bot.is_admin(user): if bot.is_admin(user):
if parameter: if parameter:
bot.mumble.users[text.actor].send_text_message(util.user_unban(parameter)) bot.mumble.users[text.actor].send_text_message(util.user_unban(parameter))
@ -93,6 +102,8 @@ def cmd_user_unban(bot, user, text, command, parameter):
def cmd_url_ban(bot, user, text, command, parameter): def cmd_url_ban(bot, user, text, command, parameter):
global log
if bot.is_admin(user): if bot.is_admin(user):
if parameter: if parameter:
bot.mumble.users[text.actor].send_text_message(util.url_ban(util.get_url_from_input(parameter))) bot.mumble.users[text.actor].send_text_message(util.url_ban(util.get_url_from_input(parameter)))
@ -104,6 +115,8 @@ def cmd_url_ban(bot, user, text, command, parameter):
def cmd_url_unban(bot, user, text, command, parameter): def cmd_url_unban(bot, user, text, command, parameter):
global log
if bot.is_admin(user): if bot.is_admin(user):
if parameter: if parameter:
bot.mumble.users[text.actor].send_text_message(util.url_unban(util.get_url_from_input(parameter))) bot.mumble.users[text.actor].send_text_message(util.url_unban(util.get_url_from_input(parameter)))
@ -113,6 +126,8 @@ def cmd_url_unban(bot, user, text, command, parameter):
def cmd_play(bot, user, text, command, parameter): def cmd_play(bot, user, text, command, parameter):
global log
if var.playlist.length() > 0: if var.playlist.length() > 0:
if parameter: if parameter:
if parameter.isdigit() and int(parameter) > 0 and int(parameter) <= len(var.playlist): if parameter.isdigit() and int(parameter) > 0 and int(parameter) <= len(var.playlist):
@ -131,11 +146,15 @@ def cmd_play(bot, user, text, command, parameter):
def cmd_pause(bot, user, text, command, parameter): def cmd_pause(bot, user, text, command, parameter):
global log
bot.pause() bot.pause()
bot.send_msg(constants.strings('paused')) bot.send_msg(constants.strings('paused'))
def cmd_play_file(bot, user, text, command, parameter): def cmd_play_file(bot, user, text, command, parameter):
global log
# if parameter is {index} # if parameter is {index}
if parameter.isdigit(): if parameter.isdigit():
files = util.get_recursive_filelist_sorted(var.music_folder) files = util.get_recursive_filelist_sorted(var.music_folder)
@ -145,7 +164,7 @@ def cmd_play_file(bot, user, text, command, parameter):
'path': filename, 'path': filename,
'user': user} 'user': user}
music = var.playlist.append(music) music = var.playlist.append(music)
logging.info("cmd: add to playlist: " + util.format_debug_song_string(music)) log.info("cmd: add to playlist: " + util.format_debug_song_string(music))
bot.send_msg(constants.strings('file_added', item=util.format_song_string(music)), text) bot.send_msg(constants.strings('file_added', item=util.format_song_string(music)), text)
# if parameter is {path} # if parameter is {path}
@ -161,7 +180,7 @@ def cmd_play_file(bot, user, text, command, parameter):
'path': parameter, 'path': parameter,
'user': user} 'user': user}
music = var.playlist.append(music) music = var.playlist.append(music)
logging.info("cmd: add to playlist: " + util.format_debug_song_string(music)) log.info("cmd: add to playlist: " + util.format_debug_song_string(music))
bot.send_msg(constants.strings('file_added', item=util.format_song_string(music)), text) bot.send_msg(constants.strings('file_added', item=util.format_song_string(music)), text)
return return
@ -188,7 +207,7 @@ def cmd_play_file(bot, user, text, command, parameter):
'path': file, 'path': file,
'user': user} 'user': user}
music = var.playlist.append(music) music = var.playlist.append(music)
logging.info("cmd: add to playlist: " + util.format_debug_song_string(music)) log.info("cmd: add to playlist: " + util.format_debug_song_string(music))
msgs.append("{} ({})".format(music['title'], music['path'])) msgs.append("{} ({})".format(music['title'], music['path']))
if count != 0: if count != 0:
@ -207,7 +226,7 @@ def cmd_play_file(bot, user, text, command, parameter):
'path': matches[0][1], 'path': matches[0][1],
'user': user} 'user': user}
music = var.playlist.append(music) music = var.playlist.append(music)
logging.info("cmd: add to playlist: " + util.format_debug_song_string(music)) log.info("cmd: add to playlist: " + util.format_debug_song_string(music))
bot.send_msg(constants.strings('file_added', item=util.format_song_string(music)), text) bot.send_msg(constants.strings('file_added', item=util.format_song_string(music)), text)
else: else:
msgs = [ constants.strings('multiple_matches')] msgs = [ constants.strings('multiple_matches')]
@ -217,6 +236,8 @@ def cmd_play_file(bot, user, text, command, parameter):
def cmd_play_file_match(bot, user, text, command, parameter): def cmd_play_file_match(bot, user, text, command, parameter):
global log
music_folder = var.music_folder music_folder = var.music_folder
if parameter: if parameter:
files = util.get_recursive_filelist_sorted(music_folder) files = util.get_recursive_filelist_sorted(music_folder)
@ -231,7 +252,7 @@ def cmd_play_file_match(bot, user, text, command, parameter):
'path': file, 'path': file,
'user': user} 'user': user}
music = var.playlist.append(music) music = var.playlist.append(music)
logging.info("cmd: add to playlist: " + util.format_debug_song_string(music)) log.info("cmd: add to playlist: " + util.format_debug_song_string(music))
msgs.append("{} ({})".format(music['title'], music['path'])) msgs.append("{} ({})".format(music['title'], music['path']))
@ -248,6 +269,8 @@ def cmd_play_file_match(bot, user, text, command, parameter):
def cmd_play_url(bot, user, text, command, parameter): def cmd_play_url(bot, user, text, command, parameter):
global log
music = {'type': 'url', music = {'type': 'url',
# grab the real URL # grab the real URL
'url': util.get_url_from_input(parameter), 'url': util.get_url_from_input(parameter),
@ -257,7 +280,7 @@ def cmd_play_url(bot, user, text, command, parameter):
music = bot.validate_music(music) music = bot.validate_music(music)
if music: if music:
music = var.playlist.append(music) music = var.playlist.append(music)
logging.info("cmd: add to playlist: " + util.format_debug_song_string(music)) log.info("cmd: add to playlist: " + util.format_debug_song_string(music))
bot.send_msg(constants.strings('file_added', item=util.format_song_string(music)), text) bot.send_msg(constants.strings('file_added', item=util.format_song_string(music)), text)
if var.playlist.length() == 2: if var.playlist.length() == 2:
# If I am the second item on the playlist. (I am the next one!) # If I am the second item on the playlist. (I am the next one!)
@ -267,6 +290,8 @@ def cmd_play_url(bot, user, text, command, parameter):
def cmd_play_playlist(bot, user, text, command, parameter): def cmd_play_playlist(bot, user, text, command, parameter):
global log
offset = 0 # if you want to start the playlist at a specific index offset = 0 # if you want to start the playlist at a specific index
try: try:
offset = int(parameter.split(" ")[-1]) offset = int(parameter.split(" ")[-1])
@ -274,15 +299,17 @@ def cmd_play_playlist(bot, user, text, command, parameter):
pass pass
url = util.get_url_from_input(parameter) url = util.get_url_from_input(parameter)
logging.debug("cmd: fetching media info from playlist url %s" % url) log.debug("cmd: fetching media info from playlist url %s" % url)
items = media.playlist.get_playlist_info(url=url, start_index=offset, user=user) items = media.playlist.get_playlist_info(url=url, start_index=offset, user=user)
if len(items) > 0: if len(items) > 0:
var.playlist.extend(items) var.playlist.extend(items)
for music in items: for music in items:
logging.info("cmd: add to playlist: " + util.format_debug_song_string(music)) log.info("cmd: add to playlist: " + util.format_debug_song_string(music))
def cmd_play_radio(bot, user, text, command, parameter): def cmd_play_radio(bot, user, text, command, parameter):
global log
if not parameter: if not parameter:
all_radio = var.config.items('radio') all_radio = var.config.items('radio')
msg = constants.strings('preconfigurated_radio') msg = constants.strings('preconfigurated_radio')
@ -302,26 +329,28 @@ def cmd_play_radio(bot, user, text, command, parameter):
'url': url, 'url': url,
'user': user} 'user': user}
var.playlist.append(music) var.playlist.append(music)
logging.info("cmd: add to playlist: " + util.format_debug_song_string(music)) log.info("cmd: add to playlist: " + util.format_debug_song_string(music))
bot.async_download_next() bot.async_download_next()
else: else:
bot.send_msg(constants.strings('bad_url')) bot.send_msg(constants.strings('bad_url'))
def cmd_rb_query(bot, user, text, command, parameter): def cmd_rb_query(bot, user, text, command, parameter):
logging.info('cmd: Querying radio stations') global log
log.info('cmd: Querying radio stations')
if not parameter: if not parameter:
logging.debug('rbquery without parameter') log.debug('rbquery without parameter')
msg = constants.strings('rb_query_empty') msg = constants.strings('rb_query_empty')
bot.send_msg(msg, text) bot.send_msg(msg, text)
else: else:
logging.debug('cmd: Found query parameter: ' + parameter) log.debug('cmd: Found query parameter: ' + parameter)
# bot.send_msg('Searching for stations - this may take some seconds...', text) # bot.send_msg('Searching for stations - this may take some seconds...', text)
rb_stations = radiobrowser.getstations_byname(parameter) rb_stations = radiobrowser.getstations_byname(parameter)
msg = constants.strings('rb_query_result') msg = constants.strings('rb_query_result')
msg += '\n<table><tr><th>!rbplay ID</th><th>Station Name</th><th>Genre</th><th>Codec/Bitrate</th><th>Country</th></tr>' msg += '\n<table><tr><th>!rbplay ID</th><th>Station Name</th><th>Genre</th><th>Codec/Bitrate</th><th>Country</th></tr>'
if not rb_stations: if not rb_stations:
logging.debug('cmd: No matches found for rbquery ' + parameter) log.debug('cmd: No matches found for rbquery ' + parameter)
bot.send_msg('Radio-Browser found no matches for ' + parameter, text) bot.send_msg('Radio-Browser found no matches for ' + parameter, text)
else: else:
for s in rb_stations: for s in rb_stations:
@ -340,7 +369,7 @@ def cmd_rb_query(bot, user, text, command, parameter):
bot.send_msg(msg, text) bot.send_msg(msg, text)
# Shorten message if message too long (stage I) # Shorten message if message too long (stage I)
else: else:
logging.debug('Result too long stage I') log.debug('Result too long stage I')
msg = constants.strings('rb_query_result') + ' (shortened L1)' msg = constants.strings('rb_query_result') + ' (shortened L1)'
msg += '\n<table><tr><th>!rbplay ID</th><th>Station Name</th></tr>' msg += '\n<table><tr><th>!rbplay ID</th><th>Station Name</th></tr>'
for s in rb_stations: for s in rb_stations:
@ -353,7 +382,7 @@ def cmd_rb_query(bot, user, text, command, parameter):
bot.send_msg(msg, text) bot.send_msg(msg, text)
# Shorten message if message too long (stage II) # Shorten message if message too long (stage II)
else: else:
logging.debug('Result too long stage II') log.debug('Result too long stage II')
msg = constants.strings('rb_query_result') + ' (shortened L2)' msg = constants.strings('rb_query_result') + ' (shortened L2)'
msg += '!rbplay ID - Station Name' msg += '!rbplay ID - Station Name'
for s in rb_stations: for s in rb_stations:
@ -370,13 +399,15 @@ def cmd_rb_query(bot, user, text, command, parameter):
def cmd_rb_play(bot, user, text, command, parameter): def cmd_rb_play(bot, user, text, command, parameter):
logging.debug('cmd: Play a station by ID') global log
log.debug('cmd: Play a station by ID')
if not parameter: if not parameter:
logging.debug('rbplay without parameter') log.debug('rbplay without parameter')
msg = constants.strings('rb_play_empty') msg = constants.strings('rb_play_empty')
bot.send_msg(msg, text) bot.send_msg(msg, text)
else: else:
logging.debug('cmd: Retreiving url for station ID ' + parameter) log.debug('cmd: Retreiving url for station ID ' + parameter)
rstation = radiobrowser.getstationname_byid(parameter) rstation = radiobrowser.getstationname_byid(parameter)
stationname = rstation[0]['name'] stationname = rstation[0]['name']
country = rstation[0]['country'] country = rstation[0]['country']
@ -390,42 +421,50 @@ def cmd_rb_play(bot, user, text, command, parameter):
msg += '<table><tr><th>ID</th><th>Station Name</th><th>Genre</th><th>Codec/Bitrate</th><th>Country</th><th>Homepage</th></tr>' + \ msg += '<table><tr><th>ID</th><th>Station Name</th><th>Genre</th><th>Codec/Bitrate</th><th>Country</th><th>Homepage</th></tr>' + \
'<tr><td>%s</td><td>%s</td><td>%s</td><td>%s/%s</td><td>%s</td><td>%s</td></tr></table>' \ '<tr><td>%s</td><td>%s</td><td>%s</td><td>%s/%s</td><td>%s</td><td>%s</td></tr></table>' \
% (parameter, stationname, genre, codec, bitrate, country, homepage) % (parameter, stationname, genre, codec, bitrate, country, homepage)
logging.debug('cmd: Added station to playlist %s' % stationname) log.debug('cmd: Added station to playlist %s' % stationname)
bot.send_msg(msg, text) bot.send_msg(msg, text)
url = radiobrowser.geturl_byid(parameter) url = radiobrowser.geturl_byid(parameter)
if url != "-1": if url != "-1":
logging.info('cmd: Found url: ' + url) log.info('cmd: Found url: ' + url)
music = {'type': 'radio', music = {'type': 'radio',
'title': stationname, 'title': stationname,
'artist': homepage, 'artist': homepage,
'url': url, 'url': url,
'user': user} 'user': user}
var.playlist.append(music) var.playlist.append(music)
logging.info("cmd: add to playlist: " + util.format_debug_song_string(music)) log.info("cmd: add to playlist: " + util.format_debug_song_string(music))
bot.async_download_next() bot.async_download_next()
else: else:
logging.info('cmd: No playable url found.') log.info('cmd: No playable url found.')
msg += "No playable url found for this station, please try another station." msg += "No playable url found for this station, please try another station."
bot.send_msg(msg, text) bot.send_msg(msg, text)
def cmd_help(bot, user, text, command, parameter): def cmd_help(bot, user, text, command, parameter):
global log
bot.send_msg(constants.strings('help'), text) bot.send_msg(constants.strings('help'), text)
if bot.is_admin(user): if bot.is_admin(user):
bot.send_msg(constants.strings('admin_help'), text) bot.send_msg(constants.strings('admin_help'), text)
def cmd_stop(bot, user, text, command, parameter): def cmd_stop(bot, user, text, command, parameter):
global log
bot.stop() bot.stop()
bot.send_msg(constants.strings('stopped'), text) bot.send_msg(constants.strings('stopped'), text)
def cmd_clear(bot, user, text, command, parameter): def cmd_clear(bot, user, text, command, parameter):
global log
bot.clear() bot.clear()
bot.send_msg(constants.strings('cleared'), text) bot.send_msg(constants.strings('cleared'), text)
def cmd_kill(bot, user, text, command, parameter): def cmd_kill(bot, user, text, command, parameter):
global log
if bot.is_admin(user): if bot.is_admin(user):
bot.pause() bot.pause()
bot.exit = True bot.exit = True
@ -435,6 +474,8 @@ def cmd_kill(bot, user, text, command, parameter):
def cmd_update(bot, user, text, command, parameter): def cmd_update(bot, user, text, command, parameter):
global log
if bot.is_admin(user): if bot.is_admin(user):
bot.mumble.users[text.actor].send_text_message( bot.mumble.users[text.actor].send_text_message(
constants.strings('start_updating')) constants.strings('start_updating'))
@ -446,24 +487,30 @@ def cmd_update(bot, user, text, command, parameter):
def cmd_stop_and_getout(bot, user, text, command, parameter): def cmd_stop_and_getout(bot, user, text, command, parameter):
global log
bot.stop() bot.stop()
if bot.channel: if bot.channel:
bot.mumble.channels.find_by_name(bot.channel).move_in() bot.mumble.channels.find_by_name(bot.channel).move_in()
def cmd_volume(bot, user, text, command, parameter): def cmd_volume(bot, user, text, command, parameter):
global log
# The volume is a percentage # The volume is a percentage
if parameter and parameter.isdigit() and 0 <= int(parameter) <= 100: if parameter and parameter.isdigit() and 0 <= int(parameter) <= 100:
bot.volume_set = float(float(parameter) / 100) bot.volume_set = float(float(parameter) / 100)
bot.send_msg(constants.strings('change_volume', bot.send_msg(constants.strings('change_volume',
volume=int(bot.volume_set * 100), user=bot.mumble.users[text.actor]['name']), text) volume=int(bot.volume_set * 100), user=bot.mumble.users[text.actor]['name']), text)
var.db.set('bot', 'volume', str(bot.volume_set)) var.db.set('bot', 'volume', str(bot.volume_set))
logging.info('cmd: volume set to %d' % (bot.volume_set * 100)) log.info('cmd: volume set to %d' % (bot.volume_set * 100))
else: else:
bot.send_msg(constants.strings('current_volume', volume=int(bot.volume_set * 100)), text) bot.send_msg(constants.strings('current_volume', volume=int(bot.volume_set * 100)), text)
def cmd_ducking(bot, user, text, command, parameter): def cmd_ducking(bot, user, text, command, parameter):
global log
if parameter == "" or parameter == "on": if parameter == "" or parameter == "on":
bot.is_ducking = True bot.is_ducking = True
var.db.set('bot', 'ducking', True) var.db.set('bot', 'ducking', True)
@ -472,7 +519,7 @@ def cmd_ducking(bot, user, text, command, parameter):
bot.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_SOUNDRECEIVED, bot.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_SOUNDRECEIVED,
bot.ducking_sound_received) bot.ducking_sound_received)
bot.mumble.set_receive_sound(True) bot.mumble.set_receive_sound(True)
logging.info('cmd: ducking is on') log.info('cmd: ducking is on')
msg = "Ducking on." msg = "Ducking on."
bot.send_msg(msg, text) bot.send_msg(msg, text)
elif parameter == "off": elif parameter == "off":
@ -480,11 +527,13 @@ def cmd_ducking(bot, user, text, command, parameter):
bot.mumble.set_receive_sound(False) bot.mumble.set_receive_sound(False)
var.db.set('bot', 'ducking', False) var.db.set('bot', 'ducking', False)
msg = "Ducking off." msg = "Ducking off."
logging.info('cmd: ducking is off') log.info('cmd: ducking is off')
bot.send_msg(msg, text) bot.send_msg(msg, text)
def cmd_ducking_threshold(bot, user, text, command, parameter): def cmd_ducking_threshold(bot, user, text, command, parameter):
global log
if parameter and parameter.isdigit(): if parameter and parameter.isdigit():
bot.ducking_threshold = int(parameter) bot.ducking_threshold = int(parameter)
var.db.set('bot', 'ducking_threshold', str(bot.ducking_threshold)) var.db.set('bot', 'ducking_threshold', str(bot.ducking_threshold))
@ -496,6 +545,8 @@ def cmd_ducking_threshold(bot, user, text, command, parameter):
def cmd_ducking_volume(bot, user, text, command, parameter): def cmd_ducking_volume(bot, user, text, command, parameter):
global log
# The volume is a percentage # The volume is a percentage
if parameter and parameter.isdigit() and 0 <= int(parameter) <= 100: if parameter and parameter.isdigit() and 0 <= int(parameter) <= 100:
bot.ducking_volume = float(float(parameter) / 100) bot.ducking_volume = float(float(parameter) / 100)
@ -503,12 +554,14 @@ def cmd_ducking_volume(bot, user, text, command, parameter):
volume=int(bot.ducking_volume * 100), user=bot.mumble.users[text.actor]['name']), text) volume=int(bot.ducking_volume * 100), user=bot.mumble.users[text.actor]['name']), text)
# var.db.set('bot', 'volume', str(bot.volume_set)) # var.db.set('bot', 'volume', str(bot.volume_set))
var.db.set('bot', 'ducking_volume', str(bot.ducking_volume)) var.db.set('bot', 'ducking_volume', str(bot.ducking_volume))
logging.info('cmd: volume on ducking set to %d' % (bot.ducking_volume * 100)) log.info('cmd: volume on ducking set to %d' % (bot.ducking_volume * 100))
else: else:
bot.send_msg(constants.strings('current_ducking_volume', volume=int(bot.ducking_volume * 100)), text) bot.send_msg(constants.strings('current_ducking_volume', volume=int(bot.ducking_volume * 100)), text)
def cmd_current_music(bot, user, text, command, parameter): def cmd_current_music(bot, user, text, command, parameter):
global log
reply = "" reply = ""
if var.playlist.length() > 0: if var.playlist.length() > 0:
bot.send_msg(util.format_current_playing()) bot.send_msg(util.format_current_playing())
@ -518,6 +571,8 @@ def cmd_current_music(bot, user, text, command, parameter):
def cmd_skip(bot, user, text, command, parameter): def cmd_skip(bot, user, text, command, parameter):
global log
if var.playlist.length() > 0: if var.playlist.length() > 0:
bot.stop() bot.stop()
bot.launch_music() bot.launch_music()
@ -527,6 +582,8 @@ def cmd_skip(bot, user, text, command, parameter):
def cmd_remove(bot, user, text, command, parameter): def cmd_remove(bot, user, text, command, parameter):
global log
# Allow to remove specific music into the queue with a number # Allow to remove specific music into the queue with a number
if parameter and parameter.isdigit() and int(parameter) > 0 \ if parameter and parameter.isdigit() and int(parameter) > 0 \
and int(parameter) <= var.playlist.length(): and int(parameter) <= var.playlist.length():
@ -554,12 +611,14 @@ def cmd_remove(bot, user, text, command, parameter):
bot.send_msg(constants.strings('removing_item', bot.send_msg(constants.strings('removing_item',
item=removed['title'] if 'title' in removed else removed['url']), text) item=removed['title'] if 'title' in removed else removed['url']), text)
logging.info("cmd: delete from playlist: " + str(removed['path'] if 'path' in removed else removed['url'])) log.info("cmd: delete from playlist: " + str(removed['path'] if 'path' in removed else removed['url']))
else: else:
bot.send_msg(constants.strings('bad_parameter', command=command)) bot.send_msg(constants.strings('bad_parameter', command=command))
def cmd_list_file(bot, user, text, command, parameter): def cmd_list_file(bot, user, text, command, parameter):
global log
folder_path = var.music_folder folder_path = var.music_folder
files = util.get_recursive_filelist_sorted(folder_path) files = util.get_recursive_filelist_sorted(folder_path)
@ -586,6 +645,8 @@ def cmd_list_file(bot, user, text, command, parameter):
def cmd_queue(bot, user, text, command, parameter): def cmd_queue(bot, user, text, command, parameter):
global log
if len(var.playlist) == 0: if len(var.playlist) == 0:
msg = constants.strings('queue_empty') msg = constants.strings('queue_empty')
bot.send_msg(msg, text) bot.send_msg(msg, text)
@ -605,10 +666,14 @@ def cmd_queue(bot, user, text, command, parameter):
send_multi_lines(bot, msgs, text) send_multi_lines(bot, msgs, text)
def cmd_random(bot, user, text, command, parameter): def cmd_random(bot, user, text, command, parameter):
global log
bot.interrupt_playing() bot.interrupt_playing()
var.playlist.randomize() var.playlist.randomize()
def cmd_repeat(bot, user, text, command, parameter): def cmd_repeat(bot, user, text, command, parameter):
global log
repeat = 1 repeat = 1
if parameter and parameter.isdigit(): if parameter and parameter.isdigit():
repeat = int(parameter) repeat = int(parameter)
@ -619,11 +684,13 @@ def cmd_repeat(bot, user, text, command, parameter):
var.playlist.current_index + 1, var.playlist.current_index + 1,
music music
) )
logging.info("bot: add to playlist: " + util.format_debug_song_string(music)) log.info("bot: add to playlist: " + util.format_debug_song_string(music))
bot.send_msg(constants.strings("repeat", song=util.format_song_string(music), n=str(repeat)), text) bot.send_msg(constants.strings("repeat", song=util.format_song_string(music), n=str(repeat)), text)
def cmd_mode(bot, user, text, command, parameter): def cmd_mode(bot, user, text, command, parameter):
global log
if not parameter: if not parameter:
bot.send_msg(constants.strings("current_mode", mode=var.playlist.mode), text) bot.send_msg(constants.strings("current_mode", mode=var.playlist.mode), text)
return return
@ -632,7 +699,7 @@ def cmd_mode(bot, user, text, command, parameter):
else: else:
var.db.set('playlist', 'playback_mode', parameter) var.db.set('playlist', 'playback_mode', parameter)
var.playlist.set_mode(parameter) var.playlist.set_mode(parameter)
logging.info("command: playback mode changed to %s." % parameter) log.info("command: playback mode changed to %s." % parameter)
bot.send_msg(constants.strings("change_mode", mode=var.playlist.mode, bot.send_msg(constants.strings("change_mode", mode=var.playlist.mode,
user=bot.mumble.users[text.actor]['name']), text) user=bot.mumble.users[text.actor]['name']), text)
if parameter == "random": if parameter == "random":
@ -642,6 +709,8 @@ def cmd_mode(bot, user, text, command, parameter):
def cmd_drop_database(bot, user, text, command, parameter): def cmd_drop_database(bot, user, text, command, parameter):
global log
var.db.drop_table() var.db.drop_table()
var.db = Database(var.dbfile) var.db = Database(var.dbfile)
bot.send_msg(constants.strings('database_dropped'), text) bot.send_msg(constants.strings('database_dropped'), text)

View File

@ -79,6 +79,7 @@ enabled = False
is_web_proxified = True is_web_proxified = True
listening_addr = 127.0.0.1 listening_addr = 127.0.0.1
listening_port = 8181 listening_port = 8181
web_logfile =
# Set this option to True to enable password protection for the web interface # Set this option to True to enable password protection for the web interface
require_auth = False require_auth = False

View File

@ -93,6 +93,9 @@ port = 64738
#listening_port = 8181 #listening_port = 8181
#is_web_proxified = True #is_web_proxified = True
# 'web_logfile': write access logs of the web server into this file.
#web_logfile =
# 'required_auth': Set this to True to enable password protection for the web interface. # 'required_auth': Set this to True to enable password protection for the web interface.
#require_auth = False #require_auth = False
#user = #user =

View File

@ -56,7 +56,7 @@ class ReverseProxied(object):
web = Flask(__name__) web = Flask(__name__)
log = logging.getLogger("bot")
def init_proxy(): def init_proxy():
global web global web
@ -73,7 +73,7 @@ def check_auth(username, password):
def authenticate(): def authenticate():
"""Sends a 401 response that enables basic auth""" """Sends a 401 response that enables basic auth"""
logging.info("Web Interface login failed.") global log
return Response( return Response(
'Could not verify your access level for that URL.\n' 'Could not verify your access level for that URL.\n'
'You have to login with proper credentials', 401, 'You have to login with proper credentials', 401,
@ -82,10 +82,11 @@ def authenticate():
def requires_auth(f): def requires_auth(f):
@wraps(f) @wraps(f)
def decorated(*args, **kwargs): def decorated(*args, **kwargs):
global log
auth = request.authorization auth = request.authorization
if var.config.getboolean("webinterface", "require_auth") and (not auth or not check_auth(auth.username, auth.password)): if var.config.getboolean("webinterface", "require_auth") and (not auth or not check_auth(auth.username, auth.password)):
if auth: if auth:
logging.info("Web Interface login attempt, user: %s" % auth.username) log.info("web: Failed login attempt, user: %s" % auth.username)
return authenticate() return authenticate()
return f(*args, **kwargs) return f(*args, **kwargs)
return decorated return decorated
@ -148,10 +149,12 @@ def status():
@web.route("/post", methods=['POST']) @web.route("/post", methods=['POST'])
@requires_auth @requires_auth
def post(): def post():
global log
folder_path = var.music_folder folder_path = var.music_folder
if request.method == 'POST': if request.method == 'POST':
if request.form: if request.form:
logging.debug("Post request: "+ str(request.form)) log.debug("web: Post request from %s: %s" % ( request.remote_addr, str(request.form)))
if 'add_file_bottom' in request.form and ".." not in request.form['add_file_bottom']: if 'add_file_bottom' in request.form and ".." not in request.form['add_file_bottom']:
path = var.music_folder + request.form['add_file_bottom'] path = var.music_folder + request.form['add_file_bottom']
if os.path.isfile(path): if os.path.isfile(path):
@ -160,7 +163,7 @@ def post():
'title' : '', 'title' : '',
'user' : 'Remote Control'} 'user' : 'Remote Control'}
item = var.playlist.append(util.get_music_tag_info(item)) item = var.playlist.append(util.get_music_tag_info(item))
logging.info('web: add to playlist(bottom): ' + util.format_debug_song_string(item)) log.info('web: add to playlist(bottom): ' + util.format_debug_song_string(item))
elif 'add_file_next' in request.form and ".." not in request.form['add_file_next']: elif 'add_file_next' in request.form and ".." not in request.form['add_file_next']:
path = var.music_folder + request.form['add_file_next'] path = var.music_folder + request.form['add_file_next']
@ -173,7 +176,7 @@ def post():
var.playlist.current_index + 1, var.playlist.current_index + 1,
item item
) )
logging.info('web: add to playlist(next): ' + util.format_debug_song_string(item)) log.info('web: add to playlist(next): ' + util.format_debug_song_string(item))
elif ('add_folder' in request.form and ".." not in request.form['add_folder']) or ('add_folder_recursively' in request.form and ".." not in request.form['add_folder_recursively']): elif ('add_folder' in request.form and ".." not in request.form['add_folder']) or ('add_folder_recursively' in request.form and ".." not in request.form['add_folder_recursively']):
try: try:
@ -206,7 +209,7 @@ def post():
files = var.playlist.extend(files) files = var.playlist.extend(files)
for file in files: for file in files:
logging.info("web: add to playlist: %s" % util.format_debug_song_string(file)) log.info("web: add to playlist: %s" % util.format_debug_song_string(file))
elif 'add_url' in request.form: elif 'add_url' in request.form:
@ -217,7 +220,7 @@ def post():
music = var.botamusique.validate_music(music) music = var.botamusique.validate_music(music)
if music: if music:
var.playlist.append(music) var.playlist.append(music)
logging.info("web: add to playlist: " + util.format_debug_song_string(music)) log.info("web: add to playlist: " + util.format_debug_song_string(music))
if var.playlist.length() == 2: if var.playlist.length() == 2:
# If I am the second item on the playlist. (I am the next one!) # If I am the second item on the playlist. (I am the next one!)
var.botamusique.async_download_next() var.botamusique.async_download_next()
@ -226,11 +229,11 @@ def post():
music = var.playlist.append({'type': 'radio', music = var.playlist.append({'type': 'radio',
'path': request.form['add_radio'], 'path': request.form['add_radio'],
'user': "Remote Control"}) 'user': "Remote Control"})
logging.info("web: add to playlist: " + util.format_debug_song_string(music)) log.info("web: add to playlist: " + util.format_debug_song_string(music))
elif 'delete_music' in request.form: elif 'delete_music' in request.form:
music = var.playlist[int(request.form['delete_music'])] music = var.playlist[int(request.form['delete_music'])]
logging.info("web: delete from playlist: " + util.format_debug_song_string(music)) log.info("web: delete from playlist: " + util.format_debug_song_string(music))
if var.playlist.length() >= int(request.form['delete_music']): if var.playlist.length() >= int(request.form['delete_music']):
index = int(request.form['delete_music']) index = int(request.form['delete_music'])
@ -254,7 +257,7 @@ def post():
elif 'play_music' in request.form: elif 'play_music' in request.form:
music = var.playlist[int(request.form['play_music'])] music = var.playlist[int(request.form['play_music'])]
logging.info("web: jump to: " + util.format_debug_song_string(music)) log.info("web: jump to: " + util.format_debug_song_string(music))
if len(var.playlist) >= int(request.form['play_music']): if len(var.playlist) >= int(request.form['play_music']):
var.botamusique.interrupt_playing() var.botamusique.interrupt_playing()
@ -263,13 +266,13 @@ def post():
elif 'delete_music_file' in request.form and ".." not in request.form['delete_music_file']: elif 'delete_music_file' in request.form and ".." not in request.form['delete_music_file']:
path = var.music_folder + request.form['delete_music_file'] path = var.music_folder + request.form['delete_music_file']
if os.path.isfile(path): if os.path.isfile(path):
logging.info("web: delete file " + path) log.info("web: delete file " + path)
os.remove(path) os.remove(path)
elif 'delete_folder' in request.form and ".." not in request.form['delete_folder']: elif 'delete_folder' in request.form and ".." not in request.form['delete_folder']:
path = var.music_folder + request.form['delete_folder'] path = var.music_folder + request.form['delete_folder']
if os.path.isdir(path): if os.path.isdir(path):
logging.info("web: delete folder " + path) log.info("web: delete folder " + path)
shutil.rmtree(path) shutil.rmtree(path)
time.sleep(0.1) time.sleep(0.1)
@ -279,15 +282,15 @@ def post():
var.botamusique.interrupt_playing() var.botamusique.interrupt_playing()
var.playlist.set_mode("random") var.playlist.set_mode("random")
var.db.set('playlist', 'playback_mode', "random") var.db.set('playlist', 'playback_mode', "random")
logging.info("web: playback mode changed to random.") log.info("web: playback mode changed to random.")
if action == "one-shot": if action == "one-shot":
var.playlist.set_mode("one-shot") var.playlist.set_mode("one-shot")
var.db.set('playlist', 'playback_mode', "one-shot") var.db.set('playlist', 'playback_mode', "one-shot")
logging.info("web: playback mode changed to one-shot.") log.info("web: playback mode changed to one-shot.")
if action == "repeat": if action == "repeat":
var.playlist.set_mode("repeat") var.playlist.set_mode("repeat")
var.db.set('playlist', 'playback_mode', "repeat") var.db.set('playlist', 'playback_mode', "repeat")
logging.info("web: playback mode changed to repeat.") log.info("web: playback mode changed to repeat.")
elif action == "stop": elif action == "stop":
var.botamusique.stop() var.botamusique.stop()
elif action == "pause": elif action == "pause":
@ -302,19 +305,21 @@ def post():
else: else:
var.botamusique.volume_set = 1.0 var.botamusique.volume_set = 1.0
var.db.set('bot', 'volume', str(var.botamusique.volume_set)) var.db.set('bot', 'volume', str(var.botamusique.volume_set))
logging.info("web: volume up to %d" % (var.botamusique.volume_set * 100)) log.info("web: volume up to %d" % (var.botamusique.volume_set * 100))
elif action == "volume_down": elif action == "volume_down":
if var.botamusique.volume_set - 0.03 > 0: if var.botamusique.volume_set - 0.03 > 0:
var.botamusique.volume_set = var.botamusique.volume_set - 0.03 var.botamusique.volume_set = var.botamusique.volume_set - 0.03
else: else:
var.botamusique.volume_set = 0 var.botamusique.volume_set = 0
var.db.set('bot', 'volume', str(var.botamusique.volume_set)) var.db.set('bot', 'volume', str(var.botamusique.volume_set))
logging.info("web: volume up to %d" % (var.botamusique.volume_set * 100)) log.info("web: volume up to %d" % (var.botamusique.volume_set * 100))
return status() return status()
@web.route('/upload', methods=["POST"]) @web.route('/upload', methods=["POST"])
def upload(): def upload():
global log
files = request.files.getlist("file[]") files = request.files.getlist("file[]")
if not files: if not files:
return redirect("./", code=406) return redirect("./", code=406)
@ -331,10 +336,10 @@ def upload():
elif '../' in targetdir: elif '../' in targetdir:
return redirect("./", code=406) return redirect("./", code=406)
logging.info('Uploading file:') log.info('web: Uploading file from %s:' % request.remote_addr)
logging.info(' - filename: ' + filename) log.info('web: - filename: ' + filename)
logging.info(' - targetdir: ' + targetdir) log.info('web: - targetdir: ' + targetdir)
logging.info(' - mimetype: ' + file.mimetype) log.info('web: - mimetype: ' + file.mimetype)
if "audio" in file.mimetype: if "audio" in file.mimetype:
storagepath = os.path.abspath(os.path.join(var.music_folder, targetdir)) storagepath = os.path.abspath(os.path.join(var.music_folder, targetdir))
@ -349,7 +354,7 @@ def upload():
return redirect("./", code=500) return redirect("./", code=500)
filepath = os.path.join(storagepath, filename) filepath = os.path.join(storagepath, filename)
logging.info(' - filepath: ' + filepath) log.info(' - filepath: ' + filepath)
if os.path.exists(filepath): if os.path.exists(filepath):
return redirect("./", code=406) return redirect("./", code=406)
@ -362,8 +367,11 @@ def upload():
@web.route('/download', methods=["GET"]) @web.route('/download', methods=["GET"])
def download(): def download():
global log
if 'file' in request.args: if 'file' in request.args:
requested_file = request.args['file'] requested_file = request.args['file']
log.info('web: Download of file %s requested from %s:' % (requested_file, request.remote_addr))
if '../' not in requested_file: if '../' not in requested_file:
folder_path = var.music_folder folder_path = var.music_folder
files = util.get_recursive_filelist_sorted(var.music_folder) files = util.get_recursive_filelist_sorted(var.music_folder)
@ -373,7 +381,7 @@ def download():
try: try:
return send_file(filepath, as_attachment=True) return send_file(filepath, as_attachment=True)
except Exception as e: except Exception as e:
logging.exception(e) log.exception(e)
abort(404) abort(404)
elif 'directory' in request.args: elif 'directory' in request.args:
requested_dir = request.args['directory'] requested_dir = request.args['directory']
@ -388,7 +396,7 @@ def download():
try: try:
return send_file(zipfile, as_attachment=True) return send_file(zipfile, as_attachment=True)
except Exception as e: except Exception as e:
logging.exception(e) log.exception(e)
abort(404) abort(404)
return redirect("./", code=400) return redirect("./", code=400)

View File

@ -64,7 +64,7 @@ class PlayList(list):
return False return False
self.version += 1 self.version += 1
logging.debug("playlist: Next into the queue") #logging.debug("playlist: Next into the queue")
if self.current_index < len(self) - 1: if self.current_index < len(self) - 1:
if self.mode == "one-shot" and self.current_index != -1: if self.mode == "one-shot" and self.current_index != -1:

View File

@ -19,7 +19,7 @@ def get_radio_server_description(url):
response = urllib.request.urlopen(request) response = urllib.request.urlopen(request)
data = json.loads(response.read().decode("utf-8")) data = json.loads(response.read().decode("utf-8"))
title_server = data['servertitle'] title_server = data['servertitle']
logging.info("TITLE FOUND SHOUTCAST: " + title_server) # logging.info("TITLE FOUND SHOUTCAST: " + title_server)
except urllib.error.HTTPError: except urllib.error.HTTPError:
pass pass
except http.client.BadStatusLine: except http.client.BadStatusLine:
@ -40,7 +40,7 @@ def get_radio_server_description(url):
title_server = source['server_name'] title_server = source['server_name']
if 'server_description' in source: if 'server_description' in source:
title_server += ' - ' + source['server_description'] title_server += ' - ' + source['server_description']
logging.info("TITLE FOUND ICECAST: " + title_server) # logging.info("TITLE FOUND ICECAST: " + title_server)
if not title_server: if not title_server:
title_server = url title_server = url
except urllib.error.URLError: except urllib.error.URLError:

View File

@ -1,8 +1,12 @@
import logging import logging
import os import os
log = logging.getLogger("bot")
def get_size_folder(path): def get_size_folder(path):
global log
folder_size = 0 folder_size = 0
for (path, dirs, files) in os.walk(path): for (path, dirs, files) in os.walk(path):
for file in files: for file in files:
@ -12,6 +16,8 @@ def get_size_folder(path):
def clear_tmp_folder(path, size): def clear_tmp_folder(path, size):
global log
if size == -1: if size == -1:
return return
elif size == 0: elif size == 0:
@ -29,10 +35,10 @@ def clear_tmp_folder(path, size):
for idx, file in enumerate(all_files): for idx, file in enumerate(all_files):
size_tp += os.path.getsize(file) size_tp += os.path.getsize(file)
if int(size_tp / (1024 * 1024)) > size: if int(size_tp / (1024 * 1024)) > size:
logging.info("Cleaning tmp folder") log.info("Cleaning tmp folder")
to_remove = all_files[:idx] to_remove = all_files[:idx]
print(to_remove) print(to_remove)
for f in to_remove: for f in to_remove:
logging.debug("Removing " + f) log.debug("Removing " + f)
os.remove(os.path.join(path, f)) os.remove(os.path.join(path, f))
return return

View File

@ -14,11 +14,11 @@ import argparse
import os import os
import os.path import os.path
import pymumble.pymumble_py3 as pymumble import pymumble.pymumble_py3 as pymumble
import interface
import variables as var import variables as var
import hashlib import hashlib
import youtube_dl import youtube_dl
import logging import logging
import logging.handlers
import traceback import traceback
import util import util
@ -68,8 +68,8 @@ class MumbleBot:
version = 5 version = 5
def __init__(self, args): def __init__(self, args):
self.log = logging.getLogger("bot")
logging.info("bot: botamusique version %d, starting..." % self.version) self.log.info("bot: botamusique version %d, starting..." % self.version)
signal.signal(signal.SIGINT, self.ctrl_caught) signal.signal(signal.SIGINT, self.ctrl_caught)
self.cmd_handle = {} self.cmd_handle = {}
self.volume_set = var.config.getfloat('bot', 'volume') self.volume_set = var.config.getfloat('bot', 'volume')
@ -84,11 +84,11 @@ class MumbleBot:
self.channel = var.config.get("server", "channel", fallback=None) self.channel = var.config.get("server", "channel", fallback=None)
if args.verbose: if args.verbose:
root.setLevel(logging.DEBUG) self.log.setLevel(logging.DEBUG)
logging.debug("Starting in DEBUG loglevel") self.log.debug("Starting in DEBUG loglevel")
elif args.quiet: elif args.quiet:
root.setLevel(logging.ERROR) self.log.setLevel(logging.ERROR)
logging.error("Starting in ERROR loglevel") self.log.error("Starting in ERROR loglevel")
var.user = args.user var.user = args.user
var.music_folder = util.solve_filepath(var.config.get('bot', 'music_folder')) var.music_folder = util.solve_filepath(var.config.get('bot', 'music_folder'))
@ -106,10 +106,10 @@ class MumbleBot:
if var.config.getboolean("webinterface", "enabled"): if var.config.getboolean("webinterface", "enabled"):
wi_addr = var.config.get("webinterface", "listening_addr") wi_addr = var.config.get("webinterface", "listening_addr")
wi_port = var.config.getint("webinterface", "listening_port") wi_port = var.config.getint("webinterface", "listening_port")
interface.init_proxy()
tt = threading.Thread( tt = threading.Thread(
target=start_web_interface, name="WebThread", args=(wi_addr, wi_port)) target=start_web_interface, name="WebThread", args=(wi_addr, wi_port))
tt.daemon = True tt.daemon = True
self.log.info('Starting web interface on {}:{}'.format(wi_addr, wi_port))
tt.start() tt.start()
if var.config.getboolean("bot", "auto_check_update"): if var.config.getboolean("bot", "auto_check_update"):
@ -184,23 +184,23 @@ class MumbleBot:
# Set the CTRL+C shortcut # Set the CTRL+C shortcut
def ctrl_caught(self, signal, frame): def ctrl_caught(self, signal, frame):
logging.info( self.log.info(
"\nSIGINT caught, quitting, {} more to kill".format(2 - self.nb_exit)) "\nSIGINT caught, quitting, {} more to kill".format(2 - self.nb_exit))
self.exit = True self.exit = True
self.pause() self.pause()
if self.nb_exit > 1: if self.nb_exit > 1:
logging.info("Forced Quit") self.log.info("Forced Quit")
sys.exit(0) sys.exit(0)
self.nb_exit += 1 self.nb_exit += 1
def check_update(self): def check_update(self):
logging.debug("update: checking for updates...") self.log.debug("update: checking for updates...")
new_version = util.new_release_version() new_version = util.new_release_version()
if new_version > self.version: if new_version > self.version:
logging.info("update: new version %d found, current installed version %d." % (new_version, self.version)) self.log.info("update: new version %d found, current installed version %d." % (new_version, self.version))
self.send_msg(constants.strings('new_version_found')) self.send_msg(constants.strings('new_version_found'))
else: else:
logging.debug("update: no new version found.") self.log.debug("update: no new version found.")
def register_command(self, cmd, handle): def register_command(self, cmd, handle):
cmds = cmd.split(",") cmds = cmd.split(",")
@ -208,7 +208,7 @@ class MumbleBot:
command = command.strip() command = command.strip()
if command: if command:
self.cmd_handle[command] = handle self.cmd_handle[command] = handle
logging.debug("bot: command added: " + command) self.log.debug("bot: command added: " + command)
def set_comment(self): def set_comment(self):
self.mumble.users.myself.comment(var.config.get('bot', 'comment')) self.mumble.users.myself.comment(var.config.get('bot', 'comment'))
@ -240,7 +240,7 @@ class MumbleBot:
else: else:
return return
logging.info('bot: received command ' + command + ' - ' + parameter + ' by ' + user) self.log.info('bot: received command ' + command + ' - ' + parameter + ' by ' + user)
# Anti stupid guy function # Anti stupid guy function
if not self.is_admin(user) and not var.config.getboolean('bot', 'allow_other_channel_message') and self.mumble.users[text.actor]['channel_id'] != self.mumble.users.myself['channel_id']: if not self.is_admin(user) and not var.config.getboolean('bot', 'allow_other_channel_message') and self.mumble.users[text.actor]['channel_id'] != self.mumble.users.myself['channel_id']:
@ -281,7 +281,7 @@ class MumbleBot:
matches.append(cmd) matches.append(cmd)
if len(matches) == 1: if len(matches) == 1:
logging.info("bot: {:s} matches {:s}".format(command, matches[0])) self.log.info("bot: {:s} matches {:s}".format(command, matches[0]))
command_exc = matches[0] command_exc = matches[0]
self.cmd_handle[matches[0]](self, user, text, command, parameter) self.cmd_handle[matches[0]](self, user, text, command, parameter)
elif len(matches) > 1: elif len(matches) > 1:
@ -293,7 +293,7 @@ class MumbleBot:
except: except:
error_traceback = traceback.format_exc() error_traceback = traceback.format_exc()
error = error_traceback.rstrip().split("\n")[-1] error = error_traceback.rstrip().split("\n")[-1]
logging.error("bot: command %s failed with error: %s\n" % (command_exc, error_traceback)) self.log.error("bot: command %s failed with error: %s\n" % (command_exc, error_traceback))
self.send_msg(constants.strings('error_executing_command', command=command_exc, error=error), text) self.send_msg(constants.strings('error_executing_command', command=command_exc, error=error), text)
def send_msg(self, msg, text=None): def send_msg(self, msg, text=None):
@ -327,7 +327,7 @@ class MumbleBot:
else: else:
music = var.playlist.jump(index) music = var.playlist.jump(index)
logging.info("bot: play music " + util.format_debug_song_string(music)) self.log.info("bot: play music " + util.format_debug_song_string(music))
if music["type"] == "url": if music["type"] == "url":
# Delete older music is the tmp folder is too big # Delete older music is the tmp folder is too big
media.system.clear_tmp_folder(var.tmp_folder, var.config.getint('bot', 'tmp_folder_max_size')) media.system.clear_tmp_folder(var.tmp_folder, var.config.getint('bot', 'tmp_folder_max_size'))
@ -336,10 +336,10 @@ class MumbleBot:
if music["ready"] == "downloading": if music["ready"] == "downloading":
return return
elif music["ready"] != "yes" or not os.path.exists(music['path']): elif music["ready"] != "yes" or not os.path.exists(music['path']):
logging.info("bot: current music isn't ready, downloading...") self.log.info("bot: current music isn't ready, downloading...")
downloaded_music = self.download_music() downloaded_music = self.download_music()
if not downloaded_music: if not downloaded_music:
logging.info("bot: removing music from the playlist: %s" % util.format_debug_song_string(music)) self.log.info("bot: removing music from the playlist: %s" % util.format_debug_song_string(music))
var.playlist.remove(index) var.playlist.remove(index)
return return
music = downloaded_music music = downloaded_music
@ -353,7 +353,7 @@ class MumbleBot:
elif music["type"] == "radio": elif music["type"] == "radio":
uri = music["url"] uri = music["url"]
if 'title' not in music: if 'title' not in music:
logging.info("bot: fetching radio server description") self.log.info("bot: fetching radio server description")
title = media.radio.get_radio_server_description(uri) title = media.radio.get_radio_server_description(uri)
music["title"] = title music["title"] = title
@ -367,7 +367,7 @@ class MumbleBot:
command = ("ffmpeg", '-v', ffmpeg_debug, '-nostdin', '-i', command = ("ffmpeg", '-v', ffmpeg_debug, '-nostdin', '-i',
uri, '-ac', '1', '-f', 's16le', '-ar', '48000', '-') uri, '-ac', '1', '-f', 's16le', '-ar', '48000', '-')
logging.info("bot: execute ffmpeg command: " + " ".join(command)) self.log.debug("bot: execute ffmpeg command: " + " ".join(command))
# The ffmpeg process is a thread # The ffmpeg process is a thread
# prepare pipe for catching stderr of ffmpeg # prepare pipe for catching stderr of ffmpeg
@ -391,18 +391,18 @@ class MumbleBot:
# Download only if music is not existed # Download only if music is not existed
if os.path.isfile(mp3): if os.path.isfile(mp3):
logging.info("bot: file existed for url %s " % music['url']) self.log.info("bot: file existed for url %s " % music['url'])
music['ready'] = 'yes' music['ready'] = 'yes'
return music return music
music = media.url.get_url_info(music) music = media.url.get_url_info(music)
logging.info("bot: verifying the duration of url %s " % music['url']) self.log.info("bot: verifying the duration of url %s " % music['url'])
if music: if music:
if music['duration'] > var.config.getint('bot', 'max_track_duration'): if music['duration'] > var.config.getint('bot', 'max_track_duration'):
# Check the length, useful in case of playlist, it wasn't checked before) # Check the length, useful in case of playlist, it wasn't checked before)
logging.info( self.log.info(
"the music " + music["url"] + " has a duration of " + music['duration'] + "s -- too long") "the music " + music["url"] + " has a duration of " + music['duration'] + "s -- too long")
self.send_msg(constants.strings('too_long')) self.send_msg(constants.strings('too_long'))
return False return False
@ -411,7 +411,7 @@ class MumbleBot:
return music return music
else: else:
logging.error("bot: error while fetching info from the URL") self.log.error("bot: error while fetching info from the URL")
self.send_msg(constants.strings('unable_download')) self.send_msg(constants.strings('unable_download'))
return False return False
@ -438,7 +438,7 @@ class MumbleBot:
music['ready'] = "downloading" music['ready'] = "downloading"
logging.info("bot: downloading url (%s) %s " % (music['title'], url)) self.log.info("bot: downloading url (%s) %s " % (music['title'], url))
ydl_opts = "" ydl_opts = ""
ydl_opts = { ydl_opts = {
@ -459,7 +459,7 @@ class MumbleBot:
attempts = var.config.getint('bot', 'download_attempts', fallback=2) attempts = var.config.getint('bot', 'download_attempts', fallback=2)
download_succeed = False download_succeed = False
for i in range(attempts): for i in range(attempts):
logging.info("bot: download attempts %d / %d" % (i+1, attempts)) self.log.info("bot: download attempts %d / %d" % (i+1, attempts))
try: try:
ydl.extract_info(url) ydl.extract_info(url)
if os.path.exists(mp3) and os.stat(mp3).st_size > 0: if os.path.exists(mp3) and os.stat(mp3).st_size > 0:
@ -467,19 +467,19 @@ class MumbleBot:
download_succeed = True download_succeed = True
break break
else: else:
logging.error("bot: download failed: file not existed or file size is 0.") self.log.error("bot: download failed: file not existed or file size is 0.")
except: except:
error_traceback = traceback.format_exc() error_traceback = traceback.format_exc()
logging.error("bot: download failed with error:\n %s" % error_traceback) self.log.error("bot: download failed with error:\n %s" % error_traceback)
if not download_succeed: if not download_succeed:
self.send_msg(constants.strings('unable_download')) self.send_msg(constants.strings('unable_download'))
return False return False
else: else:
logging.info("bot: music file existed, skip downloading " + mp3) self.log.info("bot: music file existed, skip downloading " + mp3)
music['ready'] = "yes" music['ready'] = "yes"
logging.info("bot: finished downloading url (%s) %s, saved to %s." % (music['title'], url, music['path'])) self.log.info("bot: finished downloading url (%s) %s, saved to %s." % (music['title'], url, music['path']))
music = util.get_music_tag_info(music) music = util.get_music_tag_info(music)
var.playlist.update(music, index) var.playlist.update(music, index)
@ -488,12 +488,12 @@ class MumbleBot:
def async_download_next(self): def async_download_next(self):
# Function start if the next music isn't ready # Function start if the next music isn't ready
# Do nothing in case the next music is already downloaded # Do nothing in case the next music is already downloaded
logging.debug("bot: Async download next asked ") self.log.debug("bot: Async download next asked ")
if var.playlist.length() > 1 and var.playlist.next_item()['type'] == 'url' \ if var.playlist.length() > 1 and var.playlist.next_item()['type'] == 'url' \
and (var.playlist.next_item()['ready'] in ["no", "validation"]): and (var.playlist.next_item()['ready'] in ["no", "validation"]):
th = threading.Thread( th = threading.Thread(
target=self.download_music, name="DownloadThread", args=(var.playlist.next_index(),)) target=self.download_music, name="DownloadThread", args=(var.playlist.next_index(),))
logging.info( self.log.info(
"bot: start downloading item in thread: " + util.format_debug_song_string(var.playlist.next_item())) "bot: start downloading item in thread: " + util.format_debug_song_string(var.playlist.next_item()))
th.daemon = True th.daemon = True
th.start() th.start()
@ -520,7 +520,7 @@ class MumbleBot:
elif music["type"] == "file": elif music["type"] == "file":
uri = var.music_folder + music["path"] uri = var.music_folder + music["path"]
if not os.path.exists(uri): if not os.path.exists(uri):
logging.info("bot: music file missed. removing music from the playlist: %s" % util.format_debug_song_string(music)) self.log.info("bot: music file missed. removing music from the playlist: %s" % util.format_debug_song_string(music))
self.send_msg(constants.strings('file_missed', file=music["path"])) self.send_msg(constants.strings('file_missed', file=music["path"]))
var.playlist.remove(index) var.playlist.remove(index)
return False return False
@ -551,7 +551,7 @@ class MumbleBot:
try: try:
stderr_msg = self.thread_stderr.readline() stderr_msg = self.thread_stderr.readline()
if stderr_msg: if stderr_msg:
logging.debug("ffmpeg: " + stderr_msg.strip("\n")) self.log.debug("ffmpeg: " + stderr_msg.strip("\n"))
except: except:
pass pass
@ -578,7 +578,7 @@ class MumbleBot:
if self.exit: if self.exit:
if var.config.getboolean('bot', 'save_playlist', fallback=True): if var.config.getboolean('bot', 'save_playlist', fallback=True):
logging.info("bot: save playlist into database") self.log.info("bot: save playlist into database")
var.playlist.save() var.playlist.save()
def volume_cycle(self): def volume_cycle(self):
@ -599,7 +599,7 @@ class MumbleBot:
def ducking_sound_received(self, user, sound): def ducking_sound_received(self, user, sound):
if audioop.rms(sound.pcm, 2) > self.ducking_threshold: if audioop.rms(sound.pcm, 2) > self.ducking_threshold:
if self.on_ducking is False: if self.on_ducking is False:
logging.debug("bot: ducking triggered") self.log.debug("bot: ducking triggered")
self.on_ducking = True self.on_ducking = True
self.ducking_release = time.time() + 1 # ducking release after 1s self.ducking_release = time.time() + 1 # ducking release after 1s
@ -613,7 +613,7 @@ class MumbleBot:
self.thread.kill() self.thread.kill()
self.thread = None self.thread = None
var.playlist.clear() var.playlist.clear()
logging.info("bot: music stopped. playlist trashed.") self.log.info("bot: music stopped. playlist trashed.")
def stop(self): def stop(self):
# stop and move to the next item in the playlist # stop and move to the next item in the playlist
@ -621,7 +621,7 @@ class MumbleBot:
self.interrupt_playing() self.interrupt_playing()
self.playhead = 0 self.playhead = 0
var.playlist.next() var.playlist.next()
logging.info("bot: music stopped.") self.log.info("bot: music stopped.")
def interrupt_playing(self): def interrupt_playing(self):
# Kill the ffmpeg thread # Kill the ffmpeg thread
@ -637,7 +637,7 @@ class MumbleBot:
self.thread = None self.thread = None
self.is_pause = True self.is_pause = True
self.song_start_at = -1 self.song_start_at = -1
logging.info("bot: music paused at %.2f seconds." % self.playhead) self.log.info("bot: music paused at %.2f seconds." % self.playhead)
def resume(self): def resume(self):
self.is_pause = False self.is_pause = False
@ -656,7 +656,7 @@ class MumbleBot:
else: else:
ffmpeg_debug = "warning" ffmpeg_debug = "warning"
logging.info("bot: resume music at %.2f seconds" % self.playhead) self.log.info("bot: resume music at %.2f seconds" % self.playhead)
uri = "" uri = ""
if music["type"] == "url": if music["type"] == "url":
@ -672,7 +672,7 @@ class MumbleBot:
if var.config.getboolean('bot', 'announce_current_music'): if var.config.getboolean('bot', 'announce_current_music'):
self.send_msg(util.format_current_playing()) self.send_msg(util.format_current_playing())
logging.info("bot: execute ffmpeg command: " + " ".join(command)) self.log.info("bot: execute ffmpeg command: " + " ".join(command))
# The ffmpeg process is a thread # The ffmpeg process is a thread
# prepare pipe for catching stderr of ffmpeg # prepare pipe for catching stderr of ffmpeg
pipe_rd, pipe_wd = os.pipe() pipe_rd, pipe_wd = os.pipe()
@ -688,12 +688,26 @@ class MumbleBot:
user.sound.lock.acquire() user.sound.lock.acquire()
user.sound.queue.clear() user.sound.queue.clear()
user.sound.lock.release() user.sound.lock.release()
logging.debug("bot: pymumble soundqueue cleared.") self.log.debug("bot: pymumble soundqueue cleared.")
def start_web_interface(addr, port): def start_web_interface(addr, port):
logging.info('Starting web interface on {}:{}'.format(addr, port)) global formatter
import interface
# setup logger
werkzeug_logger = logging.getLogger('werkzeug')
logfile = util.solve_filepath(var.config.get('webinterface', 'web_logfile'))
handler = None
if logfile:
handler = logging.handlers.RotatingFileHandler(logfile, mode='a', maxBytes=10240) # Rotate after 10KB
else:
handler = logging.StreamHandler()
werkzeug_logger.addHandler(handler)
interface.init_proxy()
interface.web.run(port=port, host=addr) interface.web.run(port=port, host=addr)
@ -744,20 +758,20 @@ if __name__ == '__main__':
var.db = Database(var.dbfile) var.db = Database(var.dbfile)
# Setup logger # Setup logger
root = logging.getLogger() bot_logger = logging.getLogger("bot")
formatter = logging.Formatter('[%(asctime)s %(levelname)s %(threadName)s] %(message)s', "%b %d %H:%M:%S") formatter = logging.Formatter('[%(asctime)s %(levelname)s %(threadName)s] %(message)s', "%b %d %H:%M:%S")
root.setLevel(logging.INFO) bot_logger.setLevel(logging.INFO)
logfile = util.solve_filepath(var.config.get('bot', 'logfile')) logfile = util.solve_filepath(var.config.get('bot', 'logfile'))
handler = None handler = None
if logfile: if logfile:
handler = logging.FileHandler(logfile) handler = logging.handlers.RotatingFileHandler(logfile, mode='a', maxBytes=10240) # Rotate after 10KB
else: else:
handler = logging.StreamHandler(sys.stdout) handler = logging.StreamHandler()
handler.setFormatter(formatter) handler.setFormatter(formatter)
root.addHandler(handler) bot_logger.addHandler(handler)
var.bot_logger = bot_logger
var.playlist = PlayList() # playlist should be initialized after the database var.playlist = PlayList() # playlist should be initialized after the database
var.botamusique = MumbleBot(args) var.botamusique = MumbleBot(args)
@ -765,7 +779,7 @@ if __name__ == '__main__':
# load playlist # load playlist
if var.config.getboolean('bot', 'save_playlist', fallback=True): if var.config.getboolean('bot', 'save_playlist', fallback=True):
logging.info("bot: load playlist from previous session") var.bot_logger.info("bot: load playlist from previous session")
var.playlist.load() var.playlist.load()
# load playback mode # load playback mode

12
util.py
View File

@ -22,6 +22,8 @@ import base64
import media import media
import media.radio import media.radio
log = logging.getLogger("bot")
def solve_filepath(path): def solve_filepath(path):
if not path: if not path:
return '' return ''
@ -261,17 +263,19 @@ def new_release_version():
return v return v
def update(version): def update(version):
global log
v = new_release_version() v = new_release_version()
if v > version: if v > version:
logging.info('update: new version, start updating...') log.info('update: new version, start updating...')
tp = sp.check_output(['/usr/bin/env', 'bash', 'update.sh']).decode() tp = sp.check_output(['/usr/bin/env', 'bash', 'update.sh']).decode()
logging.debug(tp) log.debug(tp)
logging.info('update: update pip librairies dependancies') log.info('update: update pip librairies dependancies')
tp = sp.check_output([var.config.get('bot', 'pip3_path'), 'install', '--upgrade', '-r', 'requirements.txt']).decode() tp = sp.check_output([var.config.get('bot', 'pip3_path'), 'install', '--upgrade', '-r', 'requirements.txt']).decode()
msg = "New version installed, please restart the bot." msg = "New version installed, please restart the bot."
else: else:
logging.info('update: starting update youtube-dl via pip3') log.info('update: starting update youtube-dl via pip3')
tp = sp.check_output([var.config.get('bot', 'pip3_path'), 'install', '--upgrade', 'youtube-dl']).decode() tp = sp.check_output([var.config.get('bot', 'pip3_path'), 'install', '--upgrade', 'youtube-dl']).decode()
msg = "" msg = ""
if "Requirement already up-to-date" in tp: if "Requirement already up-to-date" in tp:

View File

@ -8,5 +8,7 @@ dbfile = None
db = None db = None
config = None config = None
bot_logger = None
music_folder = "" music_folder = ""
tmp_folder = "" tmp_folder = ""