def build_dir_cache(self): 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: item = item_builders['file'](path=file) self.log.debug("library: music save into database: %s" % item.format_debug_string()) self.db.insert_music(item.to_dict()) self.db.manage_special_tags() self.dir_lock.release()
def build_library_query_condition(form): try: condition = Condition() types = form['type'].split(",") sub_cond = Condition() for type in types: sub_cond.or_equal("type", type) condition.and_sub_condition(sub_cond) if form['type'] == 'file': folder = form['dir'] if not folder.endswith('/') and folder: folder += '/' condition.and_like('path', folder + '%') tags = form['tags'].split(",") for tag in tags: if tag: condition.and_like("tags", f"%{tag},%", case_sensitive=False) _keywords = form['keywords'].split(" ") keywords = [] for kw in _keywords: if kw: keywords.append(kw) for keyword in keywords: condition.and_like("keywords", f"%{keyword}%", case_sensitive=False) condition.order_by('create_at', desc=True) return condition except KeyError: abort(400)
def refresh(self): dicts = var.music_db.query_random_music(var.config.getint("bot", "autoplay_length", fallback=5), Condition().and_not_sub_condition( Condition().and_like('tags', "%don't autoplay,%"))) if dicts: _list = [get_cached_wrapper_from_dict(var.bot, _dict, "AutoPlay") for _dict in dicts] self.from_list(_list, -1)
def cmd_play_file(bot, user, text, command, parameter, do_not_refresh_cache=False): global log, song_shortlist # assume parameter is a path music_wrappers = get_cached_wrappers_from_dicts(var.music_db.query_music(Condition().and_equal('path', parameter)), user) if music_wrappers: var.playlist.append(music_wrappers[0]) log.info("cmd: add to playlist: " + music_wrappers[0].format_debug_string()) send_item_added_message(bot, music_wrappers[0], len(var.playlist) - 1, text) return # 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) if music_wrappers: msgs = [tr('multiple_file_added')] for music_wrapper in music_wrappers: log.info("cmd: add to playlist: " + music_wrapper.format_debug_string()) msgs.append("<b>{:s}</b> ({:s})".format(music_wrapper.item().title, music_wrapper.item().path)) var.playlist.extend(music_wrappers) send_multi_lines_in_channel(bot, msgs) return # try to do a partial match matches = var.music_db.query_music(Condition() .and_equal('type', 'file') .and_like('path', '%' + parameter + '%', case_sensitive=False)) if len(matches) == 1: music_wrapper = get_cached_wrapper_from_dict(matches[0], user) var.playlist.append(music_wrapper) log.info("cmd: add to playlist: " + music_wrapper.format_debug_string()) send_item_added_message(bot, music_wrapper, len(var.playlist) - 1, text) return elif len(matches) > 1: song_shortlist = matches msgs = [tr('multiple_matches')] for index, match in enumerate(matches): msgs.append("<b>{:d}</b> - <b>{:s}</b> ({:s})".format( index + 1, match['title'], match['path'])) msgs.append(tr("shortlist_instruction")) send_multi_lines(bot, msgs, text) return if do_not_refresh_cache: bot.send_msg(tr("no_file"), text) else: var.cache.build_dir_cache() cmd_play_file(bot, user, text, command, parameter, do_not_refresh_cache=True)
def download(): global log if 'id' in request.args and request.args['id']: item = dicts_to_items( var.music_db.query_music(Condition().and_equal( 'id', request.args['id'])))[0] requested_file = item.uri() log.info('web: Download of file %s requested from %s:' % (requested_file, request.remote_addr)) try: return send_file(requested_file, as_attachment=True) except Exception as e: log.exception(e) abort(404) else: condition = build_library_query_condition(request.args) items = dicts_to_items(var.music_db.query_music(condition)) zipfile = util.zipdir([item.uri() for item in items]) try: return send_file(zipfile, as_attachment=True) except Exception as e: log.exception(e) abort(404) return abort(400)
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 = [tr("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(tr("records_omitted")) msgs.append(tr("shortlist_instruction")) send_multi_lines(bot, msgs, text, "") else: bot.send_msg(tr("no_file"), text) except re.error as e: msg = tr('wrong_pattern', error=str(e)) bot.send_msg(msg, text)
def free_and_delete(self, id): item = self.get_item_by_id(id) if item: self.log.debug("library: DELETE item from the database: %s" % item.format_debug_string()) if item.type == 'url': if os.path.exists(item.path): os.remove(item.path) if item.id in self: del self[item.id] self.db.delete_music(Condition().and_equal("id", item.id))
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 = [tr('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(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_in_channel(bot, msgs, "") else: if do_not_refresh_cache: bot.send_msg(tr("no_file"), text) else: var.cache.build_dir_cache() cmd_play_file_match(bot, user, text, command, parameter, do_not_refresh_cache=True) except re.error as e: msg = tr('wrong_pattern', error=str(e)) bot.send_msg(msg, text) else: bot.send_msg(tr('bad_parameter', command=command), text)
def build_dir_cache(self): self.dir_lock.acquire() self.log.info("library: rebuild directory cache") files = util.get_recursive_file_list_sorted(var.music_folder) for file in files: results = self.db.query_music(Condition().and_equal('path', file)) if not results: item = item_builders['file'](path=file) self.log.debug("library: music save into database: %s" % item.format_debug_string()) self.db.insert_music(item.to_dict()) self.dir_lock.release()
def cmd_list_file(bot, user, text, command, parameter): global log page = 0 files = [ file['path'] for file in var.music_db.query_music(Condition().and_equal( 'type', 'file').order_by('path').limit(ITEMS_PER_PAGE).offset( page * ITEMS_PER_PAGE)) ] msgs = [constants.strings("multiple_file_found")] try: count = 0 for index, file in enumerate(files): if parameter: match = re.search(parameter, file) if not match: continue count += 1 if count > ITEMS_PER_PAGE: break msgs.append("<b>{:0>3d}</b> - {:s}".format(index, file)) if count != 0: if count > ITEMS_PER_PAGE: msgs.append(constants.strings("records_omitted")) 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_file(bot, user, text, command, parameter, do_not_refresh_cache=False): global log, song_shortlist # if parameter is {index} if parameter.isdigit(): music_wrappers = get_cached_wrappers_from_dicts( bot, var.music_db.query_music(Condition().and_equal( 'type', 'file').order_by('path').limit(1).offset(int(parameter))), user) if music_wrappers: var.playlist.append(music_wrappers[0]) log.info("cmd: add to playlist: " + music_wrappers[0].format_debug_string()) bot.send_msg( constants.strings('file_added', item=music_wrappers[0].format_song_string())) return # assume parameter is a path music_wrappers = get_cached_wrappers_from_dicts( bot, var.music_db.query_music(Condition().and_equal('path', parameter)), user) if music_wrappers: var.playlist.append(music_wrappers[0]) log.info("cmd: add to playlist: " + music_wrappers[0].format_debug_string()) bot.send_msg( constants.strings('file_added', item=music_wrappers[0].format_song_string())) return # assume parameter is a folder music_wrappers = get_cached_wrappers_from_dicts( bot, var.music_db.query_music(Condition().and_equal( 'type', 'file').and_like('path', parameter + '%')), user) if music_wrappers: msgs = [constants.strings('multiple_file_added')] for music_wrapper in music_wrappers: 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)) send_multi_lines(bot, msgs, None) return # try to do a partial match matches = var.music_db.query_music(Condition().and_equal( 'type', 'file').and_like('path', '%' + parameter + '%', case_sensitive=False)) if len(matches) == 1: music_wrapper = get_cached_wrapper_from_dict(bot, matches[0], 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())) return elif len(matches) > 1: song_shortlist = matches msgs = [constants.strings('multiple_matches')] for index, match in enumerate(matches): msgs.append("<b>{:d}</b> - <b>{:s}</b> ({:s})".format( index + 1, match['title'], match['path'])) msgs.append(constants.strings("shortlist_instruction")) send_multi_lines(bot, msgs, text) return if do_not_refresh_cache: bot.send_msg(constants.strings("no_file"), text) else: var.cache.build_dir_cache(bot) cmd_play_file(bot, user, text, command, parameter, do_not_refresh_cache=True)