From e261239daa86347fa41b93f4d4f8d79e52742de2 Mon Sep 17 00:00:00 2001 From: hpcll <1471009316@qq.com> Date: Wed, 11 Feb 2026 07:07:34 +0800 Subject: [PATCH] feat: add dirname parameter to /downloadonemusic API (#749) Add optional dirname parameter to single music download endpoint, allowing downloads to be saved to a subdirectory under download_path. This makes it consistent with /downloadplaylist which already supports dirname. Changes: - Add dirname field to DownloadOneMusic schema (default empty) - Update download_one_music() to accept dirname parameter - Update /downloadonemusic endpoint to pass dirname Co-authored-by: pc hu <> --- xiaomusic/api/models.py | 1 + xiaomusic/api/routers/file.py | 19 ++++++++++++++++--- xiaomusic/utils/network_utils.py | 11 +++++++++-- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/xiaomusic/api/models.py b/xiaomusic/api/models.py index 4a748d7..dd0cc3c 100644 --- a/xiaomusic/api/models.py +++ b/xiaomusic/api/models.py @@ -56,6 +56,7 @@ class DownloadPlayList(BaseModel): class DownloadOneMusic(BaseModel): name: str = "" url: str + dirname: str = "" class PlayListObj(BaseModel): diff --git a/xiaomusic/api/routers/file.py b/xiaomusic/api/routers/file.py index f51ec21..39a8a84 100644 --- a/xiaomusic/api/routers/file.py +++ b/xiaomusic/api/routers/file.py @@ -167,15 +167,28 @@ async def downloadplaylist(data: DownloadPlayList, Verifcation=Depends(verificat @router.post("/downloadonemusic") async def downloadonemusic(data: DownloadOneMusic, Verifcation=Depends(verification)): - """下载单首歌曲""" + """下载单首歌曲 + + Args: + data.name: 文件名(可选) + data.url: 下载链接(必填) + data.dirname: 子目录名(可选),相对于下载目录 + """ try: - download_proc = await download_one_music(config, data.url, data.name) + download_proc = await download_one_music( + config, data.url, data.name, data.dirname + ) + + # 计算实际下载路径 + download_path = config.download_path + if data.dirname: + download_path = os.path.join(config.download_path, data.dirname) async def check_download_proc(): # 等待子进程完成 exit_code = await download_proc.wait() log.info(f"Download completed with exit code {exit_code}") - chmoddir(config.download_path) + chmoddir(download_path) asyncio.create_task(check_download_proc()) return {"ret": "OK"} diff --git a/xiaomusic/utils/network_utils.py b/xiaomusic/utils/network_utils.py index 78dccc1..b674ba1 100644 --- a/xiaomusic/utils/network_utils.py +++ b/xiaomusic/utils/network_utils.py @@ -191,7 +191,7 @@ async def download_playlist(config, url: str, dirname: str): return download_proc -async def download_one_music(config, url: str, name: str = ""): +async def download_one_music(config, url: str, name: str = "", dirname: str = ""): """ 下载单首歌曲 @@ -199,10 +199,17 @@ async def download_one_music(config, url: str, name: str = ""): config: 配置对象 url: 歌曲 URL name: 文件名(可选) + dirname: 子目录名(可选),相对于 download_path Returns: 下载进程对象 """ + # 计算下载路径 + download_path = config.download_path + if dirname: + download_path = os.path.join(config.download_path, dirname) + os.makedirs(download_path, exist_ok=True) + title = "%(title)s.%(ext)s" if name: title = f"{name}.%(ext)s" @@ -215,7 +222,7 @@ async def download_one_music(config, url: str, name: str = ""): "--audio-quality", "0", "--paths", - config.download_path, + download_path, "-o", title, "--ffmpeg-location",