Compare commits
127 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99c4296c7a | ||
|
|
0ae24f4810 | ||
|
|
77cca0d18c | ||
|
|
ddc24595df | ||
|
|
ce1bfb164c | ||
|
|
78dbba6c1f | ||
|
|
7eb0ab1e46 | ||
|
|
0a2e3cc579 | ||
|
|
75ec336285 | ||
|
|
a19d53f000 | ||
|
|
cdb6190e7a | ||
|
|
1aa9b58561 | ||
|
|
6a990f48d0 | ||
|
|
82e92a0380 | ||
|
|
ecce5c8848 | ||
|
|
87fb34e5c9 | ||
|
|
df3c4b7fa9 | ||
|
|
cb2af0ee9f | ||
|
|
8f9bba0ca3 | ||
|
|
b86e8d3196 | ||
|
|
65067346f3 | ||
|
|
865b412fb7 | ||
|
|
441fffd59e | ||
|
|
2ee7b956cf | ||
|
|
126bfa43a2 | ||
|
|
3a4d702070 | ||
|
|
2c7a09b9d4 | ||
|
|
74837baaef | ||
|
|
def63b2407 | ||
|
|
93d2047c7a | ||
|
|
9a1b9d1949 | ||
|
|
88fa4318dc | ||
|
|
0bc4bc8b13 | ||
|
|
ca2ddcd89c | ||
|
|
78acc35a62 | ||
|
|
323a832a9e | ||
|
|
0c99f4d537 | ||
|
|
b2737f745d | ||
|
|
464a1e1bd1 | ||
|
|
7bd613f74c | ||
|
|
3fb0a3bae9 | ||
|
|
b4f0e7b349 | ||
|
|
7c1ce81b5e | ||
|
|
052027fb50 | ||
|
|
b4d8434507 | ||
|
|
ec6018eabf | ||
|
|
bdeb2b5647 | ||
|
|
657e046379 | ||
|
|
bd6dd43737 | ||
|
|
5766919e69 | ||
|
|
0fe5f74d12 | ||
|
|
a2d6d1c357 | ||
|
|
5c61ef4b26 | ||
|
|
e57a02a192 | ||
|
|
5587411e37 | ||
|
|
95f756fb28 | ||
|
|
25ed90efa3 | ||
|
|
147bbcdd4c | ||
|
|
8dd9cfe0ac | ||
|
|
089bafd693 | ||
|
|
13b72bff97 | ||
|
|
3e959a08f0 | ||
|
|
3d1517854c | ||
|
|
e65c2ca3c9 | ||
|
|
6d7ff48913 | ||
|
|
7291826b56 | ||
|
|
fa06a7ad17 | ||
|
|
614cff3f05 | ||
|
|
a8d924e31f | ||
|
|
a9a6ead73f | ||
|
|
bd41735df2 | ||
|
|
655f0f9ab7 | ||
|
|
a003b6d0bf | ||
|
|
16f224b8e5 | ||
|
|
d4ca2c886f | ||
|
|
48b9e0a837 | ||
|
|
38df7aa6b9 | ||
|
|
29756c29a7 | ||
|
|
89287164ad | ||
|
|
81fb330db9 | ||
|
|
365954ecb0 | ||
|
|
d7fd7c43dc | ||
|
|
e48c6456fc | ||
|
|
193e1885e0 | ||
|
|
9acd5820ef | ||
|
|
119283693a | ||
|
|
dc9eb96a27 | ||
|
|
c022b5a0b1 | ||
|
|
bcbbfc5f52 | ||
|
|
3da07ce816 | ||
|
|
8629c16fe4 | ||
|
|
ac6fbd1b82 | ||
|
|
6995afed16 | ||
|
|
b49e250488 | ||
|
|
5032747f1e | ||
|
|
f749edcf16 | ||
|
|
14598aedee | ||
|
|
8845148cce | ||
|
|
1513a59726 | ||
|
|
497c1f34ef | ||
|
|
77920dffac | ||
|
|
c452136537 | ||
|
|
aa2992b5d7 | ||
|
|
7fcd3eeae5 | ||
|
|
30194272d9 | ||
|
|
1b71301b06 | ||
|
|
13bbff8d67 | ||
|
|
ae3507b811 | ||
|
|
bdfb0a4127 | ||
|
|
3d0a38cbb8 | ||
|
|
f469f63d97 | ||
|
|
6544bb2ff1 | ||
|
|
668237401e | ||
|
|
139ebf37c4 | ||
|
|
7146d61fcb | ||
|
|
6033c1a6fc | ||
|
|
e77a4fc10d | ||
|
|
bf2909d35a | ||
|
|
b3255a17ce | ||
|
|
a3140ff23a | ||
|
|
becfdbf338 | ||
|
|
8b74b664f0 | ||
|
|
0daba20885 | ||
|
|
8ac39af8cd | ||
|
|
d6fb62eb8e | ||
|
|
24ac876632 | ||
|
|
fcdb7bf035 |
45
.github/workflows/build-base-image.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
name: Build Docker Base Image
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'Dockerfile.builder'
|
||||
- 'Dockerfile.runtime'
|
||||
- 'install_dependencies.sh'
|
||||
- '.github/workflows/build-base-image.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-image:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name != 'pull_request'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push runtime
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile.runtime
|
||||
platforms: linux/amd64, linux/arm64, linux/arm/v7
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:runtime
|
||||
|
||||
- name: Build and push builder
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile.builder
|
||||
platforms: linux/amd64, linux/arm64, linux/arm/v7
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:builder
|
||||
|
||||
73
.github/workflows/ci.yml
vendored
@@ -1,37 +1,88 @@
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "*"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
TEST_TAG: ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:${{ github.ref_name }}
|
||||
jobs:
|
||||
build-image:
|
||||
build-test-publish:
|
||||
runs-on: ubuntu-latest
|
||||
# run unless event type is pull_request
|
||||
if: github.event_name != 'pull_request'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
|
||||
- name: Build Docker image (linux/amd64)
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
context: .
|
||||
push: false
|
||||
load: true
|
||||
tags: ${{ env.TEST_TAG }}-linux-amd64
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache-new
|
||||
|
||||
- name: Build Docker image (linux/arm64)
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
platforms: linux/arm64
|
||||
context: .
|
||||
push: false
|
||||
load: true
|
||||
tags: ${{ env.TEST_TAG }}-linux-arm64
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache-new
|
||||
|
||||
- name: Build Docker image (linux/arm/v7)
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
platforms: linux/arm/v7
|
||||
context: .
|
||||
push: false
|
||||
load: true
|
||||
tags: ${{ env.TEST_TAG }}-linux-arm-v7
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache-new
|
||||
|
||||
# We test all the images on amd64 host here. This uses QEMU to emulate
|
||||
# the other platforms.
|
||||
- run: docker run --rm ${TEST_TAG}-linux-amd64 -h
|
||||
- run: docker run --rm ${TEST_TAG}-linux-arm64 -h
|
||||
- run: docker run --rm ${TEST_TAG}-linux-arm-v7 -h
|
||||
|
||||
# This will only push the previously built images.
|
||||
- name: Publish to Docker Hub
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:${{ github.ref_name }}
|
||||
tags: ${{ env.TEST_TAG }}
|
||||
cache-from: type=local,src=/tmp/.buildx-cache-new
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache-new
|
||||
|
||||
- name: Docker Hub Description
|
||||
uses: peter-evans/dockerhub-description@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
repository: hanxi/xiaomusic
|
||||
|
||||
- name: Move cache to limit growth
|
||||
run: |
|
||||
rm -rf /tmp/.buildx-cache
|
||||
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||
|
||||
3
.github/workflows/release.yml
vendored
@@ -38,7 +38,6 @@ jobs:
|
||||
|
||||
build-image:
|
||||
runs-on: ubuntu-latest
|
||||
#needs: release-pypi
|
||||
# run unless event type is pull_request
|
||||
if: github.event_name != 'pull_request'
|
||||
steps:
|
||||
@@ -56,6 +55,6 @@ jobs:
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
platforms: linux/amd64, linux/arm64, linux/arm/v7
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:${{ github.ref_name }}, ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:latest, ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:stable
|
||||
|
||||
1
.gitignore
vendored
@@ -169,3 +169,4 @@ setting.json
|
||||
.DS_Store
|
||||
cache
|
||||
tmp/
|
||||
xiaomusic.log.txt
|
||||
|
||||
154
CHANGELOG.md
@@ -1,9 +1,161 @@
|
||||
## v0.3.53 (2024-12-03)
|
||||
|
||||
### Fix
|
||||
|
||||
- 解决播放接口修改后播放失败的问题
|
||||
|
||||
## v0.3.52 (2024-12-03)
|
||||
|
||||
### Fix
|
||||
|
||||
- 修复播放接口参数错误的问题
|
||||
|
||||
## v0.3.51 (2024-12-03)
|
||||
|
||||
### Fix
|
||||
|
||||
- 修复空配置启动失败问题 close #284
|
||||
|
||||
## v0.3.50 (2024-12-03)
|
||||
|
||||
### Feat
|
||||
|
||||
- 修改日志文件的默认值
|
||||
- 新增修改tag缓存信息的接口 close #266
|
||||
- 新增专用的播放歌曲和播放歌单接口,解决默认口令提示词被修改了导致后台失效的问题
|
||||
- 统计设备型号
|
||||
- 页面与设置中的HOST不一致时弹窗提醒 (#281)
|
||||
- 未发现小爱设备时给予提示 (#278)
|
||||
- 优化设置页面提示
|
||||
|
||||
### Fix
|
||||
|
||||
- 更新 yt-dlp ,解决 B 站下载问题 close #279
|
||||
- 网页播放audio获取到错误url无法播放时提醒用户 (#280)
|
||||
- input标签自闭合
|
||||
|
||||
### Refactor
|
||||
|
||||
- 调整设置页面
|
||||
|
||||
## v0.3.49 (2024-11-28)
|
||||
|
||||
### Feat
|
||||
|
||||
- 临时文件目录支持配置 #99
|
||||
- 新增单曲播放和顺序播放功能 close #277
|
||||
- 设置播放类型支持配置语音提示词,定时任务支持设置播放类型
|
||||
|
||||
### Fix
|
||||
|
||||
- 修复中文数字转换函数对'十、十一'等数字的处理 (#275)
|
||||
|
||||
## v0.3.48 (2024-11-20)
|
||||
|
||||
### Feat
|
||||
|
||||
- 支持替换默认口令,而不是追加 close #259
|
||||
- 新增自定义个歌单接口 #242
|
||||
|
||||
### Fix
|
||||
|
||||
- 锁定 PWA 应用旋转方向
|
||||
|
||||
## v0.3.47 (2024-11-14)
|
||||
|
||||
### Feat
|
||||
|
||||
- 支持 PWA 应用安装
|
||||
- 新增模糊匹配测试用例
|
||||
|
||||
### Fix
|
||||
|
||||
- 修复 PWA 应用有密码时报错的问题
|
||||
- 修复播放顺序没有按数字排序的问题 close #249
|
||||
|
||||
## v0.3.46 (2024-11-08)
|
||||
|
||||
### Feat
|
||||
|
||||
- 升级依赖库
|
||||
|
||||
### Fix
|
||||
|
||||
- 添加依赖库 requests
|
||||
|
||||
### Refactor
|
||||
|
||||
- 依赖库已经支持分段获取静态文件,重构代码
|
||||
|
||||
## v0.3.45 (2024-11-08)
|
||||
|
||||
### Feat
|
||||
|
||||
- 定时任务支持设置音量
|
||||
- 播放歌单口令支持配置
|
||||
|
||||
### Fix
|
||||
|
||||
- 修复定时任务报错问题
|
||||
|
||||
## v0.3.44 (2024-11-01)
|
||||
|
||||
### Feat
|
||||
|
||||
- 日志时间里加上日期
|
||||
|
||||
### Fix
|
||||
|
||||
- 修复搜索失败的问题
|
||||
|
||||
## v0.3.43 (2024-10-30)
|
||||
|
||||
### Feat
|
||||
|
||||
- 播放列表可以删除当前歌曲(!危险操作,请在设置中心开启相关功能) (#250)
|
||||
- 插件自定义口令支持获取语音输入内容 #105
|
||||
|
||||
### Fix
|
||||
|
||||
- 修复谷歌统计导致的卡顿问题
|
||||
- 解决挂载网盘卡死的问题
|
||||
|
||||
## v0.3.42 (2024-10-24)
|
||||
|
||||
### Fix
|
||||
|
||||
- 尝试修复缺少 libtiff.so.6 文件的问题 #244
|
||||
- 修复默认主题播放歌曲输入框空的情况
|
||||
- 尝试修复停止后自动播放的问题
|
||||
|
||||
## v0.3.41 (2024-10-17)
|
||||
|
||||
### Feat
|
||||
|
||||
- 设置默认时区为东八区 closed #236
|
||||
|
||||
### Fix
|
||||
|
||||
- 修复获取标签信息报错问题
|
||||
- remove_id3_tags return None if no id3 tag (#238)
|
||||
- bug in del_music (#237)
|
||||
|
||||
## v0.3.40 (2024-10-16)
|
||||
|
||||
### Feat
|
||||
|
||||
- 默认主题的播放列表上显示歌曲数量
|
||||
|
||||
### Fix
|
||||
|
||||
- 修复播放卡顿问题(谷歌统计地址无法访问的情况)
|
||||
|
||||
## v0.3.39 (2024-10-15)
|
||||
|
||||
### Feat
|
||||
|
||||
- 固定的播放列表全部初始化
|
||||
- 生产环境与开发环境接口分离、关于页面增加返回到主页的链接
|
||||
- 生产环境与开发环境接口分离、关于页面增加返回到主页的链接
|
||||
update: 支持https页面未及时更新的问题
|
||||
|
||||
### Fix
|
||||
|
||||
14
Dockerfile
@@ -1,4 +1,4 @@
|
||||
FROM python:3.10 AS builder
|
||||
FROM hanxi/xiaomusic:builder AS builder
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN pip install -U pdm
|
||||
ENV PDM_CHECK_UPDATE=false
|
||||
@@ -8,20 +8,18 @@ COPY xiaomusic/ ./xiaomusic/
|
||||
COPY plugins/ ./plugins/
|
||||
COPY xiaomusic.py .
|
||||
RUN pdm install --prod --no-editable
|
||||
COPY install_dependencies.sh .
|
||||
RUN bash install_dependencies.sh
|
||||
|
||||
FROM python:3.10-slim
|
||||
FROM hanxi/xiaomusic:runtime
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/.venv /app/.venv
|
||||
COPY --from=builder /app/ffmpeg /app/ffmpeg
|
||||
COPY xiaomusic/ ./xiaomusic/
|
||||
COPY plugins/ ./plugins/
|
||||
COPY xiaomusic.py .
|
||||
COPY --from=builder /app/xiaomusic/ ./xiaomusic/
|
||||
COPY --from=builder /app/plugins/ ./plugins/
|
||||
COPY --from=builder /app/xiaomusic.py .
|
||||
ENV XIAOMUSIC_HOSTNAME=192.168.2.5
|
||||
ENV XIAOMUSIC_PORT=8090
|
||||
VOLUME /app/conf
|
||||
VOLUME /app/music
|
||||
EXPOSE 8090
|
||||
ENV TZ=Asia/Shanghai
|
||||
ENV PATH=/app/.venv/bin:$PATH
|
||||
ENTRYPOINT [".venv/bin/python3","xiaomusic.py"]
|
||||
|
||||
11
Dockerfile.builder
Normal file
@@ -0,0 +1,11 @@
|
||||
FROM python:3.10
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN pip install -U pdm
|
||||
ENV PDM_CHECK_UPDATE=false
|
||||
WORKDIR /app
|
||||
COPY pyproject.toml README.md .
|
||||
COPY xiaomusic/ ./xiaomusic/
|
||||
COPY plugins/ ./plugins/
|
||||
COPY xiaomusic.py .
|
||||
RUN pdm install --prod --no-editable
|
||||
|
||||
14
Dockerfile.runtime
Normal file
@@ -0,0 +1,14 @@
|
||||
FROM python:3.10-slim
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
wget \
|
||||
xz-utils \
|
||||
libtiff6 \
|
||||
libopenjp2-7 \
|
||||
libxcb1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
COPY install_dependencies.sh .
|
||||
RUN bash install_dependencies.sh
|
||||
65
README.md
@@ -6,7 +6,8 @@
|
||||
[](https://pypi.org/project/xiaomusic/)
|
||||
[](https://pypi.org/project/xiaomusic/)
|
||||
[](https://github.com/hanxi/xiaomusic/releases)
|
||||
|
||||
[](https://visitorbadge.io/status?path=hanxi%2Fxiaomusic)
|
||||
[](https://visitorbadge.io/status?path=hanxi%2Fxiaomusic)
|
||||
|
||||
|
||||
使用小爱音箱播放音乐,音乐使用 yt-dlp 下载。
|
||||
@@ -24,6 +25,12 @@
|
||||
docker run -p 8090:8090 -v /xiaomusic/music:/app/music -v /xiaomusic/conf:/app/conf hanxi/xiaomusic
|
||||
```
|
||||
|
||||
🔥 国内:
|
||||
|
||||
```bash
|
||||
docker run -p 8090:8090 -v /xiaomusic/music:/app/music -v /xiaomusic/conf:/app/conf m.daocloud.io/docker.io/hanxi/xiaomusic
|
||||
```
|
||||
|
||||
对应的 docker compose 配置如下:
|
||||
|
||||
```yaml
|
||||
@@ -39,6 +46,21 @@ services:
|
||||
- /xiaomusic/conf:/app/conf
|
||||
```
|
||||
|
||||
🔥 国内:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
xiaomusic:
|
||||
image: m.daocloud.io/docker.io/hanxi/xiaomusic
|
||||
container_name: xiaomusic
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 8090:8090
|
||||
volumes:
|
||||
- /xiaomusic/music:/app/music
|
||||
- /xiaomusic/conf:/app/conf
|
||||
```
|
||||
|
||||
其中 conf 目录为配置文件存放目录,music 目录为音乐存放目录,建议分开配置为不同的目录。
|
||||
|
||||
> [!NOTE]
|
||||
@@ -51,6 +73,29 @@ docker 和 docker compose 二选一即可,启动成功后,在 web 页面可
|
||||
|
||||
### 🔥 修改默认8090端口映射
|
||||
|
||||
#### 方法1: 不修改监听端口 8090
|
||||
|
||||
【监听端口】保持为默认的 8090 不变,把【外网访问端口】改为 5678 。
|
||||
|
||||
```yaml
|
||||
services:
|
||||
xiaomusic:
|
||||
image: hanxi/xiaomusic
|
||||
container_name: xiaomusic
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 5678:8090
|
||||
volumes:
|
||||
- /xiaomusic/music:/app/music
|
||||
- /xiaomusic/conf:/app/conf
|
||||
environment:
|
||||
XIAOMUSIC_PUBLIC_PORT: 5678
|
||||
```
|
||||
|
||||
XIAOMUSIC_PUBLIC_PORT 对应后台设置里的【外网访问端口】,修改后可以不用重启。
|
||||
|
||||
#### 方法2: 修改监听端口 8090 为 5678
|
||||
|
||||
如果需要修改 8090 端口为其他端口,比如 5678,需要这样配,3个数字都需要是 5678 。见 <https://github.com/hanxi/xiaomusic/issues/19>
|
||||
|
||||
```yaml
|
||||
@@ -73,7 +118,7 @@ services:
|
||||
遇到问题可以去 web 设置页面底部点击【下载日志文件】按钮,然后搜索一下日志文件内容确保里面没有账号密码信息后(有就删除这些敏感信息),然后在提 issues 反馈问题时把下载的日志文件带上。
|
||||
|
||||
> [!IMPORTANT]
|
||||
> XIAOMUSIC_PORT 也可以在后台配置,对应的是监听端口。
|
||||
> XIAOMUSIC_PORT 也可以在后台配置,对应的是监听端口,修改后记得重启。
|
||||
|
||||
|
||||
### 🤐 支持语音口令
|
||||
@@ -98,8 +143,6 @@ services:
|
||||
> [!TIP]
|
||||
> 隐藏玩法: 对小爱同学说播放歌曲小猪佩奇的故事,会先下载小猪佩奇的故事,然后再播放小猪佩奇的故事。
|
||||
|
||||
更多功能见 [📝 文档汇总](https://github.com/hanxi/xiaomusic/issues/211)
|
||||
|
||||
## 🛠️ pip 方式安装运行
|
||||
|
||||
```shell
|
||||
@@ -182,6 +225,7 @@ docker build -t xiaomusic .
|
||||
| L05C | [小米小爱音箱Play 增强版](https://home.mi.com/baike/index.html#/detail?model=xiaomi.wifispeaker.l05c) |
|
||||
| L09A | [小米音箱Art](https://home.mi.com/webapp/content/baike/product/index.html?model=xiaomi.wifispeaker.l09a) |
|
||||
| LX04 X10A X08A | 已经支持的触屏版 |
|
||||
| X08C X08E X8F M01 | 需要设置【型号兼容模式】选项为 true |
|
||||
| M01/XMYX01JY | 小米小爱音箱HD (获取对话记录的接口比较特殊) |
|
||||
|
||||
型号与产品名称对照可以在这里查询 <https://home.miot-spec.com/s/xiaomi.wifispeaker>
|
||||
@@ -281,22 +325,13 @@ docker build -t xiaomusic .
|
||||
- [微信小程序: XIAO晓音](https://github.com/F-loat/xiaoplayer)
|
||||
- [pure 主题 xiaomusicUI](https://github.com/52fisher/xiaomusicUI)
|
||||
- [移动端的播放器主题](https://github.com/52fisher/XMusicPlayer)
|
||||
- [一个第三方的主题](https://github.com/DarrenWen/xiaomusicui)
|
||||
- 所有帮忙调试和测试的朋友
|
||||
- 所有反馈问题和建议的朋友
|
||||
|
||||
### 👉 其他教程
|
||||
|
||||
> [!NOTE]
|
||||
> 下面教程可能比较旧,只供参考
|
||||
|
||||
- [NAS部署教程](https://post.m.smzdm.com/p/avpe7n99/)
|
||||
- [群晖部署教程](https://post.m.smzdm.com/p/a7px7dol/)
|
||||
- [QNAS部署教程](https://post.smzdm.com/p/a5xz5x63/)
|
||||
- [视频教程](https://www.bilibili.com/video/BV1ZZpweHEtT/)
|
||||
- [TechHive](https://mp.weixin.qq.com/s/4a41muFtPaFKtHeZYu795w)
|
||||
- [弹个AI](https://mp.weixin.qq.com/s/sIsKxB7Y8b83AhnvaWiMog)
|
||||
- [简单免费!教你用绿联NAS联动小爱音箱,私人音乐库也能语音点播](https://post.m.smzdm.com/p/a8pldgg7/)
|
||||
- [飞牛教程](https://mp.weixin.qq.com/s?t=pages/image_detail&__biz=MzkxODc1NDMwOA==&mid=2247483725&idx=1&sn=2d615f14733b9bf989557fa766b4e1fc)
|
||||
更多功能见 [📝 文档汇总](https://github.com/hanxi/xiaomusic/issues/211)
|
||||
|
||||
## 🚨 免责声明
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ install_from_github() {
|
||||
mkdir -p ffmpeg/bin
|
||||
mv $pkg/bin/ffmpeg ffmpeg/bin/
|
||||
mv $pkg/bin/ffprobe ffmpeg/bin/
|
||||
rm -rf $pkg $pkg.tar.xz
|
||||
}
|
||||
|
||||
install_from_ffmpeg() {
|
||||
@@ -26,6 +27,7 @@ install_from_ffmpeg() {
|
||||
mkdir -p ffmpeg/bin
|
||||
mv $pkg/*/ffmpeg ffmpeg/bin/
|
||||
mv $pkg/*/ffprobe ffmpeg/bin/
|
||||
rm -rf $pkg $pkg.tar.xz
|
||||
}
|
||||
|
||||
# 基于架构执行不同的操作
|
||||
|
||||
594
pdm.lock
generated
@@ -5,7 +5,7 @@
|
||||
groups = ["default", "dev", "lint"]
|
||||
strategy = ["inherit_metadata"]
|
||||
lock_version = "4.5.0"
|
||||
content_hash = "sha256:c7b4db9b4f139c1e6f1f2bd499d57c8f2246688fc5a39d675627d23920dc4403"
|
||||
content_hash = "sha256:d22d4b03450cd369683d3ddf827359cd96541ee09e29bfa1fa666d72aa7d3ab0"
|
||||
|
||||
[[metadata.targets]]
|
||||
requires_python = "==3.10.12"
|
||||
@@ -39,23 +39,24 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "aiohttp"
|
||||
version = "3.10.0"
|
||||
requires_python = ">=3.8"
|
||||
version = "3.11.9"
|
||||
requires_python = ">=3.9"
|
||||
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\"",
|
||||
"async-timeout<6.0,>=4.0; python_version < \"3.11\"",
|
||||
"attrs>=17.3.0",
|
||||
"frozenlist>=1.1.1",
|
||||
"multidict<7.0,>=4.5",
|
||||
"yarl<2.0,>=1.0",
|
||||
"propcache>=0.2.0",
|
||||
"yarl<2.0,>=1.17.0",
|
||||
]
|
||||
files = [
|
||||
{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"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39625703540feb50b6b7f938b3856d1f4886d2e585d88274e62b1bd273fae09b"},
|
||||
{file = "aiohttp-3.11.9.tar.gz", hash = "sha256:a9266644064779840feec0e34f10a89b3ff1d2d6b751fe90017abcad1864fa7c"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -108,20 +109,18 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "apscheduler"
|
||||
version = "3.10.4"
|
||||
requires_python = ">=3.6"
|
||||
version = "3.11.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "In-process task scheduler with Cron-like capabilities"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"importlib-metadata>=3.6.0; python_version < \"3.8\"",
|
||||
"pytz",
|
||||
"six>=1.4.0",
|
||||
"tzlocal!=3.*,>=2.0",
|
||||
"backports-zoneinfo; python_version < \"3.9\"",
|
||||
"tzlocal>=3.0",
|
||||
]
|
||||
files = [
|
||||
{file = "APScheduler-3.10.4-py3-none-any.whl", hash = "sha256:fb91e8a768632a4756a585f79ec834e0e27aad5860bac7eaa523d9ccefd87661"},
|
||||
{file = "APScheduler-3.10.4.tar.gz", hash = "sha256:e6df071b27d9be898e486bc7940a7be50b4af2e9da7c08f0744a96d4bd4cef4a"},
|
||||
{file = "APScheduler-3.11.0-py3-none-any.whl", hash = "sha256:fc134ca32e50f5eadcc4938e3a4545ab19131435e851abb40b34d63d5141c6da"},
|
||||
{file = "apscheduler-3.11.0.tar.gz", hash = "sha256:4c622d250b0955a65d5d0eb91c33e6d43fd879834bf541e0a18661ae60460133"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -173,55 +172,20 @@ summary = "Python bindings for the Brotli compression library"
|
||||
groups = ["default"]
|
||||
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"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-win32.whl", hash = "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-win32.whl", hash = "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-win32.whl", hash = "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951"},
|
||||
{file = "Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2024.7.4"
|
||||
version = "2024.8.30"
|
||||
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"},
|
||||
{file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
|
||||
{file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -311,13 +275,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "commitizen"
|
||||
version = "3.28.0"
|
||||
requires_python = ">=3.8"
|
||||
version = "4.0.0"
|
||||
requires_python = ">=3.9"
|
||||
summary = "Python commitizen client tool"
|
||||
groups = ["dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"argcomplete<3.5,>=1.12.1",
|
||||
"argcomplete<3.6,>=1.12.1",
|
||||
"charset-normalizer<4,>=2.1.0",
|
||||
"colorama<0.5.0,>=0.4.1",
|
||||
"decli<0.7.0,>=0.6.0",
|
||||
@@ -328,11 +292,11 @@ dependencies = [
|
||||
"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\"",
|
||||
"typing-extensions<5.0.0,>=4.0.1; python_version < \"3.11\"",
|
||||
]
|
||||
files = [
|
||||
{file = "commitizen-3.28.0-py3-none-any.whl", hash = "sha256:372dba10bb082be0e571cfa9ac0946f4333c3f4b2e242fbe32ae2f2afea143e4"},
|
||||
{file = "commitizen-3.28.0.tar.gz", hash = "sha256:de3a90b3246233260649e423963cd702d56a3b499ea02886a6412ebfb76f9462"},
|
||||
{file = "commitizen-4.0.0-py3-none-any.whl", hash = "sha256:52873ee589a64cf77fc55570dbd3f987c6ffcd33132d179eb625c4d06ae935f7"},
|
||||
{file = "commitizen-4.0.0.tar.gz", hash = "sha256:16aff27e01b43015eab1c74eabbca3e284b4988dd1b146a0963282db241dc2c0"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -347,34 +311,6 @@ files = [
|
||||
{file = "decli-0.6.2.tar.gz", hash = "sha256:36f71eb55fd0093895efb4f416ec32b7f6e00147dda448e3365cf73ceab42d6f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dnspython"
|
||||
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"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "email-validator"
|
||||
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",
|
||||
]
|
||||
files = [
|
||||
{file = "email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631"},
|
||||
{file = "email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exceptiongroup"
|
||||
version = "1.2.2"
|
||||
@@ -389,40 +325,19 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "fastapi"
|
||||
version = "0.111.1"
|
||||
version = "0.115.5"
|
||||
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",
|
||||
"httpx>=0.23.0",
|
||||
"jinja2>=2.11.2",
|
||||
"pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.7.4",
|
||||
"python-multipart>=0.0.7",
|
||||
"starlette<0.38.0,>=0.37.2",
|
||||
"starlette<0.42.0,>=0.40.0",
|
||||
"typing-extensions>=4.8.0",
|
||||
"uvicorn[standard]>=0.12.0",
|
||||
]
|
||||
files = [
|
||||
{file = "fastapi-0.111.1-py3-none-any.whl", hash = "sha256:4f51cfa25d72f9fbc3280832e84b32494cf186f50158d364a8765aabf22587bf"},
|
||||
{file = "fastapi-0.111.1.tar.gz", hash = "sha256:ddd1ac34cb1f76c2e2d7f8545a4bcb5463bce4834e81abf0b189e0c359ab2413"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastapi-cli"
|
||||
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",
|
||||
]
|
||||
files = [
|
||||
{file = "fastapi_cli-0.0.4-py3-none-any.whl", hash = "sha256:a2552f3a7ae64058cdbb530be6fa6dbfc975dc165e4fa66d224c3d396e25e809"},
|
||||
{file = "fastapi_cli-0.0.4.tar.gz", hash = "sha256:e2e9ffaffc1f7767f488d6da34b6f5a377751c996f397902eb6abb99a67bde32"},
|
||||
{file = "fastapi-0.115.5-py3-none-any.whl", hash = "sha256:596b95adbe1474da47049e802f9a65ab2ffa9c2b07e7efee70eb8a66c9f2f796"},
|
||||
{file = "fastapi-0.115.5.tar.gz", hash = "sha256:0e7a4d0dc0d01c68df21887cce0945e72d3c48b9f4f79dfe7a7d53aa08fbb289"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -509,73 +424,6 @@ files = [
|
||||
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpcore"
|
||||
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",
|
||||
]
|
||||
files = [
|
||||
{file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"},
|
||||
{file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httptools"
|
||||
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"},
|
||||
{file = "httptools-0.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58"},
|
||||
{file = "httptools-0.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185"},
|
||||
{file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142"},
|
||||
{file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658"},
|
||||
{file = "httptools-0.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b"},
|
||||
{file = "httptools-0.6.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1"},
|
||||
{file = "httptools-0.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0"},
|
||||
{file = "httptools-0.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc"},
|
||||
{file = "httptools-0.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2"},
|
||||
{file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837"},
|
||||
{file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d"},
|
||||
{file = "httptools-0.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3"},
|
||||
{file = "httptools-0.6.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0"},
|
||||
{file = "httptools-0.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2"},
|
||||
{file = "httptools-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90"},
|
||||
{file = "httptools-0.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503"},
|
||||
{file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84"},
|
||||
{file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb"},
|
||||
{file = "httptools-0.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949"},
|
||||
{file = "httptools-0.6.1.tar.gz", hash = "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
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",
|
||||
"httpcore==1.*",
|
||||
"idna",
|
||||
"sniffio",
|
||||
]
|
||||
files = [
|
||||
{file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"},
|
||||
{file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.7"
|
||||
@@ -593,7 +441,7 @@ name = "jinja2"
|
||||
version = "3.1.4"
|
||||
requires_python = ">=3.7"
|
||||
summary = "A very fast and expressive template engine."
|
||||
groups = ["default", "dev"]
|
||||
groups = ["dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
dependencies = [
|
||||
"MarkupSafe>=2.0",
|
||||
@@ -623,7 +471,7 @@ name = "markupsafe"
|
||||
version = "2.1.5"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Safely add untrusted strings to HTML/XML markup."
|
||||
groups = ["default", "dev"]
|
||||
groups = ["dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
|
||||
@@ -673,7 +521,7 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "miservice-fork"
|
||||
version = "2.7.0"
|
||||
version = "2.7.1"
|
||||
requires_python = ">=3.8"
|
||||
summary = "XiaoMi Cloud Service fork from https://github.com/Yonsm/MiService"
|
||||
groups = ["default"]
|
||||
@@ -684,8 +532,8 @@ dependencies = [
|
||||
"rich",
|
||||
]
|
||||
files = [
|
||||
{file = "miservice_fork-2.7.0-py3-none-any.whl", hash = "sha256:8e2c91ebe1fc4b3c63b01cbf1818e5d5833d024fd3a8311970d649ad2d49d6e6"},
|
||||
{file = "miservice_fork-2.7.0.tar.gz", hash = "sha256:8e87ef6d89adceaf3f7a98242cdae1c9135498d77f2c743ec3871d2e42bcbab8"},
|
||||
{file = "miservice_fork-2.7.1-py3-none-any.whl", hash = "sha256:0f908de6db2c77bb1a27b217cf3ab99835b408804cda5f7d16329e8e60948d13"},
|
||||
{file = "miservice_fork-2.7.1.tar.gz", hash = "sha256:a10c82e353dcc69183e50ce00a50cb602d9dc5992d83989b4a259d4830b48ea1"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -782,15 +630,15 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pillow"
|
||||
version = "10.4.0"
|
||||
requires_python = ">=3.8"
|
||||
version = "11.0.0"
|
||||
requires_python = ">=3.9"
|
||||
summary = "Python Imaging Library (Fork)"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"},
|
||||
{file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"},
|
||||
{file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"},
|
||||
{file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9"},
|
||||
{file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f"},
|
||||
{file = "pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -808,29 +656,29 @@ files = [
|
||||
{file = "prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "propcache"
|
||||
version = "0.2.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Accelerated property cache"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"},
|
||||
{file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"},
|
||||
{file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pycryptodomex"
|
||||
version = "3.20.0"
|
||||
requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
version = "3.21.0"
|
||||
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
|
||||
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"},
|
||||
{file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91852d4480a4537d169c29a9d104dda44094c78f1f5b67bca76c29a91042b623"},
|
||||
{file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca649483d5ed251d06daf25957f802e44e6bb6df2e8f218ae71968ff8f8edc4"},
|
||||
{file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e186342cfcc3aafaad565cbd496060e5a614b441cacc3995ef0091115c1f6c5"},
|
||||
{file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:25cd61e846aaab76d5791d006497134602a9e451e954833018161befc3b5b9ed"},
|
||||
{file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:9c682436c359b5ada67e882fec34689726a09c461efd75b6ea77b2403d5665b7"},
|
||||
{file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7a7a8f33a1f1fb762ede6cc9cbab8f2a9ba13b196bfaf7bc6f0b39d2ba315a43"},
|
||||
{file = "pycryptodomex-3.20.0-cp35-abi3-win32.whl", hash = "sha256:c39778fd0548d78917b61f03c1fa8bfda6cfcf98c767decf360945fe6f97461e"},
|
||||
{file = "pycryptodomex-3.20.0-cp35-abi3-win_amd64.whl", hash = "sha256:2a47bcc478741b71273b917232f521fd5704ab4b25d301669879e7273d3586cc"},
|
||||
{file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e497413560e03421484189a6b65e33fe800d3bd75590e6d78d4dfdb7accf3b"},
|
||||
{file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e48217c7901edd95f9f097feaa0388da215ed14ce2ece803d3f300b4e694abea"},
|
||||
{file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d00fe8596e1cc46b44bf3907354e9377aa030ec4cd04afbbf6e899fc1e2a7781"},
|
||||
{file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:88afd7a3af7ddddd42c2deda43d53d3dfc016c11327d0915f90ca34ebda91499"},
|
||||
{file = "pycryptodomex-3.20.0.tar.gz", hash = "sha256:7a710b79baddd65b806402e14766c721aee8fb83381769c27920f26476276c1e"},
|
||||
{file = "pycryptodomex-3.21.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9aa0cf13a1a1128b3e964dc667e5fe5c6235f7d7cfb0277213f0e2a783837cc2"},
|
||||
{file = "pycryptodomex-3.21.0.tar.gz", hash = "sha256:222d0bd05381dd25c32dd6065c071ebf084212ab79bab4599ba9e6a3e0009e6c"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -933,39 +781,16 @@ files = [
|
||||
{file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-dotenv"
|
||||
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"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-multipart"
|
||||
version = "0.0.12"
|
||||
version = "0.0.19"
|
||||
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.12-py3-none-any.whl", hash = "sha256:43dcf96cf65888a9cd3423544dd0d75ac10f7aa0c3c28a175bbcd00c9ce1aebf"},
|
||||
{file = "python_multipart-0.0.12.tar.gz", hash = "sha256:045e1f98d719c1ce085ed7f7e1ef9d8ccc8c02ba02b5566d5f7521410ced58cb"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytz"
|
||||
version = "2024.2"
|
||||
summary = "World timezone definitions, modern and historical"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"},
|
||||
{file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"},
|
||||
{file = "python_multipart-0.0.19-py3-none-any.whl", hash = "sha256:f8d5b0b9c618575bf9df01c684ded1d94a338839bdd8223838afacfb4bb2082d"},
|
||||
{file = "python_multipart-0.0.19.tar.gz", hash = "sha256:905502ef39050557b7a6af411f454bc19526529ca46ae6831508438890ce12cc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -973,7 +798,7 @@ name = "pyyaml"
|
||||
version = "6.0.1"
|
||||
requires_python = ">=3.6"
|
||||
summary = "YAML parser and emitter for Python"
|
||||
groups = ["default", "dev"]
|
||||
groups = ["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"},
|
||||
@@ -1054,38 +879,14 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.5.5"
|
||||
version = "0.8.1"
|
||||
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.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]]
|
||||
name = "shellingham"
|
||||
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"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
summary = "Python 2 and 3 compatibility utilities"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||
{file = "ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c"},
|
||||
{file = "ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1102,7 +903,7 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "starlette"
|
||||
version = "0.37.2"
|
||||
version = "0.41.3"
|
||||
requires_python = ">=3.8"
|
||||
summary = "The little ASGI library that shines."
|
||||
groups = ["default"]
|
||||
@@ -1112,8 +913,8 @@ dependencies = [
|
||||
"typing-extensions>=3.10.0; python_version < \"3.10\"",
|
||||
]
|
||||
files = [
|
||||
{file = "starlette-0.37.2-py3-none-any.whl", hash = "sha256:6fe59f29268538e5d0d182f2791a479a0c64638e6935d1c6989e63fb2699c6ee"},
|
||||
{file = "starlette-0.37.2.tar.gz", hash = "sha256:9af890290133b79fc3db55474ade20f6220a364a0402e0b556e7cd5e1e093823"},
|
||||
{file = "starlette-0.41.3-py3-none-any.whl", hash = "sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7"},
|
||||
{file = "starlette-0.41.3.tar.gz", hash = "sha256:0e4ab3d16522a255be6b28260b938eae2482f98ce5cc934cb08dce8dc3ba5835"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1140,30 +941,12 @@ files = [
|
||||
{file = "tomlkit-0.13.0.tar.gz", hash = "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typer"
|
||||
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",
|
||||
"shellingham>=1.3.0",
|
||||
"typing-extensions>=3.7.4.3",
|
||||
]
|
||||
files = [
|
||||
{file = "typer-0.12.3-py3-none-any.whl", hash = "sha256:070d7ca53f785acbccba8e7d28b08dcd88f79f1fbda035ade0aecec71ca5c914"},
|
||||
{file = "typer-0.12.3.tar.gz", hash = "sha256:49e73131481d804288ef62598d97a1ceef3058905aa536a1134f90891ba35482"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.12.2"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Backported and Experimental Type Hints for Python 3.8+"
|
||||
groups = ["default"]
|
||||
groups = ["default", "dev"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
|
||||
@@ -1188,19 +971,19 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.2.2"
|
||||
version = "2.2.3"
|
||||
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"},
|
||||
{file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"},
|
||||
{file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uvicorn"
|
||||
version = "0.30.4"
|
||||
version = "0.32.1"
|
||||
requires_python = ">=3.8"
|
||||
summary = "The lightning-fast ASGI server."
|
||||
groups = ["default"]
|
||||
@@ -1211,116 +994,8 @@ dependencies = [
|
||||
"typing-extensions>=4.0; python_version < \"3.11\"",
|
||||
]
|
||||
files = [
|
||||
{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.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.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.4-py3-none-any.whl", hash = "sha256:06b00e3087e58c6865c284143c0c42f810b32ff4f265ab19d08c566f74a08728"},
|
||||
{file = "uvicorn-0.30.4.tar.gz", hash = "sha256:00db9a9e3711a5fa59866e2b02fac69d8dc70ce0814aaec9a66d1d9e5c832a30"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uvloop"
|
||||
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\" 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"},
|
||||
{file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8"},
|
||||
{file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849"},
|
||||
{file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957"},
|
||||
{file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd"},
|
||||
{file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef"},
|
||||
{file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2"},
|
||||
{file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1"},
|
||||
{file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24"},
|
||||
{file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533"},
|
||||
{file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12"},
|
||||
{file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650"},
|
||||
{file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec"},
|
||||
{file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc"},
|
||||
{file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6"},
|
||||
{file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593"},
|
||||
{file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3"},
|
||||
{file = "uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "watchfiles"
|
||||
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",
|
||||
]
|
||||
files = [
|
||||
{file = "watchfiles-0.22.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:da1e0a8caebf17976e2ffd00fa15f258e14749db5e014660f53114b676e68538"},
|
||||
{file = "watchfiles-0.22.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:61af9efa0733dc4ca462347becb82e8ef4945aba5135b1638bfc20fad64d4f0e"},
|
||||
{file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d9188979a58a096b6f8090e816ccc3f255f137a009dd4bbec628e27696d67c1"},
|
||||
{file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2bdadf6b90c099ca079d468f976fd50062905d61fae183f769637cb0f68ba59a"},
|
||||
{file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:067dea90c43bf837d41e72e546196e674f68c23702d3ef80e4e816937b0a3ffd"},
|
||||
{file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbf8a20266136507abf88b0df2328e6a9a7c7309e8daff124dda3803306a9fdb"},
|
||||
{file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1235c11510ea557fe21be5d0e354bae2c655a8ee6519c94617fe63e05bca4171"},
|
||||
{file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2444dc7cb9d8cc5ab88ebe792a8d75709d96eeef47f4c8fccb6df7c7bc5be71"},
|
||||
{file = "watchfiles-0.22.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c5af2347d17ab0bd59366db8752d9e037982e259cacb2ba06f2c41c08af02c39"},
|
||||
{file = "watchfiles-0.22.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9624a68b96c878c10437199d9a8b7d7e542feddda8d5ecff58fdc8e67b460848"},
|
||||
{file = "watchfiles-0.22.0-cp310-none-win32.whl", hash = "sha256:4b9f2a128a32a2c273d63eb1fdbf49ad64852fc38d15b34eaa3f7ca2f0d2b797"},
|
||||
{file = "watchfiles-0.22.0-cp310-none-win_amd64.whl", hash = "sha256:2627a91e8110b8de2406d8b2474427c86f5a62bf7d9ab3654f541f319ef22bcb"},
|
||||
{file = "watchfiles-0.22.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8c39987a1397a877217be1ac0fb1d8b9f662c6077b90ff3de2c05f235e6a8f96"},
|
||||
{file = "watchfiles-0.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a927b3034d0672f62fb2ef7ea3c9fc76d063c4b15ea852d1db2dc75fe2c09696"},
|
||||
{file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052d668a167e9fc345c24203b104c313c86654dd6c0feb4b8a6dfc2462239249"},
|
||||
{file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e45fb0d70dda1623a7045bd00c9e036e6f1f6a85e4ef2c8ae602b1dfadf7550"},
|
||||
{file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c49b76a78c156979759d759339fb62eb0549515acfe4fd18bb151cc07366629c"},
|
||||
{file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4a65474fd2b4c63e2c18ac67a0c6c66b82f4e73e2e4d940f837ed3d2fd9d4da"},
|
||||
{file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cc0cba54f47c660d9fa3218158b8963c517ed23bd9f45fe463f08262a4adae1"},
|
||||
{file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94ebe84a035993bb7668f58a0ebf998174fb723a39e4ef9fce95baabb42b787f"},
|
||||
{file = "watchfiles-0.22.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e0f0a874231e2839abbf473256efffe577d6ee2e3bfa5b540479e892e47c172d"},
|
||||
{file = "watchfiles-0.22.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:213792c2cd3150b903e6e7884d40660e0bcec4465e00563a5fc03f30ea9c166c"},
|
||||
{file = "watchfiles-0.22.0-cp311-none-win32.whl", hash = "sha256:b44b70850f0073b5fcc0b31ede8b4e736860d70e2dbf55701e05d3227a154a67"},
|
||||
{file = "watchfiles-0.22.0-cp311-none-win_amd64.whl", hash = "sha256:00f39592cdd124b4ec5ed0b1edfae091567c72c7da1487ae645426d1b0ffcad1"},
|
||||
{file = "watchfiles-0.22.0-cp311-none-win_arm64.whl", hash = "sha256:3218a6f908f6a276941422b035b511b6d0d8328edd89a53ae8c65be139073f84"},
|
||||
{file = "watchfiles-0.22.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c7b978c384e29d6c7372209cbf421d82286a807bbcdeb315427687f8371c340a"},
|
||||
{file = "watchfiles-0.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bd4c06100bce70a20c4b81e599e5886cf504c9532951df65ad1133e508bf20be"},
|
||||
{file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:425440e55cd735386ec7925f64d5dde392e69979d4c8459f6bb4e920210407f2"},
|
||||
{file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68fe0c4d22332d7ce53ad094622b27e67440dacefbaedd29e0794d26e247280c"},
|
||||
{file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a8a31bfd98f846c3c284ba694c6365620b637debdd36e46e1859c897123aa232"},
|
||||
{file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc2e8fe41f3cac0660197d95216c42910c2b7e9c70d48e6d84e22f577d106fc1"},
|
||||
{file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b7cc10261c2786c41d9207193a85c1db1b725cf87936df40972aab466179b6"},
|
||||
{file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28585744c931576e535860eaf3f2c0ec7deb68e3b9c5a85ca566d69d36d8dd27"},
|
||||
{file = "watchfiles-0.22.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:00095dd368f73f8f1c3a7982a9801190cc88a2f3582dd395b289294f8975172b"},
|
||||
{file = "watchfiles-0.22.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:52fc9b0dbf54d43301a19b236b4a4614e610605f95e8c3f0f65c3a456ffd7d35"},
|
||||
{file = "watchfiles-0.22.0-cp312-none-win32.whl", hash = "sha256:581f0a051ba7bafd03e17127735d92f4d286af941dacf94bcf823b101366249e"},
|
||||
{file = "watchfiles-0.22.0-cp312-none-win_amd64.whl", hash = "sha256:aec83c3ba24c723eac14225194b862af176d52292d271c98820199110e31141e"},
|
||||
{file = "watchfiles-0.22.0-cp312-none-win_arm64.whl", hash = "sha256:c668228833c5619f6618699a2c12be057711b0ea6396aeaece4ded94184304ea"},
|
||||
{file = "watchfiles-0.22.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b810a2c7878cbdecca12feae2c2ae8af59bea016a78bc353c184fa1e09f76b68"},
|
||||
{file = "watchfiles-0.22.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f7e1f9c5d1160d03b93fc4b68a0aeb82fe25563e12fbcdc8507f8434ab6f823c"},
|
||||
{file = "watchfiles-0.22.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:030bc4e68d14bcad2294ff68c1ed87215fbd9a10d9dea74e7cfe8a17869785ab"},
|
||||
{file = "watchfiles-0.22.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace7d060432acde5532e26863e897ee684780337afb775107c0a90ae8dbccfd2"},
|
||||
{file = "watchfiles-0.22.0.tar.gz", hash = "sha256:988e981aaab4f3955209e7e28c7794acdb690be1efa7f16f8ea5aba7ffdadacb"},
|
||||
{file = "uvicorn-0.32.1-py3-none-any.whl", hash = "sha256:82ad92fd58da0d12af7482ecdb5f2470a04c9c9a53ced65b9bbb4a205377602e"},
|
||||
{file = "uvicorn-0.32.1.tar.gz", hash = "sha256:ee9519c246a72b1c084cea8d3b44ed6026e78a4a309cbedae9c37e4cb9fbb175"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1339,120 +1014,52 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "websockets"
|
||||
version = "12.0"
|
||||
requires_python = ">=3.8"
|
||||
version = "14.1"
|
||||
requires_python = ">=3.9"
|
||||
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"},
|
||||
{file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"},
|
||||
{file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"},
|
||||
{file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"},
|
||||
{file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"},
|
||||
{file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"},
|
||||
{file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"},
|
||||
{file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"},
|
||||
{file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"},
|
||||
{file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"},
|
||||
{file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"},
|
||||
{file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"},
|
||||
{file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"},
|
||||
{file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"},
|
||||
{file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"},
|
||||
{file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"},
|
||||
{file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"},
|
||||
{file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"},
|
||||
{file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"},
|
||||
{file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"},
|
||||
{file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"},
|
||||
{file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"},
|
||||
{file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"},
|
||||
{file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"},
|
||||
{file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"},
|
||||
{file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"},
|
||||
{file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"},
|
||||
{file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"},
|
||||
{file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"},
|
||||
{file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"},
|
||||
{file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"},
|
||||
{file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"},
|
||||
{file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"},
|
||||
{file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"},
|
||||
{file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"},
|
||||
{file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"},
|
||||
{file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"},
|
||||
{file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"},
|
||||
{file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
|
||||
{file = "websockets-14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9607b9a442392e690a57909c362811184ea429585a71061cd5d3c2b98065c199"},
|
||||
{file = "websockets-14.1-py3-none-any.whl", hash = "sha256:4d4fc827a20abe6d544a119896f6b78ee13fe81cbfef416f3f2ddf09a03f0e2e"},
|
||||
{file = "websockets-14.1.tar.gz", hash = "sha256:398b10c77d471c0aab20a845e7a60076b6390bfdaac7a6d2edb0d2c59d75e8d8"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yarl"
|
||||
version = "1.9.4"
|
||||
requires_python = ">=3.7"
|
||||
version = "1.17.1"
|
||||
requires_python = ">=3.9"
|
||||
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\"",
|
||||
"propcache>=0.2.0",
|
||||
]
|
||||
files = [
|
||||
{file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"},
|
||||
{file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"},
|
||||
{file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"},
|
||||
{file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e844be8d536afa129366d9af76ed7cb8dfefec99f5f1c9e4f8ae542279a6dc3"},
|
||||
{file = "yarl-1.17.1-py3-none-any.whl", hash = "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06"},
|
||||
{file = "yarl-1.17.1.tar.gz", hash = "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yt-dlp"
|
||||
version = "2024.8.1"
|
||||
requires_python = ">=3.8"
|
||||
version = "2024.12.1.232904.dev0"
|
||||
requires_python = ">=3.9"
|
||||
summary = "A feature-rich command-line audio/video downloader"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
files = [
|
||||
{file = "yt_dlp-2024.12.1.232904.dev0-py3-none-any.whl", hash = "sha256:67c1fa0986662f2f26ba70789c79c6d04fda45eb530944872f4a47ef4f94047e"},
|
||||
{file = "yt_dlp-2024.12.1.232904.dev0.tar.gz", hash = "sha256:4fcce6637e70bad7c63220e4dd69a3a6b8969cbc17c93bfe569940dd173c0548"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yt-dlp"
|
||||
version = "2024.12.1.232904.dev0"
|
||||
extras = ["default"]
|
||||
requires_python = ">=3.9"
|
||||
summary = "A feature-rich command-line audio/video downloader"
|
||||
groups = ["default"]
|
||||
marker = "python_full_version == \"3.10.12\""
|
||||
@@ -1464,9 +1071,10 @@ dependencies = [
|
||||
"pycryptodomex",
|
||||
"requests<3,>=2.32.2",
|
||||
"urllib3<3,>=1.26.17",
|
||||
"websockets>=12.0",
|
||||
"websockets>=13.0",
|
||||
"yt-dlp==2024.12.1.232904.dev0",
|
||||
]
|
||||
files = [
|
||||
{file = "yt_dlp-2024.8.1-py3-none-any.whl", hash = "sha256:d0d927038e30a05f6eab26ff6189628456ea21bb159a3d9dc2e855eef2810eac"},
|
||||
{file = "yt_dlp-2024.8.1.tar.gz", hash = "sha256:4318aa523694611562f01419c8d526b662a72df34ef8ba454016b34c8366c158"},
|
||||
{file = "yt_dlp-2024.12.1.232904.dev0-py3-none-any.whl", hash = "sha256:67c1fa0986662f2f26ba70789c79c6d04fda45eb530944872f4a47ef4f94047e"},
|
||||
{file = "yt_dlp-2024.12.1.232904.dev0.tar.gz", hash = "sha256:4fcce6637e70bad7c63220e4dd69a3a6b8969cbc17c93bfe569940dd173c0548"},
|
||||
]
|
||||
|
||||
@@ -3,3 +3,7 @@ async def code1(arg1):
|
||||
log.info(f"code1:{arg1}")
|
||||
did = xiaomusic._cur_did
|
||||
await xiaomusic.do_tts(did, "你好,我是自定义的测试口令")
|
||||
|
||||
last_record = xiaomusic.last_record
|
||||
query = last_record.get("query", "").strip()
|
||||
await xiaomusic.do_tts(did, f"你说的是: {query}")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "xiaomusic"
|
||||
version = "0.3.39"
|
||||
version = "0.3.53"
|
||||
description = "Play Music with xiaomi AI speaker"
|
||||
authors = [
|
||||
{name = "涵曦", email = "im.hanxi@gmail.com"},
|
||||
@@ -9,9 +9,9 @@ dependencies = [
|
||||
"aiohttp>=3.8.6",
|
||||
"miservice-fork>=2.7.0",
|
||||
"mutagen>=1.47.0",
|
||||
"yt-dlp>=2024.07.01",
|
||||
"yt-dlp[default]>=2024.12.1.232904.dev0",
|
||||
"uvicorn>=0.30.1",
|
||||
"fastapi>=0.111.0",
|
||||
"fastapi>=0.115.4",
|
||||
"starlette>=0.37.2",
|
||||
"aiofiles>=24.1.0",
|
||||
"ga4mp>=2.0.4",
|
||||
@@ -19,8 +19,9 @@ dependencies = [
|
||||
"opencc-python-reimplemented==0.1.7",
|
||||
"pillow>=10.4.0",
|
||||
"python-multipart>=0.0.12",
|
||||
"requests>=2.32.3",
|
||||
]
|
||||
requires-python = ">=3.10,<3.12"
|
||||
requires-python = ">=3.10,<=3.12"
|
||||
readme = "README.md"
|
||||
license = {text = "MIT"}
|
||||
|
||||
|
||||
33
test/test_difflib.py
Normal file
@@ -0,0 +1,33 @@
|
||||
import difflib
|
||||
|
||||
from xiaomusic.utils import (
|
||||
find_best_match,
|
||||
keyword_detection,
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
user_input = "八年的爱"
|
||||
s1 = "冰冰超人 - 八年的爱新版"
|
||||
s2 = "冰冰超人 - 八年的爱"
|
||||
r1 = difflib.SequenceMatcher(None, s1, user_input).ratio()
|
||||
r2 = difflib.SequenceMatcher(None, s2, user_input).ratio()
|
||||
print(s1, r1)
|
||||
print(s2, r2)
|
||||
|
||||
s3 = "其他"
|
||||
str_list = [s2, s1, s3]
|
||||
matches, remains = keyword_detection(user_input, str_list, n=10)
|
||||
print(matches, remains)
|
||||
|
||||
extra_search_index = {}
|
||||
extra_search_index["1"] = s1
|
||||
extra_search_index["2"] = s2
|
||||
extra_search_index["3"] = s3
|
||||
real_names = find_best_match(
|
||||
user_input,
|
||||
str_list,
|
||||
cutoff=0.4,
|
||||
n=100,
|
||||
extra_search_index=extra_search_index,
|
||||
)
|
||||
print(real_names)
|
||||
@@ -36,8 +36,7 @@ async def main(directory):
|
||||
# await test_one_music(file)
|
||||
pass
|
||||
|
||||
await test_one_music("./music/4.mp3")
|
||||
# await test_one_music("./music/4 In Love - 一千零一个愿.mp3")
|
||||
await test_one_music("music/4 In Love - 一千零一个愿望.mp3")
|
||||
# await test_one_music("./music/程响-人间烟火.flac")
|
||||
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "0.3.39"
|
||||
__version__ = "0.3.53"
|
||||
|
||||
@@ -27,21 +27,22 @@ class Analytics:
|
||||
self.gtag = gtag
|
||||
self.log.info("analytics init ok")
|
||||
|
||||
async def run_with_timeout(self, func, *args, **kwargs):
|
||||
async def run_with_cancel(self, func, *args, **kwargs):
|
||||
try:
|
||||
return await asyncio.wait_for(func(*args, **kwargs), 3)
|
||||
except asyncio.TimeoutError as e:
|
||||
self.log.warning(f"analytics run_with_timeout failed {e}")
|
||||
asyncio.ensure_future(asyncio.to_thread(func, *args, **kwargs))
|
||||
self.log.info("analytics run_with_cancel success")
|
||||
except Exception as e:
|
||||
self.log.warning(f"analytics run_with_cancel failed {e}")
|
||||
return None
|
||||
|
||||
async def send_startup_event(self):
|
||||
try:
|
||||
await self.run_with_timeout(self._send_startup_event)
|
||||
await self.run_with_cancel(self._send_startup_event)
|
||||
except Exception as e:
|
||||
self.log.warning(f"analytics send_startup_event failed {e}")
|
||||
self.init()
|
||||
|
||||
async def _send_startup_event(self):
|
||||
def _send_startup_event(self):
|
||||
event = self.gtag.create_new_event(name="startup")
|
||||
event.set_event_param(name="version", value=__version__)
|
||||
event_list = [event]
|
||||
@@ -49,12 +50,12 @@ class Analytics:
|
||||
|
||||
async def send_daily_event(self):
|
||||
try:
|
||||
await self.run_with_timeout(self._send_daily_event)
|
||||
await self.run_with_cancel(self._send_daily_event)
|
||||
except Exception as e:
|
||||
self.log.warning(f"analytics send_daily_event failed {e}")
|
||||
self.init()
|
||||
|
||||
async def _send_daily_event(self):
|
||||
def _send_daily_event(self):
|
||||
current_date = datetime.now().strftime("%Y-%m-%d")
|
||||
if self.current_date == current_date:
|
||||
return
|
||||
@@ -66,17 +67,18 @@ class Analytics:
|
||||
self.gtag.send(events=event_list)
|
||||
self.current_date = current_date
|
||||
|
||||
async def send_play_event(self, name, sec):
|
||||
async def send_play_event(self, name, sec, hardware):
|
||||
try:
|
||||
await self.run_with_timeout(self._send_play_event, name, sec)
|
||||
await self.run_with_cancel(self._send_play_event, name, sec, hardware)
|
||||
except Exception as e:
|
||||
self.log.warning(f"analytics send_play_event failed {e}")
|
||||
self.init()
|
||||
|
||||
async def _send_play_event(self, name, sec):
|
||||
def _send_play_event(self, name, sec, hardware):
|
||||
event = self.gtag.create_new_event(name="play")
|
||||
event.set_event_param(name="version", value=__version__)
|
||||
event.set_event_param(name="music", value=name)
|
||||
event.set_event_param(name="sec", value=sec)
|
||||
event.set_event_param(name="hardware", value=hardware)
|
||||
event_list = [event]
|
||||
self.gtag.send(events=event_list)
|
||||
|
||||
@@ -6,22 +6,27 @@ import os
|
||||
from dataclasses import asdict, dataclass, field
|
||||
from typing import get_type_hints
|
||||
|
||||
from xiaomusic.const import (
|
||||
PLAY_TYPE_ALL,
|
||||
PLAY_TYPE_ONE,
|
||||
PLAY_TYPE_RND,
|
||||
PLAY_TYPE_SEQ,
|
||||
PLAY_TYPE_SIN,
|
||||
)
|
||||
from xiaomusic.utils import validate_proxy
|
||||
|
||||
|
||||
# 默认口令
|
||||
def default_key_word_dict():
|
||||
return {
|
||||
"播放歌曲": "play",
|
||||
"播放本地歌曲": "playlocal",
|
||||
"关机": "stop",
|
||||
"下一首": "play_next",
|
||||
"上一首": "play_prev",
|
||||
"单曲循环": "set_play_type_one",
|
||||
"全部循环": "set_play_type_all",
|
||||
"随机播放": "set_random_play",
|
||||
"随机播放": "set_play_type_rnd",
|
||||
"单曲播放": "set_play_type_sin",
|
||||
"顺序播放": "set_play_type_seq",
|
||||
"分钟后关机": "stop_after_minute",
|
||||
"播放列表": "play_music_list",
|
||||
"刷新列表": "gen_music_list",
|
||||
"加入收藏": "add_to_favorites",
|
||||
"收藏歌曲": "add_to_favorites",
|
||||
@@ -47,12 +52,13 @@ KEY_WORD_ARG_BEFORE_DICT = {
|
||||
def default_key_match_order():
|
||||
return [
|
||||
"分钟后关机",
|
||||
"播放歌曲",
|
||||
"下一首",
|
||||
"上一首",
|
||||
"单曲循环",
|
||||
"全部循环",
|
||||
"随机播放",
|
||||
"单曲播放",
|
||||
"顺序播放",
|
||||
"关机",
|
||||
"刷新列表",
|
||||
"播放列表第",
|
||||
@@ -82,9 +88,8 @@ class Config:
|
||||
miio_tts_command: str = os.getenv("MIIO_TTS_CMD", "")
|
||||
cookie: str = ""
|
||||
verbose: bool = os.getenv("XIAOMUSIC_VERBOSE", "").lower() == "true"
|
||||
music_path: str = os.getenv(
|
||||
"XIAOMUSIC_MUSIC_PATH", "music"
|
||||
) # 只能是music目录下的子目录
|
||||
music_path: str = os.getenv("XIAOMUSIC_MUSIC_PATH", "music")
|
||||
temp_path: str = os.getenv("XIAOMUSIC_TEMP_PATH", "music/tmp")
|
||||
download_path: str = os.getenv("XIAOMUSIC_DOWNLOAD_PATH", "music/download")
|
||||
conf_path: str = os.getenv("XIAOMUSIC_CONF_PATH", "conf")
|
||||
cache_dir: str = os.getenv("XIAOMUSIC_CACHE_DIR", "cache")
|
||||
@@ -98,7 +103,7 @@ class Config:
|
||||
ffmpeg_location: str = os.getenv("XIAOMUSIC_FFMPEG_LOCATION", "./ffmpeg/bin")
|
||||
active_cmd: str = os.getenv(
|
||||
"XIAOMUSIC_ACTIVE_CMD",
|
||||
"play,set_random_play,playlocal,play_music_list,play_music_list_index,stop_after_minute,stop",
|
||||
"play,set_play_type_rnd,playlocal,play_music_list,play_music_list_index,stop_after_minute,stop",
|
||||
)
|
||||
exclude_dirs: str = os.getenv("XIAOMUSIC_EXCLUDE_DIRS", "@eaDir,tmp")
|
||||
music_path_depth: int = int(os.getenv("XIAOMUSIC_MUSIC_PATH_DEPTH", "10"))
|
||||
@@ -122,7 +127,7 @@ class Config:
|
||||
"XIAOMUSIC_USE_MUSIC_AUDIO_ID", "1582971365183456177"
|
||||
)
|
||||
use_music_id: str = os.getenv("XIAOMUSIC_USE_MUSIC_ID", "355454500")
|
||||
log_file: str = os.getenv("XIAOMUSIC_LOG_FILE", "/tmp/xiaomusic.txt")
|
||||
log_file: str = os.getenv("XIAOMUSIC_LOG_FILE", "xiaomusic.log.txt")
|
||||
# 模糊搜索匹配的最低相似度阈值
|
||||
fuzzy_match_cutoff: float = float(os.getenv("XIAOMUSIC_FUZZY_MATCH_CUTOFF", "0.6"))
|
||||
# 开启模糊搜索
|
||||
@@ -137,6 +142,9 @@ class Config:
|
||||
)
|
||||
keywords_play: str = os.getenv("XIAOMUSIC_KEYWORDS_PLAY", "播放歌曲,放歌曲")
|
||||
keywords_stop: str = os.getenv("XIAOMUSIC_KEYWORDS_STOP", "关机,暂停,停止,停止播放")
|
||||
keywords_playlist: str = os.getenv(
|
||||
"XIAOMUSIC_KEYWORDS_PLAYLIST", "播放列表,播放歌单"
|
||||
)
|
||||
user_key_word_dict: dict[str, str] = field(
|
||||
default_factory=default_user_key_word_dict
|
||||
)
|
||||
@@ -163,6 +171,21 @@ class Config:
|
||||
get_ask_by_mina: bool = (
|
||||
os.getenv("XIAOMUSIC_GET_ASK_BY_MINA", "false").lower() == "true"
|
||||
)
|
||||
play_type_one_tts_msg: str = os.getenv(
|
||||
"XIAOMUSIC_PLAY_TYPE_ONE_TTS_MSG", "已经设置为单曲循环"
|
||||
)
|
||||
play_type_all_tts_msg: str = os.getenv(
|
||||
"XIAOMUSIC_PLAY_TYPE_ALL_TTS_MSG", "已经设置为全部循环"
|
||||
)
|
||||
play_type_rnd_tts_msg: str = os.getenv(
|
||||
"XIAOMUSIC_PLAY_TYPE_RND_TTS_MSG", "已经设置为随机播放"
|
||||
)
|
||||
play_type_sin_tts_msg: str = os.getenv(
|
||||
"XIAOMUSIC_PLAY_TYPE_SIN_TTS_MSG", "已经设置为单曲播放"
|
||||
)
|
||||
play_type_seq_tts_msg: str = os.getenv(
|
||||
"XIAOMUSIC_PLAY_TYPE_SEQ_TTS_MSG", "已经设置为顺序播放"
|
||||
)
|
||||
|
||||
def append_keyword(self, keys, action):
|
||||
for key in keys.split(","):
|
||||
@@ -183,7 +206,11 @@ class Config:
|
||||
self.append_keyword(self.keywords_playlocal, "playlocal")
|
||||
self.append_keyword(self.keywords_play, "play")
|
||||
self.append_keyword(self.keywords_stop, "stop")
|
||||
self.append_keyword(self.keywords_playlist, "play_music_list")
|
||||
self.append_user_keyword()
|
||||
self.key_match_order = [
|
||||
x for x in self.key_match_order if x in self.key_word_dict
|
||||
]
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if self.proxy:
|
||||
@@ -278,3 +305,22 @@ class Config:
|
||||
os.makedirs(self.conf_path)
|
||||
cookies_path = os.path.join(self.conf_path, "yt-dlp-cookie.txt")
|
||||
return cookies_path
|
||||
|
||||
@property
|
||||
def temp_dir(self):
|
||||
if not os.path.exists(self.temp_path):
|
||||
os.makedirs(self.temp_path)
|
||||
return self.temp_path
|
||||
|
||||
def get_play_type_tts(self, play_type):
|
||||
if play_type == PLAY_TYPE_ONE:
|
||||
return self.play_type_one_tts_msg
|
||||
if play_type == PLAY_TYPE_ALL:
|
||||
return self.play_type_all_tts_msg
|
||||
if play_type == PLAY_TYPE_RND:
|
||||
return self.play_type_rnd_tts_msg
|
||||
if play_type == PLAY_TYPE_SIN:
|
||||
return self.play_type_sin_tts_msg
|
||||
if play_type == PLAY_TYPE_SEQ:
|
||||
return self.play_type_seq_tts_msg
|
||||
return ""
|
||||
|
||||
@@ -13,12 +13,8 @@ COOKIE_TEMPLATE = "deviceId={device_id}; serviceToken={service_token}; userId={u
|
||||
PLAY_TYPE_ONE = 0 # 单曲循环
|
||||
PLAY_TYPE_ALL = 1 # 全部循环
|
||||
PLAY_TYPE_RND = 2 # 随机播放
|
||||
|
||||
PLAY_TYPE_TTS = {
|
||||
PLAY_TYPE_ONE: "已经设置为单曲循环",
|
||||
PLAY_TYPE_ALL: "已经设置为全部循环",
|
||||
PLAY_TYPE_RND: "已经设置为随机播放",
|
||||
}
|
||||
PLAY_TYPE_SIN = 3 # 单曲播放
|
||||
PLAY_TYPE_SEQ = 4 # 顺序播放
|
||||
|
||||
# 需要采用 mina 获取对话记录的设备型号
|
||||
GET_ASK_BY_MINA = {
|
||||
|
||||
@@ -45,7 +45,7 @@ class Crontab:
|
||||
# 添加语音播放任务
|
||||
def add_job_tts(self, expression, xiaomusic, did, arg1, **kwargs):
|
||||
async def job():
|
||||
xiaomusic.do_tts(did, arg1)
|
||||
await xiaomusic.do_tts(did, arg1)
|
||||
|
||||
self.add_job(expression, job)
|
||||
|
||||
@@ -56,10 +56,25 @@ class Crontab:
|
||||
|
||||
self.add_job(expression, job)
|
||||
|
||||
# 设置音量任务
|
||||
def add_job_set_volume(self, expression, xiaomusic, did, arg1, **kwargs):
|
||||
async def job():
|
||||
await xiaomusic.set_volume(did, arg1)
|
||||
|
||||
self.add_job(expression, job)
|
||||
|
||||
# 设置播放类型任务
|
||||
def add_job_set_play_type(self, expression, xiaomusic, did, arg1, **kwargs):
|
||||
async def job():
|
||||
play_type = int(arg1)
|
||||
await xiaomusic.set_play_type(did, play_type, False)
|
||||
|
||||
self.add_job(expression, job)
|
||||
|
||||
def add_job_cron(self, xiaomusic, cron):
|
||||
expression = cron["expression"] # cron 计划格式
|
||||
name = cron["name"] # stop, play, play_music_list, tts
|
||||
did = cron["did"]
|
||||
did = cron.get("did", "")
|
||||
arg1 = cron.get("arg1", "")
|
||||
jobname = f"add_job_{name}"
|
||||
func = getattr(self, jobname, None)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import asyncio
|
||||
import hashlib
|
||||
import json
|
||||
import mimetypes
|
||||
import os
|
||||
import re
|
||||
import secrets
|
||||
@@ -26,7 +25,7 @@ from fastapi import (
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
|
||||
from fastapi.openapi.utils import get_openapi
|
||||
from fastapi.responses import RedirectResponse, StreamingResponse
|
||||
from fastapi.responses import RedirectResponse
|
||||
from fastapi.security import HTTPBasic, HTTPBasicCredentials
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from pydantic import BaseModel
|
||||
@@ -304,6 +303,23 @@ async def musicinfos(
|
||||
return ret
|
||||
|
||||
|
||||
class MusicInfoObj(BaseModel):
|
||||
musicname: str
|
||||
title: str = ""
|
||||
artist: str = ""
|
||||
album: str = ""
|
||||
year: str = ""
|
||||
genre: str = ""
|
||||
lyrics: str = ""
|
||||
picture: str = "" # base64
|
||||
|
||||
|
||||
@app.post("/setmusictag")
|
||||
async def setmusictag(info: MusicInfoObj, Verifcation=Depends(verification)):
|
||||
ret = xiaomusic.set_music_tag(info.musicname, info)
|
||||
return {"ret": ret}
|
||||
|
||||
|
||||
@app.get("/curplaylist")
|
||||
async def curplaylist(did: str = "", Verifcation=Depends(verification)):
|
||||
if not xiaomusic.did_exist(did):
|
||||
@@ -316,9 +332,9 @@ class MusicItem(BaseModel):
|
||||
|
||||
|
||||
@app.post("/delmusic")
|
||||
def delmusic(data: MusicItem, Verifcation=Depends(verification)):
|
||||
async def delmusic(data: MusicItem, Verifcation=Depends(verification)):
|
||||
log.info(data)
|
||||
xiaomusic.del_music(data.name)
|
||||
await xiaomusic.del_music(data.name)
|
||||
return "success"
|
||||
|
||||
|
||||
@@ -326,6 +342,44 @@ class UrlInfo(BaseModel):
|
||||
url: str
|
||||
|
||||
|
||||
class DidPlayMusic(BaseModel):
|
||||
did: str
|
||||
musicname: str = ""
|
||||
searchkey: str = ""
|
||||
|
||||
|
||||
@app.post("/playmusic")
|
||||
async def playmusic(data: DidPlayMusic, Verifcation=Depends(verification)):
|
||||
did = data.did
|
||||
musicname = data.musicname
|
||||
searchkey = data.searchkey
|
||||
if not xiaomusic.did_exist(did):
|
||||
return {"ret": "Did not exist"}
|
||||
|
||||
log.info(f"playmusic {did} musicname:{musicname} searchkey:{searchkey}")
|
||||
await xiaomusic.do_play(did, musicname, searchkey)
|
||||
return {"ret": "OK"}
|
||||
|
||||
|
||||
class DidPlayMusicList(BaseModel):
|
||||
did: str
|
||||
listname: str = ""
|
||||
musicname: str = ""
|
||||
|
||||
|
||||
@app.post("/playmusiclist")
|
||||
async def playmusiclist(data: DidPlayMusicList, Verifcation=Depends(verification)):
|
||||
did = data.did
|
||||
listname = data.listname
|
||||
musicname = data.musicname
|
||||
if not xiaomusic.did_exist(did):
|
||||
return {"ret": "Did not exist"}
|
||||
|
||||
log.info(f"playmusiclist {did} listname:{listname} musicname:{musicname}")
|
||||
await xiaomusic.do_play_music_list(did, listname, musicname)
|
||||
return {"ret": "OK"}
|
||||
|
||||
|
||||
@app.post("/downloadjson")
|
||||
async def downloadjson(data: UrlInfo, Verifcation=Depends(verification)):
|
||||
log.info(data)
|
||||
@@ -469,6 +523,51 @@ async def upload_yt_dlp_cookie(file: UploadFile = File(...)):
|
||||
}
|
||||
|
||||
|
||||
class PlayListObj(BaseModel):
|
||||
name: str = "" # 歌单名
|
||||
|
||||
|
||||
# 新增歌单
|
||||
@app.post("/playlistadd")
|
||||
async def playlistadd(data: PlayListObj, Verifcation=Depends(verification)):
|
||||
ret = xiaomusic.play_list_add(data.name)
|
||||
if ret:
|
||||
return {"ret": "OK"}
|
||||
return {"ret": "Add failed, may be already exist."}
|
||||
|
||||
|
||||
# 移除歌单
|
||||
@app.post("/playlistdel")
|
||||
async def playlistdel(data: PlayListObj, Verifcation=Depends(verification)):
|
||||
ret = xiaomusic.play_list_del(data.name)
|
||||
if ret:
|
||||
return {"ret": "OK"}
|
||||
return {"ret": "Del failed, may be not exist."}
|
||||
|
||||
|
||||
class PlayListMusicObj(BaseModel):
|
||||
name: str = "" # 歌单名
|
||||
music_list: list[str] # 歌曲名列表
|
||||
|
||||
|
||||
# 歌单新增歌曲
|
||||
@app.post("/playlistaddmusic")
|
||||
async def playlistaddmusic(data: PlayListMusicObj, Verifcation=Depends(verification)):
|
||||
ret = xiaomusic.play_list_add_music(data.name, data.music_list)
|
||||
if ret:
|
||||
return {"ret": "OK"}
|
||||
return {"ret": "Add failed, may be playlist not exist."}
|
||||
|
||||
|
||||
# 歌单移除歌曲
|
||||
@app.post("/playlistdelmusic")
|
||||
async def playlistdelmusic(data: PlayListMusicObj, Verifcation=Depends(verification)):
|
||||
ret = xiaomusic.play_list_del_music(data.name, data.music_list)
|
||||
if ret:
|
||||
return {"ret": "OK"}
|
||||
return {"ret": "Del failed, may be playlist not exist."}
|
||||
|
||||
|
||||
async def file_iterator(file_path, start, end):
|
||||
async with aiofiles.open(file_path, mode="rb") as file:
|
||||
await file.seek(start)
|
||||
@@ -538,7 +637,7 @@ async def music_file(request: Request, file_path: str, key: str = "", code: str
|
||||
if not os.path.exists(absolute_file_path):
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
# 移除MP3 ID3 v2标签和填充,减少播放前延迟
|
||||
# 移除MP3 ID3 v2标签和填充
|
||||
if config.remove_id3tag and is_mp3(file_path):
|
||||
log.info(f"remove_id3tag:{config.remove_id3tag}, is_mp3:True ")
|
||||
temp_mp3_file = remove_id3_tags(absolute_file_path, config)
|
||||
@@ -560,34 +659,7 @@ async def music_file(request: Request, file_path: str, key: str = "", code: str
|
||||
else:
|
||||
log.warning(f"Failed to convert file to MP3 format: {absolute_file_path}")
|
||||
|
||||
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,
|
||||
)
|
||||
return FileResponse(absolute_file_path)
|
||||
|
||||
|
||||
@app.options("/music/{file_path:path}")
|
||||
@@ -610,10 +682,7 @@ async def get_picture(request: Request, file_path: str, key: str = "", code: str
|
||||
if not os.path.exists(absolute_file_path):
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
mime_type, _ = mimetypes.guess_type(absolute_file_path)
|
||||
if mime_type is None:
|
||||
mime_type = "image/jpeg"
|
||||
return FileResponse(absolute_file_path, media_type=mime_type)
|
||||
return FileResponse(absolute_file_path)
|
||||
|
||||
|
||||
@app.get("/docs", include_in_schema=False)
|
||||
|
||||
@@ -4,17 +4,21 @@ $(function(){
|
||||
append_op_button_name("加入收藏");
|
||||
append_op_button_name("取消收藏");
|
||||
|
||||
const PLAY_TYPE_ONE = 0; // 单曲循环
|
||||
const PLAY_TYPE_ALL = 1; // 全部循环
|
||||
const PLAY_TYPE_RND = 2; // 随机播放
|
||||
append_op_button("play_type_all", "全部循环", "全部循环");
|
||||
append_op_button("play_type_one", "单曲循环", "单曲循环");
|
||||
append_op_button("play_type_rnd", "随机播放", "随机播放");
|
||||
|
||||
append_op_button_name("上一首");
|
||||
append_op_button_name("关机");
|
||||
append_op_button_name("下一首");
|
||||
|
||||
const PLAY_TYPE_ONE = 0; // 单曲循环
|
||||
const PLAY_TYPE_ALL = 1; // 全部循环
|
||||
const PLAY_TYPE_RND = 2; // 随机播放
|
||||
const PLAY_TYPE_SIN = 3; // 单曲播放
|
||||
const PLAY_TYPE_SEQ = 4; // 顺序播放
|
||||
append_op_button("play_type_all", "全部循环", "全部循环");
|
||||
append_op_button("play_type_one", "单曲循环", "单曲循环");
|
||||
append_op_button("play_type_rnd", "随机播放", "随机播放");
|
||||
append_op_button("play_type_sin", "单曲播放", "单曲播放");
|
||||
append_op_button("play_type_seq", "顺序播放", "顺序播放");
|
||||
|
||||
append_op_button_name("刷新列表");
|
||||
|
||||
$container.append($("<hr>"));
|
||||
@@ -25,7 +29,7 @@ $(function(){
|
||||
|
||||
var offset = 0;
|
||||
var duration = 0;
|
||||
|
||||
let no_warning = localStorage.getItem('no-warning');
|
||||
// 拉取现有配置
|
||||
$.get("/getsetting", function(data, status) {
|
||||
console.log(data, status);
|
||||
@@ -71,6 +75,12 @@ $(function(){
|
||||
} else if (cur_device.play_type == PLAY_TYPE_RND) {
|
||||
$("#play_type_rnd").css('background-color', '#b1a8f3');
|
||||
$("#play_type_rnd").text('✔️ 随机播放');
|
||||
} else if (cur_device.play_type == PLAY_TYPE_SIN) {
|
||||
$("#play_type_sin").css('background-color', '#b1a8f3');
|
||||
$("#play_type_sin").text('✔️ 单曲播放');
|
||||
} else if (cur_device.play_type == PLAY_TYPE_SEQ) {
|
||||
$("#play_type_seq").css('background-color', '#b1a8f3');
|
||||
$("#play_type_seq").text('✔️ 顺序播放');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,7 +132,8 @@ $(function(){
|
||||
$.get("/musiclist", function(data, status) {
|
||||
console.log(data, status);
|
||||
$.each(data, function(key, value) {
|
||||
$('#music_list').append($('<option></option>').val(key).text(key));
|
||||
let cnt = value.length;
|
||||
$('#music_list').append($('<option></option>').val(key).text(`${key} (${cnt})`));
|
||||
});
|
||||
|
||||
$('#music_list').change(function() {
|
||||
@@ -181,11 +192,34 @@ $(function(){
|
||||
});
|
||||
}
|
||||
|
||||
function do_play_music_list(listname, musicname) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/playmusiclist",
|
||||
contentType: "application/json; charset=utf-8",
|
||||
data: JSON.stringify({did: did, listname: listname, musicname: musicname}),
|
||||
success: () => {
|
||||
console.log("do_play_music_list succ", listname, musicname);
|
||||
},
|
||||
error: () => {
|
||||
console.log("do_play_music_list failed", listname, musicname);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$("#play_music_list").on("click", () => {
|
||||
var music_list = $("#music_list").val();
|
||||
var music_name = $("#music_name").val();
|
||||
let cmd = "播放列表" + music_list + "|" + music_name;
|
||||
sendcmd(cmd);
|
||||
if (no_warning) {
|
||||
do_play_music_list(music_list, music_name);
|
||||
return;
|
||||
}
|
||||
$.get(`/musicinfo?name=${music_name}`, function(data, status) {
|
||||
console.log(data);
|
||||
if (data.ret == "OK") {
|
||||
validHost(data.url) && do_play_music_list(music_list, music_name);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#web_play").on("click", () => {
|
||||
@@ -193,7 +227,7 @@ $(function(){
|
||||
$.get(`/musicinfo?name=${music_name}`, function(data, status) {
|
||||
console.log(data);
|
||||
if (data.ret == "OK") {
|
||||
$('audio').attr('src',data.url);
|
||||
validHost(data.url) && $('audio').attr('src',data.url);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -248,11 +282,32 @@ $(function(){
|
||||
$container.append($button);
|
||||
}
|
||||
|
||||
function do_play_music(musicname, searchkey) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/playmusic",
|
||||
contentType: "application/json; charset=utf-8",
|
||||
data: JSON.stringify({did: did, musicname: musicname, searchkey: searchkey}),
|
||||
success: () => {
|
||||
console.log("do_play_music succ", musicname, searchkey);
|
||||
},
|
||||
error: () => {
|
||||
console.log("do_play_music failed", musicname, searchkey);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$("#play").on("click", () => {
|
||||
var search_key = $("#music-name").val();
|
||||
if (search_key == null) {
|
||||
search_key = "";
|
||||
}
|
||||
var filename = $("#music-filename").val();
|
||||
let cmd = "播放歌曲" + search_key + "|" + filename;
|
||||
sendcmd(cmd);
|
||||
if (filename == null || filename == "") {
|
||||
filename = search_key;
|
||||
}
|
||||
do_play_music(filename, search_key);
|
||||
});
|
||||
|
||||
$("#volume").on('change', function () {
|
||||
@@ -291,7 +346,7 @@ $(function(){
|
||||
if (cmd == "刷新列表") {
|
||||
check_status_refresh_music_list(3); // 最多重试3次
|
||||
}
|
||||
if (["全部循环", "单曲循环", "随机播放"].includes(cmd)) {
|
||||
if (["全部循环", "单曲循环", "随机播放", "单曲播放", "顺序播放"].includes(cmd)) {
|
||||
location.reload();
|
||||
}
|
||||
},
|
||||
@@ -358,7 +413,7 @@ $(function(){
|
||||
.catch(error => {
|
||||
console.error('Error fetching data:', error);
|
||||
});
|
||||
}, 300));
|
||||
}, 500));
|
||||
|
||||
// 动态显示保存文件名输入框
|
||||
const musicNameSelect = document.getElementById('music-name');
|
||||
@@ -418,5 +473,44 @@ $(function(){
|
||||
var minutes = Math.floor(seconds / 60);
|
||||
var remainingSeconds =Math.floor(seconds % 60);
|
||||
return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
|
||||
}
|
||||
}
|
||||
|
||||
$("audio").on("error", (e) => {
|
||||
console.log('网页播放出现错误: ', 'color: #007acc;', e.currentTarget.error.code,e.currentTarget.error.message);
|
||||
alert(e.currentTarget.error.code==4 ? "无法打开媒体文件,XIAOMUSIC_HOSTNAME或端口地址错误,请重新设置" : "在线播放失败,请截图反馈: "+e.currentTarget.error.message);
|
||||
});
|
||||
function validHost(url) {
|
||||
//如果 localStorage 中有 no-warning 则直接返回true
|
||||
if (no_warning) {
|
||||
return true;
|
||||
}
|
||||
const local = location.host;
|
||||
const host = new URL(url).host;
|
||||
// 如果当前页面的Host与设置中的XIAOMUSIC_HOSTNAME、PORT一致, 不再提醒
|
||||
if (local === host) {
|
||||
|
||||
localStorage.setItem('no-warning', 'true');
|
||||
// 设置全局变量
|
||||
no_warning = true;
|
||||
return true;
|
||||
}
|
||||
// 如果当前页面的Host与设置中的XIAOMUSIC_HOSTNAME、PORT不一致
|
||||
const validHost = document.getElementById('valid-host');
|
||||
let validFlag = false;
|
||||
$('#local-host').text(local);
|
||||
$('#setting-host').text(host);
|
||||
validHost.showModal();
|
||||
//监听validHost的close事件
|
||||
function _handleClose() {
|
||||
console.log('%c提醒HOST不一致弹窗,用户已选择: ', 'color: #007acc;', validHost.returnValue);
|
||||
if (validHost.returnValue == "no-warning") {
|
||||
localStorage.setItem('no-warning', 'true');
|
||||
no_warning = true;
|
||||
validFlag = true;
|
||||
}
|
||||
validHost.removeEventListener('close', _handleClose)
|
||||
}
|
||||
validHost.addEventListener('close', _handleClose)
|
||||
return validFlag;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Debug For XiaoMusic</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1729000721">
|
||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1733199308">
|
||||
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
||||
<script src="./jquery-3.7.1.min.js?version=1729000721"></script>
|
||||
<script src="./jquery-3.7.1.min.js?version=1733199308"></script>
|
||||
|
||||
<!-- Google tag (gtag.js) -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>歌曲下载工具</title>
|
||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1729000721">
|
||||
<script src="./jquery-3.7.1.min.js?version=1729000721"></script>
|
||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1733199308">
|
||||
<script src="./jquery-3.7.1.min.js?version=1733199308"></script>
|
||||
|
||||
<!-- Google tag (gtag.js) -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>小爱音箱操控面板</title>
|
||||
<script src="./jquery-3.7.1.min.js?version=1729000721"></script>
|
||||
<script src="./app.js?version=1729000721"></script>
|
||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1729000721">
|
||||
<script src="./jquery-3.7.1.min.js?version=1733199308"></script>
|
||||
<script src="./app.js?version=1733199308"></script>
|
||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1733199308">
|
||||
|
||||
<!-- Google tag (gtag.js) -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||
@@ -94,5 +94,17 @@ var vConsole = new window.VConsole();
|
||||
<footer>
|
||||
<p>Powered by <a href="https://github.com/hanxi/xiaomusic" target="_blank">xiaomusic</a></p>
|
||||
</footer>
|
||||
<dialog id="valid-host">
|
||||
<form method="dialog">
|
||||
<p>当前页面的HOST与设置中的HOST不一致,请检查是否设置错误</p>
|
||||
<p>当前HOST: <span id="local-host"></span></p>
|
||||
<p>设置中的HOST: <span id="setting-host"></span></p>
|
||||
<div class="btn-list">
|
||||
<a href="./setting.html" target="_blank">立即修改</a>
|
||||
<button value="no-warning" type="submit">继续并不再显示</button>
|
||||
<button value="cancle" type="submit">取消</button>
|
||||
</div>
|
||||
</form>
|
||||
</dialog>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>M3U to JSON Converter</title>
|
||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1729000721">
|
||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1733199308">
|
||||
|
||||
<!-- Google tag (gtag.js) -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>小爱音箱操控面板</title>
|
||||
<script src="./jquery-3.7.1.min.js?version=1729000721"></script>
|
||||
<script src="./setting.js?version=1729000721"></script>
|
||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1729000721">
|
||||
<script src="./jquery-3.7.1.min.js?version=1733199308"></script>
|
||||
<script src="./setting.js?version=1733199308"></script>
|
||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1733199308">
|
||||
|
||||
<!-- Google tag (gtag.js) -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||
@@ -43,13 +43,13 @@ var vConsole = new window.VConsole();
|
||||
<div id="setting">
|
||||
<div class="rows">
|
||||
<label for="account">*小米账号:</label>
|
||||
<input id="account" type="text" placeholder="填写小米登录账号"></input>
|
||||
<input id="account" type="text" placeholder="填写小米登录账号" />
|
||||
|
||||
<label for="password">*小米密码:</label>
|
||||
<input id="password" type="password" placeholder="填写小米登录密码"></input>
|
||||
<input id="password" type="password" placeholder="填写小米登录密码" />
|
||||
|
||||
<label for="hostname">*XIAOMUSIC_HOSTNAME(IP或域名):</label>
|
||||
<input id="hostname" type="text"></input>
|
||||
<input id="hostname" type="text" />
|
||||
</div>
|
||||
<hr>
|
||||
<div class="rows">
|
||||
@@ -59,36 +59,44 @@ var vConsole = new window.VConsole();
|
||||
<option value="false">false</option>
|
||||
</select>
|
||||
|
||||
<label for="group_list">设备分组配置:</label>
|
||||
<input id="group_list" type="text" placeholder="did1:组名1,did2:组名1,did3:组名2"></input>
|
||||
<label for="port">监听端口(修改后需要重启):</label>
|
||||
<input id="port" type="number" value="8090" />
|
||||
|
||||
<label for="public_port">外网访问端口(0表示跟监听端口一致):</label>
|
||||
<input id="public_port" type="number" value="0" />
|
||||
|
||||
<label for="group_list">设备分组配置:<a href="https://github.com/hanxi/xiaomusic/issues/65#issuecomment-2215736529" target="_blank">文档</a></label>
|
||||
<input id="group_list" type="text" placeholder="did1:组名1,did2:组名1,did3:组名2" />
|
||||
|
||||
<label for="music_path">音乐目录:</label>
|
||||
<input id="music_path" type="text" value="music"></input>
|
||||
<input id="music_path" type="text" value="music" />
|
||||
|
||||
<label for="download_path">音乐下载目录(必须是music的子目录):</label>
|
||||
<input id="download_path" type="text" value='music/download'></input>
|
||||
<input id="download_path" type="text" value='music/download' />
|
||||
|
||||
<label for="conf_path">配置文件目录:</label>
|
||||
<input id="conf_path" type="text"></input>
|
||||
|
||||
<input id="conf_path" type="text" />
|
||||
|
||||
<label for="cache_dir">缓存文件目录:</label>
|
||||
<input id="cache_dir" type="text"></input>
|
||||
<input id="cache_dir" type="text" />
|
||||
|
||||
<label for="temp_path">临时文件目录:</label>
|
||||
<input id="temp_path" type="text" value="music/tmp" />
|
||||
|
||||
<label for="ffmpeg_location">ffmpeg路径:</label>
|
||||
<input id="ffmpeg_location" type="text" value="./ffmpeg/bin"></input>
|
||||
<input id="ffmpeg_location" type="text" value="./ffmpeg/bin" />
|
||||
|
||||
<label for="log_file">日志路径:</label>
|
||||
<input id="log_file" type="text" value="/tmp/xiaomusic.txt"></input>
|
||||
<input id="log_file" type="text" value="xiaomusic.log.txt" />
|
||||
|
||||
<label for="active_cmd">允许唤醒的命令:</label>
|
||||
<input id="active_cmd" type="text" value="play,random_play,playlocal,play_music_list,stop"></input>
|
||||
<input id="active_cmd" type="text" value="play,random_play,playlocal,play_music_list,stop" />
|
||||
|
||||
<label for="exclude_dirs">忽略目录(逗号分割):</label>
|
||||
<input id="exclude_dirs" type="text" value="@eaDir"></input>
|
||||
<input id="exclude_dirs" type="text" value="@eaDir,tmp" />
|
||||
|
||||
<label for="music_path_depth">目录深度:</label>
|
||||
<input id="music_path_depth" type="number" value="10"></input>
|
||||
<input id="music_path_depth" type="number" value="10" />
|
||||
|
||||
<label for="search_prefix">XIAOMUSIC_SEARCH(歌曲下载方式):</label>
|
||||
<select id="search_prefix">
|
||||
@@ -97,7 +105,7 @@ var vConsole = new window.VConsole();
|
||||
</select>
|
||||
|
||||
<label for="proxy">XIAOMUSIC_PROXY(ytsearch需要):</label>
|
||||
<input id="proxy" type="text" placeholder="http://192.168.2.5:8080"></input>
|
||||
<input id="proxy" type="text" placeholder="http://192.168.2.5:8080" />
|
||||
|
||||
<label for="remove_id3tag">去除MP3 ID3v2和填充:</label>
|
||||
<select id="remove_id3tag">
|
||||
@@ -111,8 +119,8 @@ var vConsole = new window.VConsole();
|
||||
<option value="false" selected>false</option>
|
||||
</select>
|
||||
|
||||
<label for="miio_tts_command">MiIO sst 指令:</label>
|
||||
<input id="miio_tts_command" type="text" placeholder="如:5 或者 5-3"></input>
|
||||
<label for="miio_tts_command">MiIO tts 指令(解决部分型号没有提示音的问题):</label>
|
||||
<input id="miio_tts_command" type="text" placeholder="如:5 或者 5-3" />
|
||||
|
||||
<label for="disable_httpauth">关闭控制台密码验证:</label>
|
||||
<select id="disable_httpauth">
|
||||
@@ -120,9 +128,9 @@ var vConsole = new window.VConsole();
|
||||
<option value="false">false</option>
|
||||
</select>
|
||||
<label for="httpauth_username">控制台账户:</label>
|
||||
<input id="httpauth_username" type="text" value=""></input>
|
||||
<input id="httpauth_username" type="text" value="" />
|
||||
<label for="httpauth_password">控制台密码:</label>
|
||||
<input id="httpauth_password" type="password" value=""></input>
|
||||
<input id="httpauth_password" type="password" value="" />
|
||||
|
||||
<label for="disable_download">关闭下载功能:</label>
|
||||
<select id="disable_download">
|
||||
@@ -131,12 +139,12 @@ var vConsole = new window.VConsole();
|
||||
</select>
|
||||
|
||||
<label for="use_music_audio_id">触屏版显示歌曲ID:</label>
|
||||
<input id="use_music_audio_id" type="text" value="1582971365183456177"></input>
|
||||
<input id="use_music_audio_id" type="text" value="1582971365183456177" />
|
||||
<label for="use_music_id">触屏版显示歌曲分段ID:</label>
|
||||
<input id="use_music_id" type="text" value="355454500"></input>
|
||||
<input id="use_music_id" type="text" value="355454500" />
|
||||
|
||||
<label for="fuzzy_match_cutoff">模糊匹配阈值(0.1~0.9):</label>
|
||||
<input id="fuzzy_match_cutoff" type="number" value="0.6"></input>
|
||||
<input id="fuzzy_match_cutoff" type="number" value="0.6" />
|
||||
|
||||
<label for="enable_fuzzy_match">开启模糊搜索:</label>
|
||||
<select id="enable_fuzzy_match">
|
||||
@@ -156,26 +164,33 @@ var vConsole = new window.VConsole();
|
||||
<option value="false" selected>false</option>
|
||||
</select>
|
||||
|
||||
<label for="port">监听端口(修改后需要重启):</label>
|
||||
<input id="port" type="number" value="8090"></input>
|
||||
|
||||
<label for="public_port">外网访问端口(0表示跟监听端口一致):</label>
|
||||
<input id="public_port" type="number" value="0"></input>
|
||||
|
||||
<label for="pull_ask_sec">获取对话记录间隔(秒):</label>
|
||||
<input id="pull_ask_sec" type="number" value="1"></input>
|
||||
<input id="pull_ask_sec" type="number" value="1" />
|
||||
|
||||
<label for="delay_sec">下一首歌延迟播放秒数:</label>
|
||||
<input id="delay_sec" type="number" value="3"></input>
|
||||
<input id="delay_sec" type="number" value="3" />
|
||||
|
||||
<label for="stop_tts_msg">停止提示音:</label>
|
||||
<input id="stop_tts_msg" type="text" value="收到,再见"></input>
|
||||
<input id="stop_tts_msg" type="text" value="收到,再见" />
|
||||
<label for="play_type_one_tts_msg">单曲循环提示音:</label>
|
||||
<input id="play_type_one_tts_msg" type="text" value="已经设置为单曲循环" />
|
||||
<label for="play_type_all_tts_msg">全部循环提示音:</label>
|
||||
<input id="play_type_all_tts_msg" type="text" value="已经设置为全部循环" />
|
||||
<label for="play_type_rnd_tts_msg">随机播放提示音:</label>
|
||||
<input id="play_type_rnd_tts_msg" type="text" value="已经设置为随机播放" />
|
||||
<label for="play_type_sin_tts_msg">单曲播放提示音:</label>
|
||||
<input id="play_type_sin_tts_msg" type="text" value="已经设置为单曲播放" />
|
||||
<label for="play_type_seq_tts_msg">顺序播放提示音:</label>
|
||||
<input id="play_type_seq_tts_msg" type="text" value="已经设置为顺序播放" />
|
||||
|
||||
<label for="keywords_playlocal">播放本地歌曲口令:</label>
|
||||
<input id="keywords_playlocal" type="text" value="播放本地歌曲,本地播放歌曲"></input>
|
||||
<input id="keywords_playlocal" type="text" value="播放本地歌曲,本地播放歌曲" />
|
||||
<label for="keywords_play">播放歌曲口令:</label>
|
||||
<input id="keywords_play" type="text" value="播放歌曲,放歌曲"></input>
|
||||
<input id="keywords_play" type="text" value="播放歌曲,放歌曲" />
|
||||
<label for="keywords_playlist">播放列表口令:</label>
|
||||
<input id="keywords_playlist" type="text" value="播放列表,播放歌单" />
|
||||
<label for="keywords_stop">停止口令:</label>
|
||||
<input id="keywords_stop" type="text" value="关机,暂停,停止,停止播放"></input>
|
||||
<input id="keywords_stop" type="text" value="关机,暂停,停止,停止播放" />
|
||||
|
||||
<label for="enable_yt_dlp_cookies">启用yt-dlp-cookies(需要先上传yt-dlp-cookies.txt文件):</label>
|
||||
<select id="enable_yt_dlp_cookies">
|
||||
@@ -190,7 +205,7 @@ var vConsole = new window.VConsole();
|
||||
</select>
|
||||
|
||||
<label for="music_list_url">歌单地址:</label>
|
||||
<input id="music_list_url" type="text" value="https://gist.githubusercontent.com/hanxi/dda82d964a28f8110f8fba81c3ff8314/raw/example.json"></input>
|
||||
<input id="music_list_url" type="text" value="https://gist.githubusercontent.com/hanxi/dda82d964a28f8110f8fba81c3ff8314/raw/example.json" />
|
||||
|
||||
<label for="music_list_json">歌单内容:<a href="https://github.com/hanxi/xiaomusic/issues/78" target="_blank">格式文档</a></label>
|
||||
<textarea id="music_list_json" type="text"></textarea>
|
||||
|
||||
@@ -16,13 +16,19 @@ $(function(){
|
||||
});
|
||||
};
|
||||
|
||||
function updateCheckbox(selector, mi_did, device_list) {
|
||||
function updateCheckbox(selector, mi_did, device_list,accountPassValid) {
|
||||
// 清除现有的内容
|
||||
$(selector).empty();
|
||||
|
||||
// 将 mi_did 字符串通过逗号分割转换为数组,以便于判断默认选中项
|
||||
var selected_dids = mi_did.split(',');
|
||||
|
||||
//如果device_list为空,则可能是未设置小米账号密码或者已设置密码,但是没有过小米验证,此处需要提示用户
|
||||
if (device_list.length == 0) {
|
||||
const loginTips = accountPassValid ? `<div class="login-tips">未发现可用的小爱设备,请检查账号密码是否输错,并关闭加速代理或在<a href="https://www.mi.com">小米官网</a>登陆过人脸或滑块验证。如仍未解决。请根据<a href="https://github.com/hanxi/xiaomusic/issues/99">FAQ</a>的内容解决问题。</div>` : `<div class="login-tips">未发现可用的小爱设备,请先在下面的输入框中设置小米的<b>账号、密码</b></div>`;
|
||||
$(selector).append(loginTips);
|
||||
return;
|
||||
}
|
||||
$.each(device_list, function(index, device) {
|
||||
var did = device.miotDID;
|
||||
var hardware = device.hardware;
|
||||
@@ -64,7 +70,8 @@ $(function(){
|
||||
// 拉取现有配置
|
||||
$.get("/getsetting?need_device_list=true", function(data, status) {
|
||||
console.log(data, status);
|
||||
updateCheckbox("#mi_did", data.mi_did, data.device_list);
|
||||
const accountPassValid = data.account && data.password;
|
||||
updateCheckbox("#mi_did", data.mi_did, data.device_list, accountPassValid);
|
||||
|
||||
// 初始化显示
|
||||
for (const key in data) {
|
||||
|
||||
@@ -21,7 +21,6 @@ button:active, .button:active {
|
||||
}
|
||||
label {
|
||||
margin-left: 10px;
|
||||
width: 300px;
|
||||
}
|
||||
input,select {
|
||||
margin-left: 5%;
|
||||
@@ -100,3 +99,67 @@ footer {
|
||||
animation: blink 1s infinite;
|
||||
}
|
||||
|
||||
.login-tips {
|
||||
color: red;
|
||||
font-size: 12px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.login-tips a {
|
||||
color: rgb(9, 105, 218);
|
||||
text-decoration: underline;
|
||||
}
|
||||
#valid-host {
|
||||
padding: 20px;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
#valid-host::backdrop {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
|
||||
#valid-host form input {
|
||||
width: fit-content;
|
||||
margin: 0;
|
||||
height: fit-content;
|
||||
}
|
||||
#valid-host p {
|
||||
word-break: break-all;
|
||||
}
|
||||
#valid-host p span {
|
||||
color: red;
|
||||
}
|
||||
#valid-host a, #valid-host a:visited {
|
||||
color: rgb(9, 105, 218);;
|
||||
text-decoration: underline;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
#valid-host a:hover {
|
||||
color: rgb(9, 95, 198);
|
||||
}
|
||||
#valid-host .btn-list {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#valid-host .btn-list button {
|
||||
width: fit-content;
|
||||
min-width: 60px;
|
||||
height: 40px;
|
||||
border: none;
|
||||
color: white;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
border-radius: 10px;
|
||||
background-color: #008CBA;
|
||||
}
|
||||
#valid-host .btn-list button:hover {
|
||||
font-weight:bold;
|
||||
background-color: #007CBA;
|
||||
}
|
||||
BIN
xiaomusic/static/icons/android/android-launchericon-144-144.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
xiaomusic/static/icons/android/android-launchericon-192-192.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
xiaomusic/static/icons/android/android-launchericon-48-48.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
xiaomusic/static/icons/android/android-launchericon-512-512.png
Normal file
|
After Width: | Height: | Size: 281 KiB |
BIN
xiaomusic/static/icons/android/android-launchericon-72-72.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
xiaomusic/static/icons/android/android-launchericon-96-96.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
xiaomusic/static/icons/ios/100.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
xiaomusic/static/icons/ios/1024.png
Normal file
|
After Width: | Height: | Size: 990 KiB |
BIN
xiaomusic/static/icons/ios/114.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
xiaomusic/static/icons/ios/120.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
xiaomusic/static/icons/ios/128.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
xiaomusic/static/icons/ios/144.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
xiaomusic/static/icons/ios/152.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
xiaomusic/static/icons/ios/16.png
Normal file
|
After Width: | Height: | Size: 657 B |
BIN
xiaomusic/static/icons/ios/167.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
xiaomusic/static/icons/ios/180.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
xiaomusic/static/icons/ios/192.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
xiaomusic/static/icons/ios/20.png
Normal file
|
After Width: | Height: | Size: 891 B |
BIN
xiaomusic/static/icons/ios/256.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
xiaomusic/static/icons/ios/29.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
xiaomusic/static/icons/ios/32.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
xiaomusic/static/icons/ios/40.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
xiaomusic/static/icons/ios/50.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
xiaomusic/static/icons/ios/512.png
Normal file
|
After Width: | Height: | Size: 281 KiB |
BIN
xiaomusic/static/icons/ios/57.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
xiaomusic/static/icons/ios/58.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
xiaomusic/static/icons/ios/60.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
xiaomusic/static/icons/ios/64.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
xiaomusic/static/icons/ios/72.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
xiaomusic/static/icons/ios/76.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
xiaomusic/static/icons/ios/80.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
xiaomusic/static/icons/ios/87.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
xiaomusic/static/icons/windows11/LargeTile.scale-100.png
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
xiaomusic/static/icons/windows11/LargeTile.scale-125.png
Normal file
|
After Width: | Height: | Size: 164 KiB |
BIN
xiaomusic/static/icons/windows11/LargeTile.scale-150.png
Normal file
|
After Width: | Height: | Size: 233 KiB |
BIN
xiaomusic/static/icons/windows11/LargeTile.scale-200.png
Normal file
|
After Width: | Height: | Size: 404 KiB |
BIN
xiaomusic/static/icons/windows11/LargeTile.scale-400.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
xiaomusic/static/icons/windows11/SmallTile.scale-100.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
xiaomusic/static/icons/windows11/SmallTile.scale-125.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
xiaomusic/static/icons/windows11/SmallTile.scale-150.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
xiaomusic/static/icons/windows11/SmallTile.scale-200.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
xiaomusic/static/icons/windows11/SmallTile.scale-400.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
xiaomusic/static/icons/windows11/SplashScreen.scale-100.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
xiaomusic/static/icons/windows11/SplashScreen.scale-125.png
Normal file
|
After Width: | Height: | Size: 158 KiB |
BIN
xiaomusic/static/icons/windows11/SplashScreen.scale-150.png
Normal file
|
After Width: | Height: | Size: 227 KiB |
BIN
xiaomusic/static/icons/windows11/SplashScreen.scale-200.png
Normal file
|
After Width: | Height: | Size: 394 KiB |
BIN
xiaomusic/static/icons/windows11/SplashScreen.scale-400.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
xiaomusic/static/icons/windows11/Square150x150Logo.scale-100.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
xiaomusic/static/icons/windows11/Square150x150Logo.scale-125.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
xiaomusic/static/icons/windows11/Square150x150Logo.scale-150.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
xiaomusic/static/icons/windows11/Square150x150Logo.scale-200.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
xiaomusic/static/icons/windows11/Square150x150Logo.scale-400.png
Normal file
|
After Width: | Height: | Size: 379 KiB |
|
After Width: | Height: | Size: 760 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 760 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 97 KiB |