diff --git a/command.py b/command.py index 7918616..f833bf6 100644 --- a/command.py +++ b/command.py @@ -11,7 +11,7 @@ import interface import media.system import util import variables as var -from librb import radiobrowser +from pyradios import RadioBrowser from database import SettingsDatabase, MusicDatabase, Condition from media.item import item_id_generators, dict_to_item, dicts_to_items from media.cache import get_cached_wrapper_from_scrap, get_cached_wrapper_by_id, get_cached_wrappers_by_tags, \ @@ -74,8 +74,8 @@ def register_all_commands(bot): bot.register_command(constants.commands('change_user_password'), cmd_user_password, no_partial_match=True) # Just for debug use bot.register_command('rtrms', cmd_real_time_rms, True) - #bot.register_command('loop', cmd_loop_state, True) - #bot.register_command('item', cmd_item, True) + # bot.register_command('loop', cmd_loop_state, True) + # bot.register_command('item', cmd_item, True) def send_multi_lines(bot, lines, text, linebreak="
"): @@ -86,8 +86,8 @@ def send_multi_lines(bot, lines, text, linebreak="
"): for newline in lines: msg += br br = linebreak - if bot.mumble.get_max_message_length()\ - and (len(msg) + len(newline)) > (bot.mumble.get_max_message_length() - 4): # 4 == len("
") + if bot.mumble.get_max_message_length() \ + and (len(msg) + len(newline)) > (bot.mumble.get_max_message_length() - 4): # 4 == len("
") bot.send_msg(msg, text) msg = "" msg += newline @@ -227,8 +227,8 @@ def cmd_play_file(bot, user, text, command, parameter, do_not_refresh_cache=Fals # assume parameter is a folder music_wrappers = get_cached_wrappers_from_dicts(var.music_db.query_music(Condition() - .and_equal('type', 'file') - .and_like('path', parameter + '%')), user) + .and_equal('type', 'file') + .and_like('path', parameter + '%')), user) if music_wrappers: msgs = [constants.strings('multiple_file_added')] @@ -338,11 +338,10 @@ def cmd_play_playlist(bot, user, text, command, parameter): pass url = util.get_url_from_input(parameter) - log.debug("cmd: fetching media info from playlist url %s" % url) + log.debug(f"cmd: fetching media info from playlist url {url}") items = get_playlist_info(url=url, start_index=offset, user=user) if len(items) > 0: - items = var.playlist.extend(list(map( - lambda item: get_cached_wrapper_from_scrap(**item), items))) + items = var.playlist.extend(list(map(lambda item: get_cached_wrapper_from_scrap(**item), items))) for music in items: log.info("cmd: add to playlist: " + music.format_debug_string()) else: @@ -386,24 +385,22 @@ def cmd_rb_query(bot, user, text, command, parameter): bot.send_msg(msg, text) else: log.debug('cmd: Found query parameter: ' + parameter) - # bot.send_msg('Searching for stations - this may take some seconds...', text) - rb_stations = radiobrowser.getstations_byname(parameter) + rb = RadioBrowser() + rb_stations = rb.search(name=parameter, name_exact=False) msg = constants.strings('rb_query_result') msg += '\n' if not rb_stations: - log.debug('cmd: No matches found for rbquery ' + parameter) - bot.send_msg('Radio-Browser found no matches for ' + parameter, text) + log.debug(f"cmd: No matches found for rbquery {parameter}") + bot.send_msg(f"Radio-Browser found no matches for {parameter}", text) else: for s in rb_stations: - stationid = s['id'] - stationname = s['stationname'] - country = s['country'] + station_id = s['stationuuid'] + station_name = s['name'] + country = s['countrycode'] codec = s['codec'] bitrate = s['bitrate'] - genre = s['genre'] - # msg += f'' - msg += '' % ( - stationid, stationname, genre, codec, bitrate, country) + genre = s['tags'] + msg += f"" msg += '
!rbplay IDStation NameGenreCodec/BitrateCountry
{stationid}{stationname}{genre}{codec}/{bitrate}{country}
%s%s%s%s/%s%s
{station_id}{station_name}{genre}{codec}/{bitrate}{country}
' # Full message as html table if len(msg) <= 5000: @@ -414,10 +411,9 @@ def cmd_rb_query(bot, user, text, command, parameter): msg = constants.strings('rb_query_result') + ' (shortened L1)' msg += '\n' for s in rb_stations: - stationid = s['id'] - stationname = s['stationname'] - # msg += f'' - msg += '' % (stationid, stationname) + station_id = s['stationuuid'] + station_name = s['name'] + msg += f'' msg += '
!rbplay IDStation Name
{stationid}{stationname}
%s%s
{station_id}{station_name}
' if len(msg) <= 5000: bot.send_msg(msg, text) @@ -427,16 +423,14 @@ def cmd_rb_query(bot, user, text, command, parameter): msg = constants.strings('rb_query_result') + ' (shortened L2)' msg += '!rbplay ID - Station Name' for s in rb_stations: - stationid = s['id'] - stationname = s['stationname'][:12] - # msg += f'{stationid} - {stationname}' - msg += '%s - %s' % (stationid, stationname) + station_id = s['stationuuid'] + station_name = s['name'][:12] + msg += f'{station_id} - {station_name}' if len(msg) <= 5000: bot.send_msg(msg, text) # Message still too long else: - bot.send_msg('Query result too long to post (> 5000 characters), please try another query.', - text) + bot.send_msg('Query result too long to post (> 5000 characters), please try another query.', text) def cmd_rb_play(bot, user, text, command, parameter): @@ -449,22 +443,21 @@ def cmd_rb_play(bot, user, text, command, parameter): bot.send_msg(msg, text) else: log.debug('cmd: Retreiving url for station ID ' + parameter) - rstation = radiobrowser.getstationname_byid(parameter) + rb = RadioBrowser() + rstation = rb.station_by_uuid(parameter) stationname = rstation[0]['name'] - country = rstation[0]['country'] + country = rstation[0]['countrycode'] codec = rstation[0]['codec'] bitrate = rstation[0]['bitrate'] genre = rstation[0]['tags'] homepage = rstation[0]['homepage'] + url = rstation[0]['url'] msg = 'Radio station added to playlist:' - # msg += '' + \ - # f'
IDStation NameGenreCodec/BitrateCountryHomepage
{parameter}{stationname}{genre}{codec}/{bitrate}{country}{homepage}
' + msg += '' + \ - '
IDStation NameGenreCodec/BitrateCountryHomepage
%s%s%s%s/%s%s%s
' \ - % (parameter, stationname, genre, codec, bitrate, country, homepage) - log.debug('cmd: Added station to playlist %s' % stationname) + f"{parameter}{stationname}{genre}{codec}/{bitrate}{country}{homepage}" + log.debug(f'cmd: Added station to playlist {stationname}') bot.send_msg(msg, text) - url = radiobrowser.geturl_byid(parameter) if url != "-1": log.info('cmd: Found url: ' + url) music_wrapper = get_cached_wrapper_from_scrap(type='radio', url=url, name=stationname, user=user) @@ -517,7 +510,7 @@ def cmd_yt_search(bot, user, text, command, parameter): def _yt_format_result(results, start, count): msg = '' - for index, item in enumerate(results[start:start+count]): + for index, item in enumerate(results[start:start + count]): msg += ''.format( index=index + 1, title=item[1], uploader=item[2]) msg += '
IndexTitleUploader
{index:d}{title}{uploader}
' @@ -602,10 +595,9 @@ def cmd_volume(bot, user, text, command, parameter): # 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) + 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)) + log.info(f'cmd: volume set to {bot.volume_set * 100}') else: bot.send_msg(constants.strings('current_volume', volume=int(bot.volume_set * 100)), text) @@ -618,8 +610,7 @@ def cmd_ducking(bot, user, text, command, parameter): var.db.set('bot', 'ducking', True) bot.ducking_volume = var.config.getfloat("bot", "ducking_volume", fallback=0.05) bot.ducking_threshold = var.config.getint("bot", "ducking_threshold", fallback=5000) - bot.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_SOUNDRECEIVED, - bot.ducking_sound_received) + bot.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_SOUNDRECEIVED, bot.ducking_sound_received) bot.mumble.set_receive_sound(True) log.info('cmd: ducking is on') msg = "Ducking on." @@ -639,10 +630,10 @@ def cmd_ducking_threshold(bot, user, text, command, parameter): if parameter and parameter.isdigit(): bot.ducking_threshold = int(parameter) var.db.set('bot', 'ducking_threshold', str(bot.ducking_threshold)) - msg = "Ducking threshold set to %d." % bot.ducking_threshold + msg = f"Ducking threshold set to {bot.ducking_threshold}." bot.send_msg(msg, text) else: - msg = "Current ducking threshold is %d." % bot.ducking_threshold + msg = f"Current ducking threshold is {bot.ducking_threshold}." bot.send_msg(msg, text) @@ -652,11 +643,9 @@ def cmd_ducking_volume(bot, user, text, command, parameter): # The volume is a percentage if parameter and parameter.isdigit() and 0 <= int(parameter) <= 100: bot.ducking_volume = float(float(parameter) / 100) - bot.send_msg(constants.strings('change_ducking_volume', - volume=int(bot.ducking_volume * 100), user=bot.mumble.users[text.actor]['name']), text) - # var.db.set('bot', 'volume', str(bot.volume_set)) + bot.send_msg(constants.strings('change_ducking_volume', volume=int(bot.ducking_volume * 100), user=bot.mumble.users[text.actor]['name']), text) var.db.set('bot', 'ducking_volume', str(bot.ducking_volume)) - log.info('cmd: volume on ducking set to %d' % (bot.ducking_volume * 100)) + log.info(f'cmd: volume on ducking set to {bot.ducking_volume * 100}') else: bot.send_msg(constants.strings('current_ducking_volume', volume=int(bot.ducking_volume * 100)), text) @@ -826,7 +815,7 @@ def cmd_mode(bot, user, text, command, parameter): 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) + log.info(f"command: playback mode changed to {parameter}.") bot.send_msg(constants.strings("change_mode", mode=var.playlist.mode, user=bot.mumble.users[text.actor]['name']), text) if parameter == "random": @@ -878,8 +867,7 @@ def cmd_add_tag(bot, user, text, command, parameter): if tags[0]: if index.isdigit() and 1 <= int(index) <= len(var.playlist): var.playlist[int(index) - 1].add_tags(tags) - log.info("cmd: add tags %s to song %s" % (", ".join(tags), - var.playlist[int(index) - 1].format_debug_string())) + log.info(f"cmd: add tags {', '.join(tags)} to song {var.playlist[int(index) - 1].format_debug_string()}") bot.send_msg(constants.strings("added_tags", tags=", ".join(tags), song=var.playlist[int(index) - 1].format_title()), text) @@ -888,8 +876,7 @@ def cmd_add_tag(bot, user, text, command, parameter): elif index == "*": for item in var.playlist: item.add_tags(tags) - log.info("cmd: add tags %s to song %s" % (", ".join(tags), - item.format_debug_string())) + log.info(f"cmd: add tags {', '.join(tags)} to song {item.format_debug_string()}") bot.send_msg(constants.strings("added_tags_to_all", tags=", ".join(tags)), text) return @@ -917,15 +904,14 @@ def cmd_remove_tag(bot, user, text, command, parameter): 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())) + log.info(f"cmd: remove tags {', '.join(tags)} from song {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())) + log.info(f"cmd: clear tags from song {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 @@ -934,14 +920,13 @@ def cmd_remove_tag(bot, user, text, command, parameter): 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())) + log.info(f"cmd: remove tags {', '.join(tags)} from song {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())) + log.info(f"cmd: clear tags from song {item.format_debug_string()}") bot.send_msg(constants.strings("cleared_tags_from_all"), text) return @@ -969,7 +954,7 @@ def cmd_find_tagged(bot, user, text, command, parameter): count += 1 if count > ITEMS_PER_PAGE: break - msgs.append("
  • {:d} - {} ({})
  • ".format(i+1, item.title, ", ".join(item.tags))) + msgs.append("
  • {:d} - {} ({})
  • ".format(i + 1, item.title, ", ".join(item.tags))) if count != 0: msgs.append("") @@ -1210,7 +1195,7 @@ def cmd_web_user_add(bot, user, text, command, parameter): if parameter not in web_users: web_users.append(parameter) var.db.set("privilege", "web_access", json.dumps(web_users)) - bot.send_msg(constants.strings('web_user_list', users=", ". join(web_users)), text) + bot.send_msg(constants.strings('web_user_list', users=", ".join(web_users)), text) else: bot.send_msg(constants.strings('command_disabled', command=command), text) @@ -1227,7 +1212,7 @@ def cmd_web_user_remove(bot, user, text, command, parameter): if parameter in web_users: web_users.remove(parameter) var.db.set("privilege", "web_access", json.dumps(web_users)) - bot.send_msg(constants.strings('web_user_list', users=", ". join(web_users)), text) + bot.send_msg(constants.strings('web_user_list', users=", ".join(web_users)), text) else: bot.send_msg(constants.strings('command_disabled', command=command), text) @@ -1237,7 +1222,7 @@ def cmd_web_user_list(bot, user, text, command, parameter): if auth_method == 'password': web_users = json.loads(var.db.get("privilege", "web_access", fallback='[]')) - bot.send_msg(constants.strings('web_user_list', users=", ". join(web_users)), text) + bot.send_msg(constants.strings('web_user_list', users=", ".join(web_users)), text) else: bot.send_msg(constants.strings('command_disabled', command=command), text) diff --git a/librb/__init__.py b/librb/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/librb/radiobrowser.py b/librb/radiobrowser.py deleted file mode 100644 index 9499c8f..0000000 --- a/librb/radiobrowser.py +++ /dev/null @@ -1,33 +0,0 @@ -from librb.rbRadios import RadioBrowser - -rb = RadioBrowser() - - -def getstations_byname(query): - results = rb.stations_byname(query) - stations = [] - for st in results: - try: - station = {'stationname': st['name'], 'id': st['id'], 'codec': st['codec'], 'bitrate': st['bitrate'], 'country': st['country'], 'homepage': st['homepage'], 'genre': st['tags']} - stations.append(station) - except: - pass - return stations - - -def geturl_byid(id): - url = rb.playable_station(id)['url'] - if url is not None: - return url - else: - return "-1" - - -def getstationname_byid(id): - return rb.stations_byid(id) - - -if __name__ == "__main__": - r = getstations_byname('r.sh') - stationinfo = getstationname_byid(96748) - pass diff --git a/librb/rbConstants.py b/librb/rbConstants.py deleted file mode 100644 index bd0f121..0000000 --- a/librb/rbConstants.py +++ /dev/null @@ -1,16 +0,0 @@ -BASE_URL = "http://www.radio-browser.info/webservice/" - -endpoints = { - "countries": {1: "{fmt}/countries", 2: "{fmt}/countries/{filter}"}, - "codecs": {1: "{fmt}/codecs", 2: "{fmt}/codecs/{filter}"}, - "states": { - 1: "{fmt}/states", - 2: "{fmt}/states/{filter}", - 3: "{fmt}/states/{country}/{filter}", - }, - "languages": {1: "{fmt}/languages", 2: "{fmt}/languages/{filter}"}, - "tags": {1: "{fmt}/tags", 2: "{fmt}/tags/{filter}"}, - "stations": {1: "{fmt}/stations", 3: "{fmt}/stations/{by}/{search_term}"}, - "playable_station": {3: "{ver}/{fmt}/url/{station_id}"}, - "station_search": {1: "{fmt}/stations/search"}, -} diff --git a/librb/rbRadios.py b/librb/rbRadios.py deleted file mode 100644 index 77a38ed..0000000 --- a/librb/rbRadios.py +++ /dev/null @@ -1,179 +0,0 @@ -import requests - -from librb.rbConstants import endpoints, BASE_URL - - -def request(endpoint, **kwargs): - - fmt = kwargs.get("format", "json") - - if fmt == "xml": - content_type = "application/%s" % fmt - else: - content_type = "application/%s" % fmt - - headers = {"content-type": content_type, "User-Agent": "pyradios/dev"} - - params = kwargs.get("params", {}) - - url = BASE_URL + endpoint - - resp = requests.get(url, headers=headers, params=params) - - if resp.status_code == 200: - if fmt == "xml": - return resp.text - return resp.json() - - return resp.raise_for_status() - - -class EndPointBuilder: - def __init__(self, fmt="json"): - self.fmt = fmt - self._option = None - self._endpoint = None - - @property - def endpoint(self): - return endpoints[self._endpoint][self._option] - - def produce_endpoint(self, **parts): - self._option = len(parts) - self._endpoint = parts["endpoint"] - parts.update({"fmt": self.fmt}) - return self.endpoint.format(**parts) - - -class RadioBrowser: - def __init__(self, fmt="json"): - self.fmt = fmt - self.builder = EndPointBuilder(fmt=self.fmt) - - def countries(self, filter=""): - endpoint = self.builder.produce_endpoint(endpoint="countries") - return request(endpoint) - - def codecs(self, filter=""): - endpoint = self.builder.produce_endpoint(endpoint="codecs") - return request(endpoint) - - def states(self, country="", filter=""): - endpoint = self.builder.produce_endpoint( - endpoint="states", country=country, filter=filter - ) - return request(endpoint) - - def languages(self, filter=""): - endpoint = self.builder.produce_endpoint(endpoint="languages", filter=filter) - return request(endpoint) - - def tags(self, filter=""): - endpoint = self.builder.produce_endpoint(endpoint="tags", filter=filter) - return request(endpoint) - - def stations(self, **params): - endpoint = self.builder.produce_endpoint(endpoint="stations") - kwargs = {} - if params: - kwargs.update({"params": params}) - return request(endpoint, **kwargs) - - def stations_byid(self, id): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="byid", search_term=id - ) - return request(endpoint) - - def stations_byuuid(self, uuid): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="byuuid", search_term=uuid - ) - return request(endpoint) - - def stations_byname(self, name): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="byname", search_term=name - ) - return request(endpoint) - - def stations_bynameexact(self, nameexact): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="bynameexact", search_term=nameexact - ) - return request(endpoint) - - def stations_bycodec(self, codec): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="bycodec", search_term=codec - ) - return request(endpoint) - - def stations_bycodecexact(self, codecexact): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="bycodecexact", search_term=codecexact - ) - return request(endpoint) - - def stations_bycountry(self, country): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="bycountry", search_term=country - ) - return request(endpoint) - - def stations_bycountryexact(self, countryexact): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="bycountryexact", search_term=countryexact - ) - return request(endpoint) - - def stations_bystate(self, state): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="bystate", search_term=state - ) - return request(endpoint) - - def stations_bystateexact(self, stateexact): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="bystateexact", search_term=stateexact - ) - return request(endpoint) - - # - def stations_bylanguage(self, language): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="bylanguage", search_term=language - ) - return request(endpoint) - - def stations_bylanguageexact(self, languageexact): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="bylanguageexact", search_term=languageexact - ) - return request(endpoint) - - def stations_bytag(self, tag): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="bytag", search_term=tag - ) - return request(endpoint) - - def stations_bytagexact(self, tagexact): - endpoint = self.builder.produce_endpoint( - endpoint="stations", by="bytagexact", search_term=tagexact - ) - return request(endpoint) - - def playable_station(self, station_id): - endpoint = self.builder.produce_endpoint( - endpoint="playable_station", station_id=station_id, ver="v2" - ) - - return request(endpoint) - - def station_search(self, params, **kwargs): - # http://www.radio-browser.info/webservice#Advanced_station_search - assert isinstance(params, dict), "params is not a dict" - kwargs["params"] = params - endpoint = self.builder.produce_endpoint(endpoint="station_search") - return request(endpoint, **kwargs) \ No newline at end of file diff --git a/media/cache.py b/media/cache.py index 518dd5b..7ef042a 100644 --- a/media/cache.py +++ b/media/cache.py @@ -108,6 +108,16 @@ class MusicCache(dict): self.dir_lock.acquire() self.log.info("library: rebuild directory cache") files = util.get_recursive_file_list_sorted(var.music_folder) + + # remove deleted files + results = self.db.query_music(Condition().or_equal('type', 'file')) + for result in results: + if result['path'] not in files: + self.log.debug("library: music file missed: %s, delete from library." % result['path']) + self.db.delete_music(Condition().and_equal('id', result['id'])) + else: + files.remove(result['path']) + for file in files: results = self.db.query_music(Condition().and_equal('path', file)) if not results: @@ -129,7 +139,10 @@ class CachedItemWrapper: self.version = 0 def item(self): - return self.lib[self.id] + if self.id in self.lib: + return self.lib[self.id] + else: + raise ValueError(f"Uncached item of id {self.id}.") def to_dict(self): dict = self.item().to_dict() diff --git a/mumbleBot.py b/mumbleBot.py index b3da2df..bccc8ef 100644 --- a/mumbleBot.py +++ b/mumbleBot.py @@ -35,7 +35,7 @@ class MumbleBot: def __init__(self, args): self.log = logging.getLogger("bot") - self.log.info("bot: botamusique version %s, starting..." % self.version) + self.log.info(f"bot: botamusique version {self.version}, starting...") signal.signal(signal.SIGINT, self.ctrl_caught) self.cmd_handle = {} self.volume_set = var.config.getfloat('bot', 'volume') @@ -50,8 +50,6 @@ class MumbleBot: self.channel = var.config.get("server", "channel", fallback=None) var.user = args.user - var.music_folder = util.solve_filepath(var.config.get('bot', 'music_folder')) - var.tmp_folder = util.solve_filepath(var.config.get('bot', 'tmp_folder')) var.is_proxified = var.config.getboolean( "webinterface", "is_web_proxified") self.exit = False @@ -186,8 +184,8 @@ class MumbleBot: new_version = util.new_release_version() if version.parse(new_version) > version.parse(self.version): changelog = util.fetch_changelog() - self.log.info("update: new version %s found, current installed version %s." % (new_version, self.version)) - self.log.info("update: changelog: " + changelog) + self.log.info(f"update: new version {new_version} found, current installed version {self.version}.") + self.log.info(f"update: changelog: {changelog}") changelog = changelog.replace("\n", "
    ") self.send_channel_msg(constants.strings('new_version_found', new_version=new_version, changelog=changelog)) else: @@ -305,7 +303,7 @@ class MumbleBot: except: error_traceback = traceback.format_exc() error = error_traceback.rstrip().split("\n")[-1] - self.log.error("bot: command %s failed with error: %s\n" % (command_exc, error_traceback)) + self.log.error(f"bot: command {command_exc} failed with error: {error_traceback}\n") self.send_msg(constants.strings('error_executing_command', command=command_exc, error=error), text) def send_msg(self, msg, text): @@ -408,7 +406,7 @@ class MumbleBot: def async_download(self, item): th = threading.Thread( target=self._download, name="Prepare-" + item.id[:7], args=(item,)) - self.log.info("bot: start preparing item in thread: %s" % item.format_debug_string()) + self.log.info(f"bot: start preparing item in thread: {item.format_debug_string()}") th.daemon = True th.start() return th @@ -443,7 +441,7 @@ class MumbleBot: while self.thread and self.mumble.sound_output.get_buffer_size() > 0.5 and not self.exit: # If the buffer isn't empty, I cannot send new music part, so I wait - self._loop_status = 'Wait for buffer %.3f' % self.mumble.sound_output.get_buffer_size() + self._loop_status = f'Wait for buffer {self.mumble.sound_output.get_buffer_size():.3f}' time.sleep(0.01) if self.thread: @@ -629,7 +627,7 @@ class MumbleBot: self.song_start_at = -1 if len(var.playlist) > 0: self.pause_at_id = var.playlist.current_item().id - self.log.info("bot: music paused at %.2f seconds." % self.playhead) + self.log.info(f"bot: music paused at {self.playhead:.2f} seconds.") def resume(self): self.is_pause = False @@ -768,6 +766,8 @@ if __name__ == '__main__': DatabaseMigration(var.db, var.music_db).migrate() + var.music_folder = util.solve_filepath(var.config.get('bot', 'music_folder')) + var.tmp_folder = util.solve_filepath(var.config.get('bot', 'tmp_folder')) var.cache = MusicCache(var.music_db) if var.config.get("bot", "refresh_cache_on_startup", fallback=True): @@ -785,7 +785,7 @@ if __name__ == '__main__': if playback_mode in ["one-shot", "repeat", "random", "autoplay"]: var.playlist = media.playlist.get_playlist(playback_mode) else: - raise KeyError("Unknown playback mode '%s'" % playback_mode) + raise KeyError(f"Unknown playback mode '{playback_mode}'") # ====================== # Create bot instance diff --git a/requirements.txt b/requirements.txt index adc50cc..5c93931 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,3 +8,4 @@ mutagen requests packaging pymumble +pyradios \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index c4927b1..55b9612 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1 +1 @@ -botamusique web interface
    #TitleUrl/PathAction
    See item on the playlist.


    Music Library

    Filters

    {% for tag in tags_color_lookup.keys() %} {{ tag }} {% endfor %}
    Path/to/the/file
    No tag Tag
    [File] This is my title - Artist
    Path/to/the/file
    No tag Tag
    {% if upload_enabled %}
    {% else %}
    Add URL
    Add Radio
    \ No newline at end of file +botamusique web interface
    #TitleUrl/PathAction
    See item on the playlist.


    Music Library

    Filters

    {% for tag in tags_color_lookup.keys() %} {{ tag }} {% endfor %}
    {% if upload_enabled %}
    {% else %}
    Add URL
    Add Radio
    \ No newline at end of file diff --git a/web/src/templates/index.html b/web/src/templates/index.html index a4bdd71..3a92afe 100644 --- a/web/src/templates/index.html +++ b/web/src/templates/index.html @@ -28,14 +28,12 @@ -
    - @@ -63,8 +60,7 @@ - + @@ -98,8 +94,7 @@ - See item on the playlist. + See item on the playlist. @@ -161,16 +156,13 @@
    -
    @@ -188,8 +180,7 @@
    - +
    @@ -197,8 +188,7 @@
    {% for tag in tags_color_lookup.keys() %} - {{ tag }} + {{ tag }} {% endfor %}
    @@ -226,21 +216,89 @@ - -
    - +
    +
    + [File] + This is my title + - Artist +
    +
    + +
    + Path/to/the/file +
    + + No tag + Tag +
    +
    + +
    + + + +
    -
    - Path/to/the/file -
    - - No - tag - Tag +
    + +
    +
    +
      +
    • + 1 +
    • +
    +
    +
    + +
    + + + + +
    + + @@ -248,328 +306,213 @@
    -
    -
    - + + {% if upload_enabled %} +
    + {% else %} +