From f18b2f49bfe004c2cb2755aa96448e729c74f86c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B6=B5=E6=9B=A6?= Date: Sat, 29 Jun 2024 13:15:31 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20#52=20=E6=94=AF=E6=8C=81=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=A8=A1=E7=B3=8A=E5=8C=B9=E9=85=8D=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E6=AD=8C=E6=9B=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xiaomusic/config.py | 6 ++++++ xiaomusic/utils.py | 7 ++++++- xiaomusic/xiaomusic.py | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/xiaomusic/config.py b/xiaomusic/config.py index 10040b8..895c368 100644 --- a/xiaomusic/config.py +++ b/xiaomusic/config.py @@ -82,6 +82,12 @@ class Config: os.getenv("XIAOMUSIC_USE_MUSIC_API", "false").lower() == "true" ) log_file: str = os.getenv("XIAOMUSIC_MUSIC_LOG_FILE", "/tmp/xiaomusic.txt") + # 模糊搜索匹配的最低相似度阈值 + fuzzy_match_cutoff: float = float(os.getenv("XIAOMUSIC_FUZZY_MATCH_CUTOFF", "0.6")) + # 开启模糊搜索 + enable_fuzzy_match: bool = ( + os.getenv("XIAOMUSIC_ENABLE_FUZZY_MATCH", "true").lower() == "true" + ) def append_keyword(self, keys, action): for key in keys.split(","): diff --git a/xiaomusic/utils.py b/xiaomusic/utils.py index 23979c1..556a085 100644 --- a/xiaomusic/utils.py +++ b/xiaomusic/utils.py @@ -72,7 +72,12 @@ def validate_proxy(proxy_str: str) -> bool: # 模糊搜索 def fuzzyfinder(user_input, collection): - return difflib.get_close_matches(user_input, collection, 10, cutoff=0.1) + return difflib.get_close_matches(user_input, collection, n=10, cutoff=0.1) + + +def find_best_match(user_input, collection, cutoff=0.6): + matches = difflib.get_close_matches(user_input, collection, n=1, cutoff=cutoff) + return matches[0] if matches else None # 歌曲排序 diff --git a/xiaomusic/xiaomusic.py b/xiaomusic/xiaomusic.py index 6c7a027..7a3403f 100644 --- a/xiaomusic/xiaomusic.py +++ b/xiaomusic/xiaomusic.py @@ -31,6 +31,7 @@ from xiaomusic.const import ( from xiaomusic.httpserver import StartHTTPServer from xiaomusic.utils import ( custom_sort_key, + find_best_match, fuzzyfinder, get_local_music_duration, get_random, @@ -689,6 +690,20 @@ class XiaoMusic: ) return ret + def find_real_music_name(self, name): + if not self.config.enable_fuzzy_match: + self.log.debug("没开启模糊匹配") + return name + + all_music_list = list(self._all_music.keys()) + real_name = find_best_match( + name, all_music_list, cutoff=self.config.fuzzy_match_cutoff + ) + if real_name: + self.log.info(f"根据【{name}】找到歌曲【{real_name}】") + return real_name + self.log.info(f"没找到歌曲【{name}】") + # 播放本地歌曲 async def playlocal(self, **kwargs): name = kwargs.get("arg1", "") @@ -702,6 +717,7 @@ class XiaoMusic: self.log.info(f"playlocal. name:{name}") # 本地歌曲不存在时下载 + name = self.find_real_music_name(name) if not self.is_music_exist(name): await self.do_tts(f"本地不存在歌曲{name}") return @@ -737,6 +753,7 @@ class XiaoMusic: self.log.info("play. search_key:%s name:%s", search_key, name) # 本地歌曲不存在时下载 + name = self.find_real_music_name(name) if not self.is_music_exist(name): if self.config.disable_download: await self.do_tts(f"本地不存在歌曲{name}") @@ -798,10 +815,26 @@ class XiaoMusic: self.log.error(f"del ${filename} failed") self._gen_all_music_list() + def find_real_music_list_name(self, list_name): + if not self.config.enable_fuzzy_match: + self.log.debug("没开启模糊匹配") + return list_name + + # 模糊搜一个播放列表 + real_name = find_best_match( + list_name, self._music_list, cutoff=self.config.fuzzy_match_cutoff + ) + if real_name: + self.log.info(f"根据【{list_name}】找到播放列表【{real_name}】") + list_name = real_name + self.log.info(f"没找到播放列表【{list_name}】") + # 播放一个播放列表 async def play_music_list(self, **kwargs): parts = kwargs.get("arg1").split("|") list_name = parts[0] + + list_name = self.find_real_music_list_name(list_name) if list_name not in self._music_list: await self.do_tts(f"播放列表{list_name}不存在") return