1
0
mirror of https://github.com/hanxi/xiaomusic.git synced 2025-12-06 14:52:50 +08:00

Compare commits

...

201 Commits

Author SHA1 Message Date
涵曦
b9c94cf61e new version v0.1.68 2024-06-26 16:23:55 +00:00
涵曦
725d4c4ab3 新增XIAOMUSIC_DISABLE_DOWNLOAD=true时关闭音乐下载功能 see #82 2024-06-26 16:14:41 +00:00
涵曦
6a0310fe05 new version v0.1.67 2024-06-26 15:57:07 +00:00
涵曦
463fd9dd38 新增m3u文件转电台歌单工具 2024-06-26 15:56:19 +00:00
涵曦
34fe19abd1 new version v0.1.66 2024-06-26 13:41:24 +00:00
涵曦
3365f082f7 修复主页滚动问题 2024-06-26 13:41:05 +00:00
涵曦
13361c57b8 new version v0.1.65 2024-06-26 13:35:43 +00:00
涵曦
2a22b00d53 优化下载json文件逻辑 2024-06-26 10:14:11 +00:00
涵曦
925b52d979 优化下载文件的接口 2024-06-26 09:09:55 +00:00
涵曦
468efb63fb 优化下载文件的接口 2024-06-26 08:56:43 +00:00
涵曦
38aae7eca3 Update README.md 2024-06-26 12:53:05 +08:00
涵曦
44df1134a8 new version v0.1.64 2024-06-26 01:24:30 +00:00
涵曦
243c1673db new version v0.1.63 2024-06-26 01:24:27 +00:00
涵曦
82eab4810c 修复自动播放的问题 2024-06-26 01:24:27 +00:00
涵曦
e0a59b5729 修复自动播放的问题 2024-06-26 01:24:27 +00:00
涵曦
ad3bad85db 优化日志输出 2024-06-26 01:24:27 +00:00
涵曦
743d85de32 优化不定长参数arg1的用法 2024-06-26 01:24:27 +00:00
涵曦
8bd32f878f Update README.md 2024-06-26 02:03:38 +08:00
涵曦
eccb52c197 new version v0.1.62 2024-06-25 17:34:47 +00:00
涵曦
603d60d8b8 优化图标大小 2024-06-25 17:30:50 +00:00
涵曦
3ef04f4159 优化获取音乐时长接口 2024-06-25 17:27:32 +00:00
涵曦
7888ee7938 new version v0.1.61 2024-06-25 11:13:57 +00:00
涵曦
b2a3cda7b5 #78 支持配置自定义网络歌单 2024-06-25 11:13:46 +00:00
涵曦
80c6d29079 new version v0.1.60 2024-06-25 06:20:28 +00:00
涵曦
0b020deaef new version v0.1.59 2024-06-25 06:17:41 +00:00
涵曦
74c8bea756 cue不是音乐文件,排除下 2024-06-25 06:17:41 +00:00
涵曦
af10d6261f Update README.md 2024-06-25 10:50:32 +08:00
涵曦
a178278576 new version v0.1.58 2024-06-25 01:03:13 +00:00
涵曦
474fea8434 优化播放被打断的问题 2024-06-25 01:03:01 +00:00
涵曦
d271f7b0f7 代码优化 2024-06-24 16:03:10 +00:00
涵曦
7e2af515ed fix: 登陆失败不阻塞启动 2024-06-24 15:38:41 +00:00
涵曦
2d403ff18c new version v0.1.57 2024-06-24 14:28:08 +00:00
涵曦
f08244a990 update readme 2024-06-24 14:28:05 +00:00
涵曦
4869e5cf80 新增ape和cue格式文件 2024-06-24 14:27:31 +00:00
涵曦
b887504f9f Update README.md 2024-06-24 12:24:47 +08:00
涵曦
ad43a4f732 new version v0.1.56 2024-06-24 01:04:13 +00:00
涵曦
8699938b61 删除用不上的配置参数 2024-06-24 00:45:41 +00:00
涵曦
40bd099153 支持wav格式文件 2024-06-24 00:19:49 +00:00
涵曦
750923d5ca Update README.md 2024-06-24 00:38:33 +08:00
涵曦
6d99b30e2d Update README.md 2024-06-24 00:35:02 +08:00
涵曦
a155f16560 Update README.md 2024-06-24 00:30:42 +08:00
涵曦
d4aa045487 Update README.md 2024-06-23 20:05:20 +08:00
涵曦
8080dd9822 Update Dockerfile 2024-06-23 19:05:13 +08:00
涵曦
2eab8d8113 update dockerfile 2024-06-23 10:23:46 +00:00
涵曦
b51e56718a update dockerfile 2024-06-23 10:18:07 +00:00
涵曦
088d448e10 优化 Dockerfile 2024-06-23 17:40:28 +08:00
涵曦
4a89b4bce5 Update README.md 2024-06-23 16:27:22 +08:00
涵曦
b351b4bcd4 new version v0.1.55 2024-06-23 07:09:42 +00:00
涵曦
b2edaf48e4 fix: #47 支持配置基础的BaseAuth登录 2024-06-23 07:07:59 +00:00
涵曦
33e02cee82 new version v0.1.54 2024-06-23 04:17:03 +00:00
涵曦
91a8c9eb50 fix: #76 新增XIAOMUSIC_MUSIC_PATH_DEPTH配置生成播放列表的目录深度,默认10 2024-06-23 03:30:32 +00:00
涵曦
50da8a0554 fix: #74 配置目录可以和下载目录分开配置, 新增XIAOMUSIC_CONF_PATH用来设置配置目录,不配置时使用下载目录 2024-06-23 02:49:13 +00:00
涵曦
42b5978d89 new version v0.1.53 2024-06-23 01:52:42 +00:00
涵曦
bf29fc67b4 增加调试日志 2024-06-23 01:52:38 +00:00
涵曦
dbc68d6b56 new version v0.1.52 2024-06-21 14:16:52 +00:00
涵曦
5dabf66e7c 增加日志 2024-06-21 14:16:28 +00:00
涵曦
d6e4478eb6 new version v0.1.51 2024-06-20 23:10:21 +00:00
涵曦
23ef4719ba update log 2024-06-20 15:45:23 +00:00
涵曦
d799a85ab9 new version v0.1.49 2024-06-20 04:12:33 +00:00
涵曦
4ad6bcc636 播放列表排序显示,修复顺序播放问题 2024-06-20 04:12:23 +00:00
涵曦
d2473ec7e8 全部循环为顺序播放,和随机播放区分开 2024-06-18 07:06:16 +00:00
涵曦
28797edc7c new version v0.1.48 2024-06-16 06:14:37 +00:00
涵曦
be1a643071 忽略目录默认值修改 2024-06-16 06:14:33 +00:00
涵曦
ee6b9778ac new version v0.1.47 2024-06-16 05:40:38 +00:00
涵曦
881c34bcb5 新增忽略目录的环境变量 2024-06-16 05:40:30 +00:00
涵曦
c22fc99235 new version v0.1.46 2024-06-15 15:56:22 +00:00
涵曦
0874efe58b 播放歌曲指令默认播放最后一次播放的歌曲 2024-06-15 15:56:15 +00:00
涵曦
f01665c998 new version v0.1.45 2024-06-15 15:04:07 +00:00
涵曦
ac23080f6a 播放列表歌曲前打乱顺序 2024-06-15 15:03:56 +00:00
涵曦
15ee6c4dd1 new version v0.1.44 2024-06-14 15:47:02 +00:00
涵曦
aeaa8f8925 fmt 2024-06-14 15:46:47 +00:00
涵曦
59d7e056c4 new version v0.1.43 2024-06-14 15:14:56 +00:00
涵曦
e79afa46b3 新增删除歌曲按钮 2024-06-14 15:14:34 +00:00
涵曦
9714f3d064 new version v0.1.41 2024-06-14 14:11:00 +00:00
涵曦
2c35c6cfd6 add XIAOMUSIC_VERBOSE env 2024-06-14 14:10:56 +00:00
涵曦
88f0ce7e51 use ruff lint and fmt code 2024-06-14 01:58:10 +00:00
涵曦
e484164fad 修复刷新列表问题 2024-06-13 14:49:36 +00:00
涵曦
aa6bce75cd update readme 2024-06-12 17:26:00 +00:00
涵曦
512efb595a new version v0.1.40 2024-06-12 17:21:13 +00:00
涵曦
e5dea8e693 新增刷新列表指令 2024-06-12 17:21:09 +00:00
涵曦
a704f8003c new version v0.1.39 2024-06-12 17:13:00 +00:00
涵曦
349a25ad58 新增播放列表功能 #51 2024-06-12 17:12:07 +00:00
涵曦
746f46edb3 new version v0.1.38 2024-06-12 15:39:23 +00:00
涵曦
4a29c7a124 fix: #70 下一首歌曲不存在时从播放列表中删除并继续找下一首 2024-06-12 01:18:08 +00:00
涵曦
0e1e412ee9 new version v0.1.37 2024-06-04 12:17:50 +00:00
涵曦
2e84f7c830 Update ci.yml 2024-06-04 18:46:17 +08:00
涵曦
61a0d68b6a Update release.yml 2024-06-04 18:45:53 +08:00
涵曦
ae90029d8e Update README.md 2024-06-04 15:14:14 +08:00
涵曦
ccc83a518c new version v0.1.36 2024-05-30 14:42:32 +00:00
涵曦
7884a5769f 继续修复启动失败问题 2024-05-30 14:42:12 +00:00
涵曦
a663bb330e new version v0.1.35 2024-05-30 13:49:52 +00:00
涵曦
346f0af543 fix: #67 没配置did时也允许启动 http 服务 2024-05-27 14:47:40 +00:00
涵曦
49ec1bb7c0 Update README.md 2024-05-20 00:03:27 +08:00
涵曦
fc0cc75dea new version v0.1.34 2024-05-19 15:53:50 +00:00
涵曦
6fc2be5d31 消除flask启动告警 2024-05-19 15:53:31 +00:00
涵曦
db680bf1ba update readme 2024-05-19 15:22:52 +00:00
涵曦
1c2b97c0d2 new version v0.1.33 2024-05-19 15:19:19 +00:00
涵曦
59cfbb06a4 优化页面 2024-05-19 15:18:28 +00:00
涵曦
9291676543 fix: #50 新增配置页面 2024-05-19 15:11:43 +00:00
涵曦
0d2ba60728 删除不用的配置 2024-05-18 10:01:51 +00:00
firstuanl
cd1461df6d Update config.py
# 第一代小爱,型号MDZ-25-DA
2024-05-18 17:41:15 +08:00
涵曦
37abfd9ce2 fix: #62 2024-05-18 00:12:34 +00:00
涵曦
c6de3dfd00 new version v0.1.32 2024-05-17 12:27:55 +00:00
涵曦
ae297c780a update miservice 2024-05-17 12:27:47 +00:00
涵曦
e07a06c8e4 new version v0.1.31 2024-05-16 23:43:44 +00:00
涵曦
1c91f39417 日志里输出版本号 2024-05-16 23:43:39 +00:00
涵曦
13d26be0a2 new version v0.1.30 2024-05-16 23:19:11 +00:00
涵曦
c2740533a8 fix: 控制台显示版本号 #59 2024-05-16 23:19:05 +00:00
涵曦
abbc2f25bb 修复音量获取 2024-05-16 23:06:30 +00:00
涵曦
04b9738a77 new version v0.1.29 2024-05-16 22:44:38 +00:00
涵曦
f5932a301e 优化日志输出 2024-05-16 22:43:10 +00:00
涵曦
f11e194e6a fix: #57 #55 2024-05-16 22:39:05 +00:00
涵曦
259e47d4d3 new version v0.1.28 2024-05-16 00:22:16 +00:00
涵曦
96c3e00902 更新依赖,解决播放时量灯的问题 2024-05-16 00:22:08 +00:00
涵曦
066414a380 new version v0.1.27 2024-05-16 00:20:50 +00:00
涵曦
b6c7bbb2b7 Update README.md 2024-05-15 09:20:08 +08:00
涵曦
cdce558984 Update README.md 2024-05-15 09:18:50 +08:00
涵曦
a48bb89763 update dependencies 2024-05-12 14:04:08 +00:00
涵曦
e10a8137f4 Update README.md 2024-05-09 12:19:54 +08:00
涵曦
76aeb20268 new version v0.1.26 2024-05-08 14:15:15 +00:00
涵曦
de36ff7d24 默认允许播放歌曲和随机播放唤醒 2024-05-08 14:15:10 +00:00
涵曦
4b5d5b3a0a Update README.md 2024-05-07 07:22:37 +08:00
涵曦
59f150ebbd Update README.md 2024-05-07 07:21:28 +08:00
涵曦
4e2d39abac new version v0.1.25 2024-05-06 10:54:43 +00:00
涵曦
a35cde5d4a Merge pull request #43 from ominkk/main
可配置xiaomuisc激活指令,其他指令需要激活后才能使用
2024-05-02 00:21:05 +08:00
lv99
bbdf41f334 可配置xiaomuisc激活指令,其他指令需要激活后才能使用 2024-05-01 09:35:14 +08:00
涵曦
529aedede0 update readme 2024-04-30 14:04:58 +00:00
涵曦
55eaa6e751 new version v0.1.24 2024-04-30 13:52:20 +00:00
涵曦
ca59e594b4 歌名不换行 2024-04-30 13:52:16 +00:00
涵曦
836fde01b7 new version v0.1.23 2024-04-30 13:48:35 +00:00
涵曦
050ded6b2e 新增显示当前正在播放的音乐 2024-04-30 13:47:45 +00:00
涵曦
b9e1abff6b new version v0.1.22 2024-04-30 12:48:10 +00:00
涵曦
f962fcaa99 新增本地音乐模糊搜索 2024-04-30 12:47:57 +00:00
涵曦
eb35da595f Update README.md 2024-04-29 22:47:54 +08:00
涵曦
26a8b2412f new version v0.1.21 2024-04-08 07:48:02 +08:00
涵曦
601bff4404 修改input显示宽度 2024-04-08 07:47:57 +08:00
涵曦
1fadc9a479 new version v0.1.20 2024-04-08 07:41:16 +08:00
涵曦
69e53569ca 处理空值问题 2024-04-08 07:41:07 +08:00
涵曦
49a43fb997 new version v0.1.19 2024-04-04 20:41:15 +08:00
涵曦
5145ae399d Merge pull request #33 from zhanggaolei001/main
将搜索词分为搜索词及文件名两部分,便于更精确搜索以及实现保存下载保存文件名的自定义
2024-04-03 23:16:44 +08:00
张高磊
612eb636be 将搜索词分为搜索词及文件名两部分,便于更精确搜索以及实现保存下载保存文件名的自定义 2024-04-03 14:12:26 +08:00
涵曦
657af667ef Update README.md 2024-03-18 16:07:50 +08:00
涵曦
9541071c3a new version v0.1.18 2024-02-24 13:26:52 +08:00
涵曦
dfc78b6af5 new version script 2024-02-24 13:26:33 +08:00
涵曦
bea7b2d4eb new version v 2024-02-24 13:23:10 +08:00
涵曦
ddb3e9e03b newversion script 2024-02-24 13:23:03 +08:00
涵曦
812965f054 new version script 2024-02-24 13:22:12 +08:00
涵曦
006ea2d283 new version v0.1.16 2024-02-24 13:08:35 +08:00
涵曦
08a22ca03f 命令行支持 ffmpeg 路径参数 #15 2024-02-24 13:05:36 +08:00
涵曦
7a32917b63 启动时生成一次播放列表,修复下一首越界判断问题 2024-02-24 12:58:01 +08:00
涵曦
54b4417069 支持配置 ffmpeg 路径 #15 2024-02-24 12:49:17 +08:00
涵曦
17d7f54c20 歌曲目录支持子目录,优化随机播放列表 #18 2024-02-24 12:41:26 +08:00
涵曦
2261b5ba53 add ci docker 2024-02-04 14:11:40 +08:00
涵曦
833cb1a24a open debug log 2024-02-04 14:04:18 +08:00
涵曦
4494b54c15 new version v0.1.15 2024-02-03 14:51:14 +08:00
涵曦
594db5aa0c update requirements 2024-02-03 14:51:03 +08:00
涵曦
15966df548 new version v0.1.14 2024-02-03 14:24:16 +08:00
涵曦
6914dca9dc 更新 yt-dlp 版本,修复哔哩哔哩下载问题 2024-02-03 08:26:40 +08:00
涵曦
cbfb5e9531 Update README.md 2024-02-02 22:33:18 +08:00
涵曦
e6c98dd3f3 Update README.md 2024-02-02 22:24:12 +08:00
涵曦
c68fa71d24 new version v0.1.13 2024-02-02 22:11:54 +08:00
涵曦
24b46729e3 优化控制面板,声音设置改为进度条 2024-02-02 22:10:55 +08:00
涵曦
13336cd02c 支持配置歌曲下载源 #12 2024-02-02 20:56:18 +08:00
涵曦
67be9125d8 Update README.md 2024-02-01 23:40:30 +08:00
涵曦
1b0a6dd7f4 Update README.md 2024-01-31 09:17:13 +08:00
涵曦
11053ecfa7 Update README.md 2024-01-31 09:03:38 +08:00
涵曦
0736cb0fb7 new version v0.1.12 2024-01-30 08:21:48 +08:00
涵曦
2acb668101 fix: set volume failed 2024-01-30 08:21:31 +08:00
涵曦
32fb0e9548 add script to update version 2024-01-29 23:28:31 +08:00
涵曦
c69f8e4e65 new version v0.1.11 2024-01-29 23:27:59 +08:00
涵曦
42f91f6ab4 add script to update version 2024-01-29 23:25:42 +08:00
涵曦
f615f21773 new version v0.1.10 2024-01-29 23:24:07 +08:00
涵曦
cad7b53aa4 新增设置声音按钮 2024-01-29 23:10:16 +08:00
涵曦
714cae9bd1 update version 2024-01-28 19:15:08 +08:00
涵曦
15036c3755 fix: arg1 漏修改 2024-01-28 19:14:48 +08:00
涵曦
8f5e2f0560 update version 2024-01-28 18:45:58 +08:00
涵曦
a940fcd236 fix: http server listen host 2024-01-28 18:45:36 +08:00
涵曦
b32e2e29d8 update version 2024-01-28 18:35:04 +08:00
涵曦
8f22e2c66e update requirements 2024-01-28 18:34:34 +08:00
涵曦
8801bb73f4 update readme 2024-01-28 18:29:14 +08:00
涵曦
82a215e3bc update version 2024-01-28 18:26:28 +08:00
涵曦
88e5d98c68 新增输入框输入歌曲名 2024-01-28 18:25:22 +08:00
涵曦
c7ab57c06a 新增定时关机命令,新增控制面板界面 2024-01-28 18:17:45 +08:00
涵曦
f1938b9096 update readme 2024-01-27 23:09:30 +08:00
涵曦
5242deea33 update version 2024-01-27 23:00:31 +08:00
涵曦
d06b3cd2a5 新增随机播放指令 2024-01-27 23:00:17 +08:00
涵曦
2a59d1f69c 推送docker修改 2024-01-27 22:44:23 +08:00
涵曦
358f7ccb98 推送docker修改 2024-01-27 22:41:02 +08:00
涵曦
1043b6f32f update version to v0.1.4 2024-01-27 22:31:13 +08:00
涵曦
8f2d26ac10 修复本地flac音乐播放后去下载错误音乐的问题 2024-01-27 22:26:53 +08:00
涵曦
8e8a605816 支持flac格式的本地文件 2024-01-27 20:56:07 +08:00
涵曦
63eb0c22cb bugfix: kill download progress don't raise error 2023-10-16 22:53:02 +08:00
涵曦
ca07ed0dd3 fix: error when play next 2023-10-16 22:41:00 +08:00
涵曦
7d158ff40e some feat 2023-10-16 22:40:21 +08:00
涵曦
90243b395a Merge pull request #3 from dzhuang/allow_hardware_param
Use MI_HARDWARE in env.
2023-10-16 19:25:11 +08:00
涵曦
653bd417e5 Merge branch 'main' into allow_hardware_param 2023-10-16 19:24:51 +08:00
涵曦
6d89a24b28 Merge pull request #4 from dzhuang/set_proxy_to_null
Default proxy to None.
2023-10-16 19:17:30 +08:00
dzhuang
0ca2adb014 Default proxy to None. 2023-10-16 18:13:09 +08:00
dzhuang
a8a9e2bc45 Use MI_HARDWARE in env. 2023-10-16 18:07:07 +08:00
涵曦
7e7bb256b5 Update README.md 2023-10-15 21:41:12 +08:00
涵曦
35c43646cb Update README.md 2023-10-15 21:40:13 +08:00
23 changed files with 2469 additions and 459 deletions

30
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: ci
on:
push:
branches: [ main ]
workflow_dispatch:
jobs:
build-image:
runs-on: ubuntu-latest
# run unless event type is pull_request
if: github.event_name != 'pull_request'
steps:
- uses: actions/checkout@v3
- 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
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:${{ github.ref_name }}

View File

@@ -61,6 +61,6 @@ jobs:
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
push: true
tags: hanxi/xiaomusic:${{ github.ref_name }}
tags: ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:${{ github.ref_name }}, ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:latest, ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:stable

5
.gitignore vendored
View File

@@ -160,3 +160,8 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
ffmpeg
music
test.sh
conf

View File

@@ -6,7 +6,6 @@ COPY install_dependencies.sh .
RUN bash install_dependencies.sh
FROM python:3.10-slim
WORKDIR /app
COPY --from=builder /app/.venv /app/.venv
COPY --from=builder /app/ffmpeg /app/ffmpeg

186
README.md
View File

@@ -1,8 +1,38 @@
# xiaomusic
[![GitHub License](https://img.shields.io/github/license/hanxi/xiaomusic)](https://github.com/hanxi/xiaomusic)
[![Docker Image Version](https://img.shields.io/docker/v/hanxi/xiaomusic?sort=semver&label=docker%20image)](https://hub.docker.com/r/hanxi/xiaomusic)
[![Docker Pulls](https://img.shields.io/docker/pulls/hanxi/xiaomusic)](https://hub.docker.com/r/hanxi/xiaomusic)
[![PyPI - Version](https://img.shields.io/pypi/v/xiaomusic)](https://pypi.org/project/xiaomusic/)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/xiaomusic)](https://pypi.org/project/xiaomusic/)
[![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fhanxi%2Fxiaomusic%2Fmain%2Fpyproject.toml)](https://pypi.org/project/xiaomusic/)
[![GitHub Release](https://img.shields.io/github/v/release/hanxi/xiaomusic)](https://github.com/hanxi/xiaomusic/releases)
使用小爱同学播放音乐,音乐使用 yt-dlp 下载。
## 运行
使用小爱音箱播放音乐,音乐使用 yt-dlp 下载。
## 最简配置运行
已经支持在 web 页面配置其他参数docker compose 配置如下:
```yaml
services:
xiaomusic:
image: hanxi/xiaomusic
container_name: xiaomusic
restart: unless-stopped
ports:
- 8090:8090
volumes:
- ./music:/app/music
environment:
MI_USER: '小米账号'
MI_PASS: '小米密码'
XIAOMUSIC_HOSTNAME: 'docker 主机 ip'
```
启动成功后,在 web 页面可以配置 MI_DID, MI_HARDWARE, XIAOMUSIC_SEARCH, XIAOMUSIC_PROXY 参数。
## 开发环境运行
- 使用 install_dependencies.sh 下载依赖
- 使用 pdm 安装环境
@@ -12,6 +42,7 @@
export MI_USER="xxxxx"
export MI_PASS="xxxx"
export MI_DID=00000
export XIAOMUSIC_SEARCH='bilisearch:'
```
然后启动即可。默认监听了端口 8090 , 使用其他端口自行修改。
@@ -27,33 +58,178 @@ pdm run xiaomusic.py
- 下一首
- 单曲循环
- 全部循环
- 随机播放
- 关机
- 停止播放
- 刷新列表
- 播放列表+列表名 比如:播放列表其他
> 隐藏玩法: 对小爱同学说播放歌曲小猪佩奇的故事,会播放小猪佩奇的故事。
## 已测试设备
```txt
"L07A": ("5-1", "5-5"), # Redmi小爱音箱Play(l7a)
````
## 支持音乐格式
- mp3
- flac
> 本地音乐会搜索 mp3 和 flac 格式的文件,下载的歌曲是 mp3 格式的。
## 其他参数
- XIAOMUSIC_ACTIVE_CMD 环境变量,配置成'play,random_play'在非播放状态下只有这两个指令播放歌曲和随机播放可以触发触发后xiaomusic进入playing状态其他指令则可以正常触发。
## 在 Docker 里使用
```shell
docker run -e MI_USER=<your-xiaomi-account> -e MI_PASS=<your-xiaomi-password> -e MI_DID=<your-xiaomi-speaker-mid> -e XIAOMUSIC_PROXY=<proxy-for-yt-dlp> -e XIAOMUSIC_HOSTNAME=192.168.2.5 -p 8090:8090 -v ./music:/app/music hanxi/xiaomusic --hardware=<L07A> -
docker run -e MI_USER='your-xiaomi-account' \
-e MI_PASS='your-xiaomi-password' \
-e MI_DID='your-xiaomi-speaker-mid' \
-e MI_HARDWARE='L07A' \
-e XIAOMUSIC_PROXY='proxy-for-yt-dlp' \
-e XIAOMUSIC_HOSTNAME=192.168.2.5 \
-e XIAOMUSIC_SEARCH='bilisearch:' \
-p 8090:8090 \
-v ./music:/app/music hanxi/xiaomusic
```
- XIAOMUSIC_PROXY 用于配置代理yt-dlp 工具下载歌曲会用到。
- 注意端口必须映射为与容器内一致XIAOMUSIC_HOSTNAME 需要设置为宿主机的 IP 地址,否则小爱无法正常播放
- XIAOMUSIC_SEARCH 可以配置为 'bilisearch:' 表示歌曲从哔哩哔哩下载;
- 配置为 'ytsearch:' 表示歌曲从 youtube 下载
- XIAOMUSIC_PROXY 用于配置代理,默认为空;
- 当 XIAOMUSIC_SEARCH 配置为 'ytsearch:' 时在国内需要用到。
- MI_HARDWARE 是小米音箱的型号,默认为'L07A'
- 注意端口必须映射为与容器内一致, XIAOMUSIC_HOSTNAME 需要设置为宿主机的 IP 地址,否则小爱无法正常播放。
- 可以把 /app/music 目录映射到本地,用于保存下载的歌曲。
XIAOMUSIC_PROXY 参数格式参考 yt-dlp 文档说明:
```
Use the specified HTTP/HTTPS/SOCKS proxy. To
enable SOCKS proxy, specify a proper scheme,
e.g. socks5://user:pass@127.0.0.1:1080/.
Pass in an empty string (--proxy "") for
direct connection
```
<https://github.com/hanxi/xiaomusic/issues/2><https://github.com/hanxi/xiaomusic/issues/11>
### 本地编译Docker Image
```shell
docker build -t xiaomusic .
```
### docker compose 示例
使用哔哩哔哩下载歌曲:
```yaml
version: '3'
services:
xiaomusic:
image: hanxi/xiaomusic
container_name: xiaomusic
restart: unless-stopped
ports:
- 8090:8090
volumes:
- ./music:/app/music
environment:
MI_USER: '小米账号'
MI_PASS: '小米密码'
MI_DID: 00000
MI_HARDWARE: 'L07A'
XIAOMUSIC_SEARCH: 'bilisearch:'
XIAOMUSIC_HOSTNAME: '192.168.2.5'
```
使用 youtobe 下载歌曲:
```yaml
version: '3'
services:
xiaomusic:
image: hanxi/xiaomusic
container_name: xiaomusic
restart: unless-stopped
ports:
- 8090:8090
volumes:
- ./music:/app/music
environment:
MI_USER: '小米账号'
MI_PASS: '小米密码'
MI_DID: 00000
MI_HARDWARE: 'L07A'
XIAOMUSIC_SEARCH: 'ytsearch:'
XIAOMUSIC_PROXY: 'http://192.168.2.5:8080'
XIAOMUSIC_HOSTNAME: '192.168.2.5'
```
## 简易的控制面板
浏览器进入 <http://192.168.2.5:8090>
- ip 是 XIAOMUSIC_HOSTNAME 设置的
- 8090 是默认端口
- 新功能
- 显示正在播放的歌曲
- 模糊搜索本地歌曲
- 设置页面
采用新的设置页面之后,必须在启动前配置的环境变量只剩下:
- MI_USER
- MI_PASS
- XIAOMUSIC_HOSTNAME
其他的这些可以在网页里配置:
- MI_DID
- MI_HARDWARE
- XIAOMUSIC_SEARCH
- XIAOMUSIC_PROXY
## 网络歌单功能
可以配置一个 json 格式的歌单,支持电台和歌曲,也可以直接用别人分享的链接,具体用法见 <https://github.com/hanxi/xiaomusic/issues/78>
## 更多其他可选配置
- XIAOMUSIC_ACTIVE_CMD 配置唤醒命令,具体见 <https://github.com/hanxi/xiaomusic/pull/43>
- XIAOMUSIC_EXCLUDE_DIRS 配置歌曲目录里需要忽略的目录
- XIAOMUSIC_MUSIC_PATH_DEPTH 配置歌曲目录搜索深度,具体见 <https://github.com/hanxi/xiaomusic/issues/76>
- XIAOMUSIC_DISABLE_HTTPAUTH 配置成 false 表示开启密码访问web控制台具体见 <https://github.com/hanxi/xiaomusic/issues/47>
- XIAOMUSIC_HTTPAUTH_USERNAME 配置 web 控制台用户
- XIAOMUSIC_HTTPAUTH_PASSWORD 配置 web 控制台密码
- XIAOMUSIC_CONF_PATH 用来存放配置文件的目录记得把目录映射到主机默认情况会把配置存放在music目录具体见 <https://github.com/hanxi/xiaomusic/issues/74>
- XIAOMUSIC_VERBOSE 设置为 true 时开启 debug 日志,用于排查问题
## 讨论区
- [点击链接加入QQ频道【xiaomusic】](https://pd.qq.com/s/e2jybz0ss)
- [点击链接加入群聊【xiaomusic】 604526973](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=13St5PLVcTxYlWTAs_iAawazjtdD1l-a&authKey=dJWEpaT2fDBDpdUUOWj%2FLt6NS1ePBfShDfz7a6seNURi05VvVnAGQzXF%2FM%2F5HgIm&noverify=0&group_code=604526973)
- https://github.com/hanxi/xiaomusic/issues
## 感谢
- [xiaomi](https://www.mi.com/)
- [PDM](https://pdm.fming.dev/latest/)
- [xiaogpt](https://github.com/yihong0618/xiaogpt)
- [MiService](https://github.com/yihong0618/MiService)
- [yt-dlp](https://github.com/yt-dlp/yt-dlp)
- [NAS部署教程](https://post.m.smzdm.com/p/avpe7n99/)
- [群晖部署教程](https://post.m.smzdm.com/p/a7px7dol/)
- [QNAS部署教程](https://post.smzdm.com/p/a5xz5x63/)
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=hanxi/xiaomusic&type=Date)](https://star-history.com/#hanxi/xiaomusic&Date)
## 赞赏
谢谢就够了

37
newversion.sh Executable file
View File

@@ -0,0 +1,37 @@
#!/bin/bash
set -e
version_file=./pyproject.toml
init_file=./xiaomusic/__init__.py
# 获取当前版本号
current_version=$(grep -oE "version = \"[0-9]+\.[0-9]+\.[0-9]+\"" $version_file | cut -d'"' -f2)
echo "当前版本号: "$current_version
# 将版本号分割成三部分
major=$(echo $current_version | cut -d'.' -f1)
minor=$(echo $current_version | cut -d'.' -f2)
patch=$(echo $current_version | cut -d'.' -f3)
echo "major: $major"
echo "minor: $minor"
echo "patch: $patch"
# 将补丁号加1
patch=$((patch + 1))
# 生成新版本号
new_version="$major.$minor.$patch"
# 将新版本号写入文件
sed -i "s/version.*/version = \"$new_version\"/g" $version_file
sed -i "s/__version__.*/__version__ = \"$new_version\"/g" $init_file
echo "新版本号:$new_version"
git diff
git add $version_file
git add $init_file
git commit -m "new version v$new_version"
git tag v$new_version
git push -u origin main --tags

438
pdm.lock generated
View File

@@ -2,58 +2,71 @@
# It is not intended for manual editing.
[metadata]
groups = ["default"]
cross_platform = true
static_urls = false
lock_version = "4.3"
content_hash = "sha256:c123354af86c15de519dfa703c59361f09898eb635df198f3dcf9ef6ed41ffba"
groups = ["default", "lint"]
strategy = ["cross_platform"]
lock_version = "4.4.1"
content_hash = "sha256:813253734c7d7835a76cd87fe8fe0329e02ad067f535aee6a9e11cb106569dd2"
[[package]]
name = "aiohttp"
version = "3.8.6"
requires_python = ">=3.6"
version = "3.9.5"
requires_python = ">=3.8"
summary = "Async http client/server framework (asyncio)"
dependencies = [
"aiosignal>=1.1.2",
"async-timeout<5.0,>=4.0.0a3",
"async-timeout<5.0,>=4.0; python_version < \"3.11\"",
"attrs>=17.3.0",
"charset-normalizer<4.0,>=2.0",
"frozenlist>=1.1.1",
"multidict<7.0,>=4.5",
"yarl<2.0,>=1.0",
]
files = [
{file = "aiohttp-3.8.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:41d55fc043954cddbbd82503d9cc3f4814a40bcef30b3569bc7b5e34130718c1"},
{file = "aiohttp-3.8.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1d84166673694841d8953f0a8d0c90e1087739d24632fe86b1a08819168b4566"},
{file = "aiohttp-3.8.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:253bf92b744b3170eb4c4ca2fa58f9c4b87aeb1df42f71d4e78815e6e8b73c9e"},
{file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fd194939b1f764d6bb05490987bfe104287bbf51b8d862261ccf66f48fb4096"},
{file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c5f938d199a6fdbdc10bbb9447496561c3a9a565b43be564648d81e1102ac22"},
{file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2817b2f66ca82ee699acd90e05c95e79bbf1dc986abb62b61ec8aaf851e81c93"},
{file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fa375b3d34e71ccccf172cab401cd94a72de7a8cc01847a7b3386204093bb47"},
{file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9de50a199b7710fa2904be5a4a9b51af587ab24c8e540a7243ab737b45844543"},
{file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e1d8cb0b56b3587c5c01de3bf2f600f186da7e7b5f7353d1bf26a8ddca57f965"},
{file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8e31e9db1bee8b4f407b77fd2507337a0a80665ad7b6c749d08df595d88f1cf5"},
{file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7bc88fc494b1f0311d67f29fee6fd636606f4697e8cc793a2d912ac5b19aa38d"},
{file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ec00c3305788e04bf6d29d42e504560e159ccaf0be30c09203b468a6c1ccd3b2"},
{file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ad1407db8f2f49329729564f71685557157bfa42b48f4b93e53721a16eb813ed"},
{file = "aiohttp-3.8.6-cp310-cp310-win32.whl", hash = "sha256:ccc360e87341ad47c777f5723f68adbb52b37ab450c8bc3ca9ca1f3e849e5fe2"},
{file = "aiohttp-3.8.6-cp310-cp310-win_amd64.whl", hash = "sha256:93c15c8e48e5e7b89d5cb4613479d144fda8344e2d886cf694fd36db4cc86865"},
{file = "aiohttp-3.8.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e2f9cc8e5328f829f6e1fb74a0a3a939b14e67e80832975e01929e320386b34"},
{file = "aiohttp-3.8.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e6a00ffcc173e765e200ceefb06399ba09c06db97f401f920513a10c803604ca"},
{file = "aiohttp-3.8.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:41bdc2ba359032e36c0e9de5a3bd00d6fb7ea558a6ce6b70acedf0da86458321"},
{file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14cd52ccf40006c7a6cd34a0f8663734e5363fd981807173faf3a017e202fec9"},
{file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2d5b785c792802e7b275c420d84f3397668e9d49ab1cb52bd916b3b3ffcf09ad"},
{file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1bed815f3dc3d915c5c1e556c397c8667826fbc1b935d95b0ad680787896a358"},
{file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96603a562b546632441926cd1293cfcb5b69f0b4159e6077f7c7dbdfb686af4d"},
{file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d76e8b13161a202d14c9584590c4df4d068c9567c99506497bdd67eaedf36403"},
{file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e3f1e3f1a1751bb62b4a1b7f4e435afcdade6c17a4fd9b9d43607cebd242924a"},
{file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:76b36b3124f0223903609944a3c8bf28a599b2cc0ce0be60b45211c8e9be97f8"},
{file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:a2ece4af1f3c967a4390c284797ab595a9f1bc1130ef8b01828915a05a6ae684"},
{file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:16d330b3b9db87c3883e565340d292638a878236418b23cc8b9b11a054aaa887"},
{file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:42c89579f82e49db436b69c938ab3e1559e5a4409eb8639eb4143989bc390f2f"},
{file = "aiohttp-3.8.6-cp311-cp311-win32.whl", hash = "sha256:efd2fcf7e7b9d7ab16e6b7d54205beded0a9c8566cb30f09c1abe42b4e22bdcb"},
{file = "aiohttp-3.8.6-cp311-cp311-win_amd64.whl", hash = "sha256:3b2ab182fc28e7a81f6c70bfbd829045d9480063f5ab06f6e601a3eddbbd49a0"},
{file = "aiohttp-3.8.6.tar.gz", hash = "sha256:b0cf2a4501bff9330a8a5248b4ce951851e415bdcce9dc158e76cfd55e15085c"},
{file = "aiohttp-3.9.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fcde4c397f673fdec23e6b05ebf8d4751314fa7c24f93334bf1f1364c1c69ac7"},
{file = "aiohttp-3.9.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d6b3f1fabe465e819aed2c421a6743d8debbde79b6a8600739300630a01bf2c"},
{file = "aiohttp-3.9.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ae79c1bc12c34082d92bf9422764f799aee4746fd7a392db46b7fd357d4a17a"},
{file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d3ebb9e1316ec74277d19c5f482f98cc65a73ccd5430540d6d11682cd857430"},
{file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84dabd95154f43a2ea80deffec9cb44d2e301e38a0c9d331cc4aa0166fe28ae3"},
{file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c8a02fbeca6f63cb1f0475c799679057fc9268b77075ab7cf3f1c600e81dd46b"},
{file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c26959ca7b75ff768e2776d8055bf9582a6267e24556bb7f7bd29e677932be72"},
{file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:714d4e5231fed4ba2762ed489b4aec07b2b9953cf4ee31e9871caac895a839c0"},
{file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7a6a8354f1b62e15d48e04350f13e726fa08b62c3d7b8401c0a1314f02e3558"},
{file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c413016880e03e69d166efb5a1a95d40f83d5a3a648d16486592c49ffb76d0db"},
{file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ff84aeb864e0fac81f676be9f4685f0527b660f1efdc40dcede3c251ef1e867f"},
{file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ad7f2919d7dac062f24d6f5fe95d401597fbb015a25771f85e692d043c9d7832"},
{file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:702e2c7c187c1a498a4e2b03155d52658fdd6fda882d3d7fbb891a5cf108bb10"},
{file = "aiohttp-3.9.5-cp310-cp310-win32.whl", hash = "sha256:67c3119f5ddc7261d47163ed86d760ddf0e625cd6246b4ed852e82159617b5fb"},
{file = "aiohttp-3.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:471f0ef53ccedec9995287f02caf0c068732f026455f07db3f01a46e49d76bbb"},
{file = "aiohttp-3.9.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ae53e33ee7476dd3d1132f932eeb39bf6125083820049d06edcdca4381f342"},
{file = "aiohttp-3.9.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c088c4d70d21f8ca5c0b8b5403fe84a7bc8e024161febdd4ef04575ef35d474d"},
{file = "aiohttp-3.9.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:639d0042b7670222f33b0028de6b4e2fad6451462ce7df2af8aee37dcac55424"},
{file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f26383adb94da5e7fb388d441bf09c61e5e35f455a3217bfd790c6b6bc64b2ee"},
{file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66331d00fb28dc90aa606d9a54304af76b335ae204d1836f65797d6fe27f1ca2"},
{file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ff550491f5492ab5ed3533e76b8567f4b37bd2995e780a1f46bca2024223233"},
{file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f22eb3a6c1080d862befa0a89c380b4dafce29dc6cd56083f630073d102eb595"},
{file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a81b1143d42b66ffc40a441379387076243ef7b51019204fd3ec36b9f69e77d6"},
{file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f64fd07515dad67f24b6ea4a66ae2876c01031de91c93075b8093f07c0a2d93d"},
{file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:93e22add827447d2e26d67c9ac0161756007f152fdc5210277d00a85f6c92323"},
{file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:55b39c8684a46e56ef8c8d24faf02de4a2b2ac60d26cee93bc595651ff545de9"},
{file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4715a9b778f4293b9f8ae7a0a7cef9829f02ff8d6277a39d7f40565c737d3771"},
{file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:afc52b8d969eff14e069a710057d15ab9ac17cd4b6753042c407dcea0e40bf75"},
{file = "aiohttp-3.9.5-cp311-cp311-win32.whl", hash = "sha256:b3df71da99c98534be076196791adca8819761f0bf6e08e07fd7da25127150d6"},
{file = "aiohttp-3.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:88e311d98cc0bf45b62fc46c66753a83445f5ab20038bcc1b8a1cc05666f428a"},
{file = "aiohttp-3.9.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c7a4b7a6cf5b6eb11e109a9755fd4fda7d57395f8c575e166d363b9fc3ec4678"},
{file = "aiohttp-3.9.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0a158704edf0abcac8ac371fbb54044f3270bdbc93e254a82b6c82be1ef08f3c"},
{file = "aiohttp-3.9.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d153f652a687a8e95ad367a86a61e8d53d528b0530ef382ec5aaf533140ed00f"},
{file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82a6a97d9771cb48ae16979c3a3a9a18b600a8505b1115cfe354dfb2054468b4"},
{file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60cdbd56f4cad9f69c35eaac0fbbdf1f77b0ff9456cebd4902f3dd1cf096464c"},
{file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8676e8fd73141ded15ea586de0b7cda1542960a7b9ad89b2b06428e97125d4fa"},
{file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da00da442a0e31f1c69d26d224e1efd3a1ca5bcbf210978a2ca7426dfcae9f58"},
{file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18f634d540dd099c262e9f887c8bbacc959847cfe5da7a0e2e1cf3f14dbf2daf"},
{file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:320e8618eda64e19d11bdb3bd04ccc0a816c17eaecb7e4945d01deee2a22f95f"},
{file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:2faa61a904b83142747fc6a6d7ad8fccff898c849123030f8e75d5d967fd4a81"},
{file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:8c64a6dc3fe5db7b1b4d2b5cb84c4f677768bdc340611eca673afb7cf416ef5a"},
{file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:393c7aba2b55559ef7ab791c94b44f7482a07bf7640d17b341b79081f5e5cd1a"},
{file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c671dc117c2c21a1ca10c116cfcd6e3e44da7fcde37bf83b2be485ab377b25da"},
{file = "aiohttp-3.9.5-cp312-cp312-win32.whl", hash = "sha256:5a7ee16aab26e76add4afc45e8f8206c95d1d75540f1039b84a03c3b3800dd59"},
{file = "aiohttp-3.9.5-cp312-cp312-win_amd64.whl", hash = "sha256:5ca51eadbd67045396bc92a4345d1790b7301c14d1848feaac1d6a6c9289e888"},
{file = "aiohttp-3.9.5.tar.gz", hash = "sha256:edea7d15772ceeb29db4aff55e482d4bcfb6ae160ce144f2682de02f6d693551"},
]
[[package]]
@@ -69,6 +82,19 @@ files = [
{file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"},
]
[[package]]
name = "asgiref"
version = "3.7.2"
requires_python = ">=3.7"
summary = "ASGI specs, helper code, and adapters"
dependencies = [
"typing-extensions>=4; python_version < \"3.11\"",
]
files = [
{file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"},
{file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"},
]
[[package]]
name = "async-timeout"
version = "4.0.3"
@@ -89,6 +115,16 @@ files = [
{file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"},
]
[[package]]
name = "blinker"
version = "1.7.0"
requires_python = ">=3.8"
summary = "Fast, simple object-to-object and broadcast signaling"
files = [
{file = "blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9"},
{file = "blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182"},
]
[[package]]
name = "brotli"
version = "1.1.0"
@@ -280,6 +316,73 @@ files = [
{file = "charset_normalizer-3.3.0-py3-none-any.whl", hash = "sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2"},
]
[[package]]
name = "click"
version = "8.1.7"
requires_python = ">=3.7"
summary = "Composable command line interface toolkit"
dependencies = [
"colorama; platform_system == \"Windows\"",
]
files = [
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
]
[[package]]
name = "colorama"
version = "0.4.6"
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
summary = "Cross-platform colored terminal text."
files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
[[package]]
name = "flask"
version = "3.0.3"
requires_python = ">=3.8"
summary = "A simple framework for building complex web applications."
dependencies = [
"Jinja2>=3.1.2",
"Werkzeug>=3.0.0",
"blinker>=1.6.2",
"click>=8.1.3",
"itsdangerous>=2.1.2",
]
files = [
{file = "flask-3.0.3-py3-none-any.whl", hash = "sha256:34e815dfaa43340d1d15a5c3a02b8476004037eb4840b34910c6e21679d288f3"},
{file = "flask-3.0.3.tar.gz", hash = "sha256:ceb27b0af3823ea2737928a4d99d125a06175b8512c445cbd9a9ce200ef76842"},
]
[[package]]
name = "flask-httpauth"
version = "4.8.0"
summary = "HTTP authentication for Flask routes"
dependencies = [
"flask",
]
files = [
{file = "Flask-HTTPAuth-4.8.0.tar.gz", hash = "sha256:66568a05bc73942c65f1e2201ae746295816dc009edd84b482c44c758d75097a"},
{file = "Flask_HTTPAuth-4.8.0-py3-none-any.whl", hash = "sha256:a58fedd09989b9975448eef04806b096a3964a7feeebc0a78831ff55685b62b0"},
]
[[package]]
name = "flask"
version = "3.0.3"
extras = ["async"]
requires_python = ">=3.8"
summary = "A simple framework for building complex web applications."
dependencies = [
"asgiref>=3.2",
"flask==3.0.3",
]
files = [
{file = "flask-3.0.3-py3-none-any.whl", hash = "sha256:34e815dfaa43340d1d15a5c3a02b8476004037eb4840b34910c6e21679d288f3"},
{file = "flask-3.0.3.tar.gz", hash = "sha256:ceb27b0af3823ea2737928a4d99d125a06175b8512c445cbd9a9ce200ef76842"},
]
[[package]]
name = "frozenlist"
version = "1.4.0"
@@ -329,6 +432,29 @@ files = [
{file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
]
[[package]]
name = "itsdangerous"
version = "2.1.2"
requires_python = ">=3.7"
summary = "Safely pass data to untrusted environments and back."
files = [
{file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"},
{file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"},
]
[[package]]
name = "jinja2"
version = "3.1.3"
requires_python = ">=3.7"
summary = "A very fast and expressive template engine."
dependencies = [
"MarkupSafe>=2.0",
]
files = [
{file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"},
{file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"},
]
[[package]]
name = "markdown-it-py"
version = "3.0.0"
@@ -342,6 +468,45 @@ files = [
{file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"},
]
[[package]]
name = "markupsafe"
version = "2.1.4"
requires_python = ">=3.7"
summary = "Safely add untrusted strings to HTML/XML markup."
files = [
{file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de8153a7aae3835484ac168a9a9bdaa0c5eee4e0bc595503c95d53b942879c84"},
{file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e888ff76ceb39601c59e219f281466c6d7e66bd375b4ec1ce83bcdc68306796b"},
{file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b838c37ba596fcbfca71651a104a611543077156cb0a26fe0c475e1f152ee8"},
{file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac1ebf6983148b45b5fa48593950f90ed6d1d26300604f321c74a9ca1609f8e"},
{file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbad3d346df8f9d72622ac71b69565e621ada2ce6572f37c2eae8dacd60385d"},
{file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5291d98cd3ad9a562883468c690a2a238c4a6388ab3bd155b0c75dd55ece858"},
{file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a7cc49ef48a3c7a0005a949f3c04f8baa5409d3f663a1b36f0eba9bfe2a0396e"},
{file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83041cda633871572f0d3c41dddd5582ad7d22f65a72eacd8d3d6d00291df26"},
{file = "MarkupSafe-2.1.4-cp310-cp310-win32.whl", hash = "sha256:0c26f67b3fe27302d3a412b85ef696792c4a2386293c53ba683a89562f9399b0"},
{file = "MarkupSafe-2.1.4-cp310-cp310-win_amd64.whl", hash = "sha256:a76055d5cb1c23485d7ddae533229039b850db711c554a12ea64a0fd8a0129e2"},
{file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9e9e3c4020aa2dc62d5dd6743a69e399ce3de58320522948af6140ac959ab863"},
{file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0042d6a9880b38e1dd9ff83146cc3c9c18a059b9360ceae207805567aacccc69"},
{file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d03fea4c4e9fd0ad75dc2e7e2b6757b80c152c032ea1d1de487461d8140efc"},
{file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ab3a886a237f6e9c9f4f7d272067e712cdb4efa774bef494dccad08f39d8ae6"},
{file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abf5ebbec056817057bfafc0445916bb688a255a5146f900445d081db08cbabb"},
{file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e1a0d1924a5013d4f294087e00024ad25668234569289650929ab871231668e7"},
{file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e7902211afd0af05fbadcc9a312e4cf10f27b779cf1323e78d52377ae4b72bea"},
{file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c669391319973e49a7c6230c218a1e3044710bc1ce4c8e6eb71f7e6d43a2c131"},
{file = "MarkupSafe-2.1.4-cp311-cp311-win32.whl", hash = "sha256:31f57d64c336b8ccb1966d156932f3daa4fee74176b0fdc48ef580be774aae74"},
{file = "MarkupSafe-2.1.4-cp311-cp311-win_amd64.whl", hash = "sha256:54a7e1380dfece8847c71bf7e33da5d084e9b889c75eca19100ef98027bd9f56"},
{file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a76cd37d229fc385738bd1ce4cba2a121cf26b53864c1772694ad0ad348e509e"},
{file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:987d13fe1d23e12a66ca2073b8d2e2a75cec2ecb8eab43ff5624ba0ad42764bc"},
{file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5244324676254697fe5c181fc762284e2c5fceeb1c4e3e7f6aca2b6f107e60dc"},
{file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78bc995e004681246e85e28e068111a4c3f35f34e6c62da1471e844ee1446250"},
{file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4d176cfdfde84f732c4a53109b293d05883e952bbba68b857ae446fa3119b4f"},
{file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f9917691f410a2e0897d1ef99619fd3f7dd503647c8ff2475bf90c3cf222ad74"},
{file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f06e5a9e99b7df44640767842f414ed5d7bedaaa78cd817ce04bbd6fd86e2dd6"},
{file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:396549cea79e8ca4ba65525470d534e8a41070e6b3500ce2414921099cb73e8d"},
{file = "MarkupSafe-2.1.4-cp312-cp312-win32.whl", hash = "sha256:f6be2d708a9d0e9b0054856f07ac7070fbe1754be40ca8525d5adccdbda8f475"},
{file = "MarkupSafe-2.1.4-cp312-cp312-win_amd64.whl", hash = "sha256:5045e892cfdaecc5b4c01822f353cf2c8feb88a6ec1c0adef2a2e705eef0f656"},
{file = "MarkupSafe-2.1.4.tar.gz", hash = "sha256:3aae9af4cac263007fd6309c64c6ab4506dd2b79382d9d19a1994f9240b8db4f"},
]
[[package]]
name = "mdurl"
version = "0.1.2"
@@ -354,15 +519,17 @@ files = [
[[package]]
name = "miservice-fork"
version = "2.2.1"
requires_python = ">=3.7"
version = "2.5.0"
requires_python = ">=3.8"
summary = "XiaoMi Cloud Service fork from https://github.com/Yonsm/MiService"
dependencies = [
"aiohttp",
"mutagen",
"rich",
]
files = [
{file = "miservice_fork-2.2.1-py3-none-any.whl", hash = "sha256:cf8f3e30b3008de29a69d9a8293cca8428e670ae10a0f791840428ee947fc27e"},
{file = "miservice_fork-2.2.1.tar.gz", hash = "sha256:f3f742ccd7cb4a1ed22cfdf95da14f791eff0c6c3a54032dcfe445ae540664df"},
{file = "miservice_fork-2.5.0-py3-none-any.whl", hash = "sha256:97b6360ea53c34fe035ac9d94e8705f305b8fa7fc2b44a7aea182449a76cb622"},
{file = "miservice_fork-2.5.0.tar.gz", hash = "sha256:8ca2d370d5b32f7e330add38aa1912d734aefa7880f16cef9eac110a5a3029e2"},
]
[[package]]
@@ -465,8 +632,8 @@ files = [
[[package]]
name = "requests"
version = "2.31.0"
requires_python = ">=3.7"
version = "2.32.3"
requires_python = ">=3.8"
summary = "Python HTTP for Humans."
dependencies = [
"certifi>=2017.4.17",
@@ -475,13 +642,13 @@ dependencies = [
"urllib3<3,>=1.21.1",
]
files = [
{file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
{file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
{file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
{file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
]
[[package]]
name = "rich"
version = "13.6.0"
version = "13.7.1"
requires_python = ">=3.7.0"
summary = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
dependencies = [
@@ -489,8 +656,43 @@ dependencies = [
"pygments<3.0.0,>=2.13.0",
]
files = [
{file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"},
{file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"},
{file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"},
{file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"},
]
[[package]]
name = "ruff"
version = "0.4.9"
requires_python = ">=3.7"
summary = "An extremely fast Python linter and code formatter, written in Rust."
files = [
{file = "ruff-0.4.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b262ed08d036ebe162123170b35703aaf9daffecb698cd367a8d585157732991"},
{file = "ruff-0.4.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:98ec2775fd2d856dc405635e5ee4ff177920f2141b8e2d9eb5bd6efd50e80317"},
{file = "ruff-0.4.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4555056049d46d8a381f746680db1c46e67ac3b00d714606304077682832998e"},
{file = "ruff-0.4.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e91175fbe48f8a2174c9aad70438fe9cb0a5732c4159b2a10a3565fea2d94cde"},
{file = "ruff-0.4.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e8e7b95673f22e0efd3571fb5b0cf71a5eaaa3cc8a776584f3b2cc878e46bff"},
{file = "ruff-0.4.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2d45ddc6d82e1190ea737341326ecbc9a61447ba331b0a8962869fcada758505"},
{file = "ruff-0.4.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:78de3fdb95c4af084087628132336772b1c5044f6e710739d440fc0bccf4d321"},
{file = "ruff-0.4.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:06b60f91bfa5514bb689b500a25ba48e897d18fea14dce14b48a0c40d1635893"},
{file = "ruff-0.4.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88bffe9c6a454bf8529f9ab9091c99490578a593cc9f9822b7fc065ee0712a06"},
{file = "ruff-0.4.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:673bddb893f21ab47a8334c8e0ea7fd6598ecc8e698da75bcd12a7b9d0a3206e"},
{file = "ruff-0.4.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8c1aff58c31948cc66d0b22951aa19edb5af0a3af40c936340cd32a8b1ab7438"},
{file = "ruff-0.4.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:784d3ec9bd6493c3b720a0b76f741e6c2d7d44f6b2be87f5eef1ae8cc1d54c84"},
{file = "ruff-0.4.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:732dd550bfa5d85af8c3c6cbc47ba5b67c6aed8a89e2f011b908fc88f87649db"},
{file = "ruff-0.4.9-py3-none-win32.whl", hash = "sha256:8064590fd1a50dcf4909c268b0e7c2498253273309ad3d97e4a752bb9df4f521"},
{file = "ruff-0.4.9-py3-none-win_amd64.whl", hash = "sha256:e0a22c4157e53d006530c902107c7f550b9233e9706313ab57b892d7197d8e52"},
{file = "ruff-0.4.9-py3-none-win_arm64.whl", hash = "sha256:5d5460f789ccf4efd43f265a58538a2c24dbce15dbf560676e430375f20a8198"},
{file = "ruff-0.4.9.tar.gz", hash = "sha256:f1cb0828ac9533ba0135d148d214e284711ede33640465e706772645483427e3"},
]
[[package]]
name = "typing-extensions"
version = "4.9.0"
requires_python = ">=3.8"
summary = "Backported and Experimental Type Hints for Python 3.8+"
files = [
{file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
{file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
]
[[package]]
@@ -503,51 +705,85 @@ files = [
{file = "urllib3-2.0.6.tar.gz", hash = "sha256:b19e1a85d206b56d7df1d5e683df4a7725252a964e3993648dd0fb5a1c157564"},
]
[[package]]
name = "waitress"
version = "3.0.0"
requires_python = ">=3.8.0"
summary = "Waitress WSGI server"
files = [
{file = "waitress-3.0.0-py3-none-any.whl", hash = "sha256:2a06f242f4ba0cc563444ca3d1998959447477363a2d7e9b8b4d75d35cfd1669"},
{file = "waitress-3.0.0.tar.gz", hash = "sha256:005da479b04134cdd9dd602d1ee7c49d79de0537610d653674cc6cbde222b8a1"},
]
[[package]]
name = "websockets"
version = "11.0.3"
requires_python = ">=3.7"
version = "12.0"
requires_python = ">=3.8"
summary = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
files = [
{file = "websockets-11.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3ccc8a0c387629aec40f2fc9fdcb4b9d5431954f934da3eaf16cdc94f67dbfac"},
{file = "websockets-11.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d67ac60a307f760c6e65dad586f556dde58e683fab03323221a4e530ead6f74d"},
{file = "websockets-11.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84d27a4832cc1a0ee07cdcf2b0629a8a72db73f4cf6de6f0904f6661227f256f"},
{file = "websockets-11.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564"},
{file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7622a89d696fc87af8e8d280d9b421db5133ef5b29d3f7a1ce9f1a7bf7fcfa11"},
{file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bceab846bac555aff6427d060f2fcfff71042dba6f5fca7dc4f75cac815e57ca"},
{file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:54c6e5b3d3a8936a4ab6870d46bdd6ec500ad62bde9e44462c32d18f1e9a8e54"},
{file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:41f696ba95cd92dc047e46b41b26dd24518384749ed0d99bea0a941ca87404c4"},
{file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:86d2a77fd490ae3ff6fae1c6ceaecad063d3cc2320b44377efdde79880e11526"},
{file = "websockets-11.0.3-cp310-cp310-win32.whl", hash = "sha256:2d903ad4419f5b472de90cd2d40384573b25da71e33519a67797de17ef849b69"},
{file = "websockets-11.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:1d2256283fa4b7f4c7d7d3e84dc2ece74d341bce57d5b9bf385df109c2a1a82f"},
{file = "websockets-11.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e848f46a58b9fcf3d06061d17be388caf70ea5b8cc3466251963c8345e13f7eb"},
{file = "websockets-11.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aa5003845cdd21ac0dc6c9bf661c5beddd01116f6eb9eb3c8e272353d45b3288"},
{file = "websockets-11.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b58cbf0697721120866820b89f93659abc31c1e876bf20d0b3d03cef14faf84d"},
{file = "websockets-11.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:660e2d9068d2bedc0912af508f30bbeb505bbbf9774d98def45f68278cea20d3"},
{file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1f0524f203e3bd35149f12157438f406eff2e4fb30f71221c8a5eceb3617b6b"},
{file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:def07915168ac8f7853812cc593c71185a16216e9e4fa886358a17ed0fd9fcf6"},
{file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b30c6590146e53149f04e85a6e4fcae068df4289e31e4aee1fdf56a0dead8f97"},
{file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:619d9f06372b3a42bc29d0cd0354c9bb9fb39c2cbc1a9c5025b4538738dbffaf"},
{file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd"},
{file = "websockets-11.0.3-cp311-cp311-win32.whl", hash = "sha256:e1459677e5d12be8bbc7584c35b992eea142911a6236a3278b9b5ce3326f282c"},
{file = "websockets-11.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:e7837cb169eca3b3ae94cc5787c4fed99eef74c0ab9506756eea335e0d6f3ed8"},
{file = "websockets-11.0.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e58f2c36cc52d41f2659e4c0cbf7353e28c8c9e63e30d8c6d3494dc9fdedcf"},
{file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de36fe9c02995c7e6ae6efe2e205816f5f00c22fd1fbf343d4d18c3d5ceac2f5"},
{file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998"},
{file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e052b8467dd07d4943936009f46ae5ce7b908ddcac3fda581656b1b19c083d9b"},
{file = "websockets-11.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:42cc5452a54a8e46a032521d7365da775823e21bfba2895fb7b77633cce031bb"},
{file = "websockets-11.0.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e6316827e3e79b7b8e7d8e3b08f4e331af91a48e794d5d8b099928b6f0b85f20"},
{file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8531fdcad636d82c517b26a448dcfe62f720e1922b33c81ce695d0edb91eb931"},
{file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c114e8da9b475739dde229fd3bc6b05a6537a88a578358bc8eb29b4030fac9c9"},
{file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e063b1865974611313a3849d43f2c3f5368093691349cf3c7c8f8f75ad7cb280"},
{file = "websockets-11.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:92b2065d642bf8c0a82d59e59053dd2fdde64d4ed44efe4870fa816c1232647b"},
{file = "websockets-11.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0ee68fe502f9031f19d495dae2c268830df2760c0524cbac5d759921ba8c8e82"},
{file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcacf2c7a6c3a84e720d1bb2b543c675bf6c40e460300b628bab1b1efc7c034c"},
{file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b67c6f5e5a401fc56394f191f00f9b3811fe843ee93f4a70df3c389d1adf857d"},
{file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d5023a4b6a5b183dc838808087033ec5df77580485fc533e7dab2567851b0a4"},
{file = "websockets-11.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ed058398f55163a79bb9f06a90ef9ccc063b204bb346c4de78efc5d15abfe602"},
{file = "websockets-11.0.3-py3-none-any.whl", hash = "sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6"},
{file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"},
{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-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"},
{file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"},
{file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"},
{file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"},
{file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"},
{file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"},
{file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"},
{file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"},
{file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"},
{file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"},
{file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"},
{file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
]
[[package]]
name = "werkzeug"
version = "3.0.1"
requires_python = ">=3.8"
summary = "The comprehensive WSGI web application library."
dependencies = [
"MarkupSafe>=2.1.1",
]
files = [
{file = "werkzeug-3.0.1-py3-none-any.whl", hash = "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10"},
{file = "werkzeug-3.0.1.tar.gz", hash = "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc"},
]
[[package]]
@@ -595,18 +831,20 @@ files = [
[[package]]
name = "yt-dlp"
version = "2023.10.13"
requires_python = ">=3.7"
summary = "A youtube-dl fork with additional features and patches"
version = "2024.6.17.232743.dev0"
requires_python = ">=3.8"
summary = "A feature-rich command-line audio/video downloader"
dependencies = [
"brotli; platform_python_implementation == \"CPython\"",
"brotlicffi; platform_python_implementation != \"CPython\"",
"brotli; implementation_name == \"cpython\"",
"brotlicffi; implementation_name != \"cpython\"",
"certifi",
"mutagen",
"pycryptodomex",
"websockets",
"requests<3,>=2.32.2",
"urllib3<3,>=1.26.17",
"websockets>=12.0",
]
files = [
{file = "yt-dlp-2023.10.13.tar.gz", hash = "sha256:e026ea1c435ff36eef1215bc4c5bb8c479938b90054997ba99f63a4541fe63b4"},
{file = "yt_dlp-2023.10.13-py2.py3-none-any.whl", hash = "sha256:2b069f22675532eebacdfd6372b1825651a751fef848de9ae6efe6491b2dc38a"},
{file = "yt_dlp-2024.6.17.232743.dev0-py3-none-any.whl", hash = "sha256:dd6e7e194b96e778691f58a0cb6b42956cf956b22f6bb1a12bdef5ab3ac0c9ad"},
{file = "yt_dlp-2024.6.17.232743.dev0.tar.gz", hash = "sha256:2f6f44eff755a7b051cdcd3c4375771033dbeb64d6164351022efdc67cce0c52"},
]

View File

@@ -1,17 +1,19 @@
[project]
name = "xiaomusic"
version = "0.1.3"
version = "0.1.68"
description = "Play Music with xiaomi AI speaker"
authors = [
{name = "涵曦", email = "im.hanxi@gmail.com"},
]
dependencies = [
"rich>=13.6.0",
"requests>=2.31.0",
"aiohttp>=3.8.6",
"miservice-fork>=2.2.1",
"miservice-fork>=2.5.0",
"mutagen>=1.47.0",
"yt-dlp>=2023.10.13",
"yt-dlp>=2024.04.09",
"flask[async]>=3.0.1",
"waitress>=3.0.0",
"flask-HTTPAuth>=4.8.0",
]
requires-python = ">=3.10"
readme = "README.md"
@@ -20,3 +22,31 @@ license = {text = "MIT"}
[build-system]
requires = ["pdm-backend"]
build-backend = "pdm.backend"
[tool.pdm]
[tool.pdm.dev-dependencies]
lint = [
"ruff>=0.4.8",
]
[tool.ruff]
lint.select = [
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"E", # pycodestyle - Error
"F", # Pyflakes
"I", # isort
"W", # pycodestyle - Warning
"UP", # pyupgrade
]
lint.ignore = [
"E501", # line-too-long
"W191", # tab-indentation
]
include = ["**/*.py", "**/*.pyi", "**/pyproject.toml"]
[tool.ruff.lint.pydocstyle]
convention = "google"
[tool.pdm.scripts]
lint = "ruff check ."
fmt = "ruff format ."

View File

@@ -1,48 +1,69 @@
# This file is @generated by PDM.
# Please do not edit it manually.
aiohttp==3.8.6 \
--hash=sha256:0fa375b3d34e71ccccf172cab401cd94a72de7a8cc01847a7b3386204093bb47 \
--hash=sha256:14cd52ccf40006c7a6cd34a0f8663734e5363fd981807173faf3a017e202fec9 \
--hash=sha256:16d330b3b9db87c3883e565340d292638a878236418b23cc8b9b11a054aaa887 \
--hash=sha256:1bed815f3dc3d915c5c1e556c397c8667826fbc1b935d95b0ad680787896a358 \
--hash=sha256:1d84166673694841d8953f0a8d0c90e1087739d24632fe86b1a08819168b4566 \
--hash=sha256:253bf92b744b3170eb4c4ca2fa58f9c4b87aeb1df42f71d4e78815e6e8b73c9e \
--hash=sha256:2817b2f66ca82ee699acd90e05c95e79bbf1dc986abb62b61ec8aaf851e81c93 \
--hash=sha256:2d5b785c792802e7b275c420d84f3397668e9d49ab1cb52bd916b3b3ffcf09ad \
--hash=sha256:3b2ab182fc28e7a81f6c70bfbd829045d9480063f5ab06f6e601a3eddbbd49a0 \
--hash=sha256:3fd194939b1f764d6bb05490987bfe104287bbf51b8d862261ccf66f48fb4096 \
--hash=sha256:41bdc2ba359032e36c0e9de5a3bd00d6fb7ea558a6ce6b70acedf0da86458321 \
--hash=sha256:41d55fc043954cddbbd82503d9cc3f4814a40bcef30b3569bc7b5e34130718c1 \
--hash=sha256:42c89579f82e49db436b69c938ab3e1559e5a4409eb8639eb4143989bc390f2f \
--hash=sha256:6c5f938d199a6fdbdc10bbb9447496561c3a9a565b43be564648d81e1102ac22 \
--hash=sha256:6e2f9cc8e5328f829f6e1fb74a0a3a939b14e67e80832975e01929e320386b34 \
--hash=sha256:76b36b3124f0223903609944a3c8bf28a599b2cc0ce0be60b45211c8e9be97f8 \
--hash=sha256:7bc88fc494b1f0311d67f29fee6fd636606f4697e8cc793a2d912ac5b19aa38d \
--hash=sha256:8e31e9db1bee8b4f407b77fd2507337a0a80665ad7b6c749d08df595d88f1cf5 \
--hash=sha256:93c15c8e48e5e7b89d5cb4613479d144fda8344e2d886cf694fd36db4cc86865 \
--hash=sha256:96603a562b546632441926cd1293cfcb5b69f0b4159e6077f7c7dbdfb686af4d \
--hash=sha256:9de50a199b7710fa2904be5a4a9b51af587ab24c8e540a7243ab737b45844543 \
--hash=sha256:a2ece4af1f3c967a4390c284797ab595a9f1bc1130ef8b01828915a05a6ae684 \
--hash=sha256:ad1407db8f2f49329729564f71685557157bfa42b48f4b93e53721a16eb813ed \
--hash=sha256:b0cf2a4501bff9330a8a5248b4ce951851e415bdcce9dc158e76cfd55e15085c \
--hash=sha256:ccc360e87341ad47c777f5723f68adbb52b37ab450c8bc3ca9ca1f3e849e5fe2 \
--hash=sha256:d76e8b13161a202d14c9584590c4df4d068c9567c99506497bdd67eaedf36403 \
--hash=sha256:e1d8cb0b56b3587c5c01de3bf2f600f186da7e7b5f7353d1bf26a8ddca57f965 \
--hash=sha256:e3f1e3f1a1751bb62b4a1b7f4e435afcdade6c17a4fd9b9d43607cebd242924a \
--hash=sha256:e6a00ffcc173e765e200ceefb06399ba09c06db97f401f920513a10c803604ca \
--hash=sha256:ec00c3305788e04bf6d29d42e504560e159ccaf0be30c09203b468a6c1ccd3b2 \
--hash=sha256:efd2fcf7e7b9d7ab16e6b7d54205beded0a9c8566cb30f09c1abe42b4e22bdcb
aiohttp==3.9.5 \
--hash=sha256:0a158704edf0abcac8ac371fbb54044f3270bdbc93e254a82b6c82be1ef08f3c \
--hash=sha256:18f634d540dd099c262e9f887c8bbacc959847cfe5da7a0e2e1cf3f14dbf2daf \
--hash=sha256:2faa61a904b83142747fc6a6d7ad8fccff898c849123030f8e75d5d967fd4a81 \
--hash=sha256:320e8618eda64e19d11bdb3bd04ccc0a816c17eaecb7e4945d01deee2a22f95f \
--hash=sha256:393c7aba2b55559ef7ab791c94b44f7482a07bf7640d17b341b79081f5e5cd1a \
--hash=sha256:4715a9b778f4293b9f8ae7a0a7cef9829f02ff8d6277a39d7f40565c737d3771 \
--hash=sha256:471f0ef53ccedec9995287f02caf0c068732f026455f07db3f01a46e49d76bbb \
--hash=sha256:4d3ebb9e1316ec74277d19c5f482f98cc65a73ccd5430540d6d11682cd857430 \
--hash=sha256:4ff550491f5492ab5ed3533e76b8567f4b37bd2995e780a1f46bca2024223233 \
--hash=sha256:55b39c8684a46e56ef8c8d24faf02de4a2b2ac60d26cee93bc595651ff545de9 \
--hash=sha256:5a7ee16aab26e76add4afc45e8f8206c95d1d75540f1039b84a03c3b3800dd59 \
--hash=sha256:5ca51eadbd67045396bc92a4345d1790b7301c14d1848feaac1d6a6c9289e888 \
--hash=sha256:5d6b3f1fabe465e819aed2c421a6743d8debbde79b6a8600739300630a01bf2c \
--hash=sha256:60cdbd56f4cad9f69c35eaac0fbbdf1f77b0ff9456cebd4902f3dd1cf096464c \
--hash=sha256:639d0042b7670222f33b0028de6b4e2fad6451462ce7df2af8aee37dcac55424 \
--hash=sha256:66331d00fb28dc90aa606d9a54304af76b335ae204d1836f65797d6fe27f1ca2 \
--hash=sha256:67c3119f5ddc7261d47163ed86d760ddf0e625cd6246b4ed852e82159617b5fb \
--hash=sha256:6ae79c1bc12c34082d92bf9422764f799aee4746fd7a392db46b7fd357d4a17a \
--hash=sha256:702e2c7c187c1a498a4e2b03155d52658fdd6fda882d3d7fbb891a5cf108bb10 \
--hash=sha256:714d4e5231fed4ba2762ed489b4aec07b2b9953cf4ee31e9871caac895a839c0 \
--hash=sha256:82a6a97d9771cb48ae16979c3a3a9a18b600a8505b1115cfe354dfb2054468b4 \
--hash=sha256:84dabd95154f43a2ea80deffec9cb44d2e301e38a0c9d331cc4aa0166fe28ae3 \
--hash=sha256:8676e8fd73141ded15ea586de0b7cda1542960a7b9ad89b2b06428e97125d4fa \
--hash=sha256:88e311d98cc0bf45b62fc46c66753a83445f5ab20038bcc1b8a1cc05666f428a \
--hash=sha256:8c64a6dc3fe5db7b1b4d2b5cb84c4f677768bdc340611eca673afb7cf416ef5a \
--hash=sha256:93e22add827447d2e26d67c9ac0161756007f152fdc5210277d00a85f6c92323 \
--hash=sha256:a81b1143d42b66ffc40a441379387076243ef7b51019204fd3ec36b9f69e77d6 \
--hash=sha256:ad7f2919d7dac062f24d6f5fe95d401597fbb015a25771f85e692d043c9d7832 \
--hash=sha256:afc52b8d969eff14e069a710057d15ab9ac17cd4b6753042c407dcea0e40bf75 \
--hash=sha256:b3df71da99c98534be076196791adca8819761f0bf6e08e07fd7da25127150d6 \
--hash=sha256:c088c4d70d21f8ca5c0b8b5403fe84a7bc8e024161febdd4ef04575ef35d474d \
--hash=sha256:c26959ca7b75ff768e2776d8055bf9582a6267e24556bb7f7bd29e677932be72 \
--hash=sha256:c413016880e03e69d166efb5a1a95d40f83d5a3a648d16486592c49ffb76d0db \
--hash=sha256:c671dc117c2c21a1ca10c116cfcd6e3e44da7fcde37bf83b2be485ab377b25da \
--hash=sha256:c7a4b7a6cf5b6eb11e109a9755fd4fda7d57395f8c575e166d363b9fc3ec4678 \
--hash=sha256:c8a02fbeca6f63cb1f0475c799679057fc9268b77075ab7cf3f1c600e81dd46b \
--hash=sha256:d153f652a687a8e95ad367a86a61e8d53d528b0530ef382ec5aaf533140ed00f \
--hash=sha256:da00da442a0e31f1c69d26d224e1efd3a1ca5bcbf210978a2ca7426dfcae9f58 \
--hash=sha256:e0ae53e33ee7476dd3d1132f932eeb39bf6125083820049d06edcdca4381f342 \
--hash=sha256:e7a6a8354f1b62e15d48e04350f13e726fa08b62c3d7b8401c0a1314f02e3558 \
--hash=sha256:edea7d15772ceeb29db4aff55e482d4bcfb6ae160ce144f2682de02f6d693551 \
--hash=sha256:f22eb3a6c1080d862befa0a89c380b4dafce29dc6cd56083f630073d102eb595 \
--hash=sha256:f26383adb94da5e7fb388d441bf09c61e5e35f455a3217bfd790c6b6bc64b2ee \
--hash=sha256:f64fd07515dad67f24b6ea4a66ae2876c01031de91c93075b8093f07c0a2d93d \
--hash=sha256:fcde4c397f673fdec23e6b05ebf8d4751314fa7c24f93334bf1f1364c1c69ac7 \
--hash=sha256:ff84aeb864e0fac81f676be9f4685f0527b660f1efdc40dcede3c251ef1e867f
aiosignal==1.3.1 \
--hash=sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc \
--hash=sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17
async-timeout==4.0.3 \
asgiref==3.7.2 \
--hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \
--hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed
async-timeout==4.0.3; python_version < "3.11" \
--hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \
--hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028
attrs==23.1.0 \
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
brotli==1.1.0 \
blinker==1.7.0 \
--hash=sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9 \
--hash=sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182
brotli==1.1.0; implementation_name == "cpython" \
--hash=sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128 \
--hash=sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9 \
--hash=sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3 \
@@ -80,9 +101,71 @@ brotli==1.1.0 \
--hash=sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80 \
--hash=sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0 \
--hash=sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e
brotlicffi==1.1.0.0; implementation_name != "cpython" \
--hash=sha256:19ffc919fa4fc6ace69286e0a23b3789b4219058313cf9b45625016bf7ff996b \
--hash=sha256:1a807d760763e398bbf2c6394ae9da5815901aa93ee0a37bca5efe78d4ee3171 \
--hash=sha256:1b12b50e07c3911e1efa3a8971543e7648100713d4e0971b13631cce22c587eb \
--hash=sha256:246f1d1a90279bb6069de3de8d75a8856e073b8ff0b09dcca18ccc14cec85979 \
--hash=sha256:2a7ae37e5d79c5bdfb5b4b99f2715a6035e6c5bf538c3746abc8e26694f92f33 \
--hash=sha256:2e4aeb0bd2540cb91b069dbdd54d458da8c4334ceaf2d25df2f4af576d6766ca \
--hash=sha256:2f3711be9290f0453de8eed5275d93d286abe26b08ab4a35d7452caa1fef532f \
--hash=sha256:37c26ecb14386a44b118ce36e546ce307f4810bc9598a6e6cb4f7fca725ae7e6 \
--hash=sha256:391151ec86bb1c683835980f4816272a87eaddc46bb91cbf44f62228b84d8cca \
--hash=sha256:3de0cf28a53a3238b252aca9fed1593e9d36c1d116748013339f0949bfc84112 \
--hash=sha256:4b7b0033b0d37bb33009fb2fef73310e432e76f688af76c156b3594389d81391 \
--hash=sha256:54a07bb2374a1eba8ebb52b6fafffa2afd3c4df85ddd38fcc0511f2bb387c2a8 \
--hash=sha256:6be5ec0e88a4925c91f3dea2bb0013b3a2accda6f77238f76a34a1ea532a1cb0 \
--hash=sha256:7901a7dc4b88f1c1475de59ae9be59799db1007b7d059817948d8e4f12e24e35 \
--hash=sha256:84763dbdef5dd5c24b75597a77e1b30c66604725707565188ba54bab4f114820 \
--hash=sha256:8557a8559509b61e65083f8782329188a250102372576093c88930c875a69838 \
--hash=sha256:994a4f0681bb6c6c3b0925530a1926b7a189d878e6e5e38fae8efa47c5d9c613 \
--hash=sha256:9b6068e0f3769992d6b622a1cd2e7835eae3cf8d9da123d7f51ca9c1e9c333e5 \
--hash=sha256:9b7ae6bd1a3f0df532b6d67ff674099a96d22bc0948955cb338488c31bfb8851 \
--hash=sha256:9feb210d932ffe7798ee62e6145d3a757eb6233aa9a4e7db78dd3690d7755814 \
--hash=sha256:add0de5b9ad9e9aa293c3aa4e9deb2b61e99ad6c1634e01d01d98c03e6a354cc \
--hash=sha256:b77827a689905143f87915310b93b273ab17888fd43ef350d4832c4a71083c13 \
--hash=sha256:ca72968ae4eaf6470498d5c2887073f7efe3b1e7d7ec8be11a06a79cc810e990 \
--hash=sha256:cc4bc5d82bc56ebd8b514fb8350cfac4627d6b0743382e46d033976a5f80fab6 \
--hash=sha256:ce01c7316aebc7fce59da734286148b1d1b9455f89cf2c8a4dfce7d41db55c2d \
--hash=sha256:d9eb71bb1085d996244439154387266fd23d6ad37161f6f52f1cd41dd95a3808 \
--hash=sha256:fa8ca0623b26c94fccc3a1fdd895be1743b838f3917300506d04aa3346fd2a14
certifi==2023.7.22 \
--hash=sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082 \
--hash=sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9
cffi==1.16.0; implementation_name != "cpython" \
--hash=sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417 \
--hash=sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab \
--hash=sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520 \
--hash=sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743 \
--hash=sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684 \
--hash=sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56 \
--hash=sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d \
--hash=sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235 \
--hash=sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e \
--hash=sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088 \
--hash=sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7 \
--hash=sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e \
--hash=sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673 \
--hash=sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2 \
--hash=sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a \
--hash=sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896 \
--hash=sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e \
--hash=sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9 \
--hash=sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b \
--hash=sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6 \
--hash=sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404 \
--hash=sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0 \
--hash=sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc \
--hash=sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936 \
--hash=sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba \
--hash=sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb \
--hash=sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614 \
--hash=sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1 \
--hash=sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d \
--hash=sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969 \
--hash=sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627 \
--hash=sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956 \
--hash=sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357
charset-normalizer==3.3.0 \
--hash=sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786 \
--hash=sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e \
@@ -131,6 +214,18 @@ charset-normalizer==3.3.0 \
--hash=sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293 \
--hash=sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e \
--hash=sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e
click==8.1.7 \
--hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \
--hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de
colorama==0.4.6; platform_system == "Windows" \
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
flask==3.0.3 \
--hash=sha256:34e815dfaa43340d1d15a5c3a02b8476004037eb4840b34910c6e21679d288f3 \
--hash=sha256:ceb27b0af3823ea2737928a4d99d125a06175b8512c445cbd9a9ce200ef76842
flask-HTTPAuth==4.8.0 \
--hash=sha256:66568a05bc73942c65f1e2201ae746295816dc009edd84b482c44c758d75097a \
--hash=sha256:a58fedd09989b9975448eef04806b096a3964a7feeebc0a78831ff55685b62b0
frozenlist==1.4.0 \
--hash=sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01 \
--hash=sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251 \
@@ -166,15 +261,53 @@ frozenlist==1.4.0 \
idna==3.4 \
--hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \
--hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
itsdangerous==2.1.2 \
--hash=sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44 \
--hash=sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a
Jinja2==3.1.3 \
--hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \
--hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90
markdown-it-py==3.0.0 \
--hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \
--hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb
MarkupSafe==2.1.4 \
--hash=sha256:0042d6a9880b38e1dd9ff83146cc3c9c18a059b9360ceae207805567aacccc69 \
--hash=sha256:0c26f67b3fe27302d3a412b85ef696792c4a2386293c53ba683a89562f9399b0 \
--hash=sha256:0fbad3d346df8f9d72622ac71b69565e621ada2ce6572f37c2eae8dacd60385d \
--hash=sha256:31f57d64c336b8ccb1966d156932f3daa4fee74176b0fdc48ef580be774aae74 \
--hash=sha256:396549cea79e8ca4ba65525470d534e8a41070e6b3500ce2414921099cb73e8d \
--hash=sha256:3aae9af4cac263007fd6309c64c6ab4506dd2b79382d9d19a1994f9240b8db4f \
--hash=sha256:3ab3a886a237f6e9c9f4f7d272067e712cdb4efa774bef494dccad08f39d8ae6 \
--hash=sha256:5045e892cfdaecc5b4c01822f353cf2c8feb88a6ec1c0adef2a2e705eef0f656 \
--hash=sha256:5244324676254697fe5c181fc762284e2c5fceeb1c4e3e7f6aca2b6f107e60dc \
--hash=sha256:54a7e1380dfece8847c71bf7e33da5d084e9b889c75eca19100ef98027bd9f56 \
--hash=sha256:55d03fea4c4e9fd0ad75dc2e7e2b6757b80c152c032ea1d1de487461d8140efc \
--hash=sha256:78bc995e004681246e85e28e068111a4c3f35f34e6c62da1471e844ee1446250 \
--hash=sha256:987d13fe1d23e12a66ca2073b8d2e2a75cec2ecb8eab43ff5624ba0ad42764bc \
--hash=sha256:9e9e3c4020aa2dc62d5dd6743a69e399ce3de58320522948af6140ac959ab863 \
--hash=sha256:a0b838c37ba596fcbfca71651a104a611543077156cb0a26fe0c475e1f152ee8 \
--hash=sha256:a4d176cfdfde84f732c4a53109b293d05883e952bbba68b857ae446fa3119b4f \
--hash=sha256:a76055d5cb1c23485d7ddae533229039b850db711c554a12ea64a0fd8a0129e2 \
--hash=sha256:a76cd37d229fc385738bd1ce4cba2a121cf26b53864c1772694ad0ad348e509e \
--hash=sha256:a7cc49ef48a3c7a0005a949f3c04f8baa5409d3f663a1b36f0eba9bfe2a0396e \
--hash=sha256:abf5ebbec056817057bfafc0445916bb688a255a5146f900445d081db08cbabb \
--hash=sha256:b83041cda633871572f0d3c41dddd5582ad7d22f65a72eacd8d3d6d00291df26 \
--hash=sha256:c669391319973e49a7c6230c218a1e3044710bc1ce4c8e6eb71f7e6d43a2c131 \
--hash=sha256:d5291d98cd3ad9a562883468c690a2a238c4a6388ab3bd155b0c75dd55ece858 \
--hash=sha256:dac1ebf6983148b45b5fa48593950f90ed6d1d26300604f321c74a9ca1609f8e \
--hash=sha256:de8153a7aae3835484ac168a9a9bdaa0c5eee4e0bc595503c95d53b942879c84 \
--hash=sha256:e1a0d1924a5013d4f294087e00024ad25668234569289650929ab871231668e7 \
--hash=sha256:e7902211afd0af05fbadcc9a312e4cf10f27b779cf1323e78d52377ae4b72bea \
--hash=sha256:e888ff76ceb39601c59e219f281466c6d7e66bd375b4ec1ce83bcdc68306796b \
--hash=sha256:f06e5a9e99b7df44640767842f414ed5d7bedaaa78cd817ce04bbd6fd86e2dd6 \
--hash=sha256:f6be2d708a9d0e9b0054856f07ac7070fbe1754be40ca8525d5adccdbda8f475 \
--hash=sha256:f9917691f410a2e0897d1ef99619fd3f7dd503647c8ff2475bf90c3cf222ad74
mdurl==0.1.2 \
--hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \
--hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba
miservice-fork==2.2.1 \
--hash=sha256:cf8f3e30b3008de29a69d9a8293cca8428e670ae10a0f791840428ee947fc27e \
--hash=sha256:f3f742ccd7cb4a1ed22cfdf95da14f791eff0c6c3a54032dcfe445ae540664df
miservice-fork==2.5.0 \
--hash=sha256:8ca2d370d5b32f7e330add38aa1912d734aefa7880f16cef9eac110a5a3029e2 \
--hash=sha256:97b6360ea53c34fe035ac9d94e8705f305b8fa7fc2b44a7aea182449a76cb622
multidict==6.0.4 \
--hash=sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9 \
--hash=sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8 \
@@ -210,6 +343,9 @@ multidict==6.0.4 \
mutagen==1.47.0 \
--hash=sha256:719fadef0a978c31b4cf3c956261b3c58b6948b32023078a2117b1de09f0fc99 \
--hash=sha256:edd96f50c5907a9539d8e5bba7245f62c9f520aef333d13392a79a4f70aca719
pycparser==2.21; implementation_name != "cpython" \
--hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \
--hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206
pycryptodomex==3.19.0 \
--hash=sha256:09c9401dc06fb3d94cb1ec23b4ea067a25d1f4c6b7b118ff5631d0b5daaab3cc \
--hash=sha256:0b2f1982c5bc311f0aab8c293524b861b485d76f7c9ab2c3ac9a25b6f7655975 \
@@ -235,55 +371,75 @@ pycryptodomex==3.19.0 \
pygments==2.16.1 \
--hash=sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692 \
--hash=sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29
requests==2.31.0 \
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
--hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1
rich==13.6.0 \
--hash=sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245 \
--hash=sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef
requests==2.32.3 \
--hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \
--hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6
rich==13.7.1 \
--hash=sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222 \
--hash=sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432
typing-extensions==4.9.0; python_version < "3.11" \
--hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \
--hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd
urllib3==2.0.6 \
--hash=sha256:7a7c7003b000adf9e7ca2a377c9688bbc54ed41b985789ed576570342a375cd2 \
--hash=sha256:b19e1a85d206b56d7df1d5e683df4a7725252a964e3993648dd0fb5a1c157564
websockets==11.0.3 \
--hash=sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd \
--hash=sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998 \
--hash=sha256:0ee68fe502f9031f19d495dae2c268830df2760c0524cbac5d759921ba8c8e82 \
--hash=sha256:1d2256283fa4b7f4c7d7d3e84dc2ece74d341bce57d5b9bf385df109c2a1a82f \
--hash=sha256:1d5023a4b6a5b183dc838808087033ec5df77580485fc533e7dab2567851b0a4 \
--hash=sha256:2d903ad4419f5b472de90cd2d40384573b25da71e33519a67797de17ef849b69 \
--hash=sha256:3ccc8a0c387629aec40f2fc9fdcb4b9d5431954f934da3eaf16cdc94f67dbfac \
--hash=sha256:41f696ba95cd92dc047e46b41b26dd24518384749ed0d99bea0a941ca87404c4 \
--hash=sha256:42cc5452a54a8e46a032521d7365da775823e21bfba2895fb7b77633cce031bb \
--hash=sha256:54c6e5b3d3a8936a4ab6870d46bdd6ec500ad62bde9e44462c32d18f1e9a8e54 \
--hash=sha256:619d9f06372b3a42bc29d0cd0354c9bb9fb39c2cbc1a9c5025b4538738dbffaf \
--hash=sha256:660e2d9068d2bedc0912af508f30bbeb505bbbf9774d98def45f68278cea20d3 \
--hash=sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6 \
--hash=sha256:7622a89d696fc87af8e8d280d9b421db5133ef5b29d3f7a1ce9f1a7bf7fcfa11 \
--hash=sha256:84d27a4832cc1a0ee07cdcf2b0629a8a72db73f4cf6de6f0904f6661227f256f \
--hash=sha256:8531fdcad636d82c517b26a448dcfe62f720e1922b33c81ce695d0edb91eb931 \
--hash=sha256:86d2a77fd490ae3ff6fae1c6ceaecad063d3cc2320b44377efdde79880e11526 \
--hash=sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016 \
--hash=sha256:92b2065d642bf8c0a82d59e59053dd2fdde64d4ed44efe4870fa816c1232647b \
--hash=sha256:aa5003845cdd21ac0dc6c9bf661c5beddd01116f6eb9eb3c8e272353d45b3288 \
--hash=sha256:b30c6590146e53149f04e85a6e4fcae068df4289e31e4aee1fdf56a0dead8f97 \
--hash=sha256:b58cbf0697721120866820b89f93659abc31c1e876bf20d0b3d03cef14faf84d \
--hash=sha256:b67c6f5e5a401fc56394f191f00f9b3811fe843ee93f4a70df3c389d1adf857d \
--hash=sha256:bceab846bac555aff6427d060f2fcfff71042dba6f5fca7dc4f75cac815e57ca \
--hash=sha256:c114e8da9b475739dde229fd3bc6b05a6537a88a578358bc8eb29b4030fac9c9 \
--hash=sha256:c1f0524f203e3bd35149f12157438f406eff2e4fb30f71221c8a5eceb3617b6b \
--hash=sha256:d67ac60a307f760c6e65dad586f556dde58e683fab03323221a4e530ead6f74d \
--hash=sha256:dcacf2c7a6c3a84e720d1bb2b543c675bf6c40e460300b628bab1b1efc7c034c \
--hash=sha256:de36fe9c02995c7e6ae6efe2e205816f5f00c22fd1fbf343d4d18c3d5ceac2f5 \
--hash=sha256:def07915168ac8f7853812cc593c71185a16216e9e4fa886358a17ed0fd9fcf6 \
--hash=sha256:e052b8467dd07d4943936009f46ae5ce7b908ddcac3fda581656b1b19c083d9b \
--hash=sha256:e063b1865974611313a3849d43f2c3f5368093691349cf3c7c8f8f75ad7cb280 \
--hash=sha256:e1459677e5d12be8bbc7584c35b992eea142911a6236a3278b9b5ce3326f282c \
--hash=sha256:e6316827e3e79b7b8e7d8e3b08f4e331af91a48e794d5d8b099928b6f0b85f20 \
--hash=sha256:e7837cb169eca3b3ae94cc5787c4fed99eef74c0ab9506756eea335e0d6f3ed8 \
--hash=sha256:e848f46a58b9fcf3d06061d17be388caf70ea5b8cc3466251963c8345e13f7eb \
--hash=sha256:ed058398f55163a79bb9f06a90ef9ccc063b204bb346c4de78efc5d15abfe602 \
--hash=sha256:f2e58f2c36cc52d41f2659e4c0cbf7353e28c8c9e63e30d8c6d3494dc9fdedcf \
--hash=sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564
waitress==3.0.0 \
--hash=sha256:005da479b04134cdd9dd602d1ee7c49d79de0537610d653674cc6cbde222b8a1 \
--hash=sha256:2a06f242f4ba0cc563444ca3d1998959447477363a2d7e9b8b4d75d35cfd1669
websockets==12.0 \
--hash=sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b \
--hash=sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6 \
--hash=sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df \
--hash=sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b \
--hash=sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2 \
--hash=sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed \
--hash=sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd \
--hash=sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b \
--hash=sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931 \
--hash=sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30 \
--hash=sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370 \
--hash=sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be \
--hash=sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf \
--hash=sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b \
--hash=sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402 \
--hash=sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f \
--hash=sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123 \
--hash=sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603 \
--hash=sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45 \
--hash=sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558 \
--hash=sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4 \
--hash=sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480 \
--hash=sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447 \
--hash=sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8 \
--hash=sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04 \
--hash=sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c \
--hash=sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb \
--hash=sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b \
--hash=sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c \
--hash=sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92 \
--hash=sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113 \
--hash=sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f \
--hash=sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468 \
--hash=sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611 \
--hash=sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d \
--hash=sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca \
--hash=sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f \
--hash=sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2 \
--hash=sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077 \
--hash=sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2 \
--hash=sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374 \
--hash=sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc \
--hash=sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e \
--hash=sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53 \
--hash=sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399 \
--hash=sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547 \
--hash=sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3 \
--hash=sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870 \
--hash=sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5 \
--hash=sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7
Werkzeug==3.0.1 \
--hash=sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc \
--hash=sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10
yarl==1.9.2 \
--hash=sha256:04ab9d4b9f587c06d801c2abfe9317b77cdf996c65a90d5e84ecc45010823571 \
--hash=sha256:159d81f22d7a43e6eabc36d7194cb53f2f15f498dbbfa8edc8a3239350f59fe7 \
@@ -316,6 +472,6 @@ yarl==1.9.2 \
--hash=sha256:d4e2c6d555e77b37288eaf45b8f60f0737c9efa3452c6c44626a5455aeb250b9 \
--hash=sha256:e9fdc7ac0d42bc3ea78818557fab03af6181e076a2944f43c38684b4b6bed8e3 \
--hash=sha256:ee4afac41415d52d53a9833ebae7e32b344be72835bbb589018c9e938045a560
yt-dlp==2023.10.13 \
--hash=sha256:2b069f22675532eebacdfd6372b1825651a751fef848de9ae6efe6491b2dc38a \
--hash=sha256:e026ea1c435ff36eef1215bc4c5bb8c479938b90054997ba99f63a4541fe63b4
yt-dlp==2024.6.17.232743.dev0 \
--hash=sha256:2f6f44eff755a7b051cdcd3c4375771033dbeb64d6164351022efdc67cce0c52 \
--hash=sha256:dd6e7e194b96e778691f58a0cb6b42956cf956b22f6bb1a12bdef5ab3ac0c9ad

1
update-requirements.sh Normal file
View File

@@ -0,0 +1 @@
pdm export --prod -o requirements.txt

View File

@@ -0,0 +1 @@
__version__ = "0.1.68"

View File

@@ -27,20 +27,6 @@ def main():
dest="cookie",
help="xiaomi cookie",
)
parser.add_argument(
"--use_command",
dest="use_command",
action="store_true",
default=None,
help="use command to tts",
)
parser.add_argument(
"--mute_xiaoai",
dest="mute_xiaoai",
action="store_true",
default=None,
help="try to mute xiaoai answer",
)
parser.add_argument(
"--verbose",
dest="verbose",
@@ -53,6 +39,11 @@ def main():
dest="config",
help="config file path",
)
parser.add_argument(
"--ffmpeg_location",
dest="ffmpeg_location",
help="ffmpeg bin path",
)
options = parser.parse_args()
config = Config.from_options(options)

View File

@@ -3,73 +3,94 @@ from __future__ import annotations
import argparse
import json
import os
from dataclasses import dataclass, field
from typing import Any, Iterable
from dataclasses import dataclass
from xiaomusic.utils import validate_proxy
LATEST_ASK_API = "https://userprofile.mina.mi.com/device_profile/v2/conversation?source=dialogu&hardware={hardware}&timestamp={timestamp}&limit=2"
COOKIE_TEMPLATE = "deviceId={device_id}; serviceToken={service_token}; userId={user_id}"
HARDWARE_COMMAND_DICT = {
# hardware: (tts_command, wakeup_command)
"LX06": ("5-1", "5-5"),
"L05B": ("5-3", "5-4"),
"S12A": ("5-1", "5-5"),
"LX01": ("5-1", "5-5"),
"L06A": ("5-1", "5-5"),
"LX04": ("5-1", "5-4"),
"L05C": ("5-3", "5-4"),
"L17A": ("7-3", "7-4"),
"X08E": ("7-3", "7-4"),
"LX05A": ("5-1", "5-5"), # 小爱红外版
"LX5A": ("5-1", "5-5"), # 小爱红外版
"L07A": ("5-1", "5-5"), # Redmi小爱音箱Play(l7a)
"L15A": ("7-3", "7-4"),
"X6A": ("7-3", "7-4"), # 小米智能家庭屏6
"X10A": ("7-3", "7-4"), # 小米智能家庭屏10
# add more here
}
DEFAULT_COMMAND = ("5-1", "5-5")
KEY_WORD_DICT = {
"播放歌曲": "play",
"放歌曲": "play",
"下一首": "play_next",
"单曲循环":"set_play_type_one",
"全部循环":"set_play_type_all",
"关机":"stop",
"停止播放":"stop",
"单曲循环": "set_play_type_one",
"全部循环": "set_play_type_all",
"随机播放": "random_play",
"关机": "stop",
"停止播放": "stop",
"分钟后关机": "stop_after_minute",
"播放列表": "play_music_list",
"刷新列表": "gen_music_list",
"set_volume#": "set_volume",
"get_volume#": "get_volume",
}
# 命令参数在前面
KEY_WORD_ARG_BEFORE_DICT = {
"分钟后关机": True,
}
# 匹配优先级
KEY_MATCH_ORDER = [
"set_volume#",
"get_volume#",
"分钟后关机",
"播放歌曲",
"放歌曲",
"下一首",
"单曲循环",
"全部循环",
"随机播放",
"关机",
"停止播放",
"刷新列表",
"播放列表",
]
SUPPORT_MUSIC_TYPE = [
".mp3",
".flac",
".wav",
".ape",
]
@dataclass
class Config:
hardware: str = "L07A"
hardware: str = os.getenv("MI_HARDWARE", "L07A")
account: str = os.getenv("MI_USER", "")
password: str = os.getenv("MI_PASS", "")
mi_did: str = os.getenv("MI_DID", "")
mute_xiaoai: bool = True
cookie: str = ""
use_command: bool = True
verbose: bool = False
verbose: bool = os.getenv("XIAOMUSIC_VERBOSE", "").lower() == "true"
music_path: str = os.getenv("XIAOMUSIC_MUSIC_PATH", "music")
conf_path: str = os.getenv("XIAOMUSIC_CONF_PATH", None)
hostname: str = os.getenv("XIAOMUSIC_HOSTNAME", "192.168.2.5")
port: int = int(os.getenv("XIAOMUSIC_PORT", "8090"))
proxy: str = os.getenv("XIAOMUSIC_PROXY", "http://192.168.2.5:8080")
proxy: str | None = os.getenv("XIAOMUSIC_PROXY", None)
search_prefix: str = os.getenv(
"XIAOMUSIC_SEARCH", "ytsearch:"
) # "bilisearch:" or "ytsearch:"
ffmpeg_location: str = os.getenv("XIAOMUSIC_FFMPEG_LOCATION", "./ffmpeg/bin")
active_cmd: str = os.getenv("XIAOMUSIC_ACTIVE_CMD", "play,random_play")
exclude_dirs: str = os.getenv("XIAOMUSIC_EXCLUDE_DIRS", "@eaDir")
music_path_depth: int = int(os.getenv("XIAOMUSIC_MUSIC_PATH_DEPTH", "10"))
disable_httpauth: bool = (
os.getenv("XIAOMUSIC_DISABLE_HTTPAUTH", "true").lower() == "true"
)
httpauth_username: str = os.getenv("XIAOMUSIC_HTTPAUTH_USERNAME", "admin")
httpauth_password: str = os.getenv("XIAOMUSIC_HTTPAUTH_PASSWORD", "admin")
music_list_url: str = os.getenv("XIAOMUSIC_MUSIC_LIST_URL", "")
music_list_json: str = os.getenv("XIAOMUSIC_MUSIC_LIST_JSON", "")
disable_download: bool = (
os.getenv("XIAOMUSIC_DISABLE_DOWNLOAD", "false").lower() == "true"
)
def __post_init__(self) -> None:
if self.proxy:
validate_proxy(self.proxy)
@property
def tts_command(self) -> str:
return HARDWARE_COMMAND_DICT.get(self.hardware, DEFAULT_COMMAND)[0]
@property
def wakeup_command(self) -> str:
return HARDWARE_COMMAND_DICT.get(self.hardware, DEFAULT_COMMAND)[1]
@classmethod
def from_options(cls, options: argparse.Namespace) -> Config:
config = {}

194
xiaomusic/httpserver.py Normal file
View File

@@ -0,0 +1,194 @@
#!/usr/bin/env python3
import os
from threading import Thread
from flask import Flask, request, send_from_directory
from flask_httpauth import HTTPBasicAuth
from waitress import serve
from xiaomusic import (
__version__,
)
from xiaomusic.config import (
KEY_WORD_DICT,
)
from xiaomusic.utils import (
downloadfile,
)
app = Flask(__name__)
auth = HTTPBasicAuth()
host = "0.0.0.0"
port = 8090
static_path = "music"
xiaomusic = None
log = None
@auth.verify_password
def verify_password(username, password):
if xiaomusic.config.disable_httpauth:
return True
if (
xiaomusic.config.httpauth_username == username
and xiaomusic.config.httpauth_password == password
):
return username
@app.route("/allcmds")
@auth.login_required
def allcmds():
return KEY_WORD_DICT
@app.route("/getversion", methods=["GET"])
def getversion():
log.debug("getversion %s", __version__)
return {
"version": __version__,
}
@app.route("/getvolume", methods=["GET"])
@auth.login_required
def getvolume():
volume = xiaomusic.get_volume_ret()
return {
"volume": volume,
}
@app.route("/searchmusic", methods=["GET"])
@auth.login_required
def searchmusic():
name = request.args.get("name")
return xiaomusic.searchmusic(name)
@app.route("/playingmusic", methods=["GET"])
@auth.login_required
def playingmusic():
return xiaomusic.playingmusic()
@app.route("/isplaying", methods=["GET"])
@auth.login_required
def isplaying():
return xiaomusic.isplaying()
@app.route("/", methods=["GET"])
def index():
return send_from_directory("static", "index.html")
@app.route("/cmd", methods=["POST"])
@auth.login_required
async def do_cmd():
data = request.get_json()
cmd = data.get("cmd")
if len(cmd) > 0:
log.debug("docmd. cmd:%s", cmd)
xiaomusic.set_last_record(cmd)
return {"ret": "OK"}
return {"ret": "Unknow cmd"}
@app.route("/getsetting", methods=["GET"])
@auth.login_required
async def getsetting():
config = xiaomusic.getconfig()
log.debug(config)
alldevices = await xiaomusic.call_main_thread_function(xiaomusic.getalldevices)
log.info(alldevices)
data = {
"mi_did": config.mi_did,
"mi_did_list": alldevices["did_list"],
"mi_hardware": config.hardware,
"mi_hardware_list": alldevices["hardware_list"],
"xiaomusic_search": config.search_prefix,
"xiaomusic_proxy": config.proxy,
"xiaomusic_music_list_url": config.music_list_url,
"xiaomusic_music_list_json": config.music_list_json,
}
return data
@app.route("/savesetting", methods=["POST"])
@auth.login_required
async def savesetting():
data = request.get_json()
log.info(data)
await xiaomusic.saveconfig(data)
return "save success"
@app.route("/musiclist", methods=["GET"])
@auth.login_required
async def musiclist():
return xiaomusic.get_music_list()
@app.route("/curplaylist", methods=["GET"])
@auth.login_required
async def curplaylist():
return xiaomusic.get_cur_play_list()
@app.route("/delmusic", methods=["POST"])
@auth.login_required
def delmusic():
data = request.get_json()
log.info(data)
xiaomusic.del_music(data["name"])
return "success"
@app.route("/downloadjson", methods=["POST"])
@auth.login_required
def downloadjson():
data = request.get_json()
log.info(data)
url = data["url"]
retmsg, content = downloadfile(url)
ret = "OK"
if retmsg != "OK":
log.warning(f"downloadjson failed. url:{url} ret:{ret}")
ret = "Download JSON file failed."
return {
"ret": ret,
"content": content,
}
def static_path_handler(filename):
log.debug(filename)
log.debug(static_path)
absolute_path = os.path.abspath(static_path)
log.debug(absolute_path)
return send_from_directory(absolute_path, filename)
def run_app():
serve(app, host=host, port=port)
def StartHTTPServer(_port, _static_path, _xiaomusic):
global port, static_path, xiaomusic, log
port = _port
static_path = _static_path
xiaomusic = _xiaomusic
log = xiaomusic.log
app.add_url_rule(
f"/{static_path}/<path:filename>", "static_path_handler", static_path_handler
)
server_thread = Thread(target=run_app)
server_thread.daemon = True
server_thread.start()
xiaomusic.log.info(f"Serving on {host}:{port}")

186
xiaomusic/static/app.js Normal file
View File

@@ -0,0 +1,186 @@
$(function(){
$container=$("#cmds");
append_op_button_name("全部循环");
append_op_button_name("单曲循环");
append_op_button_name("随机播放");
append_op_button_name("刷新列表");
append_op_button_name("下一首");
append_op_button_name("关机");
$container.append($("<hr>"));
append_op_button_name("10分钟后关机");
append_op_button_name("30分钟后关机");
append_op_button_name("60分钟后关机");
// 拉取声音
sendcmd("get_volume#");
$.get("/getvolume", function(data, status) {
console.log(data, status, data["volume"]);
$("#volume").val(data.volume);
});
// 拉取版本
$.get("/getversion", function(data, status) {
console.log(data, status, data["version"]);
$("#version").text(`(${data.version})`);
});
// 拉取播放列表
function refresh_music_list() {
$('#music_list').empty();
$.get("/musiclist", function(data, status) {
console.log(data, status);
$.each(data, function(key, value) {
$('#music_list').append($('<option></option>').val(key).text(key));
});
$('#music_list').change(function() {
const selectedValue = $(this).val();
$('#music_name').empty();
const sorted_musics = data[selectedValue].sort(custom_sort_key);
$.each(sorted_musics, function(index, item) {
$('#music_name').append($('<option></option>').val(item).text(item));
});
});
$('#music_list').trigger('change');
// 获取当前播放列表
$.get("curplaylist", function(data, status) {
$('#music_list').val(data);
$('#music_list').trigger('change');
})
})
}
refresh_music_list();
$("#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);
});
$("#del_music").on("click", () => {
var del_music_name = $("#music_name").val();
if (confirm(`确定删除歌曲 ${del_music_name} 吗?`)) {
console.log(`删除歌曲 ${del_music_name}`);
$.ajax({
type: 'POST',
url: '/delmusic',
data: JSON.stringify({"name": del_music_name}),
contentType: "application/json; charset=utf-8",
success: () => {
alert(`删除 ${del_music_name} 成功`);
refresh_music_list();
},
error: () => {
alert(`删除 ${del_music_name} 失败`);
}
});
}
});
function append_op_button_name(name) {
append_op_button(name, name);
}
function append_op_button(name, cmd) {
// 创建按钮
const $button = $("<button>");
$button.text(name);
$button.attr("type", "button");
// 设置按钮点击事件
$button.on("click", () => {
sendcmd(cmd);
});
// 添加按钮到容器
$container.append($button);
}
$("#play").on("click", () => {
var search_key = $("#music-name").val();
var filename = $("#music-filename").val();
let cmd = "播放歌曲" + search_key + "|" + filename;
sendcmd(cmd);
});
$("#volume").on('input', function () {
var value = $(this).val();
sendcmd("set_volume#"+value);
});
function sendcmd(cmd) {
$.ajax({
type: "POST",
url: "/cmd",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({cmd: cmd}),
success: () => {
if (cmd == "刷新列表") {
setTimeout(refresh_music_list, 3000);
}
},
error: () => {
// 请求失败时执行的操作
}
});
}
// 监听输入框的输入事件
$("#music-name").on('input', function() {
var inputValue = $(this).val();
// 发送Ajax请求
$.ajax({
url: "searchmusic", // 服务器端处理脚本
type: "GET",
dataType: "json",
data: {
name: inputValue
},
success: function(data) {
// 清空datalist
$("#autocomplete-list").empty();
// 添加新的option元素
$.each(data, function(i, item) {
$('<option>').val(item).appendTo("#autocomplete-list");
});
}
});
});
function get_playing_music() {
$.get("/playingmusic", function(data, status) {
console.log(data);
$("#playering-music").text(data);
});
}
// 每3秒获取下正在播放的音乐
get_playing_music();
setInterval(() => {
get_playing_music();
}, 3000);
function custom_sort_key(a, b) {
// 使用正则表达式提取数字前缀
const numericPrefixA = a.match(/^(\d+)/) ? parseInt(a.match(/^(\d+)/)[1], 10) : null;
const numericPrefixB = b.match(/^(\d+)/) ? parseInt(b.match(/^(\d+)/)[1], 10) : null;
// 如果两个键都有数字前缀,则按数字大小排序
if (numericPrefixA !== null && numericPrefixB !== null) {
return numericPrefixA - numericPrefixB;
}
// 如果一个键有数字前缀而另一个没有,则有数字前缀的键排在前面
if (numericPrefixA !== null) return -1;
if (numericPrefixB !== null) return 1;
// 如果两个键都没有数字前缀,则按照常规字符串排序
return a.localeCompare(b);
}
});

View File

@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width">
<title>小爱音箱操控面板</title>
<script src="/static/jquery-3.7.1.min.js"></script>
<script src="/static/app.js"></script>
<link rel="stylesheet" type="text/css" href="/static/style.css">
</head>
<body>
<h2>小爱音箱操控面板<span id="version">(版本未知)</span></h2>
<hr>
<div id="cmds">
</div>
<hr>
<div style="margin: 20px;">
<div style="display: flex; align-items: center;">
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" fill="#8e43e7" style="height: 48px; width: 48px;"><path d="M550.826667 154.666667a47.786667 47.786667 0 0 0-19.84 4.48L298.666667 298.666667H186.453333A80 80 0 0 0 106.666667 378.453333v267.093334A80 80 0 0 0 186.453333 725.333333H298.666667l232.32 139.52a47.786667 47.786667 0 0 0 19.84 4.48A46.506667 46.506667 0 0 0 597.333333 822.826667V201.173333a46.506667 46.506667 0 0 0-46.506666-46.506666zM554.666667 822.826667c0 3.413333-3.84 3.84-3.84 3.84L320 688.853333l-9.6-6.186666H186.453333A37.12 37.12 0 0 1 149.333333 645.546667V378.453333A37.12 37.12 0 0 1 186.453333 341.333333h123.946667l10.24-6.186666 229.546667-137.6s3.84 0 3.84 3.84zM667.52 346.026667a21.333333 21.333333 0 0 0 0 30.293333 192 192 0 0 1 0 271.36 21.333333 21.333333 0 0 0 0 30.293333 21.333333 21.333333 0 0 0 30.293333 0 234.666667 234.666667 0 0 0 0-331.946666 21.333333 21.333333 0 0 0-30.293333 0z"></path><path d="M804.48 219.52a21.333333 21.333333 0 0 0-30.293333 30.293333 370.986667 370.986667 0 0 1 0 524.373334 21.333333 21.333333 0 0 0 0 30.293333 21.333333 21.333333 0 0 0 30.293333 0 414.08 414.08 0 0 0 0-584.96z"></path></svg>
<input id="volume" type="range"></input>
<a href="/static/setting.html">
<svg fill="#8e43e7" height="48px" width="48px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-11.88 -11.88 77.76 77.76" xml:space="preserve" stroke="#8e43e7" transform="rotate(0)matrix(1, 0, 0, 1, 0, 0)" stroke-width="0.00054"><g id="SVGRepo_bgCarrier" stroke-width="0" transform="translate(0,0), scale(1)"><rect x="-11.88" y="-11.88" width="77.76" height="77.76" rx="18.6624" fill="#addcff" strokewidth="0"></rect></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round" stroke="#CCCCCC" stroke-width="1.512"></g><g id="SVGRepo_iconCarrier"> <g> <path d="M51.22,21h-5.052c-0.812,0-1.481-0.447-1.792-1.197s-0.153-1.54,0.42-2.114l3.572-3.571 c0.525-0.525,0.814-1.224,0.814-1.966c0-0.743-0.289-1.441-0.814-1.967l-4.553-4.553c-1.05-1.05-2.881-1.052-3.933,0l-3.571,3.571 c-0.574,0.573-1.366,0.733-2.114,0.421C33.447,9.313,33,8.644,33,7.832V2.78C33,1.247,31.753,0,30.22,0H23.78 C22.247,0,21,1.247,21,2.78v5.052c0,0.812-0.447,1.481-1.197,1.792c-0.748,0.313-1.54,0.152-2.114-0.421l-3.571-3.571 c-1.052-1.052-2.883-1.05-3.933,0l-4.553,4.553c-0.525,0.525-0.814,1.224-0.814,1.967c0,0.742,0.289,1.44,0.814,1.966l3.572,3.571 c0.573,0.574,0.73,1.364,0.42,2.114S8.644,21,7.832,21H2.78C1.247,21,0,22.247,0,23.78v6.439C0,31.753,1.247,33,2.78,33h5.052 c0.812,0,1.481,0.447,1.792,1.197s0.153,1.54-0.42,2.114l-3.572,3.571c-0.525,0.525-0.814,1.224-0.814,1.966 c0,0.743,0.289,1.441,0.814,1.967l4.553,4.553c1.051,1.051,2.881,1.053,3.933,0l3.571-3.572c0.574-0.573,1.363-0.731,2.114-0.42 c0.75,0.311,1.197,0.98,1.197,1.792v5.052c0,1.533,1.247,2.78,2.78,2.78h6.439c1.533,0,2.78-1.247,2.78-2.78v-5.052 c0-0.812,0.447-1.481,1.197-1.792c0.751-0.312,1.54-0.153,2.114,0.42l3.571,3.572c1.052,1.052,2.883,1.05,3.933,0l4.553-4.553 c0.525-0.525,0.814-1.224,0.814-1.967c0-0.742-0.289-1.44-0.814-1.966l-3.572-3.571c-0.573-0.574-0.73-1.364-0.42-2.114 S45.356,33,46.168,33h5.052c1.533,0,2.78-1.247,2.78-2.78V23.78C54,22.247,52.753,21,51.22,21z M52,30.22 C52,30.65,51.65,31,51.22,31h-5.052c-1.624,0-3.019,0.932-3.64,2.432c-0.622,1.5-0.295,3.146,0.854,4.294l3.572,3.571 c0.305,0.305,0.305,0.8,0,1.104l-4.553,4.553c-0.304,0.304-0.799,0.306-1.104,0l-3.571-3.572c-1.149-1.149-2.794-1.474-4.294-0.854 c-1.5,0.621-2.432,2.016-2.432,3.64v5.052C31,51.65,30.65,52,30.22,52H23.78C23.35,52,23,51.65,23,51.22v-5.052 c0-1.624-0.932-3.019-2.432-3.64c-0.503-0.209-1.021-0.311-1.533-0.311c-1.014,0-1.997,0.4-2.761,1.164l-3.571,3.572 c-0.306,0.306-0.801,0.304-1.104,0l-4.553-4.553c-0.305-0.305-0.305-0.8,0-1.104l3.572-3.571c1.148-1.148,1.476-2.794,0.854-4.294 C10.851,31.932,9.456,31,7.832,31H2.78C2.35,31,2,30.65,2,30.22V23.78C2,23.35,2.35,23,2.78,23h5.052 c1.624,0,3.019-0.932,3.64-2.432c0.622-1.5,0.295-3.146-0.854-4.294l-3.572-3.571c-0.305-0.305-0.305-0.8,0-1.104l4.553-4.553 c0.304-0.305,0.799-0.305,1.104,0l3.571,3.571c1.147,1.147,2.792,1.476,4.294,0.854C22.068,10.851,23,9.456,23,7.832V2.78 C23,2.35,23.35,2,23.78,2h6.439C30.65,2,31,2.35,31,2.78v5.052c0,1.624,0.932,3.019,2.432,3.64 c1.502,0.622,3.146,0.294,4.294-0.854l3.571-3.571c0.306-0.305,0.801-0.305,1.104,0l4.553,4.553c0.305,0.305,0.305,0.8,0,1.104 l-3.572,3.571c-1.148,1.148-1.476,2.794-0.854,4.294c0.621,1.5,2.016,2.432,3.64,2.432h5.052C51.65,23,52,23.35,52,23.78V30.22z"></path> <path d="M27,18c-4.963,0-9,4.037-9,9s4.037,9,9,9s9-4.037,9-9S31.963,18,27,18z M27,34c-3.859,0-7-3.141-7-7s3.141-7,7-7 s7,3.141,7,7S30.859,34,27,34z"></path> </g> </g></svg>
</a>
</div>
</div>
<hr>
<div>
<datalist id="autocomplete-list"></datalist>
<input id="music-name" type="text" placeholder="请输入搜索关键词(如:MV高清版 周杰伦 七里香)" list="autocomplete-list"></input>
<input id="music-filename" type="text" placeholder="请输入保存为的文件名称(如:周杰伦七里香)"></input>
</div>
<button id="play">播放</button>
<div class="container">
<div id="playering-music" class="text"></div>
</div>
<hr>
<div class="rows">
<label for="music_list">播放列表:</label>
<select id="music_list"></select>
<label for="music_name">歌曲:</label>
<select id="music_name"></select>
</div>
<button id="play_music_list">播放列表歌曲</button>
<button id="del_music">删除选中歌曲</button>
<footer>
<p>Powered by <a href="https://github.com/hanxi/xiaomusic" target="_blank">xiaomusic</a></p>
</footer>
</body>
</html>

2
xiaomusic/static/jquery-3.7.1.min.js vendored Normal file

File diff suppressed because one or more lines are too long

63
xiaomusic/static/m3u.html Normal file
View File

@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>M3U to JSON Converter</title>
<link rel="stylesheet" type="text/css" href="/static/style.css">
<!--
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
<script>
// VConsole 默认会挂载到 `window.VConsole` 上
var vConsole = new window.VConsole();
</script>
-->
<script>
function handleFileSelect(evt) {
var file = evt.target.files[0];
if (file) {
var reader = new FileReader();
reader.onload = function(e) {
document.getElementById('m3u-input').value = e.target.result;
};
reader.readAsText(file);
} else {
alert('无法加载文件');
}
}
function convertToJSON() {
var m3uContent = document.getElementById('m3u-input').value;
var lines = m3uContent.split('\n');
console.log(lines);
var musicsArray = [];
var currentName = '';
lines.forEach(function(line) {
if (line.startsWith('#EXTINF:-1,')) {
currentName = line.substring(11).trim();
} else if (line.startsWith('http') && currentName !== '') {
musicsArray.push({"name": currentName, "type": "radio", "url": line.trim()});
currentName = ''; // Reset the name for the next entry
}
});
var output = [{
"name": "m3u电台",
"musics": musicsArray
}];
document.getElementById('json-output').value = JSON.stringify(output, null, 2);
}
</script>
</head>
<body>
<h1>M3U to JSON Converter</h1>
<input type="file" id="file-input" accept=".m3u" onchange="handleFileSelect(event)"/><br>
<textarea id="m3u-input" rows="10" cols="50" placeholder="粘贴m3u内容或上传文件..."></textarea><br>
<button onclick="convertToJSON()">转换</button><br>
<textarea id="json-output" rows="10" cols="50" placeholder="转换后的JSON..."></textarea>
</body>
<footer>
<p>Powered by <a href="https://github.com/hanxi/xiaomusic" target="_blank">xiaomusic</a></p>
</footer>
</html>

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width">
<title>小爱音箱操控面板</title>
<script src="/static/jquery-3.7.1.min.js"></script>
<script src="/static/setting.js"></script>
<link rel="stylesheet" type="text/css" href="/static/style.css">
</head>
<body>
<h2>小爱音箱设置面板<span id="version">(版本未知)</span></h2>
<hr>
<div class="rows">
<label for="mi_did">MI_DID:</label>
<select id="mi_did"></select>
<label for="mi_hardware">MI_HARDWARE:</label>
<select id="mi_hardware"></select>
<label for="xiaomusic_search">XIAOMUSIC_SEARCH:</label>
<select id="xiaomusic_search">
<option value="ytsearch:">ytsearch:</option>
<option value="bilisearch:">bilisearch:</option>
</select>
<label for="xiaomusic_proxy">XIAOMUSIC_PROXY(ytsearch需要):</label>
<input id="xiaomusic_proxy" type="text" placeholder="http://192.168.2.5:8080"></input>
<label for="xiaomusic_music_list_url">歌单地址:</label>
<input id="xiaomusic_music_list_url" type="text" value="https://gist.githubusercontent.com/hanxi/dda82d964a28f8110f8fba81c3ff8314/raw/example.json"></input>
<label for="xiaomusic_music_list_json">歌单内容:</label>
<textarea id="xiaomusic_music_list_json" type="text"></textarea>
</div>
<hr>
<button onclick="location.href='/';">返回首页</button>
<button id="get_music_list">获取歌单</button>
<button id="save">保存</button>
<hr>
<a href="/static/m3u.html" target="_blank">m3u文件转换工具</a>
<footer>
<p>Powered by <a href="https://github.com/hanxi/xiaomusic" target="_blank">xiaomusic</a></p>
</footer>
</body>
</html>

113
xiaomusic/static/setting.js Normal file
View File

@@ -0,0 +1,113 @@
$(function(){
// 拉取版本
$.get("/getversion", function(data, status) {
console.log(data, status, data["version"]);
$("#version").text(`(${data.version})`);
});
// 拉取现有配置
$.get("/getsetting", function(data, status) {
console.log(data, status);
var mi_did_div = $("#mi_did")
mi_did_div.empty();
$.each(data.mi_did_list, function(index, option){
mi_did_div.append($('<option>', {
value:option,
text:option,
}));
if (data.mi_did == option) {
mi_did_div.val(option);
}
});
var mi_hardware_div = $("#mi_hardware")
mi_hardware_div.empty();
$.each(data.mi_hardware_list, function(index, option){
mi_hardware_div.append($('<option>', {
value:option,
text:option,
}));
if (data.mi_hardware == option) {
mi_hardware_div.val(option);
}
});
if (data.xiaomusic_search != "") {
$("#xiaomusic_search").val(data.xiaomusic_search);
}
if (data.xiaomusic_proxy != "") {
$("#xiaomusic_proxy").val(data.xiaomusic_proxy);
}
if (data.xiaomusic_music_list_url != "") {
$("#xiaomusic_music_list_url").val(data.xiaomusic_music_list_url);
}
if (data.xiaomusic_music_list_json != "") {
$("#xiaomusic_music_list_json").val(data.xiaomusic_music_list_json);
}
});
$("#save").on("click", () => {
var mi_did = $("#mi_did").val();
var mi_hardware = $("#mi_hardware").val();
var xiaomusic_search = $("#xiaomusic_search").val();
var xiaomusic_proxy = $("#xiaomusic_proxy").val();
var xiaomusic_music_list_url = $("#xiaomusic_music_list_url").val();
var xiaomusic_music_list_json = $("#xiaomusic_music_list_json").val();
console.log("mi_did", mi_did);
console.log("mi_hardware", mi_hardware);
console.log("xiaomusic_search", xiaomusic_search);
console.log("xiaomusic_proxy", xiaomusic_proxy);
console.log("xiaomusic_music_list_url", xiaomusic_music_list_url);
console.log("xiaomusic_music_list_json", xiaomusic_music_list_json);
var data = {
mi_did: mi_did,
mi_hardware: mi_hardware,
xiaomusic_search: xiaomusic_search,
xiaomusic_proxy: xiaomusic_proxy,
xiaomusic_music_list_url: xiaomusic_music_list_url,
xiaomusic_music_list_json: xiaomusic_music_list_json,
};
$.ajax({
type: "POST",
url: "/savesetting",
contentType: "application/json",
data: JSON.stringify(data),
success: (msg) => {
alert(msg);
},
error: (msg) => {
alert(msg);
}
});
});
$("#get_music_list").on("click", () => {
var xiaomusic_music_list_url = $("#xiaomusic_music_list_url").val();
console.log("xiaomusic_music_list_url", xiaomusic_music_list_url);
var data = {
url: xiaomusic_music_list_url,
};
$.ajax({
type: "POST",
url: "/downloadjson",
contentType: "application/json",
data: JSON.stringify(data),
success: (res) => {
if (res.ret == "OK") {
$("#xiaomusic_music_list_json").val(res.content);
} else {
console.log(res);
alert(res.ret);
}
},
error: (res) => {
console.log(res);
alert(res);
}
});
});
});

View File

@@ -0,0 +1,75 @@
button {
margin: 10px;
width: 100px;
height: 50px;
border: none;
color: white;
text-align: center;
text-decoration: none;
display: inline-block;
border-radius: 10px;
background-color: #008CBA;
}
button:active {
font-weight:bold;
background-color: #007CBA;
transform: translateY(2px);
}
label {
margin-left: 10px;
width: 300px;
}
input,select {
margin: 10px;
width: 300px;
height: 40px;
}
.container{
width: 280px;
overflow: hidden;
display: inline-block;
}
@keyframes text-scroll {
0% {
left: 100%;
}
25% {
left: 50%;
}
50% {
left: 0%;
}
75% {
left: -50%;
}
100% {
left: -100%;
}
}
.text {
white-space: nowrap;
font-weight: bold;
position: relative;
animation: text-scroll 10s linear infinite;
}
.rows {
display: flex;
flex-direction: column;
margin-left: 20px;
margin-right: 20px;
}
footer {
bottom: 0;
width: 100%;
text-align: center;
padding: 10px 0;
}
textarea{
margin: 10px;
width: 300px;
height: 200px;
}

View File

@@ -1,13 +1,17 @@
#!/usr/bin/env python3
from __future__ import annotations
import difflib
import os
import re
import socket
import tempfile
from collections.abc import AsyncIterator
from http.cookies import SimpleCookie
from typing import AsyncIterator
from urllib.parse import urlparse
import aiohttp
import mutagen
import requests
from requests.utils import cookiejar_from_dict
@@ -61,3 +65,165 @@ def validate_proxy(proxy_str: str) -> bool:
return True
# 模糊搜索
def fuzzyfinder(user_input, collection):
return difflib.get_close_matches(user_input, collection, 10, cutoff=0.1)
# 歌曲排序
def custom_sort_key(s):
# 使用正则表达式分别提取字符串的数字前缀和数字后缀
prefix_match = re.match(r"^(\d+)", s)
suffix_match = re.search(r"(\d+)$", s)
numeric_prefix = int(prefix_match.group(0)) if prefix_match else None
numeric_suffix = int(suffix_match.group(0)) if suffix_match else None
if numeric_prefix is not None:
# 如果前缀是数字,先按前缀数字排序,再按整个字符串排序
return (0, numeric_prefix, s)
elif numeric_suffix is not None:
# 如果后缀是数字,先按前缀字符排序,再按后缀数字排序
return (1, s[: suffix_match.start()], numeric_suffix)
else:
# 如果前缀和后缀都不是数字,按字典序排序
return (2, s)
# fork from https://gist.github.com/dougthor42/001355248518bc64d2f8
def walk_to_depth(root, depth=None, *args, **kwargs):
"""
Wrapper around os.walk that stops after going down `depth` folders.
I had my own version, but it wasn't as efficient as
http://stackoverflow.com/a/234329/1354930, so I modified to be more
similar to nosklo's answer.
However, nosklo's answer doesn't work if topdown=False, so I kept my
version.
"""
# Let people use this as a standard `os.walk` function.
if depth is None:
return os.walk(root, *args, **kwargs)
# remove any trailing separators so that our counts are correct.
root = root.rstrip(os.path.sep)
def main_func(root, depth, *args, **kwargs):
"""Faster because it skips traversing dirs that are too deep."""
root_depth = root.count(os.path.sep)
for dirpath, dirnames, filenames in os.walk(root, *args, **kwargs):
yield (dirpath, dirnames, filenames)
# calculate how far down we are.
current_folder_depth = dirpath.count(os.path.sep)
if current_folder_depth >= root_depth + depth:
del dirnames[:]
def fallback_func(root, depth, *args, **kwargs):
"""Slower, but works when topdown is False"""
root_depth = root.count(os.path.sep)
for dirpath, dirnames, filenames in os.walk(root, *args, **kwargs):
current_folder_depth = dirpath.count(os.path.sep)
if current_folder_depth <= root_depth + depth:
yield (dirpath, dirnames, filenames)
# there's gotta be a better way do do this...
try:
if args[0] is False:
yield from fallback_func(root, depth, *args, **kwargs)
return
else:
yield from main_func(root, depth, *args, **kwargs)
return
except IndexError:
pass
try:
if kwargs["topdown"] is False:
yield from fallback_func(root, depth, *args, **kwargs)
return
else:
yield from main_func(root, depth, *args, **kwargs)
return
except KeyError:
yield from main_func(root, depth, *args, **kwargs)
return
def downloadfile(url):
# 清理和验证URL
try:
# 解析URL
parsed_url = urlparse(url)
# 基础验证仅允许HTTP和HTTPS协议
if parsed_url.scheme not in ("http", "https"):
return (
f"Invalid URL scheme: {parsed_url.scheme}. Only HTTP and HTTPS are allowed.",
"",
)
# 构建目标URL
cleaned_url = parsed_url.geturl()
except Exception as e:
return (f"Invalid URL: {e}", "")
# 发起请求
try:
response = requests.get(cleaned_url, timeout=5) # 增加超时以避免长时间挂起
response.raise_for_status() # 如果响应不是200引发HTTPError异常
return ("OK", response.text)
except requests.exceptions.HTTPError as errh:
return (f"HTTP Error: {errh}", "")
except requests.exceptions.ConnectionError as errc:
return (f"Error Connecting: {errc}", "")
except requests.exceptions.Timeout as errt:
return (f"Timeout Error: {errt}", "")
except requests.exceptions.RequestException as err:
return (f"Oops: Something Else, {err}", "")
return ("Unknown Error", "")
async def _get_web_music_duration(session, url, start=0, end=500):
duration = 0
headers = {"Range": f"bytes={start}-{end}"}
async with session.get(url, headers=headers) as response:
array_buffer = await response.read()
with tempfile.NamedTemporaryFile(delete=False) as tmp:
tmp.write(array_buffer)
name = tmp.name
try:
m = mutagen.File(name)
duration = m.info.length
except Exception:
pass
os.remove(name)
return duration
async def get_web_music_duration(url, start=0, end=500):
duration = 0
try:
# 设置总超时时间为3秒
timeout = aiohttp.ClientTimeout(total=3)
async with aiohttp.ClientSession(timeout=timeout) as session:
duration = await _get_web_music_duration(session, url, start=0, end=500)
if duration <= 0:
duration = await _get_web_music_duration(
session, url, start=0, end=1000
)
except Exception:
pass
return duration
# 获取文件播放时长
def get_local_music_duration(filename):
duration = 0
try:
m = mutagen.File(filename)
duration = m.info.length
except Exception:
pass
return duration

File diff suppressed because it is too large Load Diff