mirror of
https://github.com/hanxi/xiaomusic.git
synced 2026-03-15 08:13:16 +08:00
重构变量,优化 IDE 开发体验
This commit is contained in:
@@ -4,6 +4,6 @@ async def code1(arg1):
|
||||
did = xiaomusic.get_cur_did()
|
||||
await xiaomusic.do_tts(did, "你好,我是自定义的测试口令")
|
||||
|
||||
last_record = xiaomusic._conversation_poller.last_record
|
||||
last_record = xiaomusic.conversation_poller.last_record
|
||||
query = last_record.get("query", "").strip()
|
||||
await xiaomusic.do_tts(did, f"你说的是: {query}")
|
||||
|
||||
@@ -94,9 +94,10 @@ class _LazyProxy:
|
||||
|
||||
|
||||
# 创建代理对象,可以像普通变量一样使用
|
||||
xiaomusic = _LazyProxy("_xiaomusic")
|
||||
config = _LazyProxy("_config")
|
||||
log = _LazyProxy("_log")
|
||||
# 添加类型注解以支持 IDE 代码跳转和补全
|
||||
xiaomusic: "XiaoMusic" = _LazyProxy("_xiaomusic") # type: ignore
|
||||
config: "Config" = _LazyProxy("_config") # type: ignore
|
||||
log: "logging.Logger" = _LazyProxy("_log") # type: ignore
|
||||
|
||||
|
||||
def verification(
|
||||
|
||||
@@ -170,7 +170,7 @@ async def upload_music(playlist: str = Form(...), file: UploadFile = File(...)):
|
||||
musics = xiaomusic.music_list.get(playlist, [])
|
||||
if musics and len(musics) > 0:
|
||||
first = musics[0]
|
||||
filepath = xiaomusic._music_library.all_music.get(first, "")
|
||||
filepath = xiaomusic.music_library.all_music.get(first, "")
|
||||
if filepath:
|
||||
dest_dir = os.path.dirname(filepath)
|
||||
|
||||
@@ -203,7 +203,7 @@ async def upload_music(playlist: str = Form(...), file: UploadFile = File(...)):
|
||||
|
||||
# 重新生成音乐列表索引
|
||||
try:
|
||||
xiaomusic._music_library.gen_all_music_list()
|
||||
xiaomusic.music_library.gen_all_music_list()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -301,7 +301,7 @@ async def proxy(urlb64: str):
|
||||
|
||||
log.info(f"代理请求: {url}")
|
||||
|
||||
parsed_url, url = xiaomusic._music_library.expand_self_url(url)
|
||||
parsed_url, url = xiaomusic.music_library.expand_self_url(url)
|
||||
log.info(f"链接处理后 ${parsed_url}")
|
||||
if not parsed_url.scheme or not parsed_url.netloc:
|
||||
# Fixed: Use a new exception instance since 'e' from previous block is out of scope
|
||||
|
||||
@@ -81,7 +81,7 @@ async def get_plugin_source_url(
|
||||
# 将json字符串转换为json对象
|
||||
json_data = json.loads(json_str)
|
||||
# 调用公共函数处理
|
||||
media_source = await xiaomusic._online_music_service.get_media_source_url(
|
||||
media_source = await xiaomusic.online_music_service.get_media_source_url(
|
||||
json_data
|
||||
)
|
||||
if media_source and media_source.get("url"):
|
||||
@@ -105,7 +105,7 @@ async def get_media_source(request: Request):
|
||||
# 获取请求数据
|
||||
data = await request.json()
|
||||
# 调用公共函数处理
|
||||
return await xiaomusic._online_music_service.get_media_source_url(data)
|
||||
return await xiaomusic.online_music_service.get_media_source_url(data)
|
||||
except Exception as e:
|
||||
return {"success": False, "error": str(e)}
|
||||
|
||||
@@ -191,14 +191,14 @@ async def musiclist():
|
||||
@router.get("/musicinfo")
|
||||
async def musicinfo(name: str, musictag: bool = False):
|
||||
"""音乐信息"""
|
||||
url, _ = await xiaomusic._music_library.get_music_url(name)
|
||||
url, _ = await xiaomusic.music_library.get_music_url(name)
|
||||
info = {
|
||||
"ret": "OK",
|
||||
"name": name,
|
||||
"url": url,
|
||||
}
|
||||
if musictag:
|
||||
info["tags"] = await xiaomusic._music_library.get_music_tags(name)
|
||||
info["tags"] = await xiaomusic.music_library.get_music_tags(name)
|
||||
return info
|
||||
|
||||
|
||||
@@ -210,13 +210,13 @@ async def musicinfos(
|
||||
"""批量音乐信息"""
|
||||
ret = []
|
||||
for music_name in name:
|
||||
url, _ = await xiaomusic._music_library.get_music_url(music_name)
|
||||
url, _ = await xiaomusic.music_library.get_music_url(music_name)
|
||||
info = {
|
||||
"name": music_name,
|
||||
"url": url,
|
||||
}
|
||||
if musictag:
|
||||
info["tags"] = await xiaomusic._music_library.get_music_tags(music_name)
|
||||
info["tags"] = await xiaomusic.music_library.get_music_tags(music_name)
|
||||
ret.append(info)
|
||||
return ret
|
||||
|
||||
@@ -224,7 +224,7 @@ async def musicinfos(
|
||||
@router.post("/setmusictag")
|
||||
async def setmusictag(info: MusicInfoObj):
|
||||
"""设置音乐标签"""
|
||||
ret = xiaomusic._music_library.set_music_tag(info.musicname, info)
|
||||
ret = xiaomusic.music_library.set_music_tag(info.musicname, info)
|
||||
return {"ret": ret}
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@ async def playmusic(data: DidPlayMusic):
|
||||
@router.post("/refreshmusictag")
|
||||
async def refreshmusictag(Verifcation=Depends(verification)):
|
||||
"""刷新音乐标签"""
|
||||
xiaomusic._music_library.refresh_music_tag()
|
||||
xiaomusic.music_library.refresh_music_tag()
|
||||
return {
|
||||
"ret": "OK",
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ async def modifiysetting(request: Request):
|
||||
log.info("HTTP server configuration has been reset")
|
||||
|
||||
# 保存配置到文件
|
||||
xiaomusic._config_manager.save_cur_config(xiaomusic._device_manager.devices)
|
||||
xiaomusic.config_manager.save_cur_config(xiaomusic.device_manager.devices)
|
||||
|
||||
return {"success": True, "message": "Configuration updated successfully"}
|
||||
except json.JSONDecodeError as err:
|
||||
|
||||
@@ -5,9 +5,13 @@
|
||||
|
||||
import asyncio
|
||||
import re
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from xiaomusic.config import KEY_WORD_ARG_BEFORE_DICT
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from xiaomusic.xiaomusic import XiaoMusic
|
||||
|
||||
|
||||
class CommandHandler:
|
||||
"""命令处理器
|
||||
@@ -15,7 +19,7 @@ class CommandHandler:
|
||||
负责解析用户的语音指令,匹配对应的命令,并路由到相应的处理方法。
|
||||
"""
|
||||
|
||||
def __init__(self, config, log, xiaomusic_instance):
|
||||
def __init__(self, config, log, xiaomusic_instance: "XiaoMusic"):
|
||||
"""初始化命令处理器
|
||||
|
||||
Args:
|
||||
|
||||
@@ -6,9 +6,14 @@
|
||||
- 设备信息查询
|
||||
"""
|
||||
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from xiaomusic.device_player import XiaoMusicDevice
|
||||
from xiaomusic.utils.text_utils import parse_str_to_dict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from xiaomusic.xiaomusic import XiaoMusic
|
||||
|
||||
|
||||
class DeviceManager:
|
||||
"""设备管理器
|
||||
@@ -16,7 +21,7 @@ class DeviceManager:
|
||||
负责管理小米音箱设备列表、分组和设备信息查询。
|
||||
"""
|
||||
|
||||
def __init__(self, config, log, xiaomusic=None):
|
||||
def __init__(self, config, log, xiaomusic: Optional["XiaoMusic"] = None):
|
||||
"""初始化设备管理器
|
||||
|
||||
Args:
|
||||
|
||||
@@ -9,10 +9,14 @@ import json
|
||||
import os
|
||||
import random
|
||||
import time
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from miservice import miio_command
|
||||
|
||||
from xiaomusic.config import Device
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from xiaomusic.xiaomusic import XiaoMusic
|
||||
from xiaomusic.const import (
|
||||
NEED_USE_PLAY_MUSIC_API,
|
||||
PLAY_TYPE_ALL,
|
||||
@@ -39,7 +43,7 @@ class XiaoMusicDevice:
|
||||
- 设备状态管理
|
||||
"""
|
||||
|
||||
def __init__(self, xiaomusic, device: Device, group_name: str):
|
||||
def __init__(self, xiaomusic: "XiaoMusic", device: Device, group_name: str):
|
||||
"""初始化设备播放控制器
|
||||
|
||||
Args:
|
||||
@@ -53,7 +57,7 @@ class XiaoMusicDevice:
|
||||
self.device_id = device.device_id
|
||||
self.log = xiaomusic.log
|
||||
self.xiaomusic = xiaomusic
|
||||
self.auth_manager = xiaomusic._auth_manager
|
||||
self.auth_manager = xiaomusic.auth_manager
|
||||
self.download_path = xiaomusic.download_path
|
||||
self.ffmpeg_location = self.config.ffmpeg_location
|
||||
self.event_bus = getattr(xiaomusic, "event_bus", None)
|
||||
@@ -107,7 +111,7 @@ class XiaoMusicDevice:
|
||||
return
|
||||
# 是否启用自动添加
|
||||
auto_add_song = self.xiaomusic.js_plugin_manager.get_auto_add_song()
|
||||
is_online = self.xiaomusic._music_library.is_online_music(cur_list_name)
|
||||
is_online = self.xiaomusic.music_library.is_online_music(cur_list_name)
|
||||
# 歌单循环方式:播放全部
|
||||
play_all = self.device.play_type == PLAY_TYPE_ALL
|
||||
# 当前播放的歌曲是歌单中的最后一曲
|
||||
@@ -167,18 +171,18 @@ class XiaoMusicDevice:
|
||||
# 没有重置 list 且非初始化
|
||||
if self.device.cur_playlist == "临时搜索列表" and len(self._play_list) > 0:
|
||||
# 更新总播放列表,为了UI显示
|
||||
self.xiaomusic._music_library.music_list["临时搜索列表"] = copy.copy(
|
||||
self.xiaomusic.music_library.music_list["临时搜索列表"] = copy.copy(
|
||||
self._play_list
|
||||
)
|
||||
elif (
|
||||
self.device.cur_playlist == "临时搜索列表" and len(self._play_list) == 0
|
||||
) or (self.device.cur_playlist not in self.xiaomusic._music_library.music_list):
|
||||
) or (self.device.cur_playlist not in self.xiaomusic.music_library.music_list):
|
||||
self.device.cur_playlist = "全部"
|
||||
else:
|
||||
pass # 指定了已知的播放列表名称
|
||||
|
||||
list_name = self.device.cur_playlist
|
||||
self._play_list = copy.copy(self.xiaomusic._music_library.music_list[list_name])
|
||||
self._play_list = copy.copy(self.xiaomusic.music_library.music_list[list_name])
|
||||
|
||||
if reorder:
|
||||
if self.device.play_type == PLAY_TYPE_RND:
|
||||
@@ -246,7 +250,7 @@ class XiaoMusicDevice:
|
||||
# 本地存在歌曲,直接播放
|
||||
await self._playmusic(name)
|
||||
|
||||
elif not self.xiaomusic._music_library.is_music_exist(name):
|
||||
elif not self.xiaomusic.music_library.is_music_exist(name):
|
||||
self.log.info(f"本地不存在歌曲{name}")
|
||||
if self.config.disable_download:
|
||||
await self.do_tts(f"本地不存在歌曲{name}")
|
||||
@@ -341,7 +345,7 @@ class XiaoMusicDevice:
|
||||
self.log.debug(
|
||||
f"当前播放列表为:{list2str(self._play_list, self.config.verbose)}"
|
||||
)
|
||||
elif not self.xiaomusic._music_library.is_music_exist(name):
|
||||
elif not self.xiaomusic.music_library.is_music_exist(name):
|
||||
self.log.info(f"本地不存在歌曲{name}")
|
||||
await self.do_tts(f"本地不存在歌曲{name}")
|
||||
return
|
||||
@@ -357,7 +361,7 @@ class XiaoMusicDevice:
|
||||
self.device.playlist2music[self.device.cur_playlist] = name
|
||||
cur_playlist = self.device.cur_playlist
|
||||
self.log.info(f"cur_music {self.get_cur_music()}")
|
||||
sec, url = await self.xiaomusic._music_library.get_music_sec_url(
|
||||
sec, url = await self.xiaomusic.music_library.get_music_sec_url(
|
||||
name, cur_playlist
|
||||
)
|
||||
await self.group_force_stop_xiaoai()
|
||||
@@ -529,9 +533,9 @@ class XiaoMusicDevice:
|
||||
async def add_download_music(self, name):
|
||||
"""把下载的音乐加入播放列表"""
|
||||
filepath = os.path.join(self.download_path, f"{name}.mp3")
|
||||
self.xiaomusic._music_library.all_music[name] = filepath
|
||||
self.xiaomusic.music_library.all_music[name] = filepath
|
||||
# 应该很快,阻塞运行
|
||||
await self.xiaomusic._music_library._gen_all_music_tag({name: filepath})
|
||||
await self.xiaomusic.music_library._gen_all_music_tag({name: filepath})
|
||||
if name not in self._play_list:
|
||||
self._play_list.append(name)
|
||||
self.log.info(f"add_download_music add_music {name}")
|
||||
@@ -571,7 +575,7 @@ class XiaoMusicDevice:
|
||||
return ""
|
||||
|
||||
name = self._play_list[new_index]
|
||||
if not self.xiaomusic._music_library.is_music_exist(name):
|
||||
if not self.xiaomusic.music_library.is_music_exist(name):
|
||||
self._play_list.pop(new_index)
|
||||
self.log.info(f"pop not exist music: {name}")
|
||||
return self.get_music(direction)
|
||||
@@ -598,7 +602,7 @@ class XiaoMusicDevice:
|
||||
return True
|
||||
else:
|
||||
# 当前播放的歌曲不存在了
|
||||
if not self.xiaomusic._music_library.is_music_exist(self.get_cur_music()):
|
||||
if not self.xiaomusic.music_library.is_music_exist(self.get_cur_music()):
|
||||
self.log.info(f"当前播放的歌曲 {self.get_cur_music()} 不存在了")
|
||||
return True
|
||||
return False
|
||||
@@ -653,7 +657,7 @@ class XiaoMusicDevice:
|
||||
self.log.info(f"edge-tts 生成的文件路径: {mp3_path}")
|
||||
|
||||
# 生成播放 URL
|
||||
url = self.xiaomusic._music_library._get_file_url(mp3_path)
|
||||
url = self.xiaomusic.music_library._get_file_url(mp3_path)
|
||||
self.log.info(f"TTS 播放 URL: {url}")
|
||||
|
||||
# 播放 TTS 音频
|
||||
@@ -692,7 +696,7 @@ class XiaoMusicDevice:
|
||||
|
||||
async def group_player_play(self, url, name=""):
|
||||
"""同一组设备播放"""
|
||||
device_id_list = self.xiaomusic._device_manager.get_group_device_id_list(
|
||||
device_id_list = self.xiaomusic.device_manager.get_group_device_id_list(
|
||||
self.group_name
|
||||
)
|
||||
tasks = [
|
||||
@@ -868,7 +872,7 @@ class XiaoMusicDevice:
|
||||
|
||||
async def group_force_stop_xiaoai(self):
|
||||
"""强制停止组内所有设备"""
|
||||
device_id_list = self.xiaomusic._device_manager.get_group_device_id_list(
|
||||
device_id_list = self.xiaomusic.device_manager.get_group_device_id_list(
|
||||
self.group_name
|
||||
)
|
||||
self.log.info(f"group_force_stop_xiaoai {self.group_name} {device_id_list}")
|
||||
@@ -910,7 +914,7 @@ class XiaoMusicDevice:
|
||||
|
||||
async def cancel_group_next_timer(self):
|
||||
"""取消组内所有设备的下一首定时器"""
|
||||
devices = self.xiaomusic._device_manager.get_group_devices(self.group_name)
|
||||
devices = self.xiaomusic.device_manager.get_group_devices(self.group_name)
|
||||
self.log.info(f"cancel_group_next_timer {devices}")
|
||||
for device in devices.values():
|
||||
await device.cancel_next_timer()
|
||||
@@ -955,7 +959,7 @@ class XiaoMusicDevice:
|
||||
5. 所有电台
|
||||
6. 全部
|
||||
"""
|
||||
music_list = self.xiaomusic._music_library.music_list
|
||||
music_list = self.xiaomusic.music_library.music_list
|
||||
if name in music_list.get("收藏", []):
|
||||
return "收藏"
|
||||
if name in music_list.get("最近新增", []):
|
||||
|
||||
@@ -46,7 +46,7 @@ class JSAdapter:
|
||||
}
|
||||
|
||||
# 添加到 all_music 字典中
|
||||
self.xiaomusic._music_library.all_music[music_id] = music_item
|
||||
self.xiaomusic.music_library.all_music[music_id] = music_item
|
||||
formatted_ids.append(music_id)
|
||||
|
||||
return formatted_ids
|
||||
|
||||
@@ -375,7 +375,7 @@ class OnlineMusicService:
|
||||
converted_music_list = self._convert_song_list_to_music_items(song_list)
|
||||
if not converted_music_list:
|
||||
return {"success": False, "error": "没有有效的歌曲可以添加"}
|
||||
music_library = self.xiaomusic._music_library
|
||||
music_library = self.xiaomusic.music_library
|
||||
# 更新配置中的音乐歌单Json
|
||||
music_library.update_music_list_json(
|
||||
list_name, converted_music_list, append
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import importlib
|
||||
import inspect
|
||||
import pkgutil
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from xiaomusic.xiaomusic import XiaoMusic
|
||||
|
||||
|
||||
class PluginManager:
|
||||
def __init__(self, xiaomusic, plugin_dir="plugins"):
|
||||
def __init__(self, xiaomusic: "XiaoMusic", plugin_dir="plugins"):
|
||||
self.xiaomusic = xiaomusic
|
||||
self.log = xiaomusic.log
|
||||
self._funcs = {}
|
||||
|
||||
@@ -41,33 +41,33 @@ class XiaoMusic:
|
||||
self.event_bus = EventBus()
|
||||
|
||||
# 初始化认证管理器(延迟初始化部分属性)
|
||||
self._auth_manager = None
|
||||
self.auth_manager = None
|
||||
|
||||
# 初始化设备管理器(延迟初始化)
|
||||
self._device_manager = None
|
||||
self.device_manager = None
|
||||
|
||||
self.running_task = []
|
||||
|
||||
# 音乐库管理器(延迟初始化,在配置准备好之后)
|
||||
self._music_library = None
|
||||
self.music_library = None
|
||||
|
||||
# 命令处理器(延迟初始化,在配置准备好之后)
|
||||
self._command_handler = None
|
||||
self.command_handler = None
|
||||
|
||||
# 配置管理器(延迟初始化)
|
||||
self._config_manager = None
|
||||
self.config_manager = None
|
||||
|
||||
# 初始化配置
|
||||
self.init_config()
|
||||
|
||||
# 初始化文件监控管理器
|
||||
self._file_watcher = None
|
||||
self.file_watcher = None
|
||||
|
||||
# 初始化在线音乐服务(延迟初始化,在 js_plugin_manager 之后)
|
||||
self._online_music_service = None
|
||||
self.online_music_service = None
|
||||
|
||||
# 初始化对话轮询器(延迟初始化,在配置和服务准备好之后)
|
||||
self._conversation_poller = None
|
||||
self.conversation_poller = None
|
||||
|
||||
# 初始化日志
|
||||
self.setup_logger()
|
||||
@@ -95,18 +95,18 @@ class XiaoMusic:
|
||||
self.log.error(f"Failed to initialize JS Adapter: {e}")
|
||||
|
||||
# 初始化配置管理器(在日志准备好之后)
|
||||
self._config_manager = ConfigManager(
|
||||
self.config_manager = ConfigManager(
|
||||
config=self.config,
|
||||
log=self.log,
|
||||
)
|
||||
|
||||
# 尝试从设置里加载配置
|
||||
config_data = self._config_manager.try_init_setting()
|
||||
config_data = self.config_manager.try_init_setting()
|
||||
if config_data:
|
||||
self.update_config_from_setting(config_data)
|
||||
|
||||
# 初始化音乐库管理器(在配置准备好之后)
|
||||
self._music_library = MusicLibrary(
|
||||
self.music_library = MusicLibrary(
|
||||
config=self.config,
|
||||
log=self.log,
|
||||
music_path=self.music_path,
|
||||
@@ -117,42 +117,42 @@ class XiaoMusic:
|
||||
)
|
||||
|
||||
# 启动时重新生成一次播放列表
|
||||
self._music_library.gen_all_music_list()
|
||||
self.music_library.gen_all_music_list()
|
||||
|
||||
# 初始化在线音乐服务(在 js_plugin_manager 准备好之后)
|
||||
self._online_music_service = OnlineMusicService(
|
||||
self.online_music_service = OnlineMusicService(
|
||||
log=self.log,
|
||||
js_plugin_manager=self.js_plugin_manager,
|
||||
xiaomusic_instance=self, # 传递xiaomusic实例
|
||||
)
|
||||
|
||||
# 初始化设备管理器(在配置准备好之后)
|
||||
self._device_manager = DeviceManager(
|
||||
self.device_manager = DeviceManager(
|
||||
config=self.config,
|
||||
log=self.log,
|
||||
xiaomusic=self,
|
||||
)
|
||||
|
||||
# 初始化认证管理器(在配置和设备管理器准备好之后)
|
||||
self._auth_manager = AuthManager(
|
||||
self.auth_manager = AuthManager(
|
||||
config=self.config,
|
||||
log=self.log,
|
||||
device_manager=self._device_manager,
|
||||
device_manager=self.device_manager,
|
||||
)
|
||||
|
||||
# 初始化插件
|
||||
self.plugin_manager = PluginManager(self)
|
||||
|
||||
# 初始化对话轮询器(在 device_id_did 准备好之后)
|
||||
self._conversation_poller = ConversationPoller(
|
||||
self.conversation_poller = ConversationPoller(
|
||||
config=self.config,
|
||||
log=self.log,
|
||||
auth_manager=self._auth_manager,
|
||||
device_manager=self._device_manager,
|
||||
auth_manager=self.auth_manager,
|
||||
device_manager=self.device_manager,
|
||||
)
|
||||
|
||||
# 初始化命令处理器(在所有依赖准备好之后)
|
||||
self._command_handler = CommandHandler(
|
||||
self.command_handler = CommandHandler(
|
||||
config=self.config,
|
||||
log=self.log,
|
||||
xiaomusic_instance=self,
|
||||
@@ -231,28 +231,28 @@ class XiaoMusic:
|
||||
except RuntimeError:
|
||||
loop = None
|
||||
|
||||
if not self._file_watcher:
|
||||
self._file_watcher = FileWatcherManager(
|
||||
if not self.file_watcher:
|
||||
self.file_watcher = FileWatcherManager(
|
||||
config=self.config,
|
||||
log=self.log,
|
||||
music_path=self.music_path,
|
||||
on_change_callback=self._on_file_change,
|
||||
)
|
||||
self._file_watcher.start(loop)
|
||||
self.file_watcher.start(loop)
|
||||
|
||||
def _on_file_change(self):
|
||||
self.log.info("检测到目录音乐文件变化,正在刷新歌曲列表。")
|
||||
self._music_library.gen_all_music_list()
|
||||
self.music_library.gen_all_music_list()
|
||||
# 更新每个设备的歌单
|
||||
self.update_all_playlist()
|
||||
|
||||
def stop_file_watch(self):
|
||||
if self._file_watcher:
|
||||
self._file_watcher.stop()
|
||||
if self.file_watcher:
|
||||
self.file_watcher.stop()
|
||||
|
||||
async def run_forever(self):
|
||||
self.log.info("run_forever start")
|
||||
self._music_library.try_gen_all_music_tag() # 事件循环开始后调用一次
|
||||
self.music_library.try_gen_all_music_tag() # 事件循环开始后调用一次
|
||||
self.crontab.start()
|
||||
await asyncio.create_task(self.analytics.send_startup_event())
|
||||
# 取配置 enable_file_watch 循环开始时调用一次,控制目录监控开关
|
||||
@@ -262,22 +262,20 @@ class XiaoMusic:
|
||||
assert (
|
||||
analytics_task is not None
|
||||
) # to keep the reference to task, do not remove this
|
||||
await self._auth_manager.init_all_data()
|
||||
await self.auth_manager.init_all_data()
|
||||
# 启动对话循环,传递回调函数
|
||||
await self._conversation_poller.run_conversation_loop(
|
||||
await self.conversation_poller.run_conversation_loop(
|
||||
self.do_check_cmd, self.reset_timer_when_answer
|
||||
)
|
||||
|
||||
# 匹配命令
|
||||
async def do_check_cmd(self, did="", query="", ctrl_panel=True, **kwargs):
|
||||
"""检查并执行命令(委托给 command_handler)"""
|
||||
return await self._command_handler.do_check_cmd(
|
||||
did, query, ctrl_panel, **kwargs
|
||||
)
|
||||
return await self.command_handler.do_check_cmd(did, query, ctrl_panel, **kwargs)
|
||||
|
||||
# 重置计时器
|
||||
async def reset_timer_when_answer(self, answer_length, did):
|
||||
await self._device_manager.devices[did].reset_timer_when_answer(answer_length)
|
||||
await self.device_manager.devices[did].reset_timer_when_answer(answer_length)
|
||||
|
||||
def append_running_task(self, task):
|
||||
self.running_task.append(task)
|
||||
@@ -301,20 +299,20 @@ class XiaoMusic:
|
||||
return False
|
||||
|
||||
async def check_replay(self, did):
|
||||
return await self._device_manager.devices[did].check_replay()
|
||||
return await self.device_manager.devices[did].check_replay()
|
||||
|
||||
def find_real_music_name(self, name, n):
|
||||
"""模糊搜索音乐名称(委托给 music_library)"""
|
||||
return self._music_library.find_real_music_name(name, n)
|
||||
return self.music_library.find_real_music_name(name, n)
|
||||
|
||||
def did_exist(self, did):
|
||||
return did in self._device_manager.devices
|
||||
return did in self.device_manager.devices
|
||||
|
||||
# 播放一个 url
|
||||
async def play_url(self, did="", arg1="", **kwargs):
|
||||
self.log.info(f"手动推送链接:{arg1}")
|
||||
url = arg1
|
||||
return await self._device_manager.devices[did].group_player_play(url)
|
||||
return await self.device_manager.devices[did].group_player_play(url)
|
||||
|
||||
# 设置为单曲循环
|
||||
async def set_play_type_one(self, did="", **kwargs):
|
||||
@@ -337,11 +335,11 @@ class XiaoMusic:
|
||||
await self.set_play_type(did, PLAY_TYPE_SEQ)
|
||||
|
||||
async def set_play_type(self, did="", play_type=PLAY_TYPE_RND, dotts=True):
|
||||
await self._device_manager.devices[did].set_play_type(play_type, dotts)
|
||||
await self.device_manager.devices[did].set_play_type(play_type, dotts)
|
||||
|
||||
# 设置为刷新列表
|
||||
async def gen_music_list(self, **kwargs):
|
||||
self._music_library.gen_all_music_list()
|
||||
self.music_library.gen_all_music_list()
|
||||
self.update_all_playlist()
|
||||
self.log.info("gen_music_list ok")
|
||||
|
||||
@@ -369,7 +367,7 @@ class XiaoMusic:
|
||||
await self.del_music(name)
|
||||
|
||||
async def del_music(self, name):
|
||||
filename = self._music_library.get_filename(name)
|
||||
filename = self.music_library.get_filename(name)
|
||||
if filename == "":
|
||||
self.log.info(f"${name} not exist")
|
||||
return
|
||||
@@ -379,21 +377,21 @@ class XiaoMusic:
|
||||
except OSError:
|
||||
self.log.error(f"del ${filename} failed")
|
||||
# 重新生成音乐列表
|
||||
self._music_library.gen_all_music_list()
|
||||
self.music_library.gen_all_music_list()
|
||||
self.update_all_playlist()
|
||||
|
||||
# ===========================在线搜索函数================================
|
||||
|
||||
def default_url(self):
|
||||
"""委托给 online_music_service"""
|
||||
return self._online_music_service.default_url()
|
||||
return self.online_music_service.default_url()
|
||||
|
||||
# 在线获取歌曲列表(委托给 online_music_service)
|
||||
async def get_music_list_online(
|
||||
self, plugin="all", keyword="", page=1, limit=20, **kwargs
|
||||
):
|
||||
"""委托给 online_music_service"""
|
||||
return await self._online_music_service.get_music_list_online(
|
||||
return await self.online_music_service.get_music_list_online(
|
||||
plugin, keyword, page, limit, **kwargs
|
||||
)
|
||||
|
||||
@@ -407,48 +405,46 @@ class XiaoMusic:
|
||||
self, plugin="all", keyword="", artist="", page=1, limit=20, **kwargs
|
||||
):
|
||||
"""委托给 online_music_service"""
|
||||
return await self._online_music_service.get_music_list_mf(
|
||||
return await self.online_music_service.get_music_list_mf(
|
||||
plugin, keyword, artist, page, limit, **kwargs
|
||||
)
|
||||
|
||||
# 调用MusicFree插件获取歌词(委托给 online_music_service)
|
||||
async def get_media_lyric(self, music_item):
|
||||
"""委托给 online_music_service"""
|
||||
return await self._online_music_service.get_media_lyric(music_item)
|
||||
return await self.online_music_service.get_media_lyric(music_item)
|
||||
|
||||
# 在线搜索歌手,添加歌手歌单并播放
|
||||
async def search_singer_play(self, did, search_key, name):
|
||||
"""委托给 online_music_service"""
|
||||
return await self._online_music_service.search_singer_play(
|
||||
did, search_key, name
|
||||
)
|
||||
return await self.online_music_service.search_singer_play(did, search_key, name)
|
||||
|
||||
# 追加歌手歌曲
|
||||
async def add_singer_song(self, list_name, name):
|
||||
"""委托给 online_music_service"""
|
||||
return await self._online_music_service.add_singer_song(list_name, name)
|
||||
return await self.online_music_service.add_singer_song(list_name, name)
|
||||
|
||||
# 在线搜索搜索最符合的一首歌并播放
|
||||
async def search_top_one_play(self, did, search_key, name):
|
||||
"""委托给 online_music_service"""
|
||||
return await self._online_music_service.search_top_one_play(
|
||||
return await self.online_music_service.search_top_one_play(
|
||||
did, search_key, name
|
||||
)
|
||||
|
||||
# 在线播放:在线搜索、播放
|
||||
async def online_play(self, did="", arg1="", **kwargs):
|
||||
"""委托给 online_music_service"""
|
||||
return await self._online_music_service.online_play(did, arg1, **kwargs)
|
||||
return await self.online_music_service.online_play(did, arg1, **kwargs)
|
||||
|
||||
# 播放歌手:在线搜索歌手并存为列表播放
|
||||
async def singer_play(self, did="", arg1="", **kwargs):
|
||||
"""委托给 online_music_service"""
|
||||
return await self._online_music_service.singer_play(did, arg1, **kwargs)
|
||||
return await self.online_music_service.singer_play(did, arg1, **kwargs)
|
||||
|
||||
# 处理推送的歌单并播放
|
||||
async def push_music_list_play(self, did, song_list, list_name):
|
||||
"""委托给 online_music_service"""
|
||||
return await self._online_music_service.push_music_list_play(
|
||||
return await self.online_music_service.push_music_list_play(
|
||||
did, song_list, list_name
|
||||
)
|
||||
|
||||
@@ -456,7 +452,7 @@ class XiaoMusic:
|
||||
|
||||
def _find_real_music_list_name(self, list_name):
|
||||
"""模糊搜索播放列表名称(委托给 music_library)"""
|
||||
return self._music_library.find_real_music_list_name(list_name)
|
||||
return self.music_library.find_real_music_list_name(list_name)
|
||||
|
||||
# 播放一个播放列表
|
||||
async def play_music_list(self, did="", arg1="", **kwargs):
|
||||
@@ -472,12 +468,12 @@ class XiaoMusic:
|
||||
# 查找并获取真实的音乐列表名称
|
||||
list_name = self._find_real_music_list_name(list_name)
|
||||
# 检查音乐列表是否存在,如果不存在则进行语音提示并返回
|
||||
if list_name not in self._music_library.music_list:
|
||||
if list_name not in self.music_library.music_list:
|
||||
await self.do_tts(did, f"播放列表{list_name}不存在")
|
||||
return
|
||||
|
||||
# 调用设备播放音乐列表的方法
|
||||
await self._device_manager.devices[did].play_music_list(list_name, music_name)
|
||||
await self.device_manager.devices[did].play_music_list(list_name, music_name)
|
||||
|
||||
# 播放一个播放列表里第几个
|
||||
async def play_music_list_index(self, did="", arg1="", **kwargs):
|
||||
@@ -490,16 +486,16 @@ class XiaoMusic:
|
||||
chinese_index = matcharg.groups()[0]
|
||||
list_name = matcharg.groups()[1]
|
||||
list_name = self._find_real_music_list_name(list_name)
|
||||
if list_name not in self._music_library.music_list:
|
||||
if list_name not in self.music_library.music_list:
|
||||
await self.do_tts(did, f"播放列表{list_name}不存在")
|
||||
return
|
||||
|
||||
index = chinese_to_number(chinese_index)
|
||||
play_list = self._music_library.music_list[list_name]
|
||||
play_list = self.music_library.music_list[list_name]
|
||||
if 0 <= index - 1 < len(play_list):
|
||||
music_name = play_list[index - 1]
|
||||
self.log.info(f"即将播放 ${arg1} 里的第 ${index} 个: ${music_name}")
|
||||
await self._device_manager.devices[did].play_music_list(
|
||||
await self.device_manager.devices[did].play_music_list(
|
||||
list_name, music_name
|
||||
)
|
||||
return
|
||||
@@ -535,31 +531,31 @@ class XiaoMusic:
|
||||
async def do_play(
|
||||
self, did, name, search_key="", exact=False, update_cur_list=False
|
||||
):
|
||||
return await self._device_manager.devices[did].play(
|
||||
return await self.device_manager.devices[did].play(
|
||||
name, search_key, exact, update_cur_list
|
||||
)
|
||||
|
||||
# 本地播放
|
||||
async def playlocal(self, did="", arg1="", **kwargs):
|
||||
return await self._device_manager.devices[did].playlocal(
|
||||
return await self.device_manager.devices[did].playlocal(
|
||||
arg1, update_cur_list=True
|
||||
)
|
||||
|
||||
# 本地搜索播放
|
||||
async def search_playlocal(self, did="", arg1="", **kwargs):
|
||||
return await self._device_manager.devices[did].playlocal(
|
||||
return await self.device_manager.devices[did].playlocal(
|
||||
arg1, exact=False, update_cur_list=False
|
||||
)
|
||||
|
||||
async def play_next(self, did="", **kwargs):
|
||||
return await self._device_manager.devices[did].play_next()
|
||||
return await self.device_manager.devices[did].play_next()
|
||||
|
||||
async def play_prev(self, did="", **kwargs):
|
||||
return await self._device_manager.devices[did].play_prev()
|
||||
return await self.device_manager.devices[did].play_prev()
|
||||
|
||||
# 停止
|
||||
async def stop(self, did="", arg1="", **kwargs):
|
||||
return await self._device_manager.devices[did].stop(arg1=arg1)
|
||||
return await self.device_manager.devices[did].stop(arg1=arg1)
|
||||
|
||||
# 定时关机
|
||||
async def stop_after_minute(self, did="", arg1=0, **kwargs):
|
||||
@@ -569,7 +565,7 @@ class XiaoMusic:
|
||||
except (KeyError, ValueError):
|
||||
# 如果阿拉伯数字转换失败,尝试中文数字
|
||||
minute = chinese_to_number(str(arg1))
|
||||
return await self._device_manager.devices[did].stop_after_minute(minute)
|
||||
return await self.device_manager.devices[did].stop_after_minute(minute)
|
||||
|
||||
# 添加歌曲到收藏列表
|
||||
async def add_to_favorites(self, did="", arg1="", **kwargs):
|
||||
@@ -594,52 +590,52 @@ class XiaoMusic:
|
||||
# 更新每个设备的歌单
|
||||
def update_all_playlist(self):
|
||||
"""更新每个设备的歌单"""
|
||||
for device in self._device_manager.devices.values():
|
||||
for device in self.device_manager.devices.values():
|
||||
device.update_playlist()
|
||||
|
||||
# 获取音量
|
||||
async def get_volume(self, did="", **kwargs):
|
||||
return await self._device_manager.devices[did].get_volume()
|
||||
return await self.device_manager.devices[did].get_volume()
|
||||
|
||||
# 设置音量
|
||||
async def set_volume(self, did="", arg1=0, **kwargs):
|
||||
if did not in self._device_manager.devices:
|
||||
if did not in self.device_manager.devices:
|
||||
self.log.info(f"设备 did:{did} 不存在, 不能设置音量")
|
||||
return
|
||||
volume = int(arg1)
|
||||
return await self._device_manager.devices[did].set_volume(volume)
|
||||
return await self.device_manager.devices[did].set_volume(volume)
|
||||
|
||||
# 搜索音乐
|
||||
def searchmusic(self, name):
|
||||
"""搜索音乐(委托给 music_library)"""
|
||||
return self._music_library.searchmusic(name)
|
||||
return self.music_library.searchmusic(name)
|
||||
|
||||
# 获取播放列表
|
||||
def get_music_list(self):
|
||||
"""获取播放列表(委托给 music_library)"""
|
||||
return self._music_library.get_music_list()
|
||||
return self.music_library.get_music_list()
|
||||
|
||||
# 获取当前的播放列表
|
||||
def get_cur_play_list(self, did):
|
||||
return self._device_manager.devices[did].get_cur_play_list()
|
||||
return self.device_manager.devices[did].get_cur_play_list()
|
||||
|
||||
# 正在播放中的音乐
|
||||
def playingmusic(self, did):
|
||||
cur_music = self._device_manager.devices[did].get_cur_music()
|
||||
cur_music = self.device_manager.devices[did].get_cur_music()
|
||||
self.log.debug(f"playingmusic. cur_music:{cur_music}")
|
||||
return cur_music
|
||||
|
||||
def get_offset_duration(self, did):
|
||||
return self._device_manager.devices[did].get_offset_duration()
|
||||
return self.device_manager.devices[did].get_offset_duration()
|
||||
|
||||
# 当前是否正在播放歌曲
|
||||
def isplaying(self, did):
|
||||
return self._device_manager.devices[did].isplaying()
|
||||
return self.device_manager.devices[did].isplaying()
|
||||
|
||||
# 获取当前配置
|
||||
def getconfig(self):
|
||||
"""获取当前配置(委托给 config_manager)"""
|
||||
return self._config_manager.get_config()
|
||||
return self.config_manager.get_config()
|
||||
|
||||
# 保存配置并重新启动
|
||||
async def saveconfig(self, data):
|
||||
@@ -654,12 +650,12 @@ class XiaoMusic:
|
||||
# 把当前配置落地
|
||||
def save_cur_config(self):
|
||||
"""把当前配置落地(委托给 config_manager)"""
|
||||
self._config_manager.save_cur_config(self._device_manager.devices)
|
||||
self.config_manager.save_cur_config(self.device_manager.devices)
|
||||
|
||||
def update_config_from_setting(self, data):
|
||||
"""从设置更新配置"""
|
||||
# 委托给 config_manager 更新配置
|
||||
self._config_manager.update_config(data)
|
||||
self.config_manager.update_config(data)
|
||||
|
||||
# 重新初始化配置相关的属性
|
||||
self.init_config()
|
||||
@@ -687,8 +683,8 @@ class XiaoMusic:
|
||||
for handler in self.log.handlers:
|
||||
handler.close()
|
||||
self.setup_logger()
|
||||
await self._auth_manager.init_all_data()
|
||||
self._music_library.gen_all_music_list()
|
||||
await self.auth_manager.init_all_data()
|
||||
self.music_library.gen_all_music_list()
|
||||
self.update_all_playlist()
|
||||
|
||||
debug_config = deepcopy_data_no_sensitive_info(self.config)
|
||||
@@ -698,7 +694,7 @@ class XiaoMusic:
|
||||
async def getalldevices(self, **kwargs):
|
||||
device_list = []
|
||||
try:
|
||||
device_list = await self._auth_manager.mina_service.device_list()
|
||||
device_list = await self.auth_manager.mina_service.device_list()
|
||||
except Exception as e:
|
||||
self.log.warning(f"Execption {e}")
|
||||
# 重新初始化
|
||||
@@ -711,7 +707,7 @@ class XiaoMusic:
|
||||
data = arg1
|
||||
device_id = self.config.get_one_device_id()
|
||||
self.log.info(f"debug_play_by_music_url: {data} {device_id}")
|
||||
return await self._auth_manager.mina_service.ubus_request(
|
||||
return await self.auth_manager.mina_service.ubus_request(
|
||||
device_id,
|
||||
"player_play_music",
|
||||
"mediaplayer",
|
||||
@@ -719,13 +715,13 @@ class XiaoMusic:
|
||||
)
|
||||
|
||||
async def exec(self, did="", arg1=None, **kwargs):
|
||||
self._auth_manager._cur_did = did
|
||||
self.auth_manager._cur_did = did
|
||||
code = arg1 if arg1 else 'code1("hello")'
|
||||
await self.plugin_manager.execute_plugin(code)
|
||||
|
||||
# 此接口用于插件中获取当前设备
|
||||
def get_cur_did(self):
|
||||
return self._auth_manager._cur_did
|
||||
return self.auth_manager._cur_did
|
||||
|
||||
async def do_tts(self, did, value):
|
||||
return await self._device_manager.devices[did].do_tts(value)
|
||||
return await self.device_manager.devices[did].do_tts(value)
|
||||
|
||||
Reference in New Issue
Block a user