From f7042db65749e72c49b481d608c6cc3537362048 Mon Sep 17 00:00:00 2001 From: Terry Geng Date: Sun, 8 Mar 2020 16:56:31 +0800 Subject: [PATCH] feat: 'search' command to search the db, and 'shortlist' to add songs from search result --- command.py | 171 ++++++++++++++++++++++++++------- configuration.default.ini | 9 +- database.py | 34 +++++++ interface.py | 20 ++-- media/{library.py => cache.py} | 16 +-- media/file.py | 2 +- media/item.py | 12 +++ media/playlist.py | 21 ++-- mumbleBot.py | 12 +-- variables.py | 2 +- 10 files changed, 226 insertions(+), 73 deletions(-) rename media/{library.py => cache.py} (93%) diff --git a/command.py b/command.py index d9e0e67..4861d05 100644 --- a/command.py +++ b/command.py @@ -10,6 +10,7 @@ import util import variables as var from librb import radiobrowser from database import SettingsDatabase, MusicDatabase +from media.item import item_builders, item_loaders, item_id_generators, dict_to_item, dicts_to_items from media.playlist import get_item_wrapper, get_item_wrapper_by_id, get_item_wrappers_by_tags from media.file import FileItem from media.url_from_playlist import PlaylistURLItem, get_playlist_info @@ -58,6 +59,8 @@ def register_all_commands(bot): bot.register_command(constants.commands('add_tag'), cmd_add_tag) bot.register_command(constants.commands('remove_tag'), cmd_remove_tag) bot.register_command(constants.commands('find_tagged'), cmd_find_tagged) + bot.register_command(constants.commands('search'), cmd_search_library) + bot.register_command(constants.commands('add_from_shortlist'), cmd_shortlist) bot.register_command(constants.commands('drop_database'), cmd_drop_database, True) bot.register_command(constants.commands('rescan'), cmd_refresh_cache, True) @@ -81,6 +84,10 @@ def send_multi_lines(bot, lines, text, linebreak="
"): bot.send_msg(msg, text) +# ---------------- Variables ----------------- + +song_shortlist = [] + # ---------------- Commands ------------------ @@ -169,13 +176,13 @@ def cmd_pause(bot, user, text, command, parameter): def cmd_play_file(bot, user, text, command, parameter, do_not_refresh_cache=False): - global log + global log, song_shortlist # if parameter is {index} if parameter.isdigit(): - files = var.library.files + files = var.cache.files if int(parameter) < len(files): - music_wrapper = get_item_wrapper_by_id(bot, var.library.file_id_lookup[files[int(parameter)]], user) + music_wrapper = get_item_wrapper_by_id(bot, var.cache.file_id_lookup[files[int(parameter)]], 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) @@ -189,7 +196,7 @@ def cmd_play_file(bot, user, text, command, parameter, do_not_refresh_cache=Fals # bot.send_msg(constants.strings('no_file'), text) # return - if parameter in var.library.files: + if parameter in var.cache.files: music_wrapper = get_item_wrapper(bot, type='file', path=parameter, user=user) var.playlist.append(music_wrapper) log.info("cmd: add to playlist: " + music_wrapper.format_debug_string()) @@ -197,14 +204,14 @@ def cmd_play_file(bot, user, text, command, parameter, do_not_refresh_cache=Fals return # if parameter is {folder} - files = var.library.dir.get_files(parameter) + files = var.cache.dir.get_files(parameter) if files: msgs = [constants.strings('multiple_file_added')] count = 0 for file in files: count += 1 - music_wrapper = get_item_wrapper_by_id(bot, var.library.file_id_lookup[file],user) + music_wrapper = get_item_wrapper_by_id(bot, var.cache.file_id_lookup[file], user) var.playlist.append(music_wrapper) log.info("cmd: add to playlist: " + music_wrapper.format_debug_string()) msgs.append("{} ({})".format(music_wrapper.item().title, music_wrapper.item().path)) @@ -215,28 +222,34 @@ def cmd_play_file(bot, user, text, command, parameter, do_not_refresh_cache=Fals else: # try to do a partial match - files = var.library.files - matches = [(index, file) for index, file in enumerate(files) if parameter.lower() in file.lower()] + files = var.cache.files + matches = [ file for file in files if parameter.lower() in file.lower()] if len(matches) == 1: - file = matches[0][1] - music_wrapper = get_item_wrapper_by_id(bot, var.library.file_id_lookup[file],user) + file = matches[0] + music_wrapper = get_item_wrapper_by_id(bot, var.cache.file_id_lookup[file], 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) return elif len(matches) > 1: msgs = [ constants.strings('multiple_matches') ] - for match in matches: - music_wrapper = get_item_wrapper_by_id(bot, var.library.file_id_lookup[match[1]], user) - msgs.append("{:0>3d} - {:s} ({:s})".format( - match[0], music_wrapper.item().title, match[1])) + song_shortlist = [] + for index, match in enumerate(matches): + id = var.cache.file_id_lookup[match] + music_dict = var.music_db.query_music_by_id(id) + item = dict_to_item(bot, music_dict) + + song_shortlist.append(music_dict) + + msgs.append("{:d} - {:s} ({:s})".format( + index + 1, item.title, match)) send_multi_lines(bot, msgs, text) return if do_not_refresh_cache: bot.send_msg(constants.strings("no_file"), text) else: - var.library.build_dir_cache(bot) + var.cache.build_dir_cache(bot) cmd_play_file(bot, user, text, command, parameter, do_not_refresh_cache=True) @@ -245,7 +258,7 @@ def cmd_play_file_match(bot, user, text, command, parameter, do_not_refresh_cach music_folder = var.music_folder if parameter: - files = var.library.files + files = var.cache.files msgs = [ constants.strings('multiple_file_added') + "") + msgs.append(constants.strings("shortlist_instruction")) send_multi_lines(bot, msgs, text, "") else: bot.send_msg(constants.strings("no_file"), text) +def cmd_search_library(bot, user, text, command, parameter): + global song_shortlist + if not parameter: + bot.send_msg(constants.strings('bad_parameter', command=command)) + return + + msgs = [constants.strings('multiple_file_found') + "") + msgs.append(constants.strings("shortlist_instruction")) + send_multi_lines(bot, msgs, text, "") + else: + bot.send_msg(constants.strings("no_file"), text) + + +def cmd_shortlist(bot, user, text, command, parameter): + global song_shortlist + indexes = [] + try: + indexes = [ int(i) for i in parameter.split(" ") ] + except ValueError: + bot.send_msg(constants.strings('bad_parameter', command=command), text) + return + + if len(indexes) > 1: + msgs = [constants.strings('multiple_file_added') + "") + send_multi_lines(bot, msgs, text, "") + song_shortlist = [] + return + elif len(indexes) == 1: + index = indexes[0] + if 1 <= index <= len(song_shortlist): + kwargs = song_shortlist[index - 1] + kwargs['user'] = user + music_wrapper = get_item_wrapper(bot, **kwargs) + 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) + song_shortlist = [] + return + + bot.send_msg(constants.strings('bad_parameter', command=command), text) + + def cmd_drop_database(bot, user, text, command, parameter): global log @@ -907,7 +1006,7 @@ def cmd_drop_database(bot, user, text, command, parameter): def cmd_refresh_cache(bot, user, text, command, parameter): global log if bot.is_admin(user): - var.library.build_dir_cache(bot) + var.cache.build_dir_cache(bot) log.info("command: Local file cache refreshed.") bot.send_msg(constants.strings('cache_refreshed'), text) else: diff --git a/configuration.default.ini b/configuration.default.ini index 598945b..3697784 100644 --- a/configuration.default.ini +++ b/configuration.default.ini @@ -160,6 +160,8 @@ play_tag = tag add_tag = addtag remove_tag = untag find_tagged = findtagged, ft +search = search +add_from_shortlist = shortlist, sl user_ban = userban user_unban = userunban @@ -225,7 +227,7 @@ 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.
+yt_result = Youtube query result: {result_table} Use !sl {{indexes}} 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! @@ -237,6 +239,7 @@ removed_tags = Removed tags {tags} from {song}. removed_tags_from_all = Removed tags {tags} from songs on the playlist. cleared_tags = Removed all tags from {song}. cleared_tags_from_all = Removed all tags from songs on the playlist. +shortlist_instruction = Use !sl {indexes} to play the item you want. help =

Commands

Control @@ -264,6 +267,7 @@ help =

Commands

  • !url {url} - add Youtube or SoundCloud music
  • !playlist {url} [{offset}] - add all items in a Youtube or SoundCloud playlist, and start with the {offset}-th item
  • !tag {tags} - add all items with tags {tags}, tags separated by ",".
  • +
  • !shortlist (or !sl) {indexes} - add {indexes}-th item on the shortlist.
  • !rm {num} - remove the num-th song on the playlist
  • !repeat [{num}] - repeat current song {num} (1 by default) times.
  • !random - randomize the playlist.
  • @@ -275,8 +279,9 @@ help =

    Commands

  • !yplay {index/keywords} - play an item from the list returned by !ytquery, or add the first search result of {keywords} into the playlist.
  • - Tag + Music Library