def cmd_find_tagged(bot, user, text, command, parameter): global song_shortlist if not parameter: bot.send_msg(constants.strings('bad_parameter', command=command), text) return msgs = [constants.strings('multiple_file_found') + "<ul>"] count = 0 tags = parameter.split(",") tags = list(map(lambda t: t.strip(), tags)) music_dicts = var.music_db.query_music_by_tags(tags) song_shortlist = music_dicts for i, music_dict in enumerate(music_dicts): item = dict_to_item(bot, music_dict) count += 1 if count > ITEMS_PER_PAGE: break msgs.append("<li><b>{:d}</b> - <b>{}</b> (<i>{}</i>)</li>".format( i + 1, item.title, ", ".join(item.tags))) if count != 0: msgs.append("</ul>") if count > ITEMS_PER_PAGE: msgs.append(constants.strings("records_omitted")) msgs.append(constants.strings("shortlist_instruction")) send_multi_lines(bot, msgs, text, "") else: bot.send_msg(constants.strings("no_file"), text)
def cmd_yt_search(bot, user, text, command, parameter): global log, yt_last_result, yt_last_page, song_shortlist item_per_page = 5 if parameter: # if next page if parameter.startswith("-n"): yt_last_page += 1 if len(yt_last_result) > yt_last_page * item_per_page: song_shortlist = [{'type': 'url', 'url': "https://www.youtube.com/watch?v=" + result[0], 'title': result[1] } for result in yt_last_result[yt_last_page * item_per_page: item_per_page]] msg = _yt_format_result(yt_last_result, yt_last_page * item_per_page, item_per_page) bot.send_msg(constants.strings('yt_result', result_table=msg), text) else: bot.send_msg(constants.strings('yt_no_more'), text) # if query else: results = util.youtube_search(parameter) if results: yt_last_result = results yt_last_page = 0 song_shortlist = [{'type': 'url', 'url': "https://www.youtube.com/watch?v=" + result[0]} for result in results[0: item_per_page]] msg = _yt_format_result(results, 0, item_per_page) bot.send_msg(constants.strings('yt_result', result_table=msg), text) else: bot.send_msg(constants.strings('yt_query_error'), text) else: bot.send_msg(constants.strings('bad_parameter', command=command), text)
def cmd_play(bot, user, text, command, parameter): global log if len(var.playlist) > 0: if parameter: if parameter.isdigit() and 1 <= int(parameter) <= len( var.playlist): # First "-1" transfer 12345 to 01234, second "-1" # point to the previous item. the loop will next to # the one you want var.playlist.point_to(int(parameter) - 1 - 1) if not bot.is_pause: bot.interrupt() else: bot.is_pause = False else: bot.send_msg( constants.strings('invalid_index', index=parameter), text) elif bot.is_pause: bot.resume() else: bot.send_msg(var.playlist.current_item().format_current_playing(), text) else: bot.is_pause = False bot.send_msg(constants.strings('queue_empty'), text)
def cmd_list_file(bot, user, text, command, parameter): global song_shortlist files = var.music_db.query_music(Condition() .and_equal('type', 'file') .order_by('path')) song_shortlist = files msgs = [constants.strings("multiple_file_found") + "<ul>"] try: count = 0 for index, file in enumerate(files): if parameter: match = re.search(parameter, file['path']) if not match: continue count += 1 if count > ITEMS_PER_PAGE: break msgs.append("<li><b>{:d}</b> - <b>{:s}</b> ({:s})</li>".format(index + 1, file['title'], file['path'])) if count != 0: msgs.append("</ul>") if count > ITEMS_PER_PAGE: msgs.append(constants.strings("records_omitted")) msgs.append(constants.strings("shortlist_instruction")) send_multi_lines(bot, msgs, text, "") else: bot.send_msg(constants.strings("no_file"), text) except re.error as e: msg = constants.strings('wrong_pattern', error=str(e)) bot.send_msg(msg, text)
def cmd_play_radio(bot, user, text, command, parameter): global log if not parameter: all_radio = var.config.items('radio') msg = constants.strings('preconfigurated_radio') for i in all_radio: comment = "" if len(i[1].split(maxsplit=1)) == 2: comment = " - " + i[1].split(maxsplit=1)[1] msg += "<br />" + i[0] + comment bot.send_msg(msg, text) else: if var.config.has_option('radio', parameter): parameter = var.config.get('radio', parameter) parameter = parameter.split()[0] url = util.get_url_from_input(parameter) if url: music_wrapper = get_cached_wrapper_from_scrap(bot, type='radio', url=url, user=user) var.playlist.append(music_wrapper) log.info("cmd: add to playlist: " + music_wrapper.format_debug_string()) bot.send_msg( constants.strings('file_added', item=music_wrapper.format_song_string())) else: bot.send_msg(constants.strings('bad_url'))
def prepare_die(bot, user, parameter, sort=False): global log try: result = [] add_value = 0 dices = parameter if '+' in parameter or '-' in parameter: plus = True if '+' in parameter else False dices = parameter.split('+')[0] if plus else parameter.split('-')[0] add_value = int(parameter.split('+')[1]) if plus else int(parameter.split('-')[1]) rolls = int(dices.split('d')[0]) dice_value = int(dices.split('d')[1]) for r in range(rolls): result.append(*random.choices([x+1 for x in range(dice_value)])) total = sum(result) if add_value: total = total + add_value if plus else total - add_value if sort: result.sort() bot.send_channel_msg(constants.strings('roll', user=user, param=parameter, roll=result)) bot.send_channel_msg(constants.strings('total', total=total)) except: bot.send_channel_msg(constants.strings('bad_roll')) return
def cmd_url_ban(bot, user, text, command, parameter): global log if bot.is_admin(user): if parameter: bot.mumble.users[text.actor].send_text_message( util.url_ban(util.get_url_from_input(parameter))) id = item_id_generators['url'](url=parameter) var.cache.free_and_delete(id) var.playlist.remove_by_id(id) else: if var.playlist.current_item() and var.playlist.current_item( ).type == 'url': item = var.playlist.current_item().item() bot.mumble.users[text.actor].send_text_message( util.url_ban(util.get_url_from_input(item.url))) var.cache.free_and_delete(item.id) var.playlist.remove_by_id(item.id) else: bot.send_msg( constants.strings('bad_parameter', command=command)) else: bot.mumble.users[text.actor].send_text_message( constants.strings('not_admin')) return
def cmd_remove(bot, user, text, command, parameter): global log # Allow to remove specific music into the queue with a number if parameter and parameter.isdigit() and 0 < int(parameter) <= len( var.playlist): index = int(parameter) - 1 if index == var.playlist.current_index: removed = var.playlist[index] bot.send_msg( constants.strings('removing_item', item=removed.format_short_string()), text) log.info("cmd: delete from playlist: " + removed.format_debug_string()) var.playlist.remove(index) if index < len(var.playlist): if not bot.is_pause: bot.interrupt() var.playlist.current_index -= 1 # then the bot will move to next item else: # if item deleted is the last item of the queue var.playlist.current_index -= 1 if not bot.is_pause: bot.interrupt() else: var.playlist.remove(index) else: bot.send_msg(constants.strings('bad_parameter', command=command), text)
def cmd_refresh_cache(bot, user, text, command, parameter): global log if bot.is_admin(user): var.cache.build_dir_cache() log.info("command: Local file cache refreshed.") bot.send_msg(constants.strings('cache_refreshed'), text) else: bot.mumble.users[text.actor].send_text_message(constants.strings('not_admin'))
def cmd_update(bot, user, text, command, parameter): global log if bot.is_admin(user): bot.mumble.users[text.actor].send_text_message( constants.strings('start_updating')) msg = util.update(bot.version) bot.mumble.users[text.actor].send_text_message(msg) else: bot.mumble.users[text.actor].send_text_message( constants.strings('not_admin'))
def cmd_drop_database(bot, user, text, command, parameter): global log if bot.is_admin(user): var.db.drop_table() var.db = SettingsDatabase(var.dbfile) var.music_db.drop_table() var.music_db = MusicDatabase(var.dbfile) log.info("command: database dropped.") bot.send_msg(constants.strings('database_dropped'), text) else: bot.mumble.users[text.actor].send_text_message(constants.strings('not_admin'))
def cmd_volume(bot, user, text, command, parameter): global log # The volume is a percentage if parameter and parameter.isdigit() and 0 <= int(parameter) <= 100: bot.volume_set = float(float(parameter) / 100) bot.send_msg(constants.strings('change_volume', volume=int(bot.volume_set * 100), user=bot.mumble.users[text.actor]['name']), text) var.db.set('bot', 'volume', str(bot.volume_set)) log.info('cmd: volume set to %d' % (bot.volume_set * 100)) else: bot.send_msg(constants.strings('current_volume', volume=int(bot.volume_set * 100)), text)
def cmd_play_file_match(bot, user, text, command, parameter, do_not_refresh_cache=False): global log if parameter: file_dicts = var.music_db.query_music(Condition().and_equal( 'type', 'file')) msgs = [constants.strings('multiple_file_added') + "<ul>"] try: count = 0 music_wrappers = [] for file_dict in file_dicts: file = file_dict['title'] match = re.search(parameter, file) if match and match[0]: count += 1 music_wrapper = get_cached_wrapper( dict_to_item(bot, file_dict), user) music_wrappers.append(music_wrapper) log.info("cmd: add to playlist: " + music_wrapper.format_debug_string()) msgs.append("<li><b>{}</b> ({})</li>".format( music_wrapper.item().title, file[:match.span()[0]] + "<b style='color:pink'>" + file[match.span()[0]:match.span()[1]] + "</b>" + file[match.span()[1]:])) if count != 0: msgs.append("</ul>") var.playlist.extend(music_wrappers) send_multi_lines(bot, msgs, None, "") else: if do_not_refresh_cache: bot.send_msg(constants.strings("no_file"), text) else: var.cache.build_dir_cache(bot) cmd_play_file_match(bot, user, text, command, parameter, do_not_refresh_cache=True) except re.error as e: msg = constants.strings('wrong_pattern', error=str(e)) bot.send_msg(msg, text) else: bot.send_msg(constants.strings('bad_parameter', command=command))
def cmd_yt_play(bot, user, text, command, parameter): global log, yt_last_result, yt_last_page if parameter: results = util.youtube_search(parameter) if results: yt_last_result = results yt_last_page = 0 url = "https://www.youtube.com/watch?v=" + yt_last_result[0][0] cmd_play_url(bot, user, text, command, url) else: bot.send_msg(constants.strings('yt_query_error')) else: bot.send_msg(constants.strings('bad_parameter', command=command), text)
def cmd_remove_tag(bot, user, text, command, parameter): global log params = parameter.split(" ", 1) index = 0 tags = [] if len(params) == 2 and params[0].isdigit(): index = params[0] tags = list(map(lambda t: t.strip(), params[1].split(","))) elif len(params) == 2 and params[0] == "*": index = "*" tags = list(map(lambda t: t.strip(), params[1].split(","))) else: index = str(var.playlist.current_index + 1) tags = list(map(lambda t: t.strip(), parameter.split(","))) if tags[0]: if index.isdigit() and 1 <= int(index) <= len(var.playlist): if tags[0] != "*": var.playlist[int(index) - 1].remove_tags(tags) log.info("cmd: remove tags %s from song %s" % (", ".join(tags), var.playlist[int(index) - 1].format_debug_string())) bot.send_msg(constants.strings("removed_tags", tags=", ".join(tags), song=var.playlist[int(index) - 1].format_title()), text) return else: var.playlist[int(index) - 1].clear_tags() log.info("cmd: clear tags from song %s" % (var.playlist[int(index) - 1].format_debug_string())) bot.send_msg(constants.strings("cleared_tags", song=var.playlist[int(index) - 1].format_title()), text) return elif index == "*": if tags[0] != "*": for item in var.playlist: item.remove_tags(tags) log.info("cmd: remove tags %s from song %s" % (", ".join(tags), item.format_debug_string())) bot.send_msg(constants.strings("removed_tags_from_all", tags=", ".join(tags)), text) return else: for item in var.playlist: item.clear_tags() log.info("cmd: clear tags from song %s" % (item.format_debug_string())) bot.send_msg(constants.strings("cleared_tags_from_all"), text) return bot.send_msg(constants.strings('bad_parameter', command=command), text)
def cmd_play_url(bot, user, text, command, parameter): global log url = util.get_url_from_input(parameter) if url: music_wrapper = get_cached_wrapper_from_scrap(type='url', url=url, user=user) var.playlist.append(music_wrapper) log.info("cmd: add to playlist: " + music_wrapper.format_debug_string()) bot.send_msg(constants.strings('file_added', item=music_wrapper.format_song_string()), text) if len(var.playlist) == 2: # If I am the second item on the playlist. (I am the next one!) bot.async_download_next() else: bot.send_msg(constants.strings('bad_parameter', command=command), text)
def cmd_current_music(bot, user, text, command, parameter): global log if len(var.playlist) > 0: bot.send_msg(var.playlist.current_item().format_current_playing(), text) else: bot.send_msg(constants.strings('not_playing'), text)
def cmd_url_ban_list(bot, user, text, command, parameter): if bot.is_admin(user): bot.mumble.users[text.actor].send_text_message(util.get_url_ban()) else: bot.mumble.users[text.actor].send_text_message( constants.strings('not_admin')) return
def validate(self): self.validating_lock.acquire() if self.ready in ['yes', 'validated']: self.validating_lock.release() return True # if self.ready == 'failed': # self.validating_lock.release() # return False # if os.path.exists(self.path): self.validating_lock.release() self.ready = "yes" return True # avoid multiple process validating in the meantime info = self._get_info_from_url() self.validating_lock.release() if not info: return False if self.duration > var.config.getint('bot', 'max_track_duration') != 0: # Check the length, useful in case of playlist, it wasn't checked before) log.info("url: " + self.url + " has a duration of " + str(self.duration) + " min -- too long") raise ValidationFailedError( constants.strings('too_long', song=self.title)) else: self.ready = "validated" self.version += 1 # notify wrapper to save me return True
def format_song_string(self, user): if self.ready in ['validated', 'yes']: return constants.strings("url_item", title=self.title if self.title else "??", url=self.url, user=user) return self.url
def format_song_string(self, user): return constants.strings("url_from_playlist_item", title=self.title, url=self.url, playlist_url=self.playlist_url, playlist=self.playlist_title, user=user)
def format_song_string(self, user): return constants.strings( "radio_item", url=self.url, title=get_radio_title(self.url), # the title of current song name=self.title, # the title of radio station user=user)
def _get_info_from_url(self): self.log.info("url: fetching metadata of url %s " % self.url) ydl_opts = {'noplaylist': True} succeed = False with youtube_dl.YoutubeDL(ydl_opts) as ydl: attempts = var.config.getint('bot', 'download_attempts', fallback=2) for i in range(attempts): try: info = ydl.extract_info(self.url, download=False) self.duration = info['duration'] / 60 self.title = info['title'] self.keywords = info['title'] succeed = True return True except youtube_dl.utils.DownloadError: pass except KeyError: # info has no 'duration' break if not succeed: self.ready = 'failed' self.log.error("url: error while fetching info from the URL") raise ValidationFailedError( constants.strings('unable_download', item=self.format_title()))
def cmd_skip(bot, user, text, command, parameter): global log bot.interrupt() if len(var.playlist) == 0: bot.send_msg(constants.strings('queue_empty'), text)
def format_current_playing(self, user): display = constants.strings("now_playing", item=self.format_song_string(user)) if self.thumbnail: thumbnail_html = '<img width="80" src="data:image/jpge;base64,' + \ self.thumbnail + '"/>' display += "<br />" + thumbnail_html return display
def check_update(self): self.log.debug("update: checking for updates...") new_version = util.new_release_version() if version.parse(new_version) > version.parse(self.version): self.log.info("update: new version %s found, current installed version %s." % (new_version, self.version)) self.send_channel_msg(constants.strings('new_version_found')) else: self.log.debug("update: no new version found.")
def cmd_mode(bot, user, text, command, parameter): global log if not parameter: bot.send_msg(constants.strings("current_mode", mode=var.playlist.mode), text) return if parameter not in ["one-shot", "repeat", "random", "autoplay"]: bot.send_msg(constants.strings('unknown_mode', mode=parameter), text) else: var.db.set('playlist', 'playback_mode', parameter) var.playlist = media.playlist.get_playlist(parameter, var.playlist) log.info("command: playback mode changed to %s." % parameter) bot.send_msg(constants.strings("change_mode", mode=var.playlist.mode, user=bot.mumble.users[text.actor]['name']), text) if parameter == "random": bot.interrupt() bot.launch_music()
def cmd_last(bot, user, text, command, parameter): global log if len(var.playlist) > 0: bot.interrupt() var.playlist.point_to(len(var.playlist) - 1 - 1) else: bot.send_msg(constants.strings('queue_empty'), text)
def cmd_stop(bot, user, text, command, parameter): global log if var.config.getboolean("bot", "clear_when_stop_in_oneshot", fallback=False) \ and var.playlist.mode == 'one-shot': cmd_clear(bot, user, text, command, parameter) else: bot.stop() bot.send_msg(constants.strings('stopped'), text)
def cmd_kill(bot, user, text, command, parameter): global log if bot.is_admin(user): bot.pause() bot.exit = True else: bot.mumble.users[text.actor].send_text_message( constants.strings('not_admin'))