diff --git a/command.py b/command.py index 3bb411e..8082cf8 100644 --- a/command.py +++ b/command.py @@ -32,6 +32,8 @@ def register_all_commands(bot): bot.register_command(constants.commands('play_radio'), cmd_play_radio) bot.register_command(constants.commands('rb_query'), cmd_rb_query) bot.register_command(constants.commands('rb_play'), cmd_rb_play) + bot.register_command(constants.commands('yt_query'), cmd_yt_query) + bot.register_command(constants.commands('yt_play'), cmd_yt_play) bot.register_command(constants.commands('help'), cmd_help) bot.register_command(constants.commands('stop'), cmd_stop) bot.register_command(constants.commands('clear'), cmd_clear) @@ -439,6 +441,55 @@ def cmd_rb_play(bot, user, text, command, parameter): msg += "No playable url found for this station, please try another station." bot.send_msg(msg, text) +yt_last_result = None +yt_last_page = 0 # TODO: if we keep adding global variables, we need to consider sealing all commands up into classes. + +def cmd_yt_query(bot, user, text, command, parameter): + global log, yt_last_result, yt_last_page + 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: + 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')) + + # if query + else: + results = util.youtube_search(parameter) + if results: + yt_last_result = results + yt_last_page = 0 + 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')) + else: + bot.send_msg(constants.strings('bad_parameter', command=command), text) + +def _yt_format_result(results, start, count): + msg = '' + for index, item in enumerate(results[start:start+count]): + msg += ''.format( + index=index + 1 + start, title=item[1], uploader=item[2]) + msg += '
IndexTitleUploader
{index:d}{title}{uploader}
' + + return msg + + +def cmd_yt_play(bot, user, text, command, parameter): + global log, yt_last_result + + if parameter and parameter.isdigit() and 0 < int(parameter) - 1 < len(yt_last_result): + url = "https://www.youtube.com/watch?v=" + yt_last_result[int(parameter) - 1][0] + cmd_play_url(bot, user, text, command, url) + else: + bot.send_msg(constants.strings('bad_parameter', command=command), text) + def cmd_help(bot, user, text, command, parameter): global log diff --git a/configuration.default.ini b/configuration.default.ini index 5e0eec3..55d492c 100644 --- a/configuration.default.ini +++ b/configuration.default.ini @@ -126,6 +126,9 @@ play_playlist = playlist rb_query = rbquery rb_play = rbplay +yt_query = ytquery +yt_play = ytplay + help = help pause = pause play = p, play @@ -199,6 +202,10 @@ unknown_mode = Unknown playback mode '{mode}'. It should be one of one-shot{mode}. change_mode = Playback mode set to {mode} by {user}. repeat = Repeat {song} for {n} times. +yt_result = Youtube query result: {result_table} Use !ytplay {{index}} to play the item you want.
+ !ytquery -n for the next page. +yt_no_more = No more results! +yt_query_error = Unable to query youtube! help =

Commands

Control diff --git a/mumbleBot.py b/mumbleBot.py index fdc88dc..a0c9b12 100644 --- a/mumbleBot.py +++ b/mumbleBot.py @@ -238,7 +238,7 @@ class MumbleBot: command = message[0] parameter = '' if len(message) > 1: - parameter = message[1] + parameter = message[1].rstrip() else: return diff --git a/util.py b/util.py index d5e29c7..8795cc9 100644 --- a/util.py +++ b/util.py @@ -18,6 +18,8 @@ from importlib import reload from PIL import Image from io import BytesIO from sys import platform +import traceback +import urllib.parse, urllib.request, urllib.error import base64 import media import media.radio @@ -467,3 +469,20 @@ def get_url_from_input(string): return res.group(1) else: return False + +def youtube_search(query): + query_url = "https://www.youtube.com/results?search_query=" + urllib.parse.quote(query, safe="") + + try: + request = urllib.request.Request(query_url) + response = urllib.request.urlopen(request).read().decode("utf-8") + results = re.findall("watch\?v=(.*?)\".*?title=\"(.*?)\".*?" + "(?:user|channel).*?>(.*?)<", response) # (id, title, uploader) + + print(results) + + if len(results) > 0: + return results + except: + print(traceback.format_exc().split("During")[0]) + return False