Skip to content

Commit

Permalink
fix: #52 支持配置模糊匹配本地歌曲
Browse files Browse the repository at this point in the history
  • Loading branch information
hanxi committed Jun 29, 2024
1 parent db1e4e6 commit f18b2f4
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
6 changes: 6 additions & 0 deletions xiaomusic/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(","):
Expand Down
7 changes: 6 additions & 1 deletion xiaomusic/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


# 歌曲排序
Expand Down
33 changes: 33 additions & 0 deletions xiaomusic/xiaomusic.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from xiaomusic.httpserver import StartHTTPServer
from xiaomusic.utils import (
custom_sort_key,
find_best_match,
fuzzyfinder,
get_local_music_duration,
get_random,
Expand Down Expand Up @@ -689,6 +690,20 @@ async def play_url(self, **kwargs):
)
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", "")
Expand All @@ -702,6 +717,7 @@ async def playlocal(self, **kwargs):
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
Expand Down Expand Up @@ -737,6 +753,7 @@ async def play(self, **kwargs):
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}")
Expand Down Expand Up @@ -798,10 +815,26 @@ def del_music(self, name):
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
Expand Down

0 comments on commit f18b2f4

Please sign in to comment.