mirror of
https://github.com/hanxi/xiaomusic.git
synced 2025-12-07 15:02:55 +08:00
Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cca6e47da5 | ||
|
|
415e75d4b4 | ||
|
|
3c5573a2fc | ||
|
|
7275b59d40 | ||
|
|
a8d0631c33 | ||
|
|
3cfc96b779 | ||
|
|
489f3f1d6f | ||
|
|
a5f2fc195e | ||
|
|
393dbabf4b | ||
|
|
444e697f9d | ||
|
|
cf01039b53 | ||
|
|
a8fefc6f82 | ||
|
|
ae0b6066d9 | ||
|
|
53f5e7db8c | ||
|
|
2a1fa9f8cf | ||
|
|
6e2d674758 | ||
|
|
3bb6573ec0 | ||
|
|
4ae3774a0e | ||
|
|
b34215560c | ||
|
|
4426017ba8 | ||
|
|
f1635f8e32 | ||
|
|
4de032e193 | ||
|
|
d655157e1d | ||
|
|
ff06958ab3 | ||
|
|
6e98b5ee2b | ||
|
|
da90fe2633 | ||
|
|
eaedef452c | ||
|
|
2d5f3799a3 | ||
|
|
b52bfe0848 | ||
|
|
e2261b2d19 | ||
|
|
2443444165 | ||
|
|
7c912a51be | ||
|
|
bda55a1faa | ||
|
|
5b5f957f8e | ||
|
|
12f54e3ad4 | ||
|
|
d6594e1270 | ||
|
|
b678447417 | ||
|
|
02508f6997 | ||
|
|
d50fff9e31 | ||
|
|
2d7d7ddc95 | ||
|
|
9c9825d423 | ||
|
|
f788c0f37b | ||
|
|
36d72d1eca | ||
|
|
6b17779c59 | ||
|
|
759130e38d | ||
|
|
49f727477e | ||
|
|
43886116c1 | ||
|
|
a38194027d | ||
|
|
eab4f4bd46 | ||
|
|
6b38676766 | ||
|
|
3830f58c0b | ||
|
|
34cdea1731 | ||
|
|
22f545b99c | ||
|
|
37f73dc31f | ||
|
|
10e52f0b63 | ||
|
|
b0ac1034d2 |
26
.github/workflows/release.yml
vendored
26
.github/workflows/release.yml
vendored
@@ -10,31 +10,25 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
release-pypi:
|
||||
name: Build and Release PyPI
|
||||
pypi-publish:
|
||||
name: upload release to PyPI
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- uses: pdm-project/setup-pdm@v3
|
||||
|
||||
- name: Publish package distributions to PyPI
|
||||
run: pdm publish
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Build artifacts
|
||||
run: |
|
||||
pip install build
|
||||
python -m build
|
||||
|
||||
- uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
password: ${{ secrets.PYPI_API_TOKEN }}
|
||||
node-version: 16.x
|
||||
|
||||
- run: npx changelogithub
|
||||
continue-on-error: true
|
||||
|
||||
92
CHANGELOG.md
92
CHANGELOG.md
@@ -1,3 +1,95 @@
|
||||
## v0.3.25 (2024-08-16)
|
||||
|
||||
### Feat
|
||||
|
||||
- 设置页面支持配置 use_music_api 选项
|
||||
|
||||
## v0.3.24 (2024-08-01)
|
||||
|
||||
### Fix
|
||||
|
||||
- #131 修复多设备切换时播放模式显示错误问题
|
||||
|
||||
## v0.3.23 (2024-08-01)
|
||||
|
||||
### Fix
|
||||
|
||||
- 修复部分文件获取不到播放时长问题
|
||||
- 处理安全问题
|
||||
|
||||
## v0.3.22 (2024-08-01)
|
||||
|
||||
### Feat
|
||||
|
||||
- 网关模式支持配置,默认关闭
|
||||
|
||||
### Fix
|
||||
|
||||
- 继续优化延迟问题
|
||||
|
||||
## v0.3.21 (2024-07-30)
|
||||
|
||||
### Feat
|
||||
|
||||
- 尝试加个网关在前面处理静态文件来加速文件获取
|
||||
|
||||
### Fix
|
||||
|
||||
- 使用前置网关处理静态文件来加速,尝试解决延迟的问题
|
||||
- 播放前先立即暂停之前的音乐
|
||||
|
||||
## v0.3.20 (2024-07-30)
|
||||
|
||||
### Fix
|
||||
|
||||
- 尝试修复延迟问题,修复播放停止不了的问题
|
||||
|
||||
## v0.3.19 (2024-07-30)
|
||||
|
||||
### Fix
|
||||
|
||||
- 调整配置,优化获取歌曲时长接口
|
||||
|
||||
## v0.3.18 (2024-07-29)
|
||||
|
||||
### Fix
|
||||
|
||||
- #135 修复获取不到播放时长时只播放3秒的问题
|
||||
|
||||
## v0.3.17 (2024-07-28)
|
||||
|
||||
### Fix
|
||||
|
||||
- 优化日志输出,尝试排查延迟播放的问题
|
||||
|
||||
## v0.3.16 (2024-07-28)
|
||||
|
||||
## v0.3.15 (2024-07-28)
|
||||
|
||||
### Fix
|
||||
|
||||
- 修复自定义口令重复的问题
|
||||
- 修复日志输出问题
|
||||
- 修复退出异常问题
|
||||
|
||||
## v0.3.14 (2024-07-28)
|
||||
|
||||
### Feat
|
||||
|
||||
- 优化播放延迟问题,并新增配置下一首播放的延迟秒数
|
||||
|
||||
## v0.3.13 (2024-07-24)
|
||||
|
||||
### Fix
|
||||
|
||||
- 解决 docker 镜像问题
|
||||
|
||||
## v0.3.12 (2024-07-24)
|
||||
|
||||
### Feat
|
||||
|
||||
- 优化获取文件播放时长接口,尝试解决播放延迟和操作面板卡顿的问题
|
||||
|
||||
## v0.3.11 (2024-07-22)
|
||||
|
||||
### Feat
|
||||
|
||||
10
Dockerfile
10
Dockerfile
@@ -1,8 +1,13 @@
|
||||
FROM python:3.10 AS builder
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN pip install -U pdm
|
||||
ENV PDM_CHECK_UPDATE=false
|
||||
WORKDIR /app
|
||||
COPY requirements.txt .
|
||||
RUN python3 -m venv .venv && .venv/bin/pip install --upgrade pip && .venv/bin/pip install --no-cache-dir -r requirements.txt
|
||||
COPY pyproject.toml README.md .
|
||||
COPY xiaomusic/ ./xiaomusic/
|
||||
COPY plugins/ ./plugins/
|
||||
COPY xiaomusic.py .
|
||||
RUN pdm install --prod --no-editable
|
||||
COPY install_dependencies.sh .
|
||||
RUN bash install_dependencies.sh
|
||||
|
||||
@@ -13,7 +18,6 @@ COPY --from=builder /app/ffmpeg /app/ffmpeg
|
||||
COPY xiaomusic/ ./xiaomusic/
|
||||
COPY plugins/ ./plugins/
|
||||
COPY xiaomusic.py .
|
||||
ENV XDG_CONFIG_HOME=/config
|
||||
ENV XIAOMUSIC_HOSTNAME=192.168.2.5
|
||||
ENV XIAOMUSIC_PORT=8090
|
||||
VOLUME /app/conf
|
||||
|
||||
@@ -37,7 +37,7 @@ services:
|
||||
```yaml
|
||||
docker run -p 8090:8090 \
|
||||
-v ./music:/app/music \
|
||||
-v ./conf:/app/conf
|
||||
-v ./conf:/app/conf \
|
||||
hanxi/xiaomusic
|
||||
```
|
||||
|
||||
@@ -63,6 +63,8 @@ services:
|
||||
XIAOMUSIC_PORT: 5678
|
||||
```
|
||||
|
||||
如果不是首次修改端口,还需要修改 setting.json 文件里的端口。
|
||||
|
||||
遇到问题可以去 web 设置页面底部点击【下载日志文件】按钮,然后搜索一下日志文件内容确保里面没有账号密码信息后(有就删除这些敏感信息),然后在提 issues 反馈问题时把下载的日志文件带上。
|
||||
|
||||
> 目前除了 XIAOMUSIC_PORT 只能在启动前配置,其他参数都可以在 web 网页里配置。
|
||||
|
||||
159
pdm.lock
generated
159
pdm.lock
generated
@@ -4,16 +4,48 @@
|
||||
[metadata]
|
||||
groups = ["default", "dev", "lint"]
|
||||
strategy = ["inherit_metadata"]
|
||||
lock_version = "4.4.2"
|
||||
content_hash = "sha256:fe8f356d82d38641f48975833c27c352829a895c3c3293c36e0e010a3202966e"
|
||||
lock_version = "4.5.0"
|
||||
content_hash = "sha256:0a0b1f63fdd9dd2c4ca2a777f12d294126a880631c1b3d48108d1df283ba14a8"
|
||||
|
||||
[[metadata.targets]]
|
||||
requires_python = "==3.10.12"
|
||||
platform = "manylinux_2_35_x86_64"
|
||||
implementation = "cpython"
|
||||
gil_disabled = false
|
||||
|
||||
[[package]]
|
||||
name = "aiofiles"
|
||||
version = "24.1.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "File support for asyncio."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5"},
|
||||
{file = "aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aiohappyeyeballs"
|
||||
version = "2.3.4"
|
||||
requires_python = "<4.0,>=3.8"
|
||||
summary = "Happy Eyeballs for asyncio"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "aiohappyeyeballs-2.3.4-py3-none-any.whl", hash = "sha256:40a16ceffcf1fc9e142fd488123b2e218abc4188cf12ac20c67200e1579baa42"},
|
||||
{file = "aiohappyeyeballs-2.3.4.tar.gz", hash = "sha256:7e1ae8399c320a8adec76f6c919ed5ceae6edd4c3672f4d9eae2b27e37c80ff6"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aiohttp"
|
||||
version = "3.9.5"
|
||||
version = "3.10.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Async http client/server framework (asyncio)"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"aiohappyeyeballs>=2.3.0",
|
||||
"aiosignal>=1.1.2",
|
||||
"async-timeout<5.0,>=4.0; python_version < \"3.11\"",
|
||||
"attrs>=17.3.0",
|
||||
@@ -22,8 +54,8 @@ dependencies = [
|
||||
"yarl<2.0,>=1.0",
|
||||
]
|
||||
files = [
|
||||
{file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c26959ca7b75ff768e2776d8055bf9582a6267e24556bb7f7bd29e677932be72"},
|
||||
{file = "aiohttp-3.9.5.tar.gz", hash = "sha256:edea7d15772ceeb29db4aff55e482d4bcfb6ae160ce144f2682de02f6d693551"},
|
||||
{file = "aiohttp-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06ef0135d7ab7fb0284342fbbf8e8ddf73b7fee8ecc55f5c3a3d0a6b765e6d8b"},
|
||||
{file = "aiohttp-3.10.0.tar.gz", hash = "sha256:e8dd7da2609303e3574c95b0ec9f1fd49647ef29b94701a2862cceae76382e1d"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -32,6 +64,7 @@ version = "1.3.1"
|
||||
requires_python = ">=3.7"
|
||||
summary = "aiosignal: a list of registered asynchronous callbacks"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"frozenlist>=1.1.0",
|
||||
]
|
||||
@@ -46,6 +79,10 @@ version = "0.7.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Reusable constraint types to use with typing.Annotated"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"typing-extensions>=4.0.0; python_version < \"3.9\"",
|
||||
]
|
||||
files = [
|
||||
{file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"},
|
||||
{file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
|
||||
@@ -57,6 +94,7 @@ version = "4.4.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "High level compatibility layer for multiple asynchronous event loop implementations"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"exceptiongroup>=1.0.2; python_version < \"3.11\"",
|
||||
"idna>=2.8",
|
||||
@@ -74,6 +112,7 @@ version = "3.4.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Bash tab completion for argparse"
|
||||
groups = ["dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "argcomplete-3.4.0-py3-none-any.whl", hash = "sha256:69a79e083a716173e5532e0fa3bef45f793f4e61096cf52b5a42c0211c8b8aa5"},
|
||||
{file = "argcomplete-3.4.0.tar.gz", hash = "sha256:c2abcdfe1be8ace47ba777d4fce319eb13bf8ad9dace8d085dcad6eded88057f"},
|
||||
@@ -85,7 +124,10 @@ version = "4.0.3"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Timeout context manager for asyncio programs"
|
||||
groups = ["default"]
|
||||
marker = "python_version < \"3.11\""
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"typing-extensions>=3.6.5; python_version < \"3.8\"",
|
||||
]
|
||||
files = [
|
||||
{file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"},
|
||||
{file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"},
|
||||
@@ -97,6 +139,10 @@ version = "23.2.0"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Classes Without Boilerplate"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"importlib-metadata; python_version < \"3.8\"",
|
||||
]
|
||||
files = [
|
||||
{file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"},
|
||||
{file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"},
|
||||
@@ -107,7 +153,7 @@ name = "brotli"
|
||||
version = "1.1.0"
|
||||
summary = "Python bindings for the Brotli compression library"
|
||||
groups = ["default"]
|
||||
marker = "implementation_name == \"cpython\""
|
||||
marker = "implementation_name == \"cpython\" and python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "Brotli-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9"},
|
||||
@@ -154,6 +200,7 @@ version = "2024.7.4"
|
||||
requires_python = ">=3.6"
|
||||
summary = "Python package for providing Mozilla's CA Bundle."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"},
|
||||
{file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"},
|
||||
@@ -165,6 +212,7 @@ version = "3.3.2"
|
||||
requires_python = ">=3.7.0"
|
||||
summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
groups = ["default", "dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
|
||||
@@ -221,6 +269,11 @@ version = "8.1.7"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Composable command line interface toolkit"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"colorama; platform_system == \"Windows\"",
|
||||
"importlib-metadata; python_version < \"3.8\"",
|
||||
]
|
||||
files = [
|
||||
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
|
||||
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
|
||||
@@ -232,6 +285,7 @@ version = "0.4.6"
|
||||
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
summary = "Cross-platform colored terminal text."
|
||||
groups = ["dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
@@ -243,17 +297,20 @@ version = "3.28.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Python commitizen client tool"
|
||||
groups = ["dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"argcomplete<3.5,>=1.12.1",
|
||||
"charset-normalizer<4,>=2.1.0",
|
||||
"colorama<0.5.0,>=0.4.1",
|
||||
"decli<0.7.0,>=0.6.0",
|
||||
"importlib-metadata<9,>=8.0.0; python_version < \"3.10\"",
|
||||
"jinja2>=2.10.3",
|
||||
"packaging>=19",
|
||||
"pyyaml>=3.08",
|
||||
"questionary<3.0,>=2.0",
|
||||
"termcolor<3,>=1.1",
|
||||
"tomlkit<1.0.0,>=0.5.3",
|
||||
"typing-extensions<5.0.0,>=4.0.1; python_version < \"3.8\"",
|
||||
]
|
||||
files = [
|
||||
{file = "commitizen-3.28.0-py3-none-any.whl", hash = "sha256:372dba10bb082be0e571cfa9ac0946f4333c3f4b2e242fbe32ae2f2afea143e4"},
|
||||
@@ -266,6 +323,7 @@ version = "0.6.2"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Minimal, easy-to-use, declarative cli tool"
|
||||
groups = ["dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "decli-0.6.2-py3-none-any.whl", hash = "sha256:2fc84106ce9a8f523ed501ca543bdb7e416c064917c12a59ebdc7f311a97b7ed"},
|
||||
{file = "decli-0.6.2.tar.gz", hash = "sha256:36f71eb55fd0093895efb4f416ec32b7f6e00147dda448e3365cf73ceab42d6f"},
|
||||
@@ -277,6 +335,7 @@ version = "2.6.1"
|
||||
requires_python = ">=3.8"
|
||||
summary = "DNS toolkit"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50"},
|
||||
{file = "dnspython-2.6.1.tar.gz", hash = "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc"},
|
||||
@@ -288,6 +347,7 @@ version = "2.2.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "A robust email address syntax and deliverability validation library."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"dnspython>=2.0.0",
|
||||
"idna>=2.0.0",
|
||||
@@ -303,7 +363,7 @@ version = "1.2.2"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Backport of PEP 654 (exception groups)"
|
||||
groups = ["default"]
|
||||
marker = "python_version < \"3.11\""
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
|
||||
{file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
|
||||
@@ -315,6 +375,7 @@ version = "0.111.1"
|
||||
requires_python = ">=3.8"
|
||||
summary = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"email-validator>=2.0.0",
|
||||
"fastapi-cli>=0.0.2",
|
||||
@@ -337,6 +398,7 @@ version = "0.0.4"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Run and manage FastAPI apps from the command line with FastAPI CLI. 🚀"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"typer>=0.12.3",
|
||||
]
|
||||
@@ -351,6 +413,7 @@ version = "1.4.1"
|
||||
requires_python = ">=3.8"
|
||||
summary = "A list-like structure which implements collections.abc.MutableSequence"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"},
|
||||
{file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"},
|
||||
@@ -407,6 +470,10 @@ version = "0.14.0"
|
||||
requires_python = ">=3.7"
|
||||
summary = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"typing-extensions; python_version < \"3.8\"",
|
||||
]
|
||||
files = [
|
||||
{file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
|
||||
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
|
||||
@@ -418,6 +485,7 @@ version = "1.0.5"
|
||||
requires_python = ">=3.8"
|
||||
summary = "A minimal low-level HTTP client."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"certifi",
|
||||
"h11<0.15,>=0.13",
|
||||
@@ -433,6 +501,7 @@ version = "0.6.1"
|
||||
requires_python = ">=3.8.0"
|
||||
summary = "A collection of framework independent HTTP protocol utils."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "httptools-0.6.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f"},
|
||||
{file = "httptools-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563"},
|
||||
@@ -464,6 +533,7 @@ version = "0.27.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "The next generation HTTP client."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"anyio",
|
||||
"certifi",
|
||||
@@ -482,6 +552,7 @@ version = "3.7"
|
||||
requires_python = ">=3.5"
|
||||
summary = "Internationalized Domain Names in Applications (IDNA)"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"},
|
||||
{file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"},
|
||||
@@ -493,6 +564,7 @@ version = "3.1.4"
|
||||
requires_python = ">=3.7"
|
||||
summary = "A very fast and expressive template engine."
|
||||
groups = ["default", "dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"MarkupSafe>=2.0",
|
||||
]
|
||||
@@ -507,6 +579,7 @@ version = "3.0.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Python port of markdown-it. Markdown parsing, done right!"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"mdurl~=0.1",
|
||||
]
|
||||
@@ -521,6 +594,7 @@ version = "2.1.5"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Safely add untrusted strings to HTML/XML markup."
|
||||
groups = ["default", "dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
|
||||
@@ -561,6 +635,7 @@ version = "0.1.2"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Markdown URL utilities"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
|
||||
{file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
|
||||
@@ -572,6 +647,7 @@ version = "2.7.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "XiaoMi Cloud Service fork from https://github.com/Yonsm/MiService"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"aiohttp",
|
||||
"mutagen",
|
||||
@@ -588,6 +664,7 @@ version = "6.0.5"
|
||||
requires_python = ">=3.7"
|
||||
summary = "multidict implementation"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "multidict-6.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604"},
|
||||
@@ -644,6 +721,7 @@ version = "1.47.0"
|
||||
requires_python = ">=3.7"
|
||||
summary = "read and write audio tags for many formats"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "mutagen-1.47.0-py3-none-any.whl", hash = "sha256:edd96f50c5907a9539d8e5bba7245f62c9f520aef333d13392a79a4f70aca719"},
|
||||
{file = "mutagen-1.47.0.tar.gz", hash = "sha256:719fadef0a978c31b4cf3c956261b3c58b6948b32023078a2117b1de09f0fc99"},
|
||||
@@ -655,6 +733,7 @@ version = "24.1"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Core utilities for Python packages"
|
||||
groups = ["dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
|
||||
{file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
|
||||
@@ -666,6 +745,7 @@ version = "3.0.36"
|
||||
requires_python = ">=3.6.2"
|
||||
summary = "Library for building powerful interactive command lines in Python"
|
||||
groups = ["dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"wcwidth",
|
||||
]
|
||||
@@ -680,6 +760,7 @@ version = "3.20.0"
|
||||
requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
summary = "Cryptographic library for Python"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "pycryptodomex-3.20.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:59af01efb011b0e8b686ba7758d59cf4a8263f9ad35911bfe3f416cee4f5c08c"},
|
||||
{file = "pycryptodomex-3.20.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:82ee7696ed8eb9a82c7037f32ba9b7c59e51dda6f105b39f043b6ef293989cb3"},
|
||||
@@ -704,9 +785,11 @@ version = "2.8.2"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Data validation using Python type hints"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"annotated-types>=0.4.0",
|
||||
"pydantic-core==2.20.1",
|
||||
"typing-extensions>=4.12.2; python_version >= \"3.13\"",
|
||||
"typing-extensions>=4.6.1; python_version < \"3.13\"",
|
||||
]
|
||||
files = [
|
||||
@@ -720,6 +803,7 @@ version = "2.20.1"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Core functionality for Pydantic validation and serialization"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"typing-extensions!=4.7.0,>=4.6.0",
|
||||
]
|
||||
@@ -789,6 +873,7 @@ version = "2.18.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Pygments is a syntax highlighting package written in Python."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"},
|
||||
{file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"},
|
||||
@@ -800,6 +885,7 @@ version = "1.0.1"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Read key-value pairs from a .env file and set them as environment variables"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"},
|
||||
{file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"},
|
||||
@@ -811,6 +897,7 @@ version = "0.0.9"
|
||||
requires_python = ">=3.8"
|
||||
summary = "A streaming multipart parser for Python"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "python_multipart-0.0.9-py3-none-any.whl", hash = "sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215"},
|
||||
{file = "python_multipart-0.0.9.tar.gz", hash = "sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026"},
|
||||
@@ -822,6 +909,7 @@ version = "6.0.1"
|
||||
requires_python = ">=3.6"
|
||||
summary = "YAML parser and emitter for Python"
|
||||
groups = ["default", "dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
|
||||
@@ -855,6 +943,7 @@ version = "2.0.1"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Python library to build pretty command line user prompts ⭐️"
|
||||
groups = ["dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"prompt-toolkit<=3.0.36,>=2.0",
|
||||
]
|
||||
@@ -869,6 +958,7 @@ version = "2.32.3"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Python HTTP for Humans."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"certifi>=2017.4.17",
|
||||
"charset-normalizer<4,>=2",
|
||||
@@ -886,9 +976,11 @@ version = "13.7.1"
|
||||
requires_python = ">=3.7.0"
|
||||
summary = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"markdown-it-py>=2.2.0",
|
||||
"pygments<3.0.0,>=2.13.0",
|
||||
"typing-extensions<5.0,>=4.0.0; python_version < \"3.9\"",
|
||||
]
|
||||
files = [
|
||||
{file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"},
|
||||
@@ -897,13 +989,14 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.5.3"
|
||||
version = "0.5.5"
|
||||
requires_python = ">=3.7"
|
||||
summary = "An extremely fast Python linter and code formatter, written in Rust."
|
||||
groups = ["lint"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "ruff-0.5.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03bfe9ab5bdc0b08470c3b261643ad54ea86edc32b64d1e080892d7953add3ad"},
|
||||
{file = "ruff-0.5.3.tar.gz", hash = "sha256:2a3eb4f1841771fa5b67a56be9c2d16fd3cc88e378bd86aaeaec2f7e6bcdd0a2"},
|
||||
{file = "ruff-0.5.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3687d002f911e8a5faf977e619a034d159a8373514a587249cc00f211c67a091"},
|
||||
{file = "ruff-0.5.5.tar.gz", hash = "sha256:cc5516bdb4858d972fbc31d246bdb390eab8df1a26e2353be2dbc0c2d7f5421a"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -912,6 +1005,7 @@ version = "1.5.4"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Tool to Detect Surrounding Shell"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
|
||||
{file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
|
||||
@@ -923,6 +1017,7 @@ version = "1.3.1"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Sniff out which async library your code is running under"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
|
||||
{file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
|
||||
@@ -934,8 +1029,10 @@ version = "0.37.2"
|
||||
requires_python = ">=3.8"
|
||||
summary = "The little ASGI library that shines."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"anyio<5,>=3.4.0",
|
||||
"typing-extensions>=3.10.0; python_version < \"3.10\"",
|
||||
]
|
||||
files = [
|
||||
{file = "starlette-0.37.2-py3-none-any.whl", hash = "sha256:6fe59f29268538e5d0d182f2791a479a0c64638e6935d1c6989e63fb2699c6ee"},
|
||||
@@ -948,6 +1045,7 @@ version = "2.4.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "ANSI color formatting for output in terminal"
|
||||
groups = ["dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "termcolor-2.4.0-py3-none-any.whl", hash = "sha256:9297c0df9c99445c2412e832e882a7884038a25617c60cea2ad69488d4040d63"},
|
||||
{file = "termcolor-2.4.0.tar.gz", hash = "sha256:aab9e56047c8ac41ed798fa36d892a37aca6b3e9159f3e0c24bc64a9b3ac7b7a"},
|
||||
@@ -959,6 +1057,7 @@ version = "0.13.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Style preserving TOML library"
|
||||
groups = ["dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "tomlkit-0.13.0-py3-none-any.whl", hash = "sha256:7075d3042d03b80f603482d69bf0c8f345c2b30e41699fd8883227f89972b264"},
|
||||
{file = "tomlkit-0.13.0.tar.gz", hash = "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72"},
|
||||
@@ -970,6 +1069,7 @@ version = "0.12.3"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Typer, build great CLIs. Easy to code. Based on Python type hints."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"click>=8.0.0",
|
||||
"rich>=10.11.0",
|
||||
@@ -987,6 +1087,7 @@ version = "4.12.2"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Backported and Experimental Type Hints for Python 3.8+"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
|
||||
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
|
||||
@@ -998,6 +1099,7 @@ version = "2.2.2"
|
||||
requires_python = ">=3.8"
|
||||
summary = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"},
|
||||
{file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"},
|
||||
@@ -1005,39 +1107,42 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "uvicorn"
|
||||
version = "0.30.1"
|
||||
version = "0.30.4"
|
||||
requires_python = ">=3.8"
|
||||
summary = "The lightning-fast ASGI server."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"click>=7.0",
|
||||
"h11>=0.8",
|
||||
"typing-extensions>=4.0; python_version < \"3.11\"",
|
||||
]
|
||||
files = [
|
||||
{file = "uvicorn-0.30.1-py3-none-any.whl", hash = "sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81"},
|
||||
{file = "uvicorn-0.30.1.tar.gz", hash = "sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8"},
|
||||
{file = "uvicorn-0.30.4-py3-none-any.whl", hash = "sha256:06b00e3087e58c6865c284143c0c42f810b32ff4f265ab19d08c566f74a08728"},
|
||||
{file = "uvicorn-0.30.4.tar.gz", hash = "sha256:00db9a9e3711a5fa59866e2b02fac69d8dc70ce0814aaec9a66d1d9e5c832a30"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uvicorn"
|
||||
version = "0.30.1"
|
||||
version = "0.30.4"
|
||||
extras = ["standard"]
|
||||
requires_python = ">=3.8"
|
||||
summary = "The lightning-fast ASGI server."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"colorama>=0.4; sys_platform == \"win32\"",
|
||||
"httptools>=0.5.0",
|
||||
"python-dotenv>=0.13",
|
||||
"pyyaml>=5.1",
|
||||
"uvicorn==0.30.1",
|
||||
"uvicorn==0.30.4",
|
||||
"uvloop!=0.15.0,!=0.15.1,>=0.14.0; (sys_platform != \"cygwin\" and sys_platform != \"win32\") and platform_python_implementation != \"PyPy\"",
|
||||
"watchfiles>=0.13",
|
||||
"websockets>=10.4",
|
||||
]
|
||||
files = [
|
||||
{file = "uvicorn-0.30.1-py3-none-any.whl", hash = "sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81"},
|
||||
{file = "uvicorn-0.30.1.tar.gz", hash = "sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8"},
|
||||
{file = "uvicorn-0.30.4-py3-none-any.whl", hash = "sha256:06b00e3087e58c6865c284143c0c42f810b32ff4f265ab19d08c566f74a08728"},
|
||||
{file = "uvicorn-0.30.4.tar.gz", hash = "sha256:00db9a9e3711a5fa59866e2b02fac69d8dc70ce0814aaec9a66d1d9e5c832a30"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1046,7 +1151,7 @@ version = "0.19.0"
|
||||
requires_python = ">=3.8.0"
|
||||
summary = "Fast implementation of asyncio event loop on top of libuv"
|
||||
groups = ["default"]
|
||||
marker = "(sys_platform != \"cygwin\" and sys_platform != \"win32\") and platform_python_implementation != \"PyPy\""
|
||||
marker = "(sys_platform != \"cygwin\" and sys_platform != \"win32\") and platform_python_implementation != \"PyPy\" and python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e"},
|
||||
{file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428"},
|
||||
@@ -1075,6 +1180,7 @@ version = "0.22.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Simple, modern and high performance file watching and code reload in python."
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"anyio>=3.0.0",
|
||||
]
|
||||
@@ -1129,6 +1235,10 @@ name = "wcwidth"
|
||||
version = "0.2.13"
|
||||
summary = "Measures the displayed width of unicode strings in a terminal"
|
||||
groups = ["dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"backports-functools-lru-cache>=1.2.1; python_version < \"3.2\"",
|
||||
]
|
||||
files = [
|
||||
{file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"},
|
||||
{file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"},
|
||||
@@ -1140,6 +1250,7 @@ version = "12.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"},
|
||||
{file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"},
|
||||
@@ -1189,9 +1300,11 @@ version = "1.9.4"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Yet another URL library"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"idna>=2.0",
|
||||
"multidict>=4.0",
|
||||
"typing-extensions>=3.7.4; python_version < \"3.8\"",
|
||||
]
|
||||
files = [
|
||||
{file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"},
|
||||
@@ -1245,12 +1358,14 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "yt-dlp"
|
||||
version = "2024.7.16"
|
||||
version = "2024.8.1"
|
||||
requires_python = ">=3.8"
|
||||
summary = "A feature-rich command-line audio/video downloader"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"brotli; implementation_name == \"cpython\"",
|
||||
"brotlicffi; implementation_name != \"cpython\"",
|
||||
"certifi",
|
||||
"mutagen",
|
||||
"pycryptodomex",
|
||||
@@ -1259,6 +1374,6 @@ dependencies = [
|
||||
"websockets>=12.0",
|
||||
]
|
||||
files = [
|
||||
{file = "yt_dlp-2024.7.16-py3-none-any.whl", hash = "sha256:424805a112e757b141e767bc938d49db56d13d6415a92fa4cd8acadd55790be0"},
|
||||
{file = "yt_dlp-2024.7.16.tar.gz", hash = "sha256:c5bd517a49dea1923ec8e14f51858f10fd89dfece14cb701392b480b41b2f516"},
|
||||
{file = "yt_dlp-2024.8.1-py3-none-any.whl", hash = "sha256:d0d927038e30a05f6eab26ff6189628456ea21bb159a3d9dc2e855eef2810eac"},
|
||||
{file = "yt_dlp-2024.8.1.tar.gz", hash = "sha256:4318aa523694611562f01419c8d526b662a72df34ef8ba454016b34c8366c158"},
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "xiaomusic"
|
||||
version = "0.3.11"
|
||||
version = "0.3.25"
|
||||
description = "Play Music with xiaomi AI speaker"
|
||||
authors = [
|
||||
{name = "涵曦", email = "im.hanxi@gmail.com"},
|
||||
@@ -13,8 +13,9 @@ dependencies = [
|
||||
"uvicorn>=0.30.1",
|
||||
"fastapi>=0.111.0",
|
||||
"starlette>=0.37.2",
|
||||
"aiofiles>=24.1.0",
|
||||
]
|
||||
requires-python = ">=3.10"
|
||||
requires-python = ">=3.10,<3.12"
|
||||
readme = "README.md"
|
||||
license = {text = "MIT"}
|
||||
|
||||
|
||||
603
requirements.txt
603
requirements.txt
@@ -1,603 +0,0 @@
|
||||
# This file is @generated by PDM.
|
||||
# Please do not edit it manually.
|
||||
|
||||
aiohttp==3.9.5 \
|
||||
--hash=sha256:c26959ca7b75ff768e2776d8055bf9582a6267e24556bb7f7bd29e677932be72 \
|
||||
--hash=sha256:edea7d15772ceeb29db4aff55e482d4bcfb6ae160ce144f2682de02f6d693551
|
||||
aiosignal==1.3.1 \
|
||||
--hash=sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc \
|
||||
--hash=sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17
|
||||
annotated-types==0.7.0 \
|
||||
--hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \
|
||||
--hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89
|
||||
anyio==4.4.0 \
|
||||
--hash=sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94 \
|
||||
--hash=sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7
|
||||
async-timeout==4.0.3; python_version < "3.11" \
|
||||
--hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \
|
||||
--hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028
|
||||
attrs==23.2.0 \
|
||||
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
|
||||
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
brotli==1.1.0; implementation_name == "cpython" \
|
||||
--hash=sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128 \
|
||||
--hash=sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9 \
|
||||
--hash=sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3 \
|
||||
--hash=sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd \
|
||||
--hash=sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409 \
|
||||
--hash=sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da \
|
||||
--hash=sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50 \
|
||||
--hash=sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180 \
|
||||
--hash=sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d \
|
||||
--hash=sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc \
|
||||
--hash=sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265 \
|
||||
--hash=sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327 \
|
||||
--hash=sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd \
|
||||
--hash=sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0 \
|
||||
--hash=sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0 \
|
||||
--hash=sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451 \
|
||||
--hash=sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e \
|
||||
--hash=sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248 \
|
||||
--hash=sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91 \
|
||||
--hash=sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724 \
|
||||
--hash=sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966 \
|
||||
--hash=sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951 \
|
||||
--hash=sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8 \
|
||||
--hash=sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d \
|
||||
--hash=sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc \
|
||||
--hash=sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61 \
|
||||
--hash=sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1 \
|
||||
--hash=sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2 \
|
||||
--hash=sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6 \
|
||||
--hash=sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9 \
|
||||
--hash=sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2 \
|
||||
--hash=sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf \
|
||||
--hash=sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408 \
|
||||
--hash=sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752 \
|
||||
--hash=sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80 \
|
||||
--hash=sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0 \
|
||||
--hash=sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e
|
||||
certifi==2024.7.4 \
|
||||
--hash=sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b \
|
||||
--hash=sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90
|
||||
charset-normalizer==3.3.2 \
|
||||
--hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \
|
||||
--hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \
|
||||
--hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \
|
||||
--hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \
|
||||
--hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \
|
||||
--hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \
|
||||
--hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \
|
||||
--hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \
|
||||
--hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \
|
||||
--hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \
|
||||
--hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \
|
||||
--hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \
|
||||
--hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \
|
||||
--hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \
|
||||
--hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \
|
||||
--hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \
|
||||
--hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \
|
||||
--hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \
|
||||
--hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \
|
||||
--hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \
|
||||
--hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \
|
||||
--hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \
|
||||
--hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \
|
||||
--hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \
|
||||
--hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \
|
||||
--hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \
|
||||
--hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \
|
||||
--hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \
|
||||
--hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \
|
||||
--hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \
|
||||
--hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \
|
||||
--hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \
|
||||
--hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \
|
||||
--hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \
|
||||
--hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \
|
||||
--hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \
|
||||
--hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \
|
||||
--hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \
|
||||
--hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \
|
||||
--hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \
|
||||
--hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \
|
||||
--hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \
|
||||
--hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \
|
||||
--hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \
|
||||
--hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \
|
||||
--hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \
|
||||
--hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519
|
||||
click==8.1.7 \
|
||||
--hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \
|
||||
--hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de
|
||||
dnspython==2.6.1 \
|
||||
--hash=sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50 \
|
||||
--hash=sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc
|
||||
email-validator==2.2.0 \
|
||||
--hash=sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631 \
|
||||
--hash=sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7
|
||||
exceptiongroup==1.2.2; python_version < "3.11" \
|
||||
--hash=sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b \
|
||||
--hash=sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc
|
||||
fastapi==0.111.1 \
|
||||
--hash=sha256:4f51cfa25d72f9fbc3280832e84b32494cf186f50158d364a8765aabf22587bf \
|
||||
--hash=sha256:ddd1ac34cb1f76c2e2d7f8545a4bcb5463bce4834e81abf0b189e0c359ab2413
|
||||
fastapi-cli==0.0.4 \
|
||||
--hash=sha256:a2552f3a7ae64058cdbb530be6fa6dbfc975dc165e4fa66d224c3d396e25e809 \
|
||||
--hash=sha256:e2e9ffaffc1f7767f488d6da34b6f5a377751c996f397902eb6abb99a67bde32
|
||||
frozenlist==1.4.1 \
|
||||
--hash=sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7 \
|
||||
--hash=sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98 \
|
||||
--hash=sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad \
|
||||
--hash=sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae \
|
||||
--hash=sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e \
|
||||
--hash=sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a \
|
||||
--hash=sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6 \
|
||||
--hash=sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106 \
|
||||
--hash=sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75 \
|
||||
--hash=sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868 \
|
||||
--hash=sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1 \
|
||||
--hash=sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec \
|
||||
--hash=sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950 \
|
||||
--hash=sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19 \
|
||||
--hash=sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8 \
|
||||
--hash=sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a \
|
||||
--hash=sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86 \
|
||||
--hash=sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c \
|
||||
--hash=sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5 \
|
||||
--hash=sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0 \
|
||||
--hash=sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776 \
|
||||
--hash=sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a \
|
||||
--hash=sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09 \
|
||||
--hash=sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe \
|
||||
--hash=sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd \
|
||||
--hash=sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0 \
|
||||
--hash=sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1 \
|
||||
--hash=sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a \
|
||||
--hash=sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49 \
|
||||
--hash=sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480 \
|
||||
--hash=sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89 \
|
||||
--hash=sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b \
|
||||
--hash=sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82 \
|
||||
--hash=sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068 \
|
||||
--hash=sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b \
|
||||
--hash=sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb \
|
||||
--hash=sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2 \
|
||||
--hash=sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b \
|
||||
--hash=sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc \
|
||||
--hash=sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17 \
|
||||
--hash=sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2 \
|
||||
--hash=sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439 \
|
||||
--hash=sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5 \
|
||||
--hash=sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac \
|
||||
--hash=sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825 \
|
||||
--hash=sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced \
|
||||
--hash=sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74
|
||||
h11==0.14.0 \
|
||||
--hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \
|
||||
--hash=sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761
|
||||
httpcore==1.0.5 \
|
||||
--hash=sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61 \
|
||||
--hash=sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5
|
||||
httptools==0.6.1 \
|
||||
--hash=sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563 \
|
||||
--hash=sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142 \
|
||||
--hash=sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b \
|
||||
--hash=sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658 \
|
||||
--hash=sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2 \
|
||||
--hash=sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837 \
|
||||
--hash=sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3 \
|
||||
--hash=sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58 \
|
||||
--hash=sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d \
|
||||
--hash=sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90 \
|
||||
--hash=sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0 \
|
||||
--hash=sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1 \
|
||||
--hash=sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2 \
|
||||
--hash=sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0 \
|
||||
--hash=sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc \
|
||||
--hash=sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503 \
|
||||
--hash=sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949 \
|
||||
--hash=sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84 \
|
||||
--hash=sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb \
|
||||
--hash=sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a \
|
||||
--hash=sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f \
|
||||
--hash=sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185
|
||||
httpx==0.27.0 \
|
||||
--hash=sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5 \
|
||||
--hash=sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5
|
||||
idna==3.7 \
|
||||
--hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \
|
||||
--hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0
|
||||
jinja2==3.1.4 \
|
||||
--hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \
|
||||
--hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d
|
||||
markdown-it-py==3.0.0 \
|
||||
--hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \
|
||||
--hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb
|
||||
markupsafe==2.1.5 \
|
||||
--hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \
|
||||
--hash=sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f \
|
||||
--hash=sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f \
|
||||
--hash=sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617 \
|
||||
--hash=sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906 \
|
||||
--hash=sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f \
|
||||
--hash=sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4 \
|
||||
--hash=sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169 \
|
||||
--hash=sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad \
|
||||
--hash=sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2 \
|
||||
--hash=sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f \
|
||||
--hash=sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced \
|
||||
--hash=sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5 \
|
||||
--hash=sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c \
|
||||
--hash=sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb \
|
||||
--hash=sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad \
|
||||
--hash=sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1 \
|
||||
--hash=sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc \
|
||||
--hash=sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee \
|
||||
--hash=sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900 \
|
||||
--hash=sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5 \
|
||||
--hash=sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f \
|
||||
--hash=sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5 \
|
||||
--hash=sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a \
|
||||
--hash=sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a \
|
||||
--hash=sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b \
|
||||
--hash=sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4 \
|
||||
--hash=sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46 \
|
||||
--hash=sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b \
|
||||
--hash=sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5 \
|
||||
--hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd
|
||||
mdurl==0.1.2 \
|
||||
--hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \
|
||||
--hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba
|
||||
miservice-fork==2.7.0 \
|
||||
--hash=sha256:8e2c91ebe1fc4b3c63b01cbf1818e5d5833d024fd3a8311970d649ad2d49d6e6 \
|
||||
--hash=sha256:8e87ef6d89adceaf3f7a98242cdae1c9135498d77f2c743ec3871d2e42bcbab8
|
||||
multidict==6.0.5 \
|
||||
--hash=sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556 \
|
||||
--hash=sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29 \
|
||||
--hash=sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7 \
|
||||
--hash=sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6 \
|
||||
--hash=sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c \
|
||||
--hash=sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5 \
|
||||
--hash=sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae \
|
||||
--hash=sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442 \
|
||||
--hash=sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9 \
|
||||
--hash=sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc \
|
||||
--hash=sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c \
|
||||
--hash=sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea \
|
||||
--hash=sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5 \
|
||||
--hash=sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182 \
|
||||
--hash=sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600 \
|
||||
--hash=sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733 \
|
||||
--hash=sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda \
|
||||
--hash=sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e \
|
||||
--hash=sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e \
|
||||
--hash=sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd \
|
||||
--hash=sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf \
|
||||
--hash=sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a \
|
||||
--hash=sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271 \
|
||||
--hash=sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4 \
|
||||
--hash=sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496 \
|
||||
--hash=sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb \
|
||||
--hash=sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319 \
|
||||
--hash=sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3 \
|
||||
--hash=sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f \
|
||||
--hash=sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed \
|
||||
--hash=sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604 \
|
||||
--hash=sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef \
|
||||
--hash=sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8 \
|
||||
--hash=sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5 \
|
||||
--hash=sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc \
|
||||
--hash=sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b \
|
||||
--hash=sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450 \
|
||||
--hash=sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f \
|
||||
--hash=sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226 \
|
||||
--hash=sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf \
|
||||
--hash=sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e \
|
||||
--hash=sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1 \
|
||||
--hash=sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a \
|
||||
--hash=sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba \
|
||||
--hash=sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da \
|
||||
--hash=sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24 \
|
||||
--hash=sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef
|
||||
mutagen==1.47.0 \
|
||||
--hash=sha256:719fadef0a978c31b4cf3c956261b3c58b6948b32023078a2117b1de09f0fc99 \
|
||||
--hash=sha256:edd96f50c5907a9539d8e5bba7245f62c9f520aef333d13392a79a4f70aca719
|
||||
pycryptodomex==3.20.0 \
|
||||
--hash=sha256:25cd61e846aaab76d5791d006497134602a9e451e954833018161befc3b5b9ed \
|
||||
--hash=sha256:2a47bcc478741b71273b917232f521fd5704ab4b25d301669879e7273d3586cc \
|
||||
--hash=sha256:59af01efb011b0e8b686ba7758d59cf4a8263f9ad35911bfe3f416cee4f5c08c \
|
||||
--hash=sha256:6e186342cfcc3aafaad565cbd496060e5a614b441cacc3995ef0091115c1f6c5 \
|
||||
--hash=sha256:7a710b79baddd65b806402e14766c721aee8fb83381769c27920f26476276c1e \
|
||||
--hash=sha256:7a7a8f33a1f1fb762ede6cc9cbab8f2a9ba13b196bfaf7bc6f0b39d2ba315a43 \
|
||||
--hash=sha256:82ee7696ed8eb9a82c7037f32ba9b7c59e51dda6f105b39f043b6ef293989cb3 \
|
||||
--hash=sha256:88afd7a3af7ddddd42c2deda43d53d3dfc016c11327d0915f90ca34ebda91499 \
|
||||
--hash=sha256:91852d4480a4537d169c29a9d104dda44094c78f1f5b67bca76c29a91042b623 \
|
||||
--hash=sha256:9c682436c359b5ada67e882fec34689726a09c461efd75b6ea77b2403d5665b7 \
|
||||
--hash=sha256:bca649483d5ed251d06daf25957f802e44e6bb6df2e8f218ae71968ff8f8edc4 \
|
||||
--hash=sha256:c39778fd0548d78917b61f03c1fa8bfda6cfcf98c767decf360945fe6f97461e \
|
||||
--hash=sha256:d00fe8596e1cc46b44bf3907354e9377aa030ec4cd04afbbf6e899fc1e2a7781 \
|
||||
--hash=sha256:e48217c7901edd95f9f097feaa0388da215ed14ce2ece803d3f300b4e694abea \
|
||||
--hash=sha256:f2e497413560e03421484189a6b65e33fe800d3bd75590e6d78d4dfdb7accf3b
|
||||
pydantic==2.8.2 \
|
||||
--hash=sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a \
|
||||
--hash=sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8
|
||||
pydantic-core==2.20.1 \
|
||||
--hash=sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d \
|
||||
--hash=sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686 \
|
||||
--hash=sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482 \
|
||||
--hash=sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83 \
|
||||
--hash=sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6 \
|
||||
--hash=sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88 \
|
||||
--hash=sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a \
|
||||
--hash=sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6 \
|
||||
--hash=sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6 \
|
||||
--hash=sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43 \
|
||||
--hash=sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4 \
|
||||
--hash=sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e \
|
||||
--hash=sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203 \
|
||||
--hash=sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24 \
|
||||
--hash=sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc \
|
||||
--hash=sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc \
|
||||
--hash=sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3 \
|
||||
--hash=sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98 \
|
||||
--hash=sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2 \
|
||||
--hash=sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6 \
|
||||
--hash=sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688 \
|
||||
--hash=sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b \
|
||||
--hash=sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840 \
|
||||
--hash=sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c \
|
||||
--hash=sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd \
|
||||
--hash=sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3 \
|
||||
--hash=sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231 \
|
||||
--hash=sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953 \
|
||||
--hash=sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250 \
|
||||
--hash=sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a \
|
||||
--hash=sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20 \
|
||||
--hash=sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703 \
|
||||
--hash=sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac \
|
||||
--hash=sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121 \
|
||||
--hash=sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b \
|
||||
--hash=sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906 \
|
||||
--hash=sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9 \
|
||||
--hash=sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b \
|
||||
--hash=sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e \
|
||||
--hash=sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237 \
|
||||
--hash=sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1 \
|
||||
--hash=sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19 \
|
||||
--hash=sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0 \
|
||||
--hash=sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94 \
|
||||
--hash=sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312 \
|
||||
--hash=sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f \
|
||||
--hash=sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1 \
|
||||
--hash=sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe \
|
||||
--hash=sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99 \
|
||||
--hash=sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a \
|
||||
--hash=sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a \
|
||||
--hash=sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52 \
|
||||
--hash=sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c \
|
||||
--hash=sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1 \
|
||||
--hash=sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f \
|
||||
--hash=sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a \
|
||||
--hash=sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27
|
||||
pygments==2.18.0 \
|
||||
--hash=sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199 \
|
||||
--hash=sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a
|
||||
python-dotenv==1.0.1 \
|
||||
--hash=sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca \
|
||||
--hash=sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a
|
||||
python-multipart==0.0.9 \
|
||||
--hash=sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026 \
|
||||
--hash=sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215
|
||||
pyyaml==6.0.1 \
|
||||
--hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \
|
||||
--hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \
|
||||
--hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \
|
||||
--hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \
|
||||
--hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \
|
||||
--hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \
|
||||
--hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \
|
||||
--hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \
|
||||
--hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \
|
||||
--hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \
|
||||
--hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \
|
||||
--hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \
|
||||
--hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \
|
||||
--hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \
|
||||
--hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \
|
||||
--hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \
|
||||
--hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \
|
||||
--hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \
|
||||
--hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \
|
||||
--hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \
|
||||
--hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \
|
||||
--hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \
|
||||
--hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \
|
||||
--hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f
|
||||
requests==2.32.3 \
|
||||
--hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \
|
||||
--hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6
|
||||
rich==13.7.1 \
|
||||
--hash=sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222 \
|
||||
--hash=sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432
|
||||
shellingham==1.5.4 \
|
||||
--hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \
|
||||
--hash=sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de
|
||||
sniffio==1.3.1 \
|
||||
--hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \
|
||||
--hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc
|
||||
starlette==0.37.2 \
|
||||
--hash=sha256:6fe59f29268538e5d0d182f2791a479a0c64638e6935d1c6989e63fb2699c6ee \
|
||||
--hash=sha256:9af890290133b79fc3db55474ade20f6220a364a0402e0b556e7cd5e1e093823
|
||||
typer==0.12.3 \
|
||||
--hash=sha256:070d7ca53f785acbccba8e7d28b08dcd88f79f1fbda035ade0aecec71ca5c914 \
|
||||
--hash=sha256:49e73131481d804288ef62598d97a1ceef3058905aa536a1134f90891ba35482
|
||||
typing-extensions==4.12.2 \
|
||||
--hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \
|
||||
--hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8
|
||||
urllib3==2.2.2 \
|
||||
--hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \
|
||||
--hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168
|
||||
uvicorn==0.30.1 \
|
||||
--hash=sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81 \
|
||||
--hash=sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8
|
||||
uvicorn[standard]==0.30.1 \
|
||||
--hash=sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81 \
|
||||
--hash=sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8
|
||||
uvloop==0.19.0; (sys_platform != "cygwin" and sys_platform != "win32") and platform_python_implementation != "PyPy" \
|
||||
--hash=sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd \
|
||||
--hash=sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec \
|
||||
--hash=sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc \
|
||||
--hash=sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2 \
|
||||
--hash=sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12 \
|
||||
--hash=sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef \
|
||||
--hash=sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24 \
|
||||
--hash=sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428 \
|
||||
--hash=sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1 \
|
||||
--hash=sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849 \
|
||||
--hash=sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593 \
|
||||
--hash=sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd \
|
||||
--hash=sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6 \
|
||||
--hash=sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3 \
|
||||
--hash=sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8 \
|
||||
--hash=sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533 \
|
||||
--hash=sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957 \
|
||||
--hash=sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650 \
|
||||
--hash=sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e
|
||||
watchfiles==0.22.0 \
|
||||
--hash=sha256:00095dd368f73f8f1c3a7982a9801190cc88a2f3582dd395b289294f8975172b \
|
||||
--hash=sha256:00f39592cdd124b4ec5ed0b1edfae091567c72c7da1487ae645426d1b0ffcad1 \
|
||||
--hash=sha256:030bc4e68d14bcad2294ff68c1ed87215fbd9a10d9dea74e7cfe8a17869785ab \
|
||||
--hash=sha256:052d668a167e9fc345c24203b104c313c86654dd6c0feb4b8a6dfc2462239249 \
|
||||
--hash=sha256:067dea90c43bf837d41e72e546196e674f68c23702d3ef80e4e816937b0a3ffd \
|
||||
--hash=sha256:1235c11510ea557fe21be5d0e354bae2c655a8ee6519c94617fe63e05bca4171 \
|
||||
--hash=sha256:1cc0cba54f47c660d9fa3218158b8963c517ed23bd9f45fe463f08262a4adae1 \
|
||||
--hash=sha256:1d9188979a58a096b6f8090e816ccc3f255f137a009dd4bbec628e27696d67c1 \
|
||||
--hash=sha256:213792c2cd3150b903e6e7884d40660e0bcec4465e00563a5fc03f30ea9c166c \
|
||||
--hash=sha256:2627a91e8110b8de2406d8b2474427c86f5a62bf7d9ab3654f541f319ef22bcb \
|
||||
--hash=sha256:28585744c931576e535860eaf3f2c0ec7deb68e3b9c5a85ca566d69d36d8dd27 \
|
||||
--hash=sha256:2bdadf6b90c099ca079d468f976fd50062905d61fae183f769637cb0f68ba59a \
|
||||
--hash=sha256:3218a6f908f6a276941422b035b511b6d0d8328edd89a53ae8c65be139073f84 \
|
||||
--hash=sha256:425440e55cd735386ec7925f64d5dde392e69979d4c8459f6bb4e920210407f2 \
|
||||
--hash=sha256:4b9f2a128a32a2c273d63eb1fdbf49ad64852fc38d15b34eaa3f7ca2f0d2b797 \
|
||||
--hash=sha256:52fc9b0dbf54d43301a19b236b4a4614e610605f95e8c3f0f65c3a456ffd7d35 \
|
||||
--hash=sha256:55b7cc10261c2786c41d9207193a85c1db1b725cf87936df40972aab466179b6 \
|
||||
--hash=sha256:581f0a051ba7bafd03e17127735d92f4d286af941dacf94bcf823b101366249e \
|
||||
--hash=sha256:5e45fb0d70dda1623a7045bd00c9e036e6f1f6a85e4ef2c8ae602b1dfadf7550 \
|
||||
--hash=sha256:61af9efa0733dc4ca462347becb82e8ef4945aba5135b1638bfc20fad64d4f0e \
|
||||
--hash=sha256:68fe0c4d22332d7ce53ad094622b27e67440dacefbaedd29e0794d26e247280c \
|
||||
--hash=sha256:8c39987a1397a877217be1ac0fb1d8b9f662c6077b90ff3de2c05f235e6a8f96 \
|
||||
--hash=sha256:94ebe84a035993bb7668f58a0ebf998174fb723a39e4ef9fce95baabb42b787f \
|
||||
--hash=sha256:9624a68b96c878c10437199d9a8b7d7e542feddda8d5ecff58fdc8e67b460848 \
|
||||
--hash=sha256:988e981aaab4f3955209e7e28c7794acdb690be1efa7f16f8ea5aba7ffdadacb \
|
||||
--hash=sha256:a8a31bfd98f846c3c284ba694c6365620b637debdd36e46e1859c897123aa232 \
|
||||
--hash=sha256:a927b3034d0672f62fb2ef7ea3c9fc76d063c4b15ea852d1db2dc75fe2c09696 \
|
||||
--hash=sha256:ace7d060432acde5532e26863e897ee684780337afb775107c0a90ae8dbccfd2 \
|
||||
--hash=sha256:aec83c3ba24c723eac14225194b862af176d52292d271c98820199110e31141e \
|
||||
--hash=sha256:b44b70850f0073b5fcc0b31ede8b4e736860d70e2dbf55701e05d3227a154a67 \
|
||||
--hash=sha256:b810a2c7878cbdecca12feae2c2ae8af59bea016a78bc353c184fa1e09f76b68 \
|
||||
--hash=sha256:bbf8a20266136507abf88b0df2328e6a9a7c7309e8daff124dda3803306a9fdb \
|
||||
--hash=sha256:bd4c06100bce70a20c4b81e599e5886cf504c9532951df65ad1133e508bf20be \
|
||||
--hash=sha256:c2444dc7cb9d8cc5ab88ebe792a8d75709d96eeef47f4c8fccb6df7c7bc5be71 \
|
||||
--hash=sha256:c49b76a78c156979759d759339fb62eb0549515acfe4fd18bb151cc07366629c \
|
||||
--hash=sha256:c4a65474fd2b4c63e2c18ac67a0c6c66b82f4e73e2e4d940f837ed3d2fd9d4da \
|
||||
--hash=sha256:c5af2347d17ab0bd59366db8752d9e037982e259cacb2ba06f2c41c08af02c39 \
|
||||
--hash=sha256:c668228833c5619f6618699a2c12be057711b0ea6396aeaece4ded94184304ea \
|
||||
--hash=sha256:c7b978c384e29d6c7372209cbf421d82286a807bbcdeb315427687f8371c340a \
|
||||
--hash=sha256:da1e0a8caebf17976e2ffd00fa15f258e14749db5e014660f53114b676e68538 \
|
||||
--hash=sha256:dc2e8fe41f3cac0660197d95216c42910c2b7e9c70d48e6d84e22f577d106fc1 \
|
||||
--hash=sha256:e0f0a874231e2839abbf473256efffe577d6ee2e3bfa5b540479e892e47c172d \
|
||||
--hash=sha256:f7e1f9c5d1160d03b93fc4b68a0aeb82fe25563e12fbcdc8507f8434ab6f823c
|
||||
websockets==12.0 \
|
||||
--hash=sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df \
|
||||
--hash=sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b \
|
||||
--hash=sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2 \
|
||||
--hash=sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed \
|
||||
--hash=sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd \
|
||||
--hash=sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b \
|
||||
--hash=sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30 \
|
||||
--hash=sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be \
|
||||
--hash=sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf \
|
||||
--hash=sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b \
|
||||
--hash=sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402 \
|
||||
--hash=sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f \
|
||||
--hash=sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603 \
|
||||
--hash=sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45 \
|
||||
--hash=sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558 \
|
||||
--hash=sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4 \
|
||||
--hash=sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480 \
|
||||
--hash=sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447 \
|
||||
--hash=sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8 \
|
||||
--hash=sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04 \
|
||||
--hash=sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c \
|
||||
--hash=sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb \
|
||||
--hash=sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b \
|
||||
--hash=sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c \
|
||||
--hash=sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92 \
|
||||
--hash=sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113 \
|
||||
--hash=sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f \
|
||||
--hash=sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d \
|
||||
--hash=sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca \
|
||||
--hash=sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f \
|
||||
--hash=sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077 \
|
||||
--hash=sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2 \
|
||||
--hash=sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374 \
|
||||
--hash=sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc \
|
||||
--hash=sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e \
|
||||
--hash=sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53 \
|
||||
--hash=sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547 \
|
||||
--hash=sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3 \
|
||||
--hash=sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870 \
|
||||
--hash=sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5
|
||||
yarl==1.9.4 \
|
||||
--hash=sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51 \
|
||||
--hash=sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce \
|
||||
--hash=sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0 \
|
||||
--hash=sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81 \
|
||||
--hash=sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc \
|
||||
--hash=sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455 \
|
||||
--hash=sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099 \
|
||||
--hash=sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129 \
|
||||
--hash=sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10 \
|
||||
--hash=sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142 \
|
||||
--hash=sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98 \
|
||||
--hash=sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7 \
|
||||
--hash=sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525 \
|
||||
--hash=sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c \
|
||||
--hash=sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9 \
|
||||
--hash=sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c \
|
||||
--hash=sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8 \
|
||||
--hash=sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b \
|
||||
--hash=sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf \
|
||||
--hash=sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff \
|
||||
--hash=sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d \
|
||||
--hash=sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863 \
|
||||
--hash=sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53 \
|
||||
--hash=sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31 \
|
||||
--hash=sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b \
|
||||
--hash=sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad \
|
||||
--hash=sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7 \
|
||||
--hash=sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2 \
|
||||
--hash=sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2 \
|
||||
--hash=sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9 \
|
||||
--hash=sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e \
|
||||
--hash=sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984 \
|
||||
--hash=sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4 \
|
||||
--hash=sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074 \
|
||||
--hash=sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392 \
|
||||
--hash=sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541 \
|
||||
--hash=sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572 \
|
||||
--hash=sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66 \
|
||||
--hash=sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1 \
|
||||
--hash=sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551 \
|
||||
--hash=sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0 \
|
||||
--hash=sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe \
|
||||
--hash=sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234 \
|
||||
--hash=sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42 \
|
||||
--hash=sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385 \
|
||||
--hash=sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78 \
|
||||
--hash=sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958
|
||||
yt-dlp==2024.7.16 \
|
||||
--hash=sha256:424805a112e757b141e767bc938d49db56d13d6415a92fa4cd8acadd55790be0 \
|
||||
--hash=sha256:c5bd517a49dea1923ec8e14f51858f10fd89dfece14cb701392b480b41b2f516
|
||||
32
test/test_music_duration.py
Normal file
32
test/test_music_duration.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import math
|
||||
|
||||
from xiaomusic.const import (
|
||||
SUPPORT_MUSIC_TYPE,
|
||||
)
|
||||
from xiaomusic.utils import (
|
||||
get_local_music_duration,
|
||||
traverse_music_directory,
|
||||
)
|
||||
|
||||
|
||||
async def test_one_music(filename):
|
||||
# 获取播放时长
|
||||
duration = await get_local_music_duration(filename)
|
||||
sec = math.ceil(duration)
|
||||
print(f"本地歌曲 : {filename} 的时长 {duration} {sec} 秒")
|
||||
|
||||
|
||||
async def main(directory):
|
||||
# 获取所有歌曲文件
|
||||
local_musics = traverse_music_directory(directory, 10, [], SUPPORT_MUSIC_TYPE)
|
||||
print(local_musics)
|
||||
for _, files in local_musics.items():
|
||||
for file in files:
|
||||
await test_one_music(file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import asyncio
|
||||
|
||||
directory = "./music" # 替换为你的音乐目录路径
|
||||
asyncio.run(main(directory))
|
||||
@@ -1 +0,0 @@
|
||||
pdm export --prod -o requirements.txt
|
||||
@@ -1 +1 @@
|
||||
__version__ = "0.3.11"
|
||||
__version__ = "0.3.25"
|
||||
|
||||
132
xiaomusic/cli.py
132
xiaomusic/cli.py
@@ -1,5 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
|
||||
import uvicorn
|
||||
|
||||
@@ -75,29 +79,113 @@ def main():
|
||||
options = parser.parse_args()
|
||||
config = Config.from_options(options)
|
||||
|
||||
xiaomusic = XiaoMusic(config)
|
||||
HttpInit(xiaomusic)
|
||||
|
||||
from uvicorn.config import LOGGING_CONFIG
|
||||
|
||||
LOGGING_CONFIG["formatters"]["access"] = {
|
||||
"format": f"%(asctime)s [{__version__}] [%(levelname)s] %(filename)s:%(lineno)d: %(message)s",
|
||||
"datefmt": "[%X]",
|
||||
LOGGING_CONFIG = {
|
||||
"version": 1,
|
||||
"disable_existing_loggers": False,
|
||||
"formatters": {
|
||||
"default": {
|
||||
"format": f"%(asctime)s [{__version__}] [%(levelname)s] %(message)s",
|
||||
"datefmt": "[%X]",
|
||||
"use_colors": False,
|
||||
},
|
||||
"access": {
|
||||
"format": f"%(asctime)s [{__version__}] [%(levelname)s] %(message)s",
|
||||
"datefmt": "[%X]",
|
||||
},
|
||||
},
|
||||
"handlers": {
|
||||
"default": {
|
||||
"formatter": "default",
|
||||
"class": "logging.StreamHandler",
|
||||
"stream": "ext://sys.stderr",
|
||||
},
|
||||
"access": {
|
||||
"formatter": "access",
|
||||
"class": "logging.StreamHandler",
|
||||
"stream": "ext://sys.stdout",
|
||||
},
|
||||
"file": {
|
||||
"level": "INFO",
|
||||
"class": "logging.handlers.RotatingFileHandler",
|
||||
"formatter": "access",
|
||||
"filename": config.log_file,
|
||||
"maxBytes": 10 * 1024 * 1024,
|
||||
"backupCount": 1,
|
||||
},
|
||||
},
|
||||
"loggers": {
|
||||
"uvicorn": {
|
||||
"handlers": [
|
||||
"default",
|
||||
"file",
|
||||
],
|
||||
"level": "INFO",
|
||||
},
|
||||
"uvicorn.error": {
|
||||
"level": "INFO",
|
||||
},
|
||||
"uvicorn.access": {
|
||||
"handlers": [
|
||||
"access",
|
||||
"file",
|
||||
],
|
||||
"level": "INFO",
|
||||
"propagate": False,
|
||||
},
|
||||
},
|
||||
}
|
||||
LOGGING_CONFIG["handlers"]["access"] = {
|
||||
"level": "INFO",
|
||||
"class": "logging.handlers.RotatingFileHandler",
|
||||
"formatter": "access",
|
||||
"filename": config.log_file,
|
||||
"maxBytes": 10 * 1024 * 1024,
|
||||
"backupCount": 1,
|
||||
}
|
||||
uvicorn.run(
|
||||
HttpApp,
|
||||
host=["::", "0.0.0.0"],
|
||||
port=config.port,
|
||||
log_config=LOGGING_CONFIG,
|
||||
)
|
||||
|
||||
try:
|
||||
filename = config.getsettingfile()
|
||||
with open(filename) as f:
|
||||
data = json.loads(f.read())
|
||||
config.update_config(data)
|
||||
except Exception as e:
|
||||
print(f"Execption {e}")
|
||||
|
||||
def run_server(port):
|
||||
xiaomusic = XiaoMusic(config)
|
||||
HttpInit(xiaomusic)
|
||||
uvicorn.run(
|
||||
HttpApp,
|
||||
host=["0.0.0.0", "::"],
|
||||
port=port,
|
||||
log_config=LOGGING_CONFIG,
|
||||
)
|
||||
|
||||
process = None
|
||||
|
||||
def run_gate():
|
||||
command = [
|
||||
"uvicorn",
|
||||
"xiaomusic.gate:app",
|
||||
"--workers",
|
||||
"4",
|
||||
"--host",
|
||||
"0.0.0.0",
|
||||
"--port",
|
||||
str(config.port),
|
||||
]
|
||||
global process
|
||||
process = subprocess.Popen(command)
|
||||
|
||||
def signal_handler(sig, frame):
|
||||
print("主进程收到退出信号,准备退出...")
|
||||
if process is not None:
|
||||
process.terminate() # 终止子进程
|
||||
process.wait() # 等待子进程退出
|
||||
print("子进程已退出")
|
||||
os._exit(0) # 退出主进程
|
||||
|
||||
# 捕获主进程的退出信号
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
port = int(config.port)
|
||||
if config.enable_gate:
|
||||
run_gate()
|
||||
run_server(port + 1)
|
||||
else:
|
||||
run_server(port)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -136,6 +136,8 @@ class Config:
|
||||
remove_id3tag: bool = (
|
||||
os.getenv("XIAOMUSIC_REMOVE_ID3TAG", "false").lower() == "true"
|
||||
)
|
||||
delay_sec: int = int(os.getenv("XIAOMUSIC_DELAY_SEC", 3)) # 下一首歌延迟播放秒数
|
||||
enable_gate: bool = os.getenv("XIAOMUSIC_ENABLE_GATE", "false").lower() == "true"
|
||||
|
||||
def append_keyword(self, keys, action):
|
||||
for key in keys.split(","):
|
||||
@@ -146,9 +148,11 @@ class Config:
|
||||
def append_user_keyword(self):
|
||||
for k, v in self.user_key_word_dict.items():
|
||||
self.key_word_dict[k] = v
|
||||
self.key_match_order.append(k)
|
||||
if k not in self.key_match_order:
|
||||
self.key_match_order.append(k)
|
||||
|
||||
def init_keyword(self):
|
||||
self.key_match_order = default_key_match_order()
|
||||
self.append_keyword(self.keywords_playlocal, "playlocal")
|
||||
self.append_keyword(self.keywords_play, "play")
|
||||
self.append_keyword(self.keywords_stop, "stop")
|
||||
@@ -216,3 +220,13 @@ class Config:
|
||||
if converted_value is not None:
|
||||
setattr(self, k, converted_value)
|
||||
self.init_keyword()
|
||||
|
||||
# 获取设置文件
|
||||
def getsettingfile(self):
|
||||
# 兼容旧配置空的情况
|
||||
if not self.conf_path:
|
||||
self.conf_path = "conf"
|
||||
if not os.path.exists(self.conf_path):
|
||||
os.makedirs(self.conf_path)
|
||||
filename = os.path.join(self.conf_path, "setting.json")
|
||||
return filename
|
||||
|
||||
124
xiaomusic/gate.py
Normal file
124
xiaomusic/gate.py
Normal file
@@ -0,0 +1,124 @@
|
||||
import json
|
||||
import logging
|
||||
import mimetypes
|
||||
import os
|
||||
import re
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
import aiofiles
|
||||
import httpx
|
||||
from fastapi import FastAPI, HTTPException, Request
|
||||
from fastapi.responses import Response, StreamingResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
from xiaomusic import __version__
|
||||
from xiaomusic.config import Config
|
||||
|
||||
config = Config()
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def app_lifespan(app):
|
||||
global config
|
||||
try:
|
||||
filename = config.getsettingfile()
|
||||
with open(filename) as f:
|
||||
data = json.loads(f.read())
|
||||
config.update_config(data)
|
||||
except Exception as e:
|
||||
log.exception(f"Execption {e}")
|
||||
yield
|
||||
|
||||
|
||||
app = FastAPI(
|
||||
lifespan=app_lifespan,
|
||||
version=__version__,
|
||||
)
|
||||
|
||||
|
||||
folder = os.path.dirname(__file__)
|
||||
app.mount("/static", StaticFiles(directory=f"{folder}/static"), name="static")
|
||||
|
||||
|
||||
async def file_iterator(file_path, start, end):
|
||||
async with aiofiles.open(file_path, mode="rb") as file:
|
||||
await file.seek(start)
|
||||
chunk_size = 1024
|
||||
while start <= end:
|
||||
read_size = min(chunk_size, end - start + 1)
|
||||
data = await file.read(read_size)
|
||||
if not data:
|
||||
break
|
||||
start += len(data)
|
||||
yield data
|
||||
|
||||
|
||||
range_pattern = re.compile(r"bytes=(\d+)-(\d*)")
|
||||
|
||||
|
||||
@app.get("/music/{file_path:path}")
|
||||
async def music_file(request: Request, file_path: str):
|
||||
absolute_path = os.path.abspath(config.music_path)
|
||||
absolute_file_path = os.path.normpath(os.path.join(absolute_path, file_path))
|
||||
if not absolute_file_path.startswith(absolute_path):
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
if not os.path.exists(absolute_file_path):
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
file_size = os.path.getsize(absolute_file_path)
|
||||
range_start, range_end = 0, file_size - 1
|
||||
|
||||
range_header = request.headers.get("Range")
|
||||
log.info(f"music_file range_header {range_header}")
|
||||
if range_header:
|
||||
range_match = range_pattern.match(range_header)
|
||||
if range_match:
|
||||
range_start = int(range_match.group(1))
|
||||
if range_match.group(2):
|
||||
range_end = int(range_match.group(2))
|
||||
|
||||
log.info(f"music_file in range {absolute_file_path}")
|
||||
|
||||
log.info(f"music_file {range_start} {range_end} {absolute_file_path}")
|
||||
headers = {
|
||||
"Content-Range": f"bytes {range_start}-{range_end}/{file_size}",
|
||||
"Accept-Ranges": "bytes",
|
||||
}
|
||||
mime_type, _ = mimetypes.guess_type(file_path)
|
||||
if mime_type is None:
|
||||
mime_type = "application/octet-stream"
|
||||
return StreamingResponse(
|
||||
file_iterator(absolute_file_path, range_start, range_end),
|
||||
headers=headers,
|
||||
status_code=206 if range_header else 200,
|
||||
media_type=mime_type,
|
||||
)
|
||||
|
||||
|
||||
@app.options("/music/{file_path:path}")
|
||||
async def music_options():
|
||||
headers = {
|
||||
"Accept-Ranges": "bytes",
|
||||
}
|
||||
return Response(headers=headers)
|
||||
|
||||
|
||||
@app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
|
||||
async def proxy(path: str, request: Request):
|
||||
async with httpx.AsyncClient() as client:
|
||||
port = config.port + 1
|
||||
url = f"http://127.0.0.1:{port}/{path}"
|
||||
response = await client.request(
|
||||
method=request.method,
|
||||
url=url,
|
||||
headers=request.headers,
|
||||
params=request.query_params,
|
||||
content=await request.body() if request.method in ["POST", "PUT"] else None,
|
||||
)
|
||||
return Response(
|
||||
content=response.content,
|
||||
status_code=response.status_code,
|
||||
headers=dict(response.headers),
|
||||
)
|
||||
@@ -1,6 +1,8 @@
|
||||
import asyncio
|
||||
import json
|
||||
import mimetypes
|
||||
import os
|
||||
import re
|
||||
import secrets
|
||||
import shutil
|
||||
import tempfile
|
||||
@@ -8,12 +10,14 @@ from contextlib import asynccontextmanager
|
||||
from dataclasses import asdict
|
||||
from typing import Annotated
|
||||
|
||||
import aiofiles
|
||||
from fastapi import Depends, FastAPI, HTTPException, Request, status
|
||||
from fastapi.responses import StreamingResponse
|
||||
from fastapi.security import HTTPBasic, HTTPBasicCredentials
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from pydantic import BaseModel
|
||||
from starlette.background import BackgroundTask
|
||||
from starlette.responses import FileResponse
|
||||
from starlette.responses import FileResponse, Response
|
||||
|
||||
from xiaomusic import __version__
|
||||
from xiaomusic.utils import (
|
||||
@@ -29,9 +33,11 @@ log = None
|
||||
@asynccontextmanager
|
||||
async def app_lifespan(app):
|
||||
if xiaomusic is not None:
|
||||
task = asyncio.create_task(xiaomusic.run_forever())
|
||||
asyncio.create_task(xiaomusic.run_forever())
|
||||
try:
|
||||
yield
|
||||
task.cancel()
|
||||
except Exception as e:
|
||||
log.exception(f"Execption {e}")
|
||||
|
||||
|
||||
security = HTTPBasic()
|
||||
@@ -77,14 +83,6 @@ def reset_http_server():
|
||||
else:
|
||||
app.dependency_overrides = {}
|
||||
|
||||
# 更新 music 链接
|
||||
app.router.routes = [route for route in app.router.routes if route.path != "/music"]
|
||||
app.mount(
|
||||
"/music",
|
||||
StaticFiles(directory=config.music_path, follow_symlink=True),
|
||||
name="music",
|
||||
)
|
||||
|
||||
|
||||
def HttpInit(_xiaomusic):
|
||||
global xiaomusic, config, log
|
||||
@@ -168,7 +166,12 @@ async def do_cmd(data: DidCmd):
|
||||
return {"ret": "Did not exist"}
|
||||
|
||||
if len(cmd) > 0:
|
||||
asyncio.create_task(xiaomusic.do_check_cmd(did=did, query=cmd))
|
||||
try:
|
||||
await xiaomusic.cancel_all_tasks()
|
||||
task = asyncio.create_task(xiaomusic.do_check_cmd(did=did, query=cmd))
|
||||
xiaomusic.append_running_task(task)
|
||||
except Exception as e:
|
||||
log.warning(f"Execption {e}")
|
||||
return {"ret": "OK"}
|
||||
return {"ret": "Unknow cmd"}
|
||||
|
||||
@@ -291,3 +294,66 @@ async def debug_play_by_music_url(request: Request):
|
||||
return await xiaomusic.debug_play_by_music_url(arg1=data_dict)
|
||||
except json.JSONDecodeError as err:
|
||||
raise HTTPException(status_code=400, detail="Invalid JSON") from err
|
||||
|
||||
|
||||
async def file_iterator(file_path, start, end):
|
||||
async with aiofiles.open(file_path, mode="rb") as file:
|
||||
await file.seek(start)
|
||||
chunk_size = 1024
|
||||
while start <= end:
|
||||
read_size = min(chunk_size, end - start + 1)
|
||||
data = await file.read(read_size)
|
||||
if not data:
|
||||
break
|
||||
start += len(data)
|
||||
yield data
|
||||
|
||||
|
||||
range_pattern = re.compile(r"bytes=(\d+)-(\d*)")
|
||||
|
||||
|
||||
@app.get("/music/{file_path:path}")
|
||||
async def music_file(request: Request, file_path: str):
|
||||
absolute_path = os.path.abspath(config.music_path)
|
||||
absolute_file_path = os.path.normpath(os.path.join(absolute_path, file_path))
|
||||
if not absolute_file_path.startswith(absolute_path):
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
if not os.path.exists(absolute_file_path):
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
file_size = os.path.getsize(absolute_file_path)
|
||||
range_start, range_end = 0, file_size - 1
|
||||
|
||||
range_header = request.headers.get("Range")
|
||||
log.info(f"music_file range_header {range_header}")
|
||||
if range_header:
|
||||
range_match = range_pattern.match(range_header)
|
||||
if range_match:
|
||||
range_start = int(range_match.group(1))
|
||||
if range_match.group(2):
|
||||
range_end = int(range_match.group(2))
|
||||
|
||||
log.info(f"music_file in range {absolute_file_path}")
|
||||
|
||||
log.info(f"music_file {range_start} {range_end} {absolute_file_path}")
|
||||
headers = {
|
||||
"Content-Range": f"bytes {range_start}-{range_end}/{file_size}",
|
||||
"Accept-Ranges": "bytes",
|
||||
}
|
||||
mime_type, _ = mimetypes.guess_type(file_path)
|
||||
if mime_type is None:
|
||||
mime_type = "application/octet-stream"
|
||||
return StreamingResponse(
|
||||
file_iterator(absolute_file_path, range_start, range_end),
|
||||
headers=headers,
|
||||
status_code=206 if range_header else 200,
|
||||
media_type=mime_type,
|
||||
)
|
||||
|
||||
|
||||
@app.options("/music/{file_path:path}")
|
||||
async def music_options():
|
||||
headers = {
|
||||
"Accept-Ranges": "bytes",
|
||||
}
|
||||
return Response(headers=headers)
|
||||
|
||||
@@ -53,15 +53,17 @@ $(function(){
|
||||
.prop('selected', value === did);
|
||||
$("#did").append(option);
|
||||
|
||||
if (cur_device.play_type == PLAY_TYPE_ALL) {
|
||||
$("#play_type_all").css('background-color', '#b1a8f3');
|
||||
$("#play_type_all").text('✔️ 全部循环');
|
||||
} else if (cur_device.play_type == PLAY_TYPE_ONE) {
|
||||
$("#play_type_one").css('background-color', '#b1a8f3');
|
||||
$("#play_type_one").text('✔️ 单曲循环');
|
||||
} else if (cur_device.play_type == PLAY_TYPE_RND) {
|
||||
$("#play_type_rnd").css('background-color', '#b1a8f3');
|
||||
$("#play_type_rnd").text('✔️ 随机播放');
|
||||
if (value === did) {
|
||||
if (cur_device.play_type == PLAY_TYPE_ALL) {
|
||||
$("#play_type_all").css('background-color', '#b1a8f3');
|
||||
$("#play_type_all").text('✔️ 全部循环');
|
||||
} else if (cur_device.play_type == PLAY_TYPE_ONE) {
|
||||
$("#play_type_one").css('background-color', '#b1a8f3');
|
||||
$("#play_type_one").text('✔️ 单曲循环');
|
||||
} else if (cur_device.play_type == PLAY_TYPE_RND) {
|
||||
$("#play_type_rnd").css('background-color', '#b1a8f3');
|
||||
$("#play_type_rnd").text('✔️ 随机播放');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -72,6 +74,7 @@ $(function(){
|
||||
localStorage.setItem('cur_did', did);
|
||||
window.did = did;
|
||||
console.log('cur_did', did);
|
||||
location.reload();
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Debug For XiaoMusic</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/static/style.css?version=1721662254">
|
||||
<link rel="stylesheet" type="text/css" href="/static/style.css?version=1723807100">
|
||||
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
||||
<script src="/static/jquery-3.7.1.min.js?version=1721662254"></script>
|
||||
<script src="/static/jquery-3.7.1.min.js?version=1723807100"></script>
|
||||
|
||||
<script>
|
||||
var vConsole = new window.VConsole();
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>小爱音箱操控面板</title>
|
||||
<script src="/static/jquery-3.7.1.min.js?version=1721662254"></script>
|
||||
<script src="/static/app.js?version=1721662254"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/static/style.css?version=1721662254">
|
||||
<script src="/static/jquery-3.7.1.min.js?version=1723807100"></script>
|
||||
<script src="/static/app.js?version=1723807100"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/static/style.css?version=1723807100">
|
||||
|
||||
<!--
|
||||
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>M3U to JSON Converter</title>
|
||||
<link rel="stylesheet" type="text/css" href="/static/style.css?version=1721662254">
|
||||
<link rel="stylesheet" type="text/css" href="/static/style.css?version=1723807100">
|
||||
<!--
|
||||
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
||||
<script>
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>小爱音箱操控面板</title>
|
||||
<script src="/static/jquery-3.7.1.min.js?version=1721662254"></script>
|
||||
<script src="/static/setting.js?version=1721662254"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/static/style.css?version=1721662254">
|
||||
<script src="/static/jquery-3.7.1.min.js?version=1723807100"></script>
|
||||
<script src="/static/setting.js?version=1723807100"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/static/style.css?version=1723807100">
|
||||
|
||||
<!--
|
||||
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
||||
@@ -127,9 +127,24 @@ var vConsole = new window.VConsole();
|
||||
<option value="false">false</option>
|
||||
</select>
|
||||
|
||||
<label for="enable_gate">开启网关(重启生效):</label>
|
||||
<select id="enable_gate">
|
||||
<option value="true">true</option>
|
||||
<option value="false" selected>false</option>
|
||||
</select>
|
||||
|
||||
<label for="use_music_api">触屏版兼容模式:</label>
|
||||
<select id="use_music_api">
|
||||
<option value="true">true</option>
|
||||
<option value="false" selected>false</option>
|
||||
</select>
|
||||
|
||||
<label for="public_port">外网访问端口(0表示跟监听端口一致):</label>
|
||||
<input id="public_port" type="number" value="0"></input>
|
||||
|
||||
<label for="delay_sec">下一首歌延迟播放秒数:</label>
|
||||
<input id="delay_sec" type="number" value="3"></input>
|
||||
|
||||
<label for="stop_tts_msg">停止提示音:</label>
|
||||
<input id="stop_tts_msg" type="text" value="收到,再见"></input>
|
||||
<label for="keywords_playlocal">播放本地歌曲口令:</label>
|
||||
|
||||
@@ -68,9 +68,8 @@ $(function(){
|
||||
|
||||
// 初始化显示
|
||||
for (const key in data) {
|
||||
if (data.hasOwnProperty(key)) {
|
||||
const $element = $("#" + key);
|
||||
if ($element.length && data[key] !== '') {
|
||||
if ($element.length) {
|
||||
if (data[key] === true) {
|
||||
$element.val('true');
|
||||
} else if (data[key] === false) {
|
||||
@@ -79,7 +78,6 @@ $(function(){
|
||||
$element.val(data[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
autoSelectOne();
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import copy
|
||||
import difflib
|
||||
import logging
|
||||
import mimetypes
|
||||
import os
|
||||
import random
|
||||
@@ -139,9 +141,7 @@ def _append_files_result(result, root, joinpath, files, support_extension):
|
||||
result[dir_name].append(os.path.join(joinpath, file))
|
||||
|
||||
|
||||
def traverse_music_directory(
|
||||
directory, depth=10, exclude_dirs=None, support_extension=None
|
||||
):
|
||||
def traverse_music_directory(directory, depth, exclude_dirs, support_extension):
|
||||
result = {}
|
||||
for root, dirs, files in os.walk(directory, followlinks=True):
|
||||
# 忽略排除的目录
|
||||
@@ -193,23 +193,20 @@ async def _get_web_music_duration(session, url, start=0, end=500):
|
||||
headers = {"Range": f"bytes={start}-{end}"}
|
||||
async with session.get(url, headers=headers) as response:
|
||||
array_buffer = await response.read()
|
||||
with tempfile.NamedTemporaryFile(delete=False) as tmp:
|
||||
with tempfile.NamedTemporaryFile() as tmp:
|
||||
tmp.write(array_buffer)
|
||||
name = tmp.name
|
||||
|
||||
try:
|
||||
if is_mp3(url):
|
||||
m = mutagen.mp3.MP3(name)
|
||||
else:
|
||||
m = mutagen.File(name)
|
||||
duration = m.info.length
|
||||
except Exception:
|
||||
pass
|
||||
os.remove(name)
|
||||
try:
|
||||
if is_mp3(url):
|
||||
m = mutagen.mp3.MP3(tmp)
|
||||
else:
|
||||
m = mutagen.File(tmp)
|
||||
duration = m.info.length
|
||||
except Exception as e:
|
||||
logging.error(f"Error _get_web_music_duration: {e}")
|
||||
return duration
|
||||
|
||||
|
||||
async def get_web_music_duration(url, start=0, end=500):
|
||||
async def get_web_music_duration(url):
|
||||
duration = 0
|
||||
try:
|
||||
parsed_url = urlparse(url)
|
||||
@@ -232,24 +229,25 @@ async def get_web_music_duration(url, start=0, end=500):
|
||||
duration = await _get_web_music_duration(session, url, start=0, end=500)
|
||||
if duration <= 0:
|
||||
duration = await _get_web_music_duration(
|
||||
session, url, start=0, end=1000
|
||||
session, url, start=0, end=3000
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as e:
|
||||
logging.error(f"Error get_web_music_duration: {e}")
|
||||
return duration, url
|
||||
|
||||
|
||||
# 获取文件播放时长
|
||||
def get_local_music_duration(filename):
|
||||
async def get_local_music_duration(filename):
|
||||
loop = asyncio.get_event_loop()
|
||||
duration = 0
|
||||
try:
|
||||
if is_mp3(filename):
|
||||
m = mutagen.mp3.MP3(filename)
|
||||
m = await loop.run_in_executor(None, mutagen.mp3.MP3, filename)
|
||||
else:
|
||||
m = mutagen.File(filename)
|
||||
m = await loop.run_in_executor(None, mutagen.File, filename)
|
||||
duration = m.info.length
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as e:
|
||||
logging.error(f"Error getting local music {filename} duration: {e}")
|
||||
return duration
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import math
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
@@ -61,6 +62,7 @@ class XiaoMusic:
|
||||
self._all_radio = {} # 电台列表
|
||||
self.music_list = {} # 播放列表 key 为目录名, value 为 play_list
|
||||
self.devices = {} # key 为 did
|
||||
self.running_task = []
|
||||
|
||||
# 初始化配置
|
||||
self.init_config()
|
||||
@@ -83,15 +85,11 @@ class XiaoMusic:
|
||||
debug_config = deepcopy_data_no_sensitive_info(self.config)
|
||||
self.log.info(f"Startup OK. {debug_config}")
|
||||
|
||||
if self.conf_path == self.music_path:
|
||||
if self.config.conf_path == self.music_path:
|
||||
self.log.warning("配置文件目录和音乐目录建议设置为不同的目录")
|
||||
|
||||
def init_config(self):
|
||||
self.music_path = self.config.music_path
|
||||
self.conf_path = self.config.conf_path
|
||||
# 兼容旧配置空的情况
|
||||
if not self.conf_path:
|
||||
self.conf_path = "conf"
|
||||
self.download_path = self.config.download_path
|
||||
if not self.download_path:
|
||||
self.download_path = self.music_path
|
||||
@@ -312,10 +310,10 @@ class XiaoMusic:
|
||||
|
||||
def get_filename(self, name):
|
||||
if name not in self.all_music:
|
||||
self.log.debug(f"get_filename not in. name:{name}")
|
||||
self.log.info(f"get_filename not in. name:{name}")
|
||||
return ""
|
||||
filename = self.all_music[name]
|
||||
self.log.debug(f"try get_filename. filename:{filename}")
|
||||
self.log.info(f"try get_filename. filename:{filename}")
|
||||
if os.path.exists(filename):
|
||||
return filename
|
||||
return ""
|
||||
@@ -346,6 +344,7 @@ class XiaoMusic:
|
||||
async def get_music_sec_url(self, name):
|
||||
sec = 0
|
||||
url = self.get_music_url(name)
|
||||
self.log.info(f"get_music_sec_url. name:{name} url:{url}")
|
||||
if self.is_web_radio_music(name):
|
||||
self.log.info("电台不会有播放时长")
|
||||
return 0, url
|
||||
@@ -353,11 +352,13 @@ class XiaoMusic:
|
||||
if self.is_web_music(name):
|
||||
origin_url = url
|
||||
duration, url = await get_web_music_duration(url)
|
||||
sec = int(duration)
|
||||
sec = math.ceil(duration)
|
||||
self.log.info(f"网络歌曲 {name} : {origin_url} {url} 的时长 {sec} 秒")
|
||||
else:
|
||||
filename = self.get_filename(name)
|
||||
sec = int(get_local_music_duration(filename))
|
||||
self.log.info(f"get_music_sec_url. name:{name} filename:{filename}")
|
||||
duration = await get_local_music_duration(filename)
|
||||
sec = math.ceil(duration)
|
||||
self.log.info(f"本地歌曲 {name} : {filename} {url} 的时长 {sec} 秒")
|
||||
|
||||
if sec <= 0:
|
||||
@@ -367,7 +368,7 @@ class XiaoMusic:
|
||||
def get_music_url(self, name):
|
||||
if self.is_web_music(name):
|
||||
url = self.all_music[name]
|
||||
self.log.debug(f"get_music_url web music. name:{name}, url:{url}")
|
||||
self.log.info(f"get_music_url web music. name:{name}, url:{url}")
|
||||
return url
|
||||
|
||||
filename = self.get_filename(name)
|
||||
@@ -385,7 +386,7 @@ class XiaoMusic:
|
||||
filename = filename[len(self.config.music_path) :]
|
||||
if filename.startswith("/"):
|
||||
filename = filename[1:]
|
||||
self.log.debug(f"get_music_url local music. name:{name}, filename:{filename}")
|
||||
self.log.info(f"get_music_url local music. name:{name}, filename:{filename}")
|
||||
encoded_name = urllib.parse.quote(filename)
|
||||
return f"http://{self.hostname}:{self.public_port}/music/{encoded_name}"
|
||||
|
||||
@@ -507,6 +508,19 @@ class XiaoMusic:
|
||||
except Exception as e:
|
||||
self.log.exception(f"Execption {e}")
|
||||
|
||||
def append_running_task(self, task):
|
||||
self.running_task.append(task)
|
||||
|
||||
async def cancel_all_tasks(self):
|
||||
if len(self.running_task) == 0:
|
||||
self.log.info("cancel_all_tasks no task")
|
||||
return
|
||||
for task in self.running_task:
|
||||
self.log.info(f"cancel_all_tasks {task}")
|
||||
task.cancel()
|
||||
await asyncio.gather(*self.running_task, return_exceptions=True)
|
||||
self.running_task = []
|
||||
|
||||
async def check_replay(self, did):
|
||||
return await self.devices[did].check_replay()
|
||||
|
||||
@@ -718,16 +732,9 @@ class XiaoMusic:
|
||||
def getconfig(self):
|
||||
return self.config
|
||||
|
||||
# 获取设置文件
|
||||
def getsettingfile(self):
|
||||
if not os.path.exists(self.conf_path):
|
||||
os.makedirs(self.conf_path)
|
||||
filename = os.path.join(self.conf_path, "setting.json")
|
||||
return filename
|
||||
|
||||
def try_init_setting(self):
|
||||
try:
|
||||
filename = self.getsettingfile()
|
||||
filename = self.config.getsettingfile()
|
||||
with open(filename) as f:
|
||||
data = json.loads(f.read())
|
||||
self.update_config_from_setting(data)
|
||||
@@ -749,8 +756,7 @@ class XiaoMusic:
|
||||
|
||||
# 配置文件落地
|
||||
def do_saveconfig(self, data):
|
||||
# 默认暂时配置保存到 music 目录下
|
||||
filename = self.getsettingfile()
|
||||
filename = self.config.getsettingfile()
|
||||
with open(filename, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||
|
||||
@@ -853,7 +859,7 @@ class XiaoMusicDevice:
|
||||
async def _play(self, name="", search_key=""):
|
||||
if search_key == "" and name == "":
|
||||
if self.check_play_next():
|
||||
await self.play_next()
|
||||
await self._play_next()
|
||||
return
|
||||
else:
|
||||
name = self.cur_music
|
||||
@@ -886,7 +892,7 @@ class XiaoMusicDevice:
|
||||
or (name not in self._play_list)
|
||||
):
|
||||
name = self.get_next_music()
|
||||
self.log.info(f"play_next. name:{name}, cur_music:{self.cur_music}")
|
||||
self.log.info(f"_play_next. name:{name}, cur_music:{self.cur_music}")
|
||||
if name == "":
|
||||
await self.do_tts("本地没有歌曲")
|
||||
return
|
||||
@@ -897,7 +903,7 @@ class XiaoMusicDevice:
|
||||
self._last_cmd = "playlocal"
|
||||
if name == "":
|
||||
if self.check_play_next():
|
||||
await self.play_next()
|
||||
await self._play_next()
|
||||
return
|
||||
else:
|
||||
name = self.cur_music
|
||||
@@ -912,6 +918,9 @@ class XiaoMusicDevice:
|
||||
await self._playmusic(name)
|
||||
|
||||
async def _playmusic(self, name):
|
||||
# 取消组内所有的下一首歌曲的定时器
|
||||
self.cancel_group_next_timer()
|
||||
|
||||
self._playing = True
|
||||
self.cur_music = name
|
||||
self.log.info(f"cur_music {self.cur_music}")
|
||||
@@ -926,11 +935,13 @@ class XiaoMusicDevice:
|
||||
await self._play_next()
|
||||
return
|
||||
|
||||
self.log.info("已经开始播放了")
|
||||
self.log.info(f"【{name}】已经开始播放了")
|
||||
|
||||
# 取消组内所有的下一首歌曲的定时器
|
||||
self.cancel_group_next_timer()
|
||||
# 设置下一首歌曲的播放定时器
|
||||
if sec <= 1:
|
||||
self.log.info(f"【{name}】不会设置下一首歌的定时器")
|
||||
return
|
||||
sec = sec + self.config.delay_sec
|
||||
await self.set_next_music_timeout(sec)
|
||||
|
||||
async def do_tts(self, value):
|
||||
@@ -939,7 +950,7 @@ class XiaoMusicDevice:
|
||||
self.log.info("do_tts no value")
|
||||
return
|
||||
|
||||
await self.group_force_stop_xiaoai()
|
||||
# await self.group_force_stop_xiaoai()
|
||||
await self.text_to_speech(value)
|
||||
|
||||
# 最大等8秒
|
||||
@@ -1081,14 +1092,17 @@ class XiaoMusicDevice:
|
||||
def check_play_next(self):
|
||||
# 当前歌曲不在当前播放列表
|
||||
if self.cur_music not in self._play_list:
|
||||
self.log.info(f"当前歌曲 {self.cur_music} 不在当前播放列表")
|
||||
return True
|
||||
|
||||
# 当前没我在播放的歌曲
|
||||
if self.cur_music == "":
|
||||
self.log.info("当前没我在播放的歌曲")
|
||||
return True
|
||||
else:
|
||||
# 当前播放的歌曲不存在了
|
||||
if not self.xiaomusic.is_music_exist(self.cur_music):
|
||||
self.log.info(f"当前播放的歌曲 {self.cur_music} 不存在了")
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -1127,23 +1141,19 @@ class XiaoMusicDevice:
|
||||
|
||||
# 设置下一首歌曲的播放定时器
|
||||
async def set_next_music_timeout(self, sec):
|
||||
if sec <= 0:
|
||||
return
|
||||
|
||||
if self._next_timer:
|
||||
self._next_timer.cancel()
|
||||
self.log.info("旧定时器已取消")
|
||||
|
||||
self.cancel_next_timer()
|
||||
self._timeout = sec
|
||||
|
||||
async def _do_next():
|
||||
await asyncio.sleep(self._timeout)
|
||||
try:
|
||||
await self.play_next()
|
||||
self.log.info("定时器时间到了")
|
||||
self._next_timer = None
|
||||
await self._play_next()
|
||||
except Exception as e:
|
||||
self.log.error(f"Execption {e}")
|
||||
|
||||
self._next_timer = asyncio.ensure_future(_do_next())
|
||||
self._next_timer = asyncio.create_task(_do_next())
|
||||
self.log.info(f"{sec} 秒后将会播放下一首歌曲")
|
||||
|
||||
async def set_volume(self, volume: int):
|
||||
@@ -1183,10 +1193,8 @@ class XiaoMusicDevice:
|
||||
self._playing = False
|
||||
if arg1 != "notts":
|
||||
await self.do_tts(self.config.stop_tts_msg)
|
||||
if self._next_timer:
|
||||
self._next_timer.cancel()
|
||||
self._next_timer = None
|
||||
self.log.info("定时器已取消")
|
||||
# 取消组内所有的下一首歌曲的定时器
|
||||
self.cancel_group_next_timer()
|
||||
await self.group_force_stop_xiaoai()
|
||||
self.log.info("stop now")
|
||||
|
||||
@@ -1211,13 +1219,14 @@ class XiaoMusicDevice:
|
||||
except Exception as e:
|
||||
self.log.exception(f"Execption {e}")
|
||||
|
||||
self._stop_timer = asyncio.ensure_future(_do_stop())
|
||||
self._stop_timer = asyncio.create_task(_do_stop())
|
||||
await self.do_tts(f"收到,{minute}分钟后将关机")
|
||||
|
||||
def cancel_next_timer(self):
|
||||
if self._next_timer:
|
||||
self._next_timer.cancel()
|
||||
self.log.info("下一曲定时器已取消")
|
||||
self.log.info(f"下一曲定时器已取消 {self.device_id}")
|
||||
self._next_timer = None
|
||||
|
||||
def cancel_group_next_timer(self):
|
||||
devices = self.xiaomusic.get_group_devices(self.group_name)
|
||||
@@ -1232,10 +1241,12 @@ class XiaoMusicDevice:
|
||||
self.log.info("in cancel_all_timer")
|
||||
if self._next_timer:
|
||||
self._next_timer.cancel()
|
||||
self._next_timer = None
|
||||
self.log.info("cancel_all_timer _next_timer.cancel")
|
||||
|
||||
if self._stop_timer:
|
||||
self._stop_timer.cancel()
|
||||
self._stop_timer = None
|
||||
self.log.info("cancel_all_timer _stop_timer.cancel")
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user