feat: 新增 yt-dlp cookies 文件参数支持

This commit is contained in:
涵曦 2024-09-29 10:19:50 +08:00
parent 4330f61888
commit 86110a2e65
11 changed files with 102 additions and 22 deletions

View File

@ -61,7 +61,13 @@ include = ["**/*.py", "**/*.pyi", "**/pyproject.toml"]
convention = "google"
[tool.ruff.lint.flake8-bugbear]
extend-immutable-calls = ["fastapi.Depends", "fastapi.params.Depends", "fastapi.Query", "fastapi.params.Query"]
extend-immutable-calls = [
"fastapi.Depends",
"fastapi.params.Depends",
"fastapi.Query",
"fastapi.params.Query",
"fastapi.File"
]
[tool.pdm.scripts]
lint = "ruff check ."

View File

@ -155,6 +155,9 @@ class Config:
)
pull_ask_sec: int = int(os.getenv("XIAOMUSIC_PULL_ASK_SEC", "1"))
crontab_json: str = os.getenv("XIAOMUSIC_CRONTAB_JSON", "") # 定时任务
enable_yt_dlp_cookies: bool = (
os.getenv("XIAOMUSIC_ENABLE_YT_DLP_COOKIES", "false").lower() == "true"
)
def append_keyword(self, keys, action):
for key in keys.split(","):
@ -262,3 +265,10 @@ class Config:
if not os.path.exists(cache_path):
os.makedirs(cache_path)
return cache_path
@property
def yt_dlp_cookies_path(self):
if not os.path.exists(self.conf_path):
os.makedirs(self.conf_path)
cookies_path = os.path.join(self.conf_path, "yt-dlp-cookie.txt")
return cookies_path

View File

@ -13,7 +13,16 @@ from dataclasses import asdict
from typing import Annotated
import aiofiles
from fastapi import Depends, FastAPI, HTTPException, Query, Request, status
from fastapi import (
Depends,
FastAPI,
File,
HTTPException,
Query,
Request,
UploadFile,
status,
)
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
from fastapi.security import HTTPBasic, HTTPBasicCredentials
@ -389,15 +398,9 @@ async def downloadplaylist(data: DownloadPlayList, Verifcation=Depends(verificat
log.info(f"Download completed with exit code {exit_code}")
dir_path = os.path.join(config.download_path, data.dirname)
log.debug(f"Download dir_path: {exit_code}")
if exit_code == 0:
log.info("Download was successful.")
# 执行成功的后续逻辑:文件名处理
remove_common_prefix(dir_path)
else:
# 处理失败的情况
log.error("Download failed.")
log.debug(f"Download dir_path: {dir_path}")
# 可能只是部分失败,都需要整理下载目录
remove_common_prefix(dir_path)
asyncio.create_task(check_download_proc())
return {"ret": "OK"}
@ -424,6 +427,18 @@ async def downloadonemusic(data: DownloadOneMusic, Verifcation=Depends(verificat
return {"ret": "Failed download"}
# 上传 yt-dlp cookies
@app.post("/uploadytdlpcookie")
async def upload_yt_dlp_cookie(file: UploadFile = File(...)):
with open(config.yt_dlp_cookies_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
return {
"ret": "OK",
"filename": file.filename,
"file_location": config.yt_dlp_cookies_path,
}
async def file_iterator(file_path, start, end):
async with aiofiles.open(file_path, mode="rb") as file:
await file.seek(start)

View File

@ -6,9 +6,9 @@
<meta name="viewport" content="width=device-width">
<title>Debug For XiaoMusic</title>
<link rel="stylesheet" type="text/css" href="./style.css?version=1727434231">
<link rel="stylesheet" type="text/css" href="./style.css?version=1727575583">
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
<script src="./jquery-3.7.1.min.js?version=1727434231"></script>
<script src="./jquery-3.7.1.min.js?version=1727575583"></script>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>

View File

@ -4,8 +4,8 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>歌曲下载工具</title>
<link rel="stylesheet" type="text/css" href="./style.css?version=1727434231">
<script src="./jquery-3.7.1.min.js?version=1727434231"></script>
<link rel="stylesheet" type="text/css" href="./style.css?version=1727575583">
<script src="./jquery-3.7.1.min.js?version=1727575583"></script>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>

View File

@ -4,9 +4,9 @@
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width">
<title>小爱音箱操控面板</title>
<script src="./jquery-3.7.1.min.js?version=1727434231"></script>
<script src="./app.js?version=1727434231"></script>
<link rel="stylesheet" type="text/css" href="./style.css?version=1727434231">
<script src="./jquery-3.7.1.min.js?version=1727575583"></script>
<script src="./app.js?version=1727575583"></script>
<link rel="stylesheet" type="text/css" href="./style.css?version=1727575583">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>

View File

@ -5,7 +5,7 @@
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width">
<title>M3U to JSON Converter</title>
<link rel="stylesheet" type="text/css" href="./style.css?version=1727434231">
<link rel="stylesheet" type="text/css" href="./style.css?version=1727575583">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>

View File

@ -4,9 +4,9 @@
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width">
<title>小爱音箱操控面板</title>
<script src="./jquery-3.7.1.min.js?version=1727434231"></script>
<script src="./setting.js?version=1727434231"></script>
<link rel="stylesheet" type="text/css" href="./style.css?version=1727434231">
<script src="./jquery-3.7.1.min.js?version=1727575583"></script>
<script src="./setting.js?version=1727575583"></script>
<link rel="stylesheet" type="text/css" href="./style.css?version=1727575583">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
@ -177,6 +177,12 @@ var vConsole = new window.VConsole();
<label for="keywords_stop">停止口令:</label>
<input id="keywords_stop" type="text" value="关机,暂停,停止,停止播放"></input>
<label for="enable_yt_dlp_cookies">启用yt-dlp-cookies(需要先上传yt-dlp-cookies.txt文件):</label>
<select id="enable_yt_dlp_cookies">
<option value="true">true</option>
<option value="false" selected>false</option>
</select>
<label for="music_list_url">歌单地址:</label>
<input id="music_list_url" type="text" value="https://gist.githubusercontent.com/hanxi/dda82d964a28f8110f8fba81c3ff8314/raw/example.json"></input>
@ -198,6 +204,13 @@ var vConsole = new window.VConsole();
<a class="button" href="/downloadlog" download="xiaomusic.txt">下载日志文件</a>
<hr>
<div class="rows">
<label for="yt_dlp_cookies_file">上传yt_dlp_cookies.txt文件:<a href="https://github.com/hanxi/xiaomusic/issues/210" target="_blank">文档</a></label>
<input id="yt_dlp_cookies_file" name="file" type="file">
<button id="upload_yt_dlp_cookie">上传</button>
</div>
<hr>
<button onclick="location.href='/docs';">查看接口文档</button>
<a class="button" href="./m3u.html" target="_blank">m3u文件转换</a>
<a class="button" href="./downloadtool.html" target="_blank">歌曲下载工具</a>

View File

@ -154,4 +154,31 @@ $(function(){
});
});
$("#upload_yt_dlp_cookie").on("click", () => {
var fileInput = document.getElementById('yt_dlp_cookies_file');
var file = fileInput.files[0]; // 获取文件对象
if (file) {
var formData = new FormData();
formData.append("file", file);
$.ajax({
url: "/uploadytdlpcookie",
type: "POST",
data: formData,
processData: false,
contentType: false,
success: function(res) {
console.log(res);
alert("上传成功");
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(res);
alert("上传失败");
}
});
} else {
alert("请选择一个文件");
}
});
});

View File

@ -696,6 +696,9 @@ async def download_playlist(config, url, dirname):
if config.proxy:
sbp_args += ("--proxy", f"{config.proxy}")
if config.enable_yt_dlp_cookies:
sbp_args += ("--cookies", f"{config.yt_dlp_cookies_path}")
sbp_args += (url,)
cmd = " ".join(sbp_args)
@ -726,6 +729,9 @@ async def download_one_music(config, url, name=""):
if config.proxy:
sbp_args += ("--proxy", f"{config.proxy}")
if config.enable_yt_dlp_cookies:
sbp_args += ("--cookies", f"{config.yt_dlp_cookies_path}")
sbp_args += (url,)
cmd = " ".join(sbp_args)

View File

@ -1462,6 +1462,9 @@ class XiaoMusicDevice:
if self.config.proxy:
sbp_args += ("--proxy", f"{self.config.proxy}")
if self.config.yt_dlp_cookies:
sbp_args += ("--cookies", f"{self.config.yt_dlp_cookies}")
cmd = " ".join(sbp_args)
self.log.info(f"download cmd: {cmd}")
self._download_proc = await asyncio.create_subprocess_exec(*sbp_args)