1
0
mirror of https://github.com/hanxi/xiaomusic.git synced 2025-12-09 15:18:15 +08:00

Compare commits

..

100 Commits

Author SHA1 Message Date
涵曦
aea9786cd7 bump: version 0.3.83 → 0.3.84 2025-08-03 22:44:03 +08:00
涵曦
e0627dfe8b build: update static version 2025-08-03 22:44:03 +08:00
涵曦
2f1df2709e build: update static version 2025-08-03 22:38:52 +08:00
涵曦
e51f873fdf build: update static version 2025-08-03 22:37:15 +08:00
涵曦
80ead7512f update version 2025-08-03 22:14:39 +08:00
涵曦
f64d9b2462 fmt code 2025-08-03 17:08:44 +08:00
Issues Docs [BOT]
b3c6ca3943 Auto-Generate docs 🤖 2025-08-03 08:59:37 +00:00
涵曦
001e0ede20 fix: 修复谷歌字体问题 2025-08-03 16:51:08 +08:00
Issues Docs [BOT]
53f302c946 Auto-Generate docs 🤖 2025-08-02 09:54:59 +00:00
Issues Docs [BOT]
57ca7a38c4 Auto-Generate docs 🤖 2025-07-31 13:11:45 +00:00
Issues Docs [BOT]
b379cbf613 Auto-Generate docs 🤖 2025-07-30 04:31:47 +00:00
Issues Docs [BOT]
5d0e974a12 Auto-Generate docs 🤖 2025-07-24 16:49:17 +00:00
Issues Docs [BOT]
0b8af47702 Auto-Generate docs 🤖 2025-07-24 10:47:25 +00:00
涵曦
85da3069ed Update README.md 2025-07-24 18:44:30 +08:00
涵曦
d5eb5d5233 Update README.md 2025-07-24 18:43:49 +08:00
Issues Docs [BOT]
cf43527020 Auto-Generate docs 🤖 2025-07-24 03:34:20 +00:00
涵曦
5b310c269f Update README.md 2025-07-24 11:32:30 +08:00
AisukaYuki
b547fa08da fix: 文件监控: 忽略非文件创建、删除和移动事件 (#514)
只处理文件创建、删除和移动事件,避免处理不必要的事件类型
2025-07-23 12:31:34 +08:00
Issues Docs [BOT]
f27e5299a8 Auto-Generate docs 🤖 2025-07-20 07:25:17 +00:00
Issues Docs [BOT]
b566958843 Auto-Generate docs 🤖 2025-07-05 02:40:12 +00:00
Issues Docs [BOT]
faa3013898 Auto-Generate docs 🤖 2025-07-04 10:53:37 +00:00
13112442872
06de73e8ed fix: 修复中文定时关机无法识别的BUG (#510)
Co-authored-by: sj13112442872 <891771212@qq.com>
2025-07-04 11:05:57 +08:00
Issues Docs [BOT]
f4377069ad Auto-Generate docs 🤖 2025-06-29 23:27:05 +00:00
Issues Docs [BOT]
35fb9510c6 Auto-Generate docs 🤖 2025-06-27 14:35:03 +00:00
涵曦
74df4f0676 Update README.md 2025-06-27 22:33:04 +08:00
Issues Docs [BOT]
2ffb30415b Auto-Generate docs 🤖 2025-06-27 03:48:01 +00:00
Issues Docs [BOT]
71dcd2e628 Auto-Generate docs 🤖 2025-06-26 02:55:07 +00:00
Issues Docs [BOT]
65ee9de60c Auto-Generate docs 🤖 2025-06-20 15:24:52 +00:00
Issues Docs [BOT]
feaab8c1f5 Auto-Generate docs 🤖 2025-06-17 12:22:53 +00:00
Issues Docs [BOT]
ca427d69ef Auto-Generate docs 🤖 2025-06-14 15:07:24 +00:00
涵曦
1ac2c20604 feat: 下一首歌延迟播放秒数支持负数,用于解决播放下一首时会播放上一首的开头几秒的问题 2025-06-14 22:58:53 +08:00
涵曦
c2cb13e61e fix: 修复日志文件删除失败的问题 2025-06-14 22:51:47 +08:00
Issues Docs [BOT]
778d8f8b9d Auto-Generate docs 🤖 2025-06-14 10:22:35 +00:00
Issues Docs [BOT]
de3365fbbb Auto-Generate docs 🤖 2025-06-11 18:25:55 +00:00
涵曦
a316053d01 bump: version 0.3.82 → 0.3.83 2025-06-12 02:24:04 +08:00
涵曦
0bfa4e6251 build: update static version 2025-06-12 02:24:03 +08:00
涵曦
6ef7d4c6c2 feat: 新增开关控制是否开始谷歌统计 see #473 2025-06-12 01:07:33 +08:00
Issues Docs [BOT]
fff35783c2 Auto-Generate docs 🤖 2025-06-11 16:56:35 +00:00
涵曦
c8fad5ba1d Update Dockerfile.runtime 2025-06-12 00:47:56 +08:00
涵曦
956a4af3c9 fix: 修复安全问题 2025-06-10 18:46:15 +08:00
涵曦
4cf0ef2fdd Potential fix for code scanning alert no. 47: Incomplete URL substring sanitization (#497)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-06-10 17:24:48 +08:00
涵曦
2eb6e8035b fix: 修复安全问题 2025-06-10 16:43:43 +08:00
涵曦
1679eedb94 Potential fix for code scanning alert no. 40: Uncontrolled data used in path expression (#493)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-06-10 16:09:32 +08:00
涵曦
5b20b3c8eb Update Dockerfile.runtime 2025-06-10 15:13:02 +08:00
涵曦
4d07b48c63 Update Dockerfile.builder 2025-06-10 14:06:34 +08:00
涵曦
fb48ed13c0 Update Dockerfile.builder 2025-06-10 13:13:37 +08:00
涵曦
fe25ad6b81 Update Dockerfile.builder 2025-06-10 13:09:49 +08:00
涵曦
e98ec4f8e4 Update Dockerfile.builder 2025-06-10 11:24:37 +08:00
涵曦
80c4ca332e Update Dockerfile.builder 2025-06-10 08:43:46 +08:00
涵曦
9ceda0d524 Potential fix for code scanning alert no. 39: Workflow does not contain permissions (#492)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-06-09 23:19:49 +08:00
涵曦
b34a0fdc1e Update Dockerfile.runtime 2025-06-09 23:19:01 +08:00
涵曦
9f2dbb2457 Update Dockerfile.builder 2025-06-09 23:18:13 +08:00
Issues Docs [BOT]
684df86688 Auto-Generate docs 🤖 2025-06-09 15:02:22 +00:00
Formatter [BOT]
a62061f4ae Auto-format code 🧹🌟🤖 2025-06-09 14:57:17 +00:00
涵曦
be4028b235 Update README.md 2025-06-09 22:56:44 +08:00
Moruy
8f5fe0df98 Update Dockerfile.builder (#490) 2025-06-09 14:58:53 +08:00
Issues Docs [BOT]
6fb5917047 Auto-Generate docs 🤖 2025-06-09 04:38:17 +00:00
涵曦
a3da3523e5 Update Dockerfile 2025-06-09 12:34:31 +08:00
Moruy
5f944b8c5c feature: Migrate debian to alpine linux (#489)
* Update Dockerfile

change debian to alpine linux, reduce the image size by 50%

* Update Dockerfile.builder

change debian to alpine linux, reduce the image size by 50%

* Update Dockerfile.runtime

change debian to alpine linux, reduce the image size by 50%
2025-06-09 12:32:30 +08:00
nfzsh
c72b19ffc0 feat: 支持b站合集和收藏下载 (#487)
* feat:支持收藏夹和合集下载

* feat:支持收藏夹和合集下载

* feat:支持收藏夹和合集下载
2025-06-09 00:37:26 +08:00
Issues Docs [BOT]
acab694adc Auto-Generate docs 🤖 2025-06-08 04:45:44 +00:00
Issues Docs [BOT]
3cd1627c83 Auto-Generate docs 🤖 2025-06-07 10:15:55 +00:00
涵曦
7dfac1a71f Update README.md 2025-06-07 18:14:20 +08:00
Issues Docs [BOT]
784054b3e9 Auto-Generate docs 🤖 2025-06-07 09:53:20 +00:00
涵曦
6125d65fad Update README.md 2025-06-07 17:51:36 +08:00
Issues Docs [BOT]
17e7fc566f Auto-Generate docs 🤖 2025-06-05 03:39:22 +00:00
Issues Docs [BOT]
3193141653 Auto-Generate docs 🤖 2025-06-05 03:35:30 +00:00
Issues Docs [BOT]
01b678f4fc Auto-Generate docs 🤖 2025-06-04 04:28:07 +00:00
涵曦
c7be019b56 Update README.md 2025-06-04 12:26:25 +08:00
Issues Docs [BOT]
b005a340e1 Auto-Generate docs 🤖 2025-05-29 23:51:27 +00:00
涵曦
e4bdae4834 bump: version 0.3.81 → 0.3.82 2025-05-30 07:49:12 +08:00
涵曦
e5eb57cf05 build: update static version 2025-05-30 07:49:11 +08:00
涵曦
eb28a328ef fix: 修复节假日文件没有打包到 docker 镜像里的问题 2025-05-30 07:13:54 +08:00
Issues Docs [BOT]
e06b7a6e6c Auto-Generate docs 🤖 2025-05-29 16:28:03 +00:00
Issues Docs [BOT]
bc34c677af Auto-Generate docs 🤖 2025-05-28 15:49:21 +00:00
涵曦
bf16f837d7 bump: version 0.3.80 → 0.3.81 2025-05-28 23:47:06 +08:00
涵曦
83509eb477 build: update static version 2025-05-28 23:47:01 +08:00
Issues Docs [BOT]
0f8175a7de Auto-Generate docs 🤖 2025-05-26 03:15:43 +00:00
徒言
caabf63cc5 fix: 动态小程序码生成接口 (#478)
* Auto-format code 🧹🌟🤖

* fix: 动态小程序码生成接口

---------

Co-authored-by: Formatter [BOT] <runner@fv-az1361-149.2ktbtkyutslunjvokbglb2a1ge.bx.internal.cloudapp.net>
2025-05-26 11:00:27 +08:00
Issues Docs [BOT]
084a9c93f0 Auto-Generate docs 🤖 2025-05-24 11:57:29 +00:00
Issues Docs [BOT]
c86c60ed0a Auto-Generate docs 🤖 2025-05-23 00:55:50 +00:00
lucas
22d605627f fix: 指定日志编码,避免中文乱码 (#475) 2025-05-22 12:29:41 +08:00
Issues Docs [BOT]
d2e7e881b3 Auto-Generate docs 🤖 2025-05-21 15:16:39 +00:00
涵曦
10c60faee1 feat: 定时任务支持工作日和休息日 see #182 2025-05-21 23:01:07 +08:00
Issues Docs [BOT]
4949964130 Auto-Generate docs 🤖 2025-05-21 04:25:41 +00:00
涵曦
e9c2f18570 Update README.md 2025-05-21 12:23:59 +08:00
Issues Docs [BOT]
d484bd9707 Auto-Generate docs 🤖 2025-05-20 00:37:18 +00:00
Issues Docs [BOT]
e50605555e Auto-Generate docs 🤖 2025-05-18 06:32:16 +00:00
涵曦
bb0cf943ef bump: version 0.3.79 → 0.3.80 2025-05-18 14:30:10 +08:00
涵曦
9f520eac11 build: update static version 2025-05-18 14:30:09 +08:00
Issues Docs [BOT]
d9301dce23 Auto-Generate docs 🤖 2025-05-18 06:29:07 +00:00
涵曦
609fc9f661 Update README.md 2025-05-18 14:27:16 +08:00
涵曦
22704e15fd feat: 新增 OH2 型号的支持 2025-05-18 14:25:35 +08:00
Issues Docs [BOT]
eead12643d Auto-Generate docs 🤖 2025-05-18 04:40:00 +00:00
Issues Docs [BOT]
4838070f50 Auto-Generate docs 🤖 2025-05-15 04:19:50 +00:00
lucas
9e03c26f3f fix: 修复获取在线歌曲长度 (#469)
修复获取歌长度
2025-05-11 21:52:41 +08:00
Issues Docs [BOT]
c7c54e9446 Auto-Generate docs 🤖 2025-05-08 04:36:50 +00:00
涵曦
0690f4846e feat: 支持配置最大搜索歌曲数量 see #462 2025-05-07 22:05:52 +08:00
Issues Docs [BOT]
eb39281eb7 Auto-Generate docs 🤖 2025-05-07 13:42:13 +00:00
Issues Docs [BOT]
f12af9b8e8 Auto-Generate docs 🤖 2025-04-29 15:42:51 +00:00
63 changed files with 4963 additions and 88 deletions

View File

@@ -10,6 +10,9 @@ on:
- '.github/workflows/build-base-image.yml'
workflow_dispatch:
permissions:
contents: read
jobs:
build-image:
runs-on: ubuntu-latest

View File

@@ -1,3 +1,56 @@
## v0.3.84 (2025-08-03)
### Feat
- 下一首歌延迟播放秒数支持负数,用于解决播放下一首时会播放上一首的开头几秒的问题
### Fix
- 修复谷歌字体问题
- 文件监控: 忽略非文件创建、删除和移动事件 (#514)
- 修复中文定时关机无法识别的BUG (#510)
- 修复日志文件删除失败的问题
## v0.3.83 (2025-06-12)
### Feat
- 新增开关控制是否开始谷歌统计 see #473
- 支持b站合集和收藏下载 (#487)
### Fix
- 修复安全问题
- 修复安全问题
## v0.3.82 (2025-05-30)
### Fix
- 修复节假日文件没有打包到 docker 镜像里的问题
## v0.3.81 (2025-05-28)
### Feat
- 定时任务支持工作日和休息日 see #182
### Fix
- 动态小程序码生成接口 (#478)
- 指定日志编码,避免中文乱码 (#475)
## v0.3.80 (2025-05-18)
### Feat
- 新增 OH2 型号的支持
- 支持配置最大搜索歌曲数量 see #462
### Fix
- 修复获取在线歌曲长度 (#469)
## v0.3.79 (2025-04-29)
### Fix

View File

@@ -1,11 +1,11 @@
FROM hanxi/xiaomusic:builder AS builder
ENV DEBIAN_FRONTEND=noninteractive
RUN pip install -U pdm
ENV PDM_CHECK_UPDATE=false
WORKDIR /app
COPY pyproject.toml README.md .
COPY xiaomusic/ ./xiaomusic/
COPY plugins/ ./plugins/
COPY holiday/ ./holiday/
COPY xiaomusic.py .
RUN pdm install --prod --no-editable
@@ -14,6 +14,7 @@ WORKDIR /app
COPY --from=builder /app/.venv ./.venv
COPY --from=builder /app/xiaomusic/ ./xiaomusic/
COPY --from=builder /app/plugins/ ./plugins/
COPY --from=builder /app/holiday/ ./holiday/
COPY --from=builder /app/xiaomusic.py .
COPY --from=builder /app/xiaomusic/__init__.py /base_version.py
RUN touch /app/.dockerenv

View File

@@ -1,11 +1,14 @@
FROM python:3.10
ENV DEBIAN_FRONTEND=noninteractive
FROM python:3.12-alpine3.22
RUN apk add --no-cache --virtual .build-deps build-base python3-dev libffi-dev openssl-dev zlib-dev jpeg-dev libc6-compat gcc musl-dev
RUN pip install -U pdm
ENV PDM_CHECK_UPDATE=false
WORKDIR /app
COPY pyproject.toml README.md .
COPY xiaomusic/ ./xiaomusic/
COPY plugins/ ./plugins/
COPY xiaomusic.py .
COPY pyproject.toml README.md ./
RUN pdm install --prod --no-editable
COPY xiaomusic/ ./xiaomusic/
COPY plugins/ ./plugins/
COPY holiday/ ./holiday/
COPY xiaomusic.py .

View File

@@ -1,16 +1,18 @@
FROM python:3.10-slim
ENV DEBIAN_FRONTEND=noninteractive
FROM python:3.12-alpine3.22
RUN apt-get update && apt-get install -y \
RUN apk add --no-cache bash\
wget \
xz-utils \
libtiff6 \
libopenjp2-7 \
libxcb1 \
xz \
tiff \
openjpeg \
libxcb \
supervisor \
vim \
libc6-compat \
ffmpeg \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY install_dependencies.sh .
RUN bash install_dependencies.sh
RUN mkdir -p /app/ffmpeg/bin \
&& ln -s /usr/bin/ffmpeg /app/ffmpeg/bin/ffmpeg \
&& ln -s /usr/bin/ffprobe /app/ffmpeg/bin/ffprobe

View File

@@ -77,16 +77,19 @@ services:
> docker 和 docker compose 二选一即可,启动成功后,在 web 页面可以配置其他参数,带有 `*` 号的配置是必须要配置的,其他的用不上时不用修改。初次配置时需要在页面上输入小米账号和密码保存后才能获取到设备列表。
> [!TIP]
> 目前安装步骤已经是最简化了,如果还是嫌安装麻烦,可以微信或者 QQ 约我远程安装,我一般周末和晚上才有时间,个辛苦费 :moneybag: 50 元一次,安装失败不收费
> 目前安装步骤已经是最简化了,如果还是嫌安装麻烦,可以微信或者 QQ 约我远程安装,我一般周末和晚上才有时间,需要赞助个辛苦费 :moneybag: 50 元一次。
遇到问题可以去 web 设置页面底部点击【下载日志文件】按钮,然后搜索一下日志文件内容确保里面没有账号密码信息后(有就删除这些敏感信息),然后在提 issues 反馈问题时把下载的日志文件带上。
> [!TIP]
> 作者的另一个适用于 NAS 上安装的开源工具: <https://github.com/hanxi/tiny-nav>
> [!TIP]
>
> - 🔥【广告:可用于安装 frp 实现内网穿透】
> - 🔥 海外 RackNerd VPS 机器推荐,可支付宝付款。
> - <a href="https://my.racknerd.com/aff.php?aff=11177"><img src="https://racknerd.com/banners/320x50.gif" alt="RackNerd Mobile Leaderboard Banner" width="320" height="50"></a>
> - 不知道选哪个套餐可以直接买这个最便宜的 <https://my.racknerd.com/aff.php?aff=11177&pid=903>
> - 不知道选哪个套餐可以直接买这个最便宜的 <https://my.racknerd.com/aff.php?aff=11177&pid=912>
> - 也可以用来部署代理docker 部署方法见 <https://github.com/hanxi/blog/issues/96>
> [!TIP]
@@ -94,6 +97,11 @@ services:
> - 🔥【广告: 搭建您的专属大模型主页
告别繁琐配置难题一键即可畅享稳定流畅的AI体验】<https://university.aliyun.com/mobile?userCode=szqvatm6>
> [!TIP]
> - 免费主机
> - <a href="https://dartnode.com?aff=SnappyPigeon570"><img src="https://dartnode.com/branding/DN-Open-Source-sm.png" alt="Powered by DartNode - Free VPS for Open Source" width="320"></a>
### 🤐 支持语音口令
- 【播放歌曲】,播放本地的歌曲
@@ -208,6 +216,7 @@ docker build -t xiaomusic .
| X08C X08E X8F | 已经不需要设置了. ~需要设置【型号兼容模式】选项为 true~ |
| M01/XMYX01JY | 小米小爱音箱HD 需要设置【特殊型号获取对话记录】选项为 true 才能语音播放|
| OH2P | XIAOMI 智能音箱 Pro |
| OH2 | XIAOMI 智能音箱 |
型号与产品名称对照可以在这里查询 <https://home.miot-spec.com/s/xiaomi.wifispeaker>

View File

@@ -77,7 +77,7 @@ docker tag m.daocloud.io/docker.io/hanxi/xiaomusic:latest hanxi/xiaomusic:latest
---
### 评论 4 - ginitaimeiyty
### 评论 4 - SenyFish
如果手头上有能科学上网的机器直接把群辉的代理服务器IP填写成可以科学上网的机器IP+端口,翻墙软件打开允许局域网连接就可以
@@ -112,5 +112,114 @@ docker pull dockerhub.anzu.vip/hanxi/xiaomusic:latest
不确定,但是我访问谷歌啥的都正常啊
---
### 评论 9 - 22555642
你好我在群辉DOCKER上部署运行后一直打不开设置页面点开日志里面写的是这个请问要怎么办呢
2025/07/18 17:15:55 | stdout | [2025-07-18 17:15:54] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
-- | -- | --
2025/07/18 17:15:55 | stdout | [2025-07-18 17:15:54] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
2025/07/18 17:15:55 | stdout | ==> /app/xiaomusic.log.txt <==
2025/07/18 17:15:55 | stdout |  
2025/07/18 17:15:55 | stderr | tail: /app/xiaomusic.log.txt has been replaced; following end of new file
2025/07/18 17:15:52 | stdout | 2025-07-18 17:15:51,292 INFO spawned: 'xiaomusic' with pid 21
2025/07/18 17:15:48 | stdout | 2025-07-18 17:15:47,284 WARN exited: xiaomusic (exit status 1; not expected)
2025/07/18 17:15:48 | stdout | ==> /app/supervisord.log <==
2025/07/18 17:15:48 | stdout |  
2025/07/18 17:15:43 | stderr | tail: /app/xiaomusic.log.txt has been replaced; following end of new file
2025/07/18 17:15:43 | stdout | [2025-07-18 17:15:42] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
2025/07/18 17:15:43 | stdout | [2025-07-18 17:15:42] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
2025/07/18 17:15:43 | stdout | ==> /app/xiaomusic.log.txt <==
2025/07/18 17:15:43 | stdout |  
2025/07/18 17:15:40 | stdout | 2025-07-18 17:15:39,479 INFO spawned: 'xiaomusic' with pid 18
2025/07/18 17:15:37 | stdout | 2025-07-18 17:15:36,473 WARN exited: xiaomusic (exit status 1; not expected)
2025/07/18 17:15:37 | stdout | ==> /app/supervisord.log <==
2025/07/18 17:15:37 | stdout |  
2025/07/18 17:15:33 | stdout | [2025-07-18 17:15:32] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
2025/07/18 17:15:33 | stdout | [2025-07-18 17:15:32] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
2025/07/18 17:15:33 | stdout | ==> /app/xiaomusic.log.txt <==
---
### 评论 10 - hanxi
> 你好我在群辉DOCKER上部署运行后一直打不开设置页面点开日志里面写的是这个请问要怎么办呢
>
> 2025/07/18 17:15:55 stdout [2025-07-18 17:15:54] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
> 2025/07/18 17:15:55 stdout [2025-07-18 17:15:54] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
> 2025/07/18 17:15:55 stdout ==> /app/xiaomusic.log.txt <==
> 2025/07/18 17:15:55 stdout  
> 2025/07/18 17:15:55 stderr tail: /app/xiaomusic.log.txt has been replaced; following end of new file
> 2025/07/18 17:15:52 stdout 2025-07-18 17:15:51,292 INFO spawned: 'xiaomusic' with pid 21
> 2025/07/18 17:15:48 stdout 2025-07-18 17:15:47,284 WARN exited: xiaomusic (exit status 1; not expected)
> 2025/07/18 17:15:48 stdout ==> /app/supervisord.log <==
> 2025/07/18 17:15:48 stdout  
> 2025/07/18 17:15:43 stderr tail: /app/xiaomusic.log.txt has been replaced; following end of new file
> 2025/07/18 17:15:43 stdout [2025-07-18 17:15:42] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
> 2025/07/18 17:15:43 stdout [2025-07-18 17:15:42] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
> 2025/07/18 17:15:43 stdout ==> /app/xiaomusic.log.txt <==
> 2025/07/18 17:15:43 stdout  
> 2025/07/18 17:15:40 stdout 2025-07-18 17:15:39,479 INFO spawned: 'xiaomusic' with pid 18
> 2025/07/18 17:15:37 stdout 2025-07-18 17:15:36,473 WARN exited: xiaomusic (exit status 1; not expected)
> 2025/07/18 17:15:37 stdout ==> /app/supervisord.log <==
> 2025/07/18 17:15:37 stdout  
> 2025/07/18 17:15:33 stdout [2025-07-18 17:15:32] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
> 2025/07/18 17:15:33 stdout [2025-07-18 17:15:32] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
> 2025/07/18 17:15:33 stdout ==> /app/xiaomusic.log.txt <==
看不出来为啥
---
### 评论 11 - 22555642
我把日志发给您,您可以帮我看看嘛?
------------------&nbsp;原始邮件&nbsp;------------------
发件人: "hanxi/xiaomusic" ***@***.***&gt;;
发送时间:&nbsp;2025年7月19日(星期六) 凌晨1:31
***@***.***&gt;;
***@***.******@***.***&gt;;
主题:&nbsp;Re: [hanxi/xiaomusic] 群晖docker安装 xiaomusic (Issue #101)
hanxi left a comment (hanxi/xiaomusic#101)
你好我在群辉DOCKER上部署运行后一直打不开设置页面点开日志里面写的是这个请问要怎么办呢
2025/07/18&nbsp;17:15:55 stdout [2025-07-18&nbsp;17:15:54]&nbsp;[0.3.83]&nbsp;[INFO]&nbsp;xiaomusic.py:1373:&nbsp;The&nbsp;file&nbsp;conf/setting.json&nbsp;does&nbsp;not&nbsp;exist.
2025/07/18&nbsp;17:15:55 stdout [2025-07-18&nbsp;17:15:54]&nbsp;[0.3.83]&nbsp;[INFO]&nbsp;xiaomusic.py:1373:&nbsp;The&nbsp;file&nbsp;conf/setting.json&nbsp;does&nbsp;not&nbsp;exist.
2025/07/18&nbsp;17:15:55 stdout ==&gt;&nbsp;/app/xiaomusic.log.txt&nbsp;<==
2025/07/18&nbsp;17:15:55 stdout &nbsp;
2025/07/18&nbsp;17:15:55 stderr tail:&nbsp;/app/xiaomusic.log.txt&nbsp;has&nbsp;been&nbsp;replaced;&nbsp;following&nbsp;end&nbsp;of&nbsp;new&nbsp;file
2025/07/18&nbsp;17:15:52 stdout 2025-07-18&nbsp;17:15:51,292&nbsp;INFO&nbsp;spawned:&nbsp;'xiaomusic'&nbsp;with&nbsp;pid&nbsp;21
2025/07/18&nbsp;17:15:48 stdout 2025-07-18&nbsp;17:15:47,284&nbsp;WARN&nbsp;exited:&nbsp;xiaomusic&nbsp;(exit&nbsp;status&nbsp;1;&nbsp;not&nbsp;expected)
2025/07/18&nbsp;17:15:48 stdout ==&gt;&nbsp;/app/supervisord.log&nbsp;<==
2025/07/18&nbsp;17:15:48 stdout &nbsp;
2025/07/18&nbsp;17:15:43 stderr tail:&nbsp;/app/xiaomusic.log.txt&nbsp;has&nbsp;been&nbsp;replaced;&nbsp;following&nbsp;end&nbsp;of&nbsp;new&nbsp;file
2025/07/18&nbsp;17:15:43 stdout [2025-07-18&nbsp;17:15:42]&nbsp;[0.3.83]&nbsp;[INFO]&nbsp;xiaomusic.py:1373:&nbsp;The&nbsp;file&nbsp;conf/setting.json&nbsp;does&nbsp;not&nbsp;exist.
2025/07/18&nbsp;17:15:43 stdout [2025-07-18&nbsp;17:15:42]&nbsp;[0.3.83]&nbsp;[INFO]&nbsp;xiaomusic.py:1373:&nbsp;The&nbsp;file&nbsp;conf/setting.json&nbsp;does&nbsp;not&nbsp;exist.
2025/07/18&nbsp;17:15:43 stdout ==&gt;&nbsp;/app/xiaomusic.log.txt&nbsp;<==
2025/07/18&nbsp;17:15:43 stdout &nbsp;
2025/07/18&nbsp;17:15:40 stdout 2025-07-18&nbsp;17:15:39,479&nbsp;INFO&nbsp;spawned:&nbsp;'xiaomusic'&nbsp;with&nbsp;pid&nbsp;18
2025/07/18&nbsp;17:15:37 stdout 2025-07-18&nbsp;17:15:36,473&nbsp;WARN&nbsp;exited:&nbsp;xiaomusic&nbsp;(exit&nbsp;status&nbsp;1;&nbsp;not&nbsp;expected)
2025/07/18&nbsp;17:15:37 stdout ==&gt;&nbsp;/app/supervisord.log&nbsp;<==
2025/07/18&nbsp;17:15:37 stdout &nbsp;
2025/07/18&nbsp;17:15:33 stdout [2025-07-18&nbsp;17:15:32]&nbsp;[0.3.83]&nbsp;[INFO]&nbsp;xiaomusic.py:1373:&nbsp;The&nbsp;file&nbsp;conf/setting.json&nbsp;does&nbsp;not&nbsp;exist.
2025/07/18&nbsp;17:15:33 stdout [2025-07-18&nbsp;17:15:32]&nbsp;[0.3.83]&nbsp;[INFO]&nbsp;xiaomusic.py:1373:&nbsp;The&nbsp;file&nbsp;conf/setting.json&nbsp;does&nbsp;not&nbsp;exist.
2025/07/18&nbsp;17:15:33 stdout ==&gt;&nbsp;/app/xiaomusic.log.txt&nbsp;<==
看不出来为啥
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***&gt;
---
[链接到 GitHub Issue](https://github.com/hanxi/xiaomusic/issues/101)

View File

@@ -128,5 +128,41 @@ title: 定时任务配置格式
0.3.38版本功能。
---
### 评论 2 - F-loat
<img src="https://gproxy.hanxi.cc/proxy/user-attachments/assets/9e562aea-423e-479d-bf0c-9932b330cf98" width="25%" />
小程序已支持可视化配置定时任务
---
### 评论 3 - hanxi
有想法增加一个参数来决定法定工作日,法定节假日执行。
---
### 评论 4 - hanxi
计划这样配工作日或者休息日,末尾加上 ` #workday` 表示工作日才执行,末尾加上 ` #offday` 表示休息日才执行。
```json
[
{
"expression": "0 8 * * * #workday",
"name": "play",
"did": "123456789",
"arg1": "周杰伦晴天"
},
{
"expression": "0 10 * * * #offday",
"name": "play",
"did": "123456789",
"arg1": "周杰伦晴天"
}
]
```
---
[链接到 GitHub Issue](https://github.com/hanxi/xiaomusic/issues/182)

View File

@@ -249,5 +249,19 @@ https://tutu.to/image/1.N0FHK
估计是网络问题
---
### 评论 26 - s493321320
有办法添加到homeassistant里吗
---
### 评论 27 - Chill-26
> 按照飞牛的教程,部署成功了,一直没有设备显示出来,然后我也按照相应的问题集去处理:关闭本地代理。 如果是nas运行的网络由bridge改为host。 米家app重新登陆。 mi.com官网重新登陆。 但是还是没有办法显示设备出来请问到底是什么原因最新的37版本。
同样问题,但我重新使用 [视频教程-群晖1]进行部署就正常了
---
[链接到 GitHub Issue](https://github.com/hanxi/xiaomusic/issues/211)

View File

@@ -110,5 +110,25 @@ yt-dlp應該不用在自己額外安裝吧
感謝看來要安裝那邊要說明一下要開啟yt-dlp下載最好是上傳cookie比較保險
---
### 评论 10 - nfzsh
看日志好像只获取到了第一首?
---
### 评论 11 - hzqgogogo
已收到你的邮件!
---
### 评论 12 - nfzsh
> 已收到你的邮件!
哦我知道了你这个是针对分P的我这个是个合集我看看哪天我提个PR吧
---
[链接到 GitHub Issue](https://github.com/hanxi/xiaomusic/issues/212)

View File

@@ -10,5 +10,10 @@ title: 同步网易云歌单
## 评论
没有评论。
### 评论 1 - Ghost-Sam1222
什么时候可以同步apple music歌单就真好了
---
[链接到 GitHub Issue](https://github.com/hanxi/xiaomusic/issues/312)

View File

@@ -70,5 +70,86 @@ docker compose down
## 评论
没有评论。
### 评论 1 - tiger326
我用这个是可以正常启动和搭建好xiaomusic, 一切都OK.
不过我的NAS是qnap, 已禁用默认的admin用户, 使用自建的管理员账户登录.
但这个配置会默认使用admin用户执行, 导致一旦产生tmp和download目录以及相关文件, 都归属于admin用户.
结果我自建的用户在NAS上无法删除和编辑这些下载的文件.
xiaomusic是否支持创建时指定用户和用户组?
---
### 评论 2 - hanxi
@tiger326 把下面的 username 换成普通的用户名即可,换成 uid 数字也行,一般是 1000
```shell
mkdir -p /xiaomusic
cat <<EOF > /xiaomusic/docker-compose.yml
services:
xiaomusic:
image: docker.hanxi.cc/hanxi/xiaomusic
container_name: xiaomusic
restart: unless-stopped
user: username
ports:
- 58090:8090
environment:
XIAOMUSIC_PUBLIC_PORT: 58090
volumes:
- /xiaomusic_conf:/app/conf
- /xiaomusic_music:/app/music
EOF
```
---
### 评论 3 - worrywast
为啥我的播放完一首音乐之后,还会播放该歌曲开头一点点才会放下一首呢?
---
### 评论 4 - hanxi
> 为啥我的播放完一首音乐之后,还会播放该歌曲开头一点点才会放下一首呢?
正常现象。可以把延迟设置为0试试。
---
### 评论 5 - worrywast
> > 为啥我的播放完一首音乐之后,还会播放该歌曲开头一点点才会放下一首呢?
>
> 正常现象。可以把延迟设置为0试试。
是这个选项吗:“下一首歌延迟播放秒数:”
我设置为0也会有这个现象只是没有之前播放开头那么多
---
### 评论 6 - hanxi
@worrywast 等下个版本我优化一下,允许设置成负数吧。
---
### 评论 7 - worrywast
> [@worrywast](https://github.com/worrywast) 等下个版本我优化一下,允许设置成负数吧。
辛苦大佬~
---
### 评论 8 - hanxi
@worrywast 现在就是可以填负数的,你可以试试看。
---
[链接到 GitHub Issue](https://github.com/hanxi/xiaomusic/issues/360)

View File

@@ -388,5 +388,21 @@ Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'http://m7.music.126.net/20241216093525/
重构方案 #314
---
### 评论 17 - LiyuTian-web
下指令后会重新播放歌曲。比如正在播放晴天,下指令声音小一点,这时会重新从头开始播放晴天这首歌,而不会继续播放。
---
### 评论 18 - hanxi
> 下指令后会重新播放歌曲。比如正在播放晴天,下指令声音小一点,这时会重新从头开始播放晴天这首歌,而不会继续播放。
这是正常现象。
另外请不要在不相干的帖子下面反馈问题。 @LiyuTian-web
---
[链接到 GitHub Issue](https://github.com/hanxi/xiaomusic/issues/78)

View File

@@ -4,7 +4,7 @@ title: 微信交流群二维码
# 微信交流群二维码
![Image](https://gproxy.hanxi.cc/proxy/user-attachments/assets/63ac02ae-2051-46cf-9865-a81b5acde65d)
<img width="1031" height="1440" alt="Image" src="https://gproxy.hanxi.cc/proxy/user-attachments/assets/3fed9f9d-f828-4232-9a75-94a67f3a8bab" />
如果你刚好在买流量卡,可以在我的微信卡店里看看有没有合适的。
![mmexportc6bd050862507d2806a2da710a82cb28_1735878113870](https://gproxy.hanxi.cc/proxy/user-attachments/assets/ca5a86e0-f753-42d3-8dcb-8583d50d64aa)
@@ -30,5 +30,20 @@ title: 微信交流群二维码
![mm_reward_qrcode_1726365700471](https://gproxy.hanxi.cc/proxy/user-attachments/assets/7863e361-7e61-48a7-bd71-8f8f609f11b4)
---
### 评论 4 - weplayro
二维码过期了
---
### 评论 5 - hanxi
> 二维码过期了
更新了
---
[链接到 GitHub Issue](https://github.com/hanxi/xiaomusic/issues/86)

View File

@@ -13,5 +13,39 @@ title: ios系统上的捷径配置
## 评论
没有评论。
### 评论 1 - Yumega
为什么我的捷径设置无效
http://192.168.11.1:5678/cmd 这个电脑可以打开 显示 {"detail":"Method Not Allowed"}
参照楼主的方法 用iOS捷径无效
---
### 评论 2 - hanxi
方便截图看看怎么填的吗?
---
### 评论 3 - Yumega
![Image](https://gproxy.hanxi.cc/proxy/user-attachments/assets/448e0837-665a-4c46-9598-9c747bdbc422)
---
### 评论 4 - Yumega
> 方便截图看看怎么填的吗?
😏什么原因
---
### 评论 5 - hanxi
@Yumega 等有空我试试,目前没时间。
---
[链接到 GitHub Issue](https://github.com/hanxi/xiaomusic/issues/96)

View File

@@ -29,6 +29,8 @@ title: 💬 FAQ问题集合
> 4. mi.com官网重新登陆。
> 5. 检查 setting.json 文件里的账号密码是否正确。
如果是在 openwrt 类路由器系统上安装的,请检查路由器的防火墙设置。
## ❓ 网页后台可以播放,语音控制无效
这种情况是拉取不到对话记录导致的。
@@ -51,6 +53,10 @@ title: 💬 FAQ问题集合
如果是配了公网反代端口,注意区分是 http 还是 https ,如果是 https 的,配置 XIAOMUSIC_HOSTNAME 时需要加上 `https:// ` 前缀。
如果是在 openwrt 类路由器系统上安装的,请检查路由器的防火墙设置。
如果是在 windows 上安装的请关闭防火墙。另外ip别填localhost填192开头的那个ip.
## ❓ 无法播放 flac 格式歌曲
因设备差异和文件格式差异,已知部分设备不支持 flac 格式,比如 L05B L05C 。
@@ -201,6 +207,29 @@ docker run --rm -it browsh/browsh --startup-url https://mi.com
4. 查看容器日志中的歌曲链接是否正常,点击后台页面上的播放歌曲时,容器中会有歌曲链接,一般是 http 开头的链接,复制完整链接到浏览器试试看能否打开,能打开说明网络没问题,继续下一步排查。不能打开有可能是 ip 和端口配置错误,请使用设置页面的自动填按钮自动填 ip 和端口。
5. 歌曲文件格式是否是 mp3 格式,有些型号无法播放 flac 格式的歌曲,请使用 mp3 格式的歌曲文件测试,一个不行就多找几个文件测试。
## 在安装好第一次用语音正常,第二天就不能用语音了
拉取对话记录的问题。拉取对话记录太频繁了,可以使用[定时任务功能](/issues/182.html)设置晚上关闭拉取对话记录。比如这样设置是早上6点开启拉取对话记录晚上12点关闭
```
[
{
"expression": "0 6 * * *",
"name": "set_pull_ask",
"arg1": "enable"
},
{
"expression": "0 0 * * *",
"name": "set_pull_ask",
"arg1": "disable"
}
]
```
## 播放下一首歌曲时会重复播放上一首歌曲的前几秒
时间延迟问题,可以把【下一首歌延迟播放秒数】设置成负数,表示提前几秒结束播放。
## 评论
@@ -1639,5 +1668,601 @@ ZZZZZZ最后发现是没刷新页面, 收藏没刷新出来. 语音命令是有
部署在我台式机上,关闭了防火墙,台式机与小爱音箱连接了同一个热点
---
### 评论 105 - ocean412257013
请教 在build的时候报错是哪个意思
![Image](https://gproxy.hanxi.cc/proxy/user-attachments/assets/8e6df9f7-0dd1-4bea-b584-c271073a7411)
---
### 评论 106 - hanxi
> 请教 在build的时候报错是哪个意思
>
> ![Image](https://gproxy.hanxi.cc/proxy/user-attachments/assets/8e6df9f7-0dd1-4bea-b584-c271073a7411)
换个国内的镜像。
---
### 评论 107 - quickflash2
我用DOCKER布署的语音可以正常播放本地音乐但是说“本地搜索播放”始终无法执行都是小爱本身的的语音提示网页里的搜索和下载是正常使用的想问下怎么解决
---
### 评论 108 - hanxi
> 我用DOCKER布署的语音可以正常播放本地音乐但是说“本地搜索播放”始终无法执行都是小爱本身的的语音提示网页里的搜索和下载是正常使用的想问下怎么解决
播放歌曲口令是否正常?
---
### 评论 109 - quickflash2
> > 我用DOCKER布署的语音可以正常播放本地音乐但是说“本地搜索播放”始终无法执行都是小爱本身的的语音提示网页里的搜索和下载是正常使用的想问下怎么解决
>
> 播放歌曲口令是否正常?
播放口令正常,使用网页版搜索功能正常,就是“本地搜索播放”和“小爱搜索播放”语音不能使用
---
### 评论 110 - wtyeoh
我在设置里勾选了两台小爱音箱,叫任意一台播放的时候两台都会一起播放,是不是只能勾选一个?
---
### 评论 111 - quickflash2
> > 我用DOCKER布署的语音可以正常播放本地音乐但是说“本地搜索播放”始终无法执行都是小爱本身的的语音提示网页里的搜索和下载是正常使用的想问下怎么解决
>
> 播放歌曲口令是否正常?
楼主,我问题解决了,命令调用里不知道怎么回事这个搜索播放的命令没有了,重新加上就可以了,谢谢大佬
---
### 评论 112 - 22555642
你好我在群辉DOCKER上部署运行后一直打不开设置页面点开日志里面写的是这个请问要怎么办呢
2025/07/18 17:15:55 | stdout | [2025-07-18 17:15:54] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
-- | -- | --
2025/07/18 17:15:55 | stdout | [2025-07-18 17:15:54] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
2025/07/18 17:15:55 | stdout | ==> /app/xiaomusic.log.txt <==
2025/07/18 17:15:55 | stdout |  
2025/07/18 17:15:55 | stderr | tail: /app/xiaomusic.log.txt has been replaced; following end of new file
2025/07/18 17:15:52 | stdout | 2025-07-18 17:15:51,292 INFO spawned: 'xiaomusic' with pid 21
2025/07/18 17:15:48 | stdout | 2025-07-18 17:15:47,284 WARN exited: xiaomusic (exit status 1; not expected)
2025/07/18 17:15:48 | stdout | ==> /app/supervisord.log <==
2025/07/18 17:15:48 | stdout |  
2025/07/18 17:15:43 | stderr | tail: /app/xiaomusic.log.txt has been replaced; following end of new file
2025/07/18 17:15:43 | stdout | [2025-07-18 17:15:42] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
2025/07/18 17:15:43 | stdout | [2025-07-18 17:15:42] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
2025/07/18 17:15:43 | stdout | ==> /app/xiaomusic.log.txt <==
2025/07/18 17:15:43 | stdout |  
2025/07/18 17:15:40 | stdout | 2025-07-18 17:15:39,479 INFO spawned: 'xiaomusic' with pid 18
2025/07/18 17:15:37 | stdout | 2025-07-18 17:15:36,473 WARN exited: xiaomusic (exit status 1; not expected)
2025/07/18 17:15:37 | stdout | ==> /app/supervisord.log <==
2025/07/18 17:15:37 | stdout |  
2025/07/18 17:15:33 | stdout | [2025-07-18 17:15:32] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
2025/07/18 17:15:33 | stdout | [2025-07-18 17:15:32] [0.3.83] [INFO] xiaomusic.py:1373: The file conf/setting.json does not exist.
2025/07/18 17:15:33 | stdout | ==> /app/xiaomusic.log.txt <==
---
### 评论 113 - daheiniu851
播放歌曲时一会停止,一会又继续播放 ,怎么办
---
### 评论 114 - hanxi
> 播放歌曲时一会停止,一会又继续播放 ,怎么办
是不是歌曲文件太大了?
---
### 评论 115 - daheiniu851
小爱提示;播放失败,请检查网络,或换一个试试吧的错误
按照你的提示 本机有声音,小爱音箱没声音解决办法都试了还是不行
排查步骤:
测试链接是否能播放,能播放说明小爱音箱控制没问题,继续下一步排查。不能播放说明控制不了你的小爱音箱,一般是【型号兼容模式】设置问题。模式改了
小爱音箱和 NAS 是否在同一个局域网,检查 NAS 的 IP 和音箱的 IP 是否在同一个网段,不在同一个网段会导致音箱无法访问到 NAS 。如果在同一个局域网,检查 NAS 上的防火墙配置,关闭防火墙再测试,如果还是不行就继续下一步。
查看容器日志中的歌曲链接是否正常,点击后台页面上的播放歌曲时,容器中会有歌曲链接,一般是 http 开头的链接,复制完整链接到浏览器试试看能否打开,能打开说明网络没问题,继续下一步排查。不能打开有可能是 ip 和端口配置错误,请使用设置页面的自动填按钮自动填 ip 和端口。
歌曲文件格式是否是 mp3 格式,有些型号无法播放 flac 格式的歌曲,请使用 mp3 格式的歌曲文件测试,一个不行就多找几个文件测试。
1.模式改了true
2.nas与音箱统一网段
3.容器内的连接可以播放
4.歌曲全是MP3的
都不管用
2025/08/02 23:52:15 stdout [2025-08-02 23:52:15] [0.3.83] [WARNING] analytics.py:70: google analytics run_with_cancel failed <urlopen error [Errno 110] Operation timed out>
2025/08/02 23:52:15 stdout [2025-08-02 23:52:15] [0.3.83] [WARNING] analytics.py:70: google analytics run_with_cancel failed <urlopen error [Errno 110] Operation timed out>
2025/08/02 23:52:15 stdout [2025-08-02 23:52:15] [0.3.83] [WARNING] analytics.py:70: google analytics run_with_cancel failed <urlopen error [Errno 110] Operation timed out>
2025/08/02 23:52:15 stdout [2025-08-02 23:52:15] [0.3.83] [WARNING] analytics.py:70: google analytics run_with_cancel failed <urlopen error [Errno 110] Operation timed out>
2025/08/02 23:52:15 stdout [2025-08-02 23:52:15] [0.3.83] [WARNING] analytics.py:70: google analytics run_with_cancel failed <urlopen error [Errno 110] Operation timed out>
2025/08/02 23:52:15 stdout [2025-08-02 23:52:15] [0.3.83] [WARNING] analytics.py:70: google analytics run_with_cancel failed <urlopen error [Errno 110] Operation timed out>
2025/08/02 23:52:15 stdout [2025-08-02 23:52:15] [0.3.83] [WARNING] analytics.py:70: google analytics run_with_cancel failed <urlopen error [Errno 110] Operation timed out>
2025/08/02 23:52:15 stdout [2025-08-02 23:52:15] [0.3.83] [WARNING] analytics.py:70: google analytics run_with_cancel failed <urlopen error [Errno 110] Operation timed out>
2025/08/02 23:52:15 stdout [2025-08-02 23:52:15] [0.3.83] [WARNING] analytics.py:70: google analytics run_with_cancel failed <urlopen error [Errno 110] Operation timed out>
2025/08/02 23:50:08 stdout aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout raise client_error(req.connection_key, exc) from exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1271, in _wrap_create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transp, proto = await self._wrap_create_connection(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1530, in _create_direct_connection
2025/08/02 23:50:08 stdout raise last_exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1561, in _create_direct_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout _, proto = await self._create_direct_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1189, in _create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout proto = await self._create_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 622, in connect
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout conn = await self._connector.connect(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 723, in _connect_and_send_request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout resp = await handler(req)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 768, in _request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout self._resp: _RetType = await self._coro
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 1480, in __aenter__
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout async with session.post(url, json=data, headers=headers) as response:
2025/08/02 23:50:08 stdout File "/app/xiaomusic/analytics.py", line 107, in post_to_umami
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout The above exception was the direct cause of the following exception:
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout ConnectionResetError: [Errno 104] Connection reset by peer
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout nbytes = self._sock.recv_into(buf)
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 988, in _read_ready__get_buffer
2025/08/02 23:50:08 stdout await waiter
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1192, in _create_connection_transport
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transport, protocol = await self._create_connection_transport(
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1159, in create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout return await self._loop.create_connection(*args, **kwargs, sock=sock)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1263, in _wrap_create_connection
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout [2025-08-02 23:50:08] [0.3.83] [ERROR] analytics.py:111: Execption Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout raise client_error(req.connection_key, exc) from exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1271, in _wrap_create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transp, proto = await self._wrap_create_connection(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1530, in _create_direct_connection
2025/08/02 23:50:08 stdout raise last_exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1561, in _create_direct_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout _, proto = await self._create_direct_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1189, in _create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout proto = await self._create_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 622, in connect
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout conn = await self._connector.connect(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 723, in _connect_and_send_request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout resp = await handler(req)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 768, in _request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout self._resp: _RetType = await self._coro
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 1480, in __aenter__
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout async with session.post(url, json=data, headers=headers) as response:
2025/08/02 23:50:08 stdout File "/app/xiaomusic/analytics.py", line 107, in post_to_umami
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout The above exception was the direct cause of the following exception:
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout ConnectionResetError: [Errno 104] Connection reset by peer
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout nbytes = self._sock.recv_into(buf)
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 988, in _read_ready__get_buffer
2025/08/02 23:50:08 stdout await waiter
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1192, in _create_connection_transport
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transport, protocol = await self._create_connection_transport(
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1159, in create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout return await self._loop.create_connection(*args, **kwargs, sock=sock)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1263, in _wrap_create_connection
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout [2025-08-02 23:50:08] [0.3.83] [ERROR] analytics.py:111: Execption Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout raise client_error(req.connection_key, exc) from exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1271, in _wrap_create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transp, proto = await self._wrap_create_connection(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1530, in _create_direct_connection
2025/08/02 23:50:08 stdout raise last_exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1561, in _create_direct_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout _, proto = await self._create_direct_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1189, in _create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout proto = await self._create_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 622, in connect
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout conn = await self._connector.connect(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 723, in _connect_and_send_request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout resp = await handler(req)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 768, in _request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout self._resp: _RetType = await self._coro
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 1480, in __aenter__
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout async with session.post(url, json=data, headers=headers) as response:
2025/08/02 23:50:08 stdout File "/app/xiaomusic/analytics.py", line 107, in post_to_umami
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout The above exception was the direct cause of the following exception:
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout ConnectionResetError: [Errno 104] Connection reset by peer
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout nbytes = self._sock.recv_into(buf)
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 988, in _read_ready__get_buffer
2025/08/02 23:50:08 stdout await waiter
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1192, in _create_connection_transport
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transport, protocol = await self._create_connection_transport(
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1159, in create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout return await self._loop.create_connection(*args, **kwargs, sock=sock)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1263, in _wrap_create_connection
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout [2025-08-02 23:50:08] [0.3.83] [ERROR] analytics.py:111: Execption Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout raise client_error(req.connection_key, exc) from exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1271, in _wrap_create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transp, proto = await self._wrap_create_connection(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1530, in _create_direct_connection
2025/08/02 23:50:08 stdout raise last_exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1561, in _create_direct_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout _, proto = await self._create_direct_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1189, in _create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout proto = await self._create_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 622, in connect
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout conn = await self._connector.connect(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 723, in _connect_and_send_request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout resp = await handler(req)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 768, in _request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout self._resp: _RetType = await self._coro
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 1480, in __aenter__
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout async with session.post(url, json=data, headers=headers) as response:
2025/08/02 23:50:08 stdout File "/app/xiaomusic/analytics.py", line 107, in post_to_umami
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout The above exception was the direct cause of the following exception:
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout ConnectionResetError: [Errno 104] Connection reset by peer
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout nbytes = self._sock.recv_into(buf)
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 988, in _read_ready__get_buffer
2025/08/02 23:50:08 stdout await waiter
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1192, in _create_connection_transport
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transport, protocol = await self._create_connection_transport(
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1159, in create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout return await self._loop.create_connection(*args, **kwargs, sock=sock)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1263, in _wrap_create_connection
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout [2025-08-02 23:50:08] [0.3.83] [ERROR] analytics.py:111: Execption Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout raise client_error(req.connection_key, exc) from exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1271, in _wrap_create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transp, proto = await self._wrap_create_connection(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1530, in _create_direct_connection
2025/08/02 23:50:08 stdout raise last_exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1561, in _create_direct_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout _, proto = await self._create_direct_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1189, in _create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout proto = await self._create_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 622, in connect
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout conn = await self._connector.connect(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 723, in _connect_and_send_request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout resp = await handler(req)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 768, in _request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout self._resp: _RetType = await self._coro
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 1480, in __aenter__
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout async with session.post(url, json=data, headers=headers) as response:
2025/08/02 23:50:08 stdout File "/app/xiaomusic/analytics.py", line 107, in post_to_umami
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout The above exception was the direct cause of the following exception:
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout ConnectionResetError: [Errno 104] Connection reset by peer
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout nbytes = self._sock.recv_into(buf)
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 988, in _read_ready__get_buffer
2025/08/02 23:50:08 stdout await waiter
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1192, in _create_connection_transport
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transport, protocol = await self._create_connection_transport(
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1159, in create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout return await self._loop.create_connection(*args, **kwargs, sock=sock)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1263, in _wrap_create_connection
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout [2025-08-02 23:50:08] [0.3.83] [ERROR] analytics.py:111: Execption Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout raise client_error(req.connection_key, exc) from exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1271, in _wrap_create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transp, proto = await self._wrap_create_connection(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1530, in _create_direct_connection
2025/08/02 23:50:08 stdout raise last_exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1561, in _create_direct_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout _, proto = await self._create_direct_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1189, in _create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout proto = await self._create_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 622, in connect
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout conn = await self._connector.connect(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 723, in _connect_and_send_request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout resp = await handler(req)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 768, in _request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout self._resp: _RetType = await self._coro
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 1480, in __aenter__
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout async with session.post(url, json=data, headers=headers) as response:
2025/08/02 23:50:08 stdout File "/app/xiaomusic/analytics.py", line 107, in post_to_umami
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout The above exception was the direct cause of the following exception:
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout ConnectionResetError: [Errno 104] Connection reset by peer
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout nbytes = self._sock.recv_into(buf)
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 988, in _read_ready__get_buffer
2025/08/02 23:50:08 stdout await waiter
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1192, in _create_connection_transport
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transport, protocol = await self._create_connection_transport(
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1159, in create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout return await self._loop.create_connection(*args, **kwargs, sock=sock)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1263, in _wrap_create_connection
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout [2025-08-02 23:50:08] [0.3.83] [ERROR] analytics.py:111: Execption Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout raise client_error(req.connection_key, exc) from exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1271, in _wrap_create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transp, proto = await self._wrap_create_connection(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1530, in _create_direct_connection
2025/08/02 23:50:08 stdout raise last_exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1561, in _create_direct_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout _, proto = await self._create_direct_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1189, in _create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout proto = await self._create_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 622, in connect
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout conn = await self._connector.connect(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 723, in _connect_and_send_request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout resp = await handler(req)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 768, in _request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout self._resp: _RetType = await self._coro
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 1480, in __aenter__
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout async with session.post(url, json=data, headers=headers) as response:
2025/08/02 23:50:08 stdout File "/app/xiaomusic/analytics.py", line 107, in post_to_umami
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout The above exception was the direct cause of the following exception:
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout ConnectionResetError: [Errno 104] Connection reset by peer
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout nbytes = self._sock.recv_into(buf)
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 988, in _read_ready__get_buffer
2025/08/02 23:50:08 stdout await waiter
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1192, in _create_connection_transport
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transport, protocol = await self._create_connection_transport(
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1159, in create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout return await self._loop.create_connection(*args, **kwargs, sock=sock)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1263, in _wrap_create_connection
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout [2025-08-02 23:50:08] [0.3.83] [ERROR] analytics.py:111: Execption Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout raise client_error(req.connection_key, exc) from exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1271, in _wrap_create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transp, proto = await self._wrap_create_connection(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1530, in _create_direct_connection
2025/08/02 23:50:08 stdout raise last_exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1561, in _create_direct_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout _, proto = await self._create_direct_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1189, in _create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout proto = await self._create_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 622, in connect
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout conn = await self._connector.connect(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 723, in _connect_and_send_request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout resp = await handler(req)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 768, in _request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout self._resp: _RetType = await self._coro
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 1480, in __aenter__
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout async with session.post(url, json=data, headers=headers) as response:
2025/08/02 23:50:08 stdout File "/app/xiaomusic/analytics.py", line 107, in post_to_umami
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout The above exception was the direct cause of the following exception:
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout ConnectionResetError: [Errno 104] Connection reset by peer
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout nbytes = self._sock.recv_into(buf)
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 988, in _read_ready__get_buffer
2025/08/02 23:50:08 stdout await waiter
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1192, in _create_connection_transport
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transport, protocol = await self._create_connection_transport(
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1159, in create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout return await self._loop.create_connection(*args, **kwargs, sock=sock)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1263, in _wrap_create_connection
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout [2025-08-02 23:50:08] [0.3.83] [ERROR] analytics.py:111: Execption Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:08 stdout raise client_error(req.connection_key, exc) from exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1271, in _wrap_create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transp, proto = await self._wrap_create_connection(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1530, in _create_direct_connection
2025/08/02 23:50:08 stdout raise last_exc
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1561, in _create_direct_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout _, proto = await self._create_direct_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1189, in _create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout proto = await self._create_connection(req, traces, timeout)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 622, in connect
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout conn = await self._connector.connect(
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 723, in _connect_and_send_request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout resp = await handler(req)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 768, in _request
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout self._resp: _RetType = await self._coro
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/client.py", line 1480, in __aenter__
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout async with session.post(url, json=data, headers=headers) as response:
2025/08/02 23:50:08 stdout File "/app/xiaomusic/analytics.py", line 107, in post_to_umami
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout The above exception was the direct cause of the following exception:
2025/08/02 23:50:08 stdout
2025/08/02 23:50:08 stdout ConnectionResetError: [Errno 104] Connection reset by peer
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout nbytes = self._sock.recv_into(buf)
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 988, in _read_ready__get_buffer
2025/08/02 23:50:08 stdout await waiter
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1192, in _create_connection_transport
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout transport, protocol = await self._create_connection_transport(
2025/08/02 23:50:08 stdout File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1159, in create_connection
2025/08/02 23:50:08 stdout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025/08/02 23:50:08 stdout return await self._loop.create_connection(*args, **kwargs, sock=sock)
2025/08/02 23:50:08 stdout File "/app/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1263, in _wrap_create_connection
2025/08/02 23:50:08 stdout Traceback (most recent call last):
2025/08/02 23:50:08 stdout [2025-08-02 23:50:08] [0.3.83] [ERROR] analytics.py:111: Execption Cannot connect to host umami.hanxi.cc:443 ssl:default [Connection reset by peer]
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:101: umami data: {'payload': {'hostname': 'http://192.168.1.14', 'language': 'zh-CN', 'referrer': '', 'screen': '430x932', 'title': '后端统计', 'url': '/backend', 'website': '7bfb0890-4115-4260-8892-b391513e7e99', 'name': 'play', 'data': {'version': '0.3.83', 'music': '17岁', 'sec': 243, 'hardware': 'LX05', 'useragent': 'XiaoMusic/0.3.83 (Linux #69057 SMP Fri Jan 12 17:02:28 CST 2024; 64bit; x86_64) Python/3.12.11'}}, 'type': 'event'}
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:101: umami data: {'payload': {'hostname': 'http://192.168.1.14', 'language': 'zh-CN', 'referrer': '', 'screen': '430x932', 'title': '后端统计', 'url': '/backend', 'website': '7bfb0890-4115-4260-8892-b391513e7e99', 'name': 'play', 'data': {'version': '0.3.83', 'music': '17岁', 'sec': 243, 'hardware': 'LX05', 'useragent': 'XiaoMusic/0.3.83 (Linux #69057 SMP Fri Jan 12 17:02:28 CST 2024; 64bit; x86_64) Python/3.12.11'}}, 'type': 'event'}
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:101: umami data: {'payload': {'hostname': 'http://192.168.1.14', 'language': 'zh-CN', 'referrer': '', 'screen': '430x932', 'title': '后端统计', 'url': '/backend', 'website': '7bfb0890-4115-4260-8892-b391513e7e99', 'name': 'play', 'data': {'version': '0.3.83', 'music': '17岁', 'sec': 243, 'hardware': 'LX05', 'useragent': 'XiaoMusic/0.3.83 (Linux #69057 SMP Fri Jan 12 17:02:28 CST 2024; 64bit; x86_64) Python/3.12.11'}}, 'type': 'event'}
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:101: umami data: {'payload': {'hostname': 'http://192.168.1.14', 'language': 'zh-CN', 'referrer': '', 'screen': '430x932', 'title': '后端统计', 'url': '/backend', 'website': '7bfb0890-4115-4260-8892-b391513e7e99', 'name': 'play', 'data': {'version': '0.3.83', 'music': '17岁', 'sec': 243, 'hardware': 'LX05', 'useragent': 'XiaoMusic/0.3.83 (Linux #69057 SMP Fri Jan 12 17:02:28 CST 2024; 64bit; x86_64) Python/3.12.11'}}, 'type': 'event'}
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:101: umami data: {'payload': {'hostname': 'http://192.168.1.14', 'language': 'zh-CN', 'referrer': '', 'screen': '430x932', 'title': '后端统计', 'url': '/backend', 'website': '7bfb0890-4115-4260-8892-b391513e7e99', 'name': 'play', 'data': {'version': '0.3.83', 'music': '17岁', 'sec': 243, 'hardware': 'LX05', 'useragent': 'XiaoMusic/0.3.83 (Linux #69057 SMP Fri Jan 12 17:02:28 CST 2024; 64bit; x86_64) Python/3.12.11'}}, 'type': 'event'}
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:101: umami data: {'payload': {'hostname': 'http://192.168.1.14', 'language': 'zh-CN', 'referrer': '', 'screen': '430x932', 'title': '后端统计', 'url': '/backend', 'website': '7bfb0890-4115-4260-8892-b391513e7e99', 'name': 'play', 'data': {'version': '0.3.83', 'music': '17岁', 'sec': 243, 'hardware': 'LX05', 'useragent': 'XiaoMusic/0.3.83 (Linux #69057 SMP Fri Jan 12 17:02:28 CST 2024; 64bit; x86_64) Python/3.12.11'}}, 'type': 'event'}
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:101: umami data: {'payload': {'hostname': 'http://192.168.1.14', 'language': 'zh-CN', 'referrer': '', 'screen': '430x932', 'title': '后端统计', 'url': '/backend', 'website': '7bfb0890-4115-4260-8892-b391513e7e99', 'name': 'play', 'data': {'version': '0.3.83', 'music': '17岁', 'sec': 243, 'hardware': 'LX05', 'useragent': 'XiaoMusic/0.3.83 (Linux #69057 SMP Fri Jan 12 17:02:28 CST 2024; 64bit; x86_64) Python/3.12.11'}}, 'type': 'event'}
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:101: umami data: {'payload': {'hostname': 'http://192.168.1.14', 'language': 'zh-CN', 'referrer': '', 'screen': '430x932', 'title': '后端统计', 'url': '/backend', 'website': '7bfb0890-4115-4260-8892-b391513e7e99', 'name': 'play', 'data': {'version': '0.3.83', 'music': '17岁', 'sec': 243, 'hardware': 'LX05', 'useragent': 'XiaoMusic/0.3.83 (Linux #69057 SMP Fri Jan 12 17:02:28 CST 2024; 64bit; x86_64) Python/3.12.11'}}, 'type': 'event'}
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:101: umami data: {'payload': {'hostname': 'http://192.168.1.14', 'language': 'zh-CN', 'referrer': '', 'screen': '430x932', 'title': '后端统计', 'url': '/backend', 'website': '7bfb0890-4115-4260-8892-b391513e7e99', 'name': 'play', 'data': {'version': '0.3.83', 'music': '17岁', 'sec': 243, 'hardware': 'LX05', 'useragent': 'XiaoMusic/0.3.83 (Linux #69057 SMP Fri Jan 12 17:02:28 CST 2024; 64bit; x86_64) Python/3.12.11'}}, 'type': 'event'}
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1410: save_cur_config ok
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1410: save_cur_config ok
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1410: save_cur_config ok
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1410: save_cur_config ok
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1410: save_cur_config ok
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1410: save_cur_config ok
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1410: save_cur_config ok
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1410: save_cur_config ok
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1410: save_cur_config ok
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2063: 246 秒后将会播放下一首歌曲
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2063: 246 秒后将会播放下一首歌曲
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2063: 246 秒后将会播放下一首歌曲
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2063: 246 秒后将会播放下一首歌曲
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2063: 246 秒后将会播放下一首歌曲
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2063: 246 秒后将会播放下一首歌曲
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2063: 246 秒后将会播放下一首歌曲
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2063: 246 秒后将会播放下一首歌曲
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2063: 246 秒后将会播放下一首歌曲
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2146: 下一曲定时器不见了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2146: 下一曲定时器不见了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2146: 下一曲定时器不见了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2146: 下一曲定时器不见了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2146: 下一曲定时器不见了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2146: 下一曲定时器不见了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2146: 下一曲定时器不见了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2146: 下一曲定时器不见了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2146: 下一曲定时器不见了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2140: cancel_next_timer
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2140: cancel_next_timer
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2140: cancel_next_timer
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2140: cancel_next_timer
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2140: cancel_next_timer
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2140: cancel_next_timer
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2140: cancel_next_timer
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2140: cancel_next_timer
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:2140: cancel_next_timer
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:75: analytics run_with_cancel success
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:75: analytics run_with_cancel success
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:75: analytics run_with_cancel success
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:75: analytics run_with_cancel success
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:75: analytics run_with_cancel success
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:75: analytics run_with_cancel success
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:75: analytics run_with_cancel success
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:75: analytics run_with_cancel success
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] analytics.py:75: analytics run_with_cancel success
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1730: 【17岁】已经开始播放了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1730: 【17岁】已经开始播放了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1730: 【17岁】已经开始播放了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1730: 【17岁】已经开始播放了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1730: 【17岁】已经开始播放了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1730: 【17岁】已经开始播放了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1730: 【17岁】已经开始播放了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1730: 【17岁】已经开始播放了
2025/08/02 23:50:06 stdout [2025-08-02 23:50:06] [0.3.83] [INFO] xiaomusic.py:1730: 【17岁】已经开始播放了
---
### 评论 116 - daheiniu851
在飞牛里面可以用,群晖不可以
---
[链接到 GitHub Issue](https://github.com/hanxi/xiaomusic/issues/99)

View File

@@ -1,5 +1,51 @@
# 版本日志
## v0.3.83 (2025-06-12)
### Feat
- 新增开关控制是否开始谷歌统计 see #473
- 支持b站合集和收藏下载 (#487)
### Fix
- 修复安全问题
- 修复安全问题
## v0.3.82 (2025-05-30)
### Fix
- 修复节假日文件没有打包到 docker 镜像里的问题
## v0.3.81 (2025-05-28)
### Feat
- 定时任务支持工作日和休息日 see #182
### Fix
- 动态小程序码生成接口 (#478)
- 指定日志编码,避免中文乱码 (#475)
## v0.3.80 (2025-05-18)
### Feat
- 新增 OH2 型号的支持
- 支持配置最大搜索歌曲数量 see #462
### Fix
- 修复获取在线歌曲长度 (#469)
## v0.3.79 (2025-04-29)
### Fix
- 修复型号LX05不能播放问题
## v0.3.78 (2025-04-09)
### Feat

View File

@@ -77,16 +77,19 @@ services:
> docker 和 docker compose 二选一即可,启动成功后,在 web 页面可以配置其他参数,带有 `*` 号的配置是必须要配置的,其他的用不上时不用修改。初次配置时需要在页面上输入小米账号和密码保存后才能获取到设备列表。
> [!TIP]
> 目前安装步骤已经是最简化了,如果还是嫌安装麻烦,可以微信或者 QQ 约我远程安装,我一般周末和晚上才有时间,个辛苦费 :moneybag: 50 元一次,安装失败不收费
> 目前安装步骤已经是最简化了,如果还是嫌安装麻烦,可以微信或者 QQ 约我远程安装,我一般周末和晚上才有时间,需要赞助个辛苦费 :moneybag: 50 元一次。
遇到问题可以去 web 设置页面底部点击【下载日志文件】按钮,然后搜索一下日志文件内容确保里面没有账号密码信息后(有就删除这些敏感信息),然后在提 issues 反馈问题时把下载的日志文件带上。
> [!TIP]
> 作者的另一个适用于 NAS 上安装的开源工具: <https://github.com/hanxi/tiny-nav>
> [!TIP]
>
> - 🔥【广告:可用于安装 frp 实现内网穿透】
> - 🔥 海外 RackNerd VPS 机器推荐,可支付宝付款。
> - <a href="https://my.racknerd.com/aff.php?aff=11177"><img src="https://racknerd.com/banners/320x50.gif" alt="RackNerd Mobile Leaderboard Banner" width="320" height="50"></a>
> - 不知道选哪个套餐可以直接买这个最便宜的 <https://my.racknerd.com/aff.php?aff=11177&pid=903>
> - 不知道选哪个套餐可以直接买这个最便宜的 <https://my.racknerd.com/aff.php?aff=11177&pid=912>
> - 也可以用来部署代理docker 部署方法见 <https://github.com/hanxi/blog/issues/96>
> [!TIP]
@@ -94,6 +97,11 @@ services:
> - 🔥【广告: 搭建您的专属大模型主页
告别繁琐配置难题一键即可畅享稳定流畅的AI体验】<https://university.aliyun.com/mobile?userCode=szqvatm6>
> [!TIP]
> - 免费主机
> - <a href="https://dartnode.com?aff=SnappyPigeon570"><img src="https://dartnode.com/branding/DN-Open-Source-sm.png" alt="Powered by DartNode - Free VPS for Open Source" width="320"></a>
### 🤐 支持语音口令
- 【播放歌曲】,播放本地的歌曲
@@ -208,6 +216,7 @@ docker build -t xiaomusic .
| X08C X08E X8F | 已经不需要设置了. ~需要设置【型号兼容模式】选项为 true~ |
| M01/XMYX01JY | 小米小爱音箱HD 需要设置【特殊型号获取对话记录】选项为 true 才能语音播放|
| OH2P | XIAOMI 智能音箱 Pro |
| OH2 | XIAOMI 智能音箱 |
型号与产品名称对照可以在这里查询 <https://home.miot-spec.com/s/xiaomi.wifispeaker>

170
holiday/2007.json Normal file
View File

@@ -0,0 +1,170 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2007.json",
"year": 2007,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2008-03/28/content_1761.htm"
],
"days": [
{
"name": "元旦",
"date": "2006-12-30",
"isOffDay": false
},
{
"name": "元旦",
"date": "2006-12-31",
"isOffDay": false
},
{
"name": "元旦",
"date": "2007-01-01",
"isOffDay": true
},
{
"name": "元旦",
"date": "2007-01-02",
"isOffDay": true
},
{
"name": "元旦",
"date": "2007-01-03",
"isOffDay": true
},
{
"name": "春节",
"date": "2007-02-17",
"isOffDay": false
},
{
"name": "春节",
"date": "2007-02-18",
"isOffDay": true
},
{
"name": "春节",
"date": "2007-02-19",
"isOffDay": true
},
{
"name": "春节",
"date": "2007-02-20",
"isOffDay": true
},
{
"name": "春节",
"date": "2007-02-21",
"isOffDay": true
},
{
"name": "春节",
"date": "2007-02-22",
"isOffDay": true
},
{
"name": "春节",
"date": "2007-02-23",
"isOffDay": true
},
{
"name": "春节",
"date": "2007-02-24",
"isOffDay": true
},
{
"name": "春节",
"date": "2007-02-25",
"isOffDay": false
},
{
"name": "“五一”",
"date": "2007-04-28",
"isOffDay": false
},
{
"name": "“五一”",
"date": "2007-04-29",
"isOffDay": false
},
{
"name": "“五一”",
"date": "2007-05-01",
"isOffDay": true
},
{
"name": "“五一”",
"date": "2007-05-02",
"isOffDay": true
},
{
"name": "“五一”",
"date": "2007-05-03",
"isOffDay": true
},
{
"name": "“五一”",
"date": "2007-05-04",
"isOffDay": true
},
{
"name": "“五一”",
"date": "2007-05-05",
"isOffDay": true
},
{
"name": "“五一”",
"date": "2007-05-06",
"isOffDay": true
},
{
"name": "“五一”",
"date": "2007-05-07",
"isOffDay": true
},
{
"name": "“十一”",
"date": "2007-09-29",
"isOffDay": false
},
{
"name": "“十一”",
"date": "2007-09-30",
"isOffDay": false
},
{
"name": "“十一”",
"date": "2007-10-01",
"isOffDay": true
},
{
"name": "“十一”",
"date": "2007-10-02",
"isOffDay": true
},
{
"name": "“十一”",
"date": "2007-10-03",
"isOffDay": true
},
{
"name": "“十一”",
"date": "2007-10-04",
"isOffDay": true
},
{
"name": "“十一”",
"date": "2007-10-05",
"isOffDay": true
},
{
"name": "“十一”",
"date": "2007-10-06",
"isOffDay": true
},
{
"name": "“十一”",
"date": "2007-10-07",
"isOffDay": true
}
]
}

185
holiday/2008.json Normal file
View File

@@ -0,0 +1,185 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2008.json",
"year": 2008,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2008-03/28/content_1645.htm"
],
"days": [
{
"name": "元旦",
"date": "2007-12-29",
"isOffDay": false
},
{
"name": "元旦",
"date": "2007-12-30",
"isOffDay": true
},
{
"name": "元旦",
"date": "2007-12-31",
"isOffDay": true
},
{
"name": "元旦",
"date": "2008-01-01",
"isOffDay": true
},
{
"name": "春节",
"date": "2008-02-02",
"isOffDay": false
},
{
"name": "春节",
"date": "2008-02-03",
"isOffDay": false
},
{
"name": "春节",
"date": "2008-02-06",
"isOffDay": true
},
{
"name": "春节",
"date": "2008-02-07",
"isOffDay": true
},
{
"name": "春节",
"date": "2008-02-08",
"isOffDay": true
},
{
"name": "春节",
"date": "2008-02-09",
"isOffDay": true
},
{
"name": "春节",
"date": "2008-02-10",
"isOffDay": true
},
{
"name": "春节",
"date": "2008-02-11",
"isOffDay": true
},
{
"name": "春节",
"date": "2008-02-12",
"isOffDay": true
},
{
"name": "清明节",
"date": "2008-04-04",
"isOffDay": true
},
{
"name": "清明节",
"date": "2008-04-05",
"isOffDay": true
},
{
"name": "清明节",
"date": "2008-04-06",
"isOffDay": true
},
{
"name": "“五一”国际劳动节",
"date": "2008-05-01",
"isOffDay": true
},
{
"name": "“五一”国际劳动节",
"date": "2008-05-02",
"isOffDay": true
},
{
"name": "“五一”国际劳动节",
"date": "2008-05-03",
"isOffDay": true
},
{
"name": "“五一”国际劳动节",
"date": "2008-05-04",
"isOffDay": false
},
{
"name": "端午节",
"date": "2008-06-07",
"isOffDay": true
},
{
"name": "端午节",
"date": "2008-06-08",
"isOffDay": true
},
{
"name": "端午节",
"date": "2008-06-09",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2008-09-13",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2008-09-14",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2008-09-15",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2008-09-27",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2008-09-28",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2008-09-29",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2008-09-30",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2008-10-01",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2008-10-02",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2008-10-03",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2008-10-04",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2008-10-05",
"isOffDay": true
}
]
}

175
holiday/2009.json Normal file
View File

@@ -0,0 +1,175 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2009.json",
"year": 2009,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2008-12/10/content_1572.htm"
],
"days": [
{
"name": "元旦",
"date": "2009-01-01",
"isOffDay": true
},
{
"name": "元旦",
"date": "2009-01-02",
"isOffDay": true
},
{
"name": "元旦",
"date": "2009-01-03",
"isOffDay": true
},
{
"name": "元旦",
"date": "2009-01-04",
"isOffDay": false
},
{
"name": "春节",
"date": "2009-01-24",
"isOffDay": false
},
{
"name": "春节",
"date": "2009-01-25",
"isOffDay": true
},
{
"name": "春节",
"date": "2009-01-26",
"isOffDay": true
},
{
"name": "春节",
"date": "2009-01-27",
"isOffDay": true
},
{
"name": "春节",
"date": "2009-01-28",
"isOffDay": true
},
{
"name": "春节",
"date": "2009-01-29",
"isOffDay": true
},
{
"name": "春节",
"date": "2009-01-30",
"isOffDay": true
},
{
"name": "春节",
"date": "2009-01-31",
"isOffDay": true
},
{
"name": "春节",
"date": "2009-02-01",
"isOffDay": false
},
{
"name": "清明节",
"date": "2009-04-04",
"isOffDay": true
},
{
"name": "清明节",
"date": "2009-04-05",
"isOffDay": true
},
{
"name": "清明节",
"date": "2009-04-06",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2009-05-01",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2009-05-02",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2009-05-03",
"isOffDay": true
},
{
"name": "端午节",
"date": "2009-05-28",
"isOffDay": true
},
{
"name": "端午节",
"date": "2009-05-29",
"isOffDay": true
},
{
"name": "端午节",
"date": "2009-05-30",
"isOffDay": true
},
{
"name": "端午节",
"date": "2009-05-31",
"isOffDay": false
},
{
"name": "国庆节、中秋节",
"date": "2009-09-27",
"isOffDay": false
},
{
"name": "国庆节、中秋节",
"date": "2009-10-01",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2009-10-02",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2009-10-03",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2009-10-04",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2009-10-05",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2009-10-06",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2009-10-07",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2009-10-08",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2009-10-10",
"isOffDay": false
}
]
}

195
holiday/2010.json Normal file
View File

@@ -0,0 +1,195 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2010.json",
"year": 2010,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2009-12/08/content_1476.htm"
],
"days": [
{
"name": "元旦",
"date": "2010-01-01",
"isOffDay": true
},
{
"name": "元旦",
"date": "2010-01-02",
"isOffDay": true
},
{
"name": "元旦",
"date": "2010-01-03",
"isOffDay": true
},
{
"name": "春节",
"date": "2010-02-13",
"isOffDay": true
},
{
"name": "春节",
"date": "2010-02-14",
"isOffDay": true
},
{
"name": "春节",
"date": "2010-02-15",
"isOffDay": true
},
{
"name": "春节",
"date": "2010-02-16",
"isOffDay": true
},
{
"name": "春节",
"date": "2010-02-17",
"isOffDay": true
},
{
"name": "春节",
"date": "2010-02-18",
"isOffDay": true
},
{
"name": "春节",
"date": "2010-02-19",
"isOffDay": true
},
{
"name": "春节",
"date": "2010-02-20",
"isOffDay": false
},
{
"name": "春节",
"date": "2010-02-21",
"isOffDay": false
},
{
"name": "清明节",
"date": "2010-04-03",
"isOffDay": true
},
{
"name": "清明节",
"date": "2010-04-04",
"isOffDay": true
},
{
"name": "清明节",
"date": "2010-04-05",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2010-05-01",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2010-05-02",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2010-05-03",
"isOffDay": true
},
{
"name": "端午节",
"date": "2010-06-12",
"isOffDay": false
},
{
"name": "端午节",
"date": "2010-06-13",
"isOffDay": false
},
{
"name": "端午节",
"date": "2010-06-14",
"isOffDay": true
},
{
"name": "端午节",
"date": "2010-06-15",
"isOffDay": true
},
{
"name": "端午节",
"date": "2010-06-16",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2010-09-19",
"isOffDay": false
},
{
"name": "中秋节",
"date": "2010-09-22",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2010-09-23",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2010-09-24",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2010-09-25",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2010-09-26",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2010-10-01",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2010-10-02",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2010-10-03",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2010-10-04",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2010-10-05",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2010-10-06",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2010-10-07",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2010-10-09",
"isOffDay": false
}
]
}

180
holiday/2011.json Normal file
View File

@@ -0,0 +1,180 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2011.json",
"year": 2011,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2010-12/10/content_1423.htm"
],
"days": [
{
"name": "元旦",
"date": "2011-01-01",
"isOffDay": true
},
{
"name": "元旦",
"date": "2011-01-02",
"isOffDay": true
},
{
"name": "元旦",
"date": "2011-01-03",
"isOffDay": true
},
{
"name": "春节",
"date": "2011-01-30",
"isOffDay": false
},
{
"name": "春节",
"date": "2011-02-02",
"isOffDay": true
},
{
"name": "春节",
"date": "2011-02-03",
"isOffDay": true
},
{
"name": "春节",
"date": "2011-02-04",
"isOffDay": true
},
{
"name": "春节",
"date": "2011-02-05",
"isOffDay": true
},
{
"name": "春节",
"date": "2011-02-06",
"isOffDay": true
},
{
"name": "春节",
"date": "2011-02-07",
"isOffDay": true
},
{
"name": "春节",
"date": "2011-02-08",
"isOffDay": true
},
{
"name": "春节",
"date": "2011-02-12",
"isOffDay": false
},
{
"name": "清明节",
"date": "2011-04-02",
"isOffDay": false
},
{
"name": "清明节",
"date": "2011-04-03",
"isOffDay": true
},
{
"name": "清明节",
"date": "2011-04-04",
"isOffDay": true
},
{
"name": "清明节",
"date": "2011-04-05",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2011-04-30",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2011-05-01",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2011-05-02",
"isOffDay": true
},
{
"name": "端午节",
"date": "2011-06-04",
"isOffDay": true
},
{
"name": "端午节",
"date": "2011-06-05",
"isOffDay": true
},
{
"name": "端午节",
"date": "2011-06-06",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2011-09-10",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2011-09-11",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2011-09-12",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2011-10-01",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2011-10-02",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2011-10-03",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2011-10-04",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2011-10-05",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2011-10-06",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2011-10-07",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2011-10-08",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2011-10-09",
"isOffDay": false
}
]
}

180
holiday/2012.json Normal file
View File

@@ -0,0 +1,180 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2012.json",
"year": 2012,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2011-12/06/content_1411.htm"
],
"days": [
{
"name": "元旦",
"date": "2011-12-31",
"isOffDay": false
},
{
"name": "元旦",
"date": "2012-01-01",
"isOffDay": true
},
{
"name": "元旦",
"date": "2012-01-02",
"isOffDay": true
},
{
"name": "元旦",
"date": "2012-01-03",
"isOffDay": true
},
{
"name": "春节",
"date": "2012-01-21",
"isOffDay": false
},
{
"name": "春节",
"date": "2012-01-22",
"isOffDay": true
},
{
"name": "春节",
"date": "2012-01-23",
"isOffDay": true
},
{
"name": "春节",
"date": "2012-01-24",
"isOffDay": true
},
{
"name": "春节",
"date": "2012-01-25",
"isOffDay": true
},
{
"name": "春节",
"date": "2012-01-26",
"isOffDay": true
},
{
"name": "春节",
"date": "2012-01-27",
"isOffDay": true
},
{
"name": "春节",
"date": "2012-01-28",
"isOffDay": true
},
{
"name": "春节",
"date": "2012-01-29",
"isOffDay": false
},
{
"name": "清明节",
"date": "2012-03-31",
"isOffDay": false
},
{
"name": "清明节",
"date": "2012-04-01",
"isOffDay": false
},
{
"name": "清明节",
"date": "2012-04-02",
"isOffDay": true
},
{
"name": "清明节",
"date": "2012-04-03",
"isOffDay": true
},
{
"name": "清明节",
"date": "2012-04-04",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2012-04-28",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2012-04-29",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2012-04-30",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2012-05-01",
"isOffDay": true
},
{
"name": "端午节",
"date": "2012-06-22",
"isOffDay": true
},
{
"name": "端午节",
"date": "2012-06-23",
"isOffDay": true
},
{
"name": "端午节",
"date": "2012-06-24",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2012-09-29",
"isOffDay": false
},
{
"name": "中秋节、国庆节",
"date": "2012-09-30",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2012-10-01",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2012-10-02",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2012-10-03",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2012-10-04",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2012-10-05",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2012-10-06",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2012-10-07",
"isOffDay": true
}
]
}

215
holiday/2013.json Normal file
View File

@@ -0,0 +1,215 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2013.json",
"year": 2013,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2012-12/10/content_1353.htm"
],
"days": [
{
"name": "元旦",
"date": "2013-01-01",
"isOffDay": true
},
{
"name": "元旦",
"date": "2013-01-02",
"isOffDay": true
},
{
"name": "元旦",
"date": "2013-01-03",
"isOffDay": true
},
{
"name": "元旦",
"date": "2013-01-05",
"isOffDay": false
},
{
"name": "元旦",
"date": "2013-01-06",
"isOffDay": false
},
{
"name": "春节",
"date": "2013-02-09",
"isOffDay": true
},
{
"name": "春节",
"date": "2013-02-10",
"isOffDay": true
},
{
"name": "春节",
"date": "2013-02-11",
"isOffDay": true
},
{
"name": "春节",
"date": "2013-02-12",
"isOffDay": true
},
{
"name": "春节",
"date": "2013-02-13",
"isOffDay": true
},
{
"name": "春节",
"date": "2013-02-14",
"isOffDay": true
},
{
"name": "春节",
"date": "2013-02-15",
"isOffDay": true
},
{
"name": "春节",
"date": "2013-02-16",
"isOffDay": false
},
{
"name": "春节",
"date": "2013-02-17",
"isOffDay": false
},
{
"name": "清明节",
"date": "2013-04-04",
"isOffDay": true
},
{
"name": "清明节",
"date": "2013-04-05",
"isOffDay": true
},
{
"name": "清明节",
"date": "2013-04-06",
"isOffDay": true
},
{
"name": "清明节",
"date": "2013-04-07",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2013-04-27",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2013-04-28",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2013-04-29",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2013-04-30",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2013-05-01",
"isOffDay": true
},
{
"name": "端午节",
"date": "2013-06-08",
"isOffDay": false
},
{
"name": "端午节",
"date": "2013-06-09",
"isOffDay": false
},
{
"name": "端午节",
"date": "2013-06-10",
"isOffDay": true
},
{
"name": "端午节",
"date": "2013-06-11",
"isOffDay": true
},
{
"name": "端午节",
"date": "2013-06-12",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2013-09-19",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2013-09-20",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2013-09-21",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2013-09-22",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2013-09-29",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2013-10-01",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2013-10-02",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2013-10-03",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2013-10-04",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2013-10-05",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2013-10-06",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2013-10-07",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2013-10-12",
"isOffDay": false
}
]
}

145
holiday/2014.json Normal file
View File

@@ -0,0 +1,145 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2014.json",
"year": 2014,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2014-01/02/content_1194.htm"
],
"days": [
{
"name": "元旦",
"date": "2014-01-01",
"isOffDay": true
},
{
"name": "春节",
"date": "2014-01-26",
"isOffDay": false
},
{
"name": "春节",
"date": "2014-01-31",
"isOffDay": true
},
{
"name": "春节",
"date": "2014-02-01",
"isOffDay": true
},
{
"name": "春节",
"date": "2014-02-02",
"isOffDay": true
},
{
"name": "春节",
"date": "2014-02-03",
"isOffDay": true
},
{
"name": "春节",
"date": "2014-02-04",
"isOffDay": true
},
{
"name": "春节",
"date": "2014-02-05",
"isOffDay": true
},
{
"name": "春节",
"date": "2014-02-06",
"isOffDay": true
},
{
"name": "春节",
"date": "2014-02-08",
"isOffDay": false
},
{
"name": "清明节",
"date": "2014-04-05",
"isOffDay": true
},
{
"name": "清明节",
"date": "2014-04-07",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2014-05-01",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2014-05-02",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2014-05-03",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2014-05-04",
"isOffDay": false
},
{
"name": "端午节",
"date": "2014-06-02",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2014-09-08",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2014-09-28",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2014-10-01",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2014-10-02",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2014-10-03",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2014-10-04",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2014-10-05",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2014-10-06",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2014-10-07",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2014-10-11",
"isOffDay": false
}
]
}

166
holiday/2015.json Normal file
View File

@@ -0,0 +1,166 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2015.json",
"year": 2015,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2014-12/16/content_9302.htm",
"http://www.gov.cn/zhengce/zhengceku/2015-05/13/content_9742.htm"
],
"days": [
{
"name": "元旦",
"date": "2015-01-01",
"isOffDay": true
},
{
"name": "元旦",
"date": "2015-01-02",
"isOffDay": true
},
{
"name": "元旦",
"date": "2015-01-03",
"isOffDay": true
},
{
"name": "元旦",
"date": "2015-01-04",
"isOffDay": false
},
{
"name": "春节",
"date": "2015-02-15",
"isOffDay": false
},
{
"name": "春节",
"date": "2015-02-18",
"isOffDay": true
},
{
"name": "春节",
"date": "2015-02-19",
"isOffDay": true
},
{
"name": "春节",
"date": "2015-02-20",
"isOffDay": true
},
{
"name": "春节",
"date": "2015-02-21",
"isOffDay": true
},
{
"name": "春节",
"date": "2015-02-22",
"isOffDay": true
},
{
"name": "春节",
"date": "2015-02-23",
"isOffDay": true
},
{
"name": "春节",
"date": "2015-02-24",
"isOffDay": true
},
{
"name": "春节",
"date": "2015-02-28",
"isOffDay": false
},
{
"name": "清明节",
"date": "2015-04-05",
"isOffDay": true
},
{
"name": "清明节",
"date": "2015-04-06",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2015-05-01",
"isOffDay": true
},
{
"name": "端午节",
"date": "2015-06-20",
"isOffDay": true
},
{
"name": "端午节",
"date": "2015-06-22",
"isOffDay": true
},
{
"name": "抗日战争暨世界反法西斯战争胜利70周年纪念日",
"date": "2015-09-03",
"isOffDay": true
},
{
"name": "抗日战争暨世界反法西斯战争胜利70周年纪念日",
"date": "2015-09-04",
"isOffDay": true
},
{
"name": "抗日战争暨世界反法西斯战争胜利70周年纪念日",
"date": "2015-09-05",
"isOffDay": true
},
{
"name": "抗日战争暨世界反法西斯战争胜利70周年纪念日",
"date": "2015-09-06",
"isOffDay": false
},
{
"name": "中秋节",
"date": "2015-09-27",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2015-10-01",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2015-10-02",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2015-10-03",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2015-10-04",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2015-10-05",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2015-10-06",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2015-10-07",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2015-10-10",
"isOffDay": false
}
]
}

160
holiday/2016.json Normal file
View File

@@ -0,0 +1,160 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2016.json",
"year": 2016,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2015-12/10/content_10394.htm"
],
"days": [
{
"name": "元旦",
"date": "2016-01-01",
"isOffDay": true
},
{
"name": "春节",
"date": "2016-02-06",
"isOffDay": false
},
{
"name": "春节",
"date": "2016-02-07",
"isOffDay": true
},
{
"name": "春节",
"date": "2016-02-08",
"isOffDay": true
},
{
"name": "春节",
"date": "2016-02-09",
"isOffDay": true
},
{
"name": "春节",
"date": "2016-02-10",
"isOffDay": true
},
{
"name": "春节",
"date": "2016-02-11",
"isOffDay": true
},
{
"name": "春节",
"date": "2016-02-12",
"isOffDay": true
},
{
"name": "春节",
"date": "2016-02-13",
"isOffDay": true
},
{
"name": "春节",
"date": "2016-02-14",
"isOffDay": false
},
{
"name": "清明节",
"date": "2016-04-04",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2016-05-01",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2016-05-02",
"isOffDay": true
},
{
"name": "端午节",
"date": "2016-06-09",
"isOffDay": true
},
{
"name": "端午节",
"date": "2016-06-10",
"isOffDay": true
},
{
"name": "端午节",
"date": "2016-06-11",
"isOffDay": true
},
{
"name": "端午节",
"date": "2016-06-12",
"isOffDay": false
},
{
"name": "中秋节",
"date": "2016-09-15",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2016-09-16",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2016-09-17",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2016-09-18",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2016-10-01",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2016-10-02",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2016-10-03",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2016-10-04",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2016-10-05",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2016-10-06",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2016-10-07",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2016-10-08",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2016-10-09",
"isOffDay": false
}
]
}

155
holiday/2017.json Normal file
View File

@@ -0,0 +1,155 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2017.json",
"year": 2017,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2016-12/01/content_5141603.htm"
],
"days": [
{
"name": "元旦",
"date": "2017-01-01",
"isOffDay": true
},
{
"name": "元旦",
"date": "2017-01-02",
"isOffDay": true
},
{
"name": "春节",
"date": "2017-01-22",
"isOffDay": false
},
{
"name": "春节",
"date": "2017-01-27",
"isOffDay": true
},
{
"name": "春节",
"date": "2017-01-28",
"isOffDay": true
},
{
"name": "春节",
"date": "2017-01-29",
"isOffDay": true
},
{
"name": "春节",
"date": "2017-01-30",
"isOffDay": true
},
{
"name": "春节",
"date": "2017-01-31",
"isOffDay": true
},
{
"name": "春节",
"date": "2017-02-01",
"isOffDay": true
},
{
"name": "春节",
"date": "2017-02-02",
"isOffDay": true
},
{
"name": "春节",
"date": "2017-02-04",
"isOffDay": false
},
{
"name": "清明节",
"date": "2017-04-01",
"isOffDay": false
},
{
"name": "清明节",
"date": "2017-04-02",
"isOffDay": true
},
{
"name": "清明节",
"date": "2017-04-03",
"isOffDay": true
},
{
"name": "清明节",
"date": "2017-04-04",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2017-05-01",
"isOffDay": true
},
{
"name": "端午节",
"date": "2017-05-27",
"isOffDay": false
},
{
"name": "端午节",
"date": "2017-05-28",
"isOffDay": true
},
{
"name": "端午节",
"date": "2017-05-29",
"isOffDay": true
},
{
"name": "端午节",
"date": "2017-05-30",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2017-09-30",
"isOffDay": false
},
{
"name": "中秋节、国庆节",
"date": "2017-10-01",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2017-10-02",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2017-10-03",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2017-10-04",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2017-10-05",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2017-10-06",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2017-10-07",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2017-10-08",
"isOffDay": true
}
]
}

155
holiday/2018.json Normal file
View File

@@ -0,0 +1,155 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2018.json",
"year": 2018,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2017-11/30/content_5243579.htm"
],
"days": [
{
"name": "元旦",
"date": "2018-01-01",
"isOffDay": true
},
{
"name": "春节",
"date": "2018-02-11",
"isOffDay": false
},
{
"name": "春节",
"date": "2018-02-15",
"isOffDay": true
},
{
"name": "春节",
"date": "2018-02-16",
"isOffDay": true
},
{
"name": "春节",
"date": "2018-02-17",
"isOffDay": true
},
{
"name": "春节",
"date": "2018-02-18",
"isOffDay": true
},
{
"name": "春节",
"date": "2018-02-19",
"isOffDay": true
},
{
"name": "春节",
"date": "2018-02-20",
"isOffDay": true
},
{
"name": "春节",
"date": "2018-02-21",
"isOffDay": true
},
{
"name": "春节",
"date": "2018-02-24",
"isOffDay": false
},
{
"name": "清明节",
"date": "2018-04-05",
"isOffDay": true
},
{
"name": "清明节",
"date": "2018-04-06",
"isOffDay": true
},
{
"name": "清明节",
"date": "2018-04-07",
"isOffDay": true
},
{
"name": "清明节",
"date": "2018-04-08",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2018-04-28",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2018-04-29",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2018-04-30",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2018-05-01",
"isOffDay": true
},
{
"name": "端午节",
"date": "2018-06-18",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2018-09-24",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2018-09-29",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2018-09-30",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2018-10-01",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2018-10-02",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2018-10-03",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2018-10-04",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2018-10-05",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2018-10-06",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2018-10-07",
"isOffDay": true
}
]
}

166
holiday/2019.json Normal file
View File

@@ -0,0 +1,166 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2019.json",
"year": 2019,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2018-12/06/content_5346276.htm",
"http://www.gov.cn/zhengce/zhengceku/2019-03/22/content_5375877.htm"
],
"days": [
{
"name": "元旦",
"date": "2018-12-29",
"isOffDay": false
},
{
"name": "元旦",
"date": "2018-12-30",
"isOffDay": true
},
{
"name": "元旦",
"date": "2018-12-31",
"isOffDay": true
},
{
"name": "元旦",
"date": "2019-01-01",
"isOffDay": true
},
{
"name": "春节",
"date": "2019-02-02",
"isOffDay": false
},
{
"name": "春节",
"date": "2019-02-03",
"isOffDay": false
},
{
"name": "春节",
"date": "2019-02-04",
"isOffDay": true
},
{
"name": "春节",
"date": "2019-02-05",
"isOffDay": true
},
{
"name": "春节",
"date": "2019-02-06",
"isOffDay": true
},
{
"name": "春节",
"date": "2019-02-07",
"isOffDay": true
},
{
"name": "春节",
"date": "2019-02-08",
"isOffDay": true
},
{
"name": "春节",
"date": "2019-02-09",
"isOffDay": true
},
{
"name": "春节",
"date": "2019-02-10",
"isOffDay": true
},
{
"name": "清明节",
"date": "2019-04-05",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2019-04-28",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2019-05-01",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2019-05-02",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2019-05-03",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2019-05-04",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2019-05-05",
"isOffDay": false
},
{
"name": "端午节",
"date": "2019-06-07",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2019-09-13",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2019-09-29",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2019-10-01",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2019-10-02",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2019-10-03",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2019-10-04",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2019-10-05",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2019-10-06",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2019-10-07",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2019-10-12",
"isOffDay": false
}
]
}

196
holiday/2020.json Normal file
View File

@@ -0,0 +1,196 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2020.json",
"year": 2020,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2019-11/21/content_5454164.htm",
"http://www.gov.cn/zhengce/zhengceku/2020-01/27/content_5472352.htm"
],
"days": [
{
"name": "元旦",
"date": "2020-01-01",
"isOffDay": true
},
{
"name": "春节",
"date": "2020-01-19",
"isOffDay": false
},
{
"name": "春节",
"date": "2020-01-24",
"isOffDay": true
},
{
"name": "春节",
"date": "2020-01-25",
"isOffDay": true
},
{
"name": "春节",
"date": "2020-01-26",
"isOffDay": true
},
{
"name": "春节",
"date": "2020-01-27",
"isOffDay": true
},
{
"name": "春节",
"date": "2020-01-28",
"isOffDay": true
},
{
"name": "春节",
"date": "2020-01-29",
"isOffDay": true
},
{
"name": "春节",
"date": "2020-01-30",
"isOffDay": true
},
{
"name": "春节",
"date": "2020-01-31",
"isOffDay": true
},
{
"name": "春节",
"date": "2020-02-01",
"isOffDay": true
},
{
"name": "春节",
"date": "2020-02-02",
"isOffDay": true
},
{
"name": "春节",
"date": "2020-02-03",
"isOffDay": false
},
{
"name": "清明节",
"date": "2020-04-04",
"isOffDay": true
},
{
"name": "清明节",
"date": "2020-04-05",
"isOffDay": true
},
{
"name": "清明节",
"date": "2020-04-06",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2020-04-26",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2020-05-01",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2020-05-02",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2020-05-03",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2020-05-04",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2020-05-05",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2020-05-09",
"isOffDay": false
},
{
"name": "端午节",
"date": "2020-06-25",
"isOffDay": true
},
{
"name": "端午节",
"date": "2020-06-26",
"isOffDay": true
},
{
"name": "端午节",
"date": "2020-06-27",
"isOffDay": true
},
{
"name": "端午节",
"date": "2020-06-28",
"isOffDay": false
},
{
"name": "国庆节、中秋节",
"date": "2020-09-27",
"isOffDay": false
},
{
"name": "国庆节、中秋节",
"date": "2020-10-01",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2020-10-02",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2020-10-03",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2020-10-04",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2020-10-05",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2020-10-06",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2020-10-07",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2020-10-08",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2020-10-10",
"isOffDay": false
}
]
}

200
holiday/2021.json Normal file
View File

@@ -0,0 +1,200 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2021.json",
"year": 2021,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2020-11/25/content_5564127.htm"
],
"days": [
{
"name": "元旦",
"date": "2021-01-01",
"isOffDay": true
},
{
"name": "元旦",
"date": "2021-01-02",
"isOffDay": true
},
{
"name": "元旦",
"date": "2021-01-03",
"isOffDay": true
},
{
"name": "春节",
"date": "2021-02-07",
"isOffDay": false
},
{
"name": "春节",
"date": "2021-02-11",
"isOffDay": true
},
{
"name": "春节",
"date": "2021-02-12",
"isOffDay": true
},
{
"name": "春节",
"date": "2021-02-13",
"isOffDay": true
},
{
"name": "春节",
"date": "2021-02-14",
"isOffDay": true
},
{
"name": "春节",
"date": "2021-02-15",
"isOffDay": true
},
{
"name": "春节",
"date": "2021-02-16",
"isOffDay": true
},
{
"name": "春节",
"date": "2021-02-17",
"isOffDay": true
},
{
"name": "春节",
"date": "2021-02-20",
"isOffDay": false
},
{
"name": "清明节",
"date": "2021-04-03",
"isOffDay": true
},
{
"name": "清明节",
"date": "2021-04-04",
"isOffDay": true
},
{
"name": "清明节",
"date": "2021-04-05",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2021-04-25",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2021-05-01",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2021-05-02",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2021-05-03",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2021-05-04",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2021-05-05",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2021-05-08",
"isOffDay": false
},
{
"name": "端午节",
"date": "2021-06-12",
"isOffDay": true
},
{
"name": "端午节",
"date": "2021-06-13",
"isOffDay": true
},
{
"name": "端午节",
"date": "2021-06-14",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2021-09-18",
"isOffDay": false
},
{
"name": "中秋节",
"date": "2021-09-19",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2021-09-20",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2021-09-21",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2021-09-26",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2021-10-01",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2021-10-02",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2021-10-03",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2021-10-04",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2021-10-05",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2021-10-06",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2021-10-07",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2021-10-09",
"isOffDay": false
}
]
}

200
holiday/2022.json Normal file
View File

@@ -0,0 +1,200 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2022.json",
"year": 2022,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2021-10/25/content_5644835.htm"
],
"days": [
{
"name": "元旦",
"date": "2022-01-01",
"isOffDay": true
},
{
"name": "元旦",
"date": "2022-01-02",
"isOffDay": true
},
{
"name": "元旦",
"date": "2022-01-03",
"isOffDay": true
},
{
"name": "春节",
"date": "2022-01-29",
"isOffDay": false
},
{
"name": "春节",
"date": "2022-01-30",
"isOffDay": false
},
{
"name": "春节",
"date": "2022-01-31",
"isOffDay": true
},
{
"name": "春节",
"date": "2022-02-01",
"isOffDay": true
},
{
"name": "春节",
"date": "2022-02-02",
"isOffDay": true
},
{
"name": "春节",
"date": "2022-02-03",
"isOffDay": true
},
{
"name": "春节",
"date": "2022-02-04",
"isOffDay": true
},
{
"name": "春节",
"date": "2022-02-05",
"isOffDay": true
},
{
"name": "春节",
"date": "2022-02-06",
"isOffDay": true
},
{
"name": "清明节",
"date": "2022-04-02",
"isOffDay": false
},
{
"name": "清明节",
"date": "2022-04-03",
"isOffDay": true
},
{
"name": "清明节",
"date": "2022-04-04",
"isOffDay": true
},
{
"name": "清明节",
"date": "2022-04-05",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2022-04-24",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2022-04-30",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2022-05-01",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2022-05-02",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2022-05-03",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2022-05-04",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2022-05-07",
"isOffDay": false
},
{
"name": "端午节",
"date": "2022-06-03",
"isOffDay": true
},
{
"name": "端午节",
"date": "2022-06-04",
"isOffDay": true
},
{
"name": "端午节",
"date": "2022-06-05",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2022-09-10",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2022-09-11",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2022-09-12",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2022-10-01",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2022-10-02",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2022-10-03",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2022-10-04",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2022-10-05",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2022-10-06",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2022-10-07",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2022-10-08",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2022-10-09",
"isOffDay": false
}
]
}

180
holiday/2023.json Normal file
View File

@@ -0,0 +1,180 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2023.json",
"year": 2023,
"papers": [
"http://www.gov.cn/zhengce/zhengceku/2022-12/08/content_5730844.htm"
],
"days": [
{
"name": "元旦",
"date": "2022-12-31",
"isOffDay": true
},
{
"name": "元旦",
"date": "2023-01-01",
"isOffDay": true
},
{
"name": "元旦",
"date": "2023-01-02",
"isOffDay": true
},
{
"name": "春节",
"date": "2023-01-21",
"isOffDay": true
},
{
"name": "春节",
"date": "2023-01-22",
"isOffDay": true
},
{
"name": "春节",
"date": "2023-01-23",
"isOffDay": true
},
{
"name": "春节",
"date": "2023-01-24",
"isOffDay": true
},
{
"name": "春节",
"date": "2023-01-25",
"isOffDay": true
},
{
"name": "春节",
"date": "2023-01-26",
"isOffDay": true
},
{
"name": "春节",
"date": "2023-01-27",
"isOffDay": true
},
{
"name": "春节",
"date": "2023-01-28",
"isOffDay": false
},
{
"name": "春节",
"date": "2023-01-29",
"isOffDay": false
},
{
"name": "清明节",
"date": "2023-04-05",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2023-04-23",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2023-04-29",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2023-04-30",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2023-05-01",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2023-05-02",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2023-05-03",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2023-05-06",
"isOffDay": false
},
{
"name": "端午节",
"date": "2023-06-22",
"isOffDay": true
},
{
"name": "端午节",
"date": "2023-06-23",
"isOffDay": true
},
{
"name": "端午节",
"date": "2023-06-24",
"isOffDay": true
},
{
"name": "端午节",
"date": "2023-06-25",
"isOffDay": false
},
{
"name": "中秋节、国庆节",
"date": "2023-09-29",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2023-09-30",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2023-10-01",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2023-10-02",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2023-10-03",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2023-10-04",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2023-10-05",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2023-10-06",
"isOffDay": true
},
{
"name": "中秋节、国庆节",
"date": "2023-10-07",
"isOffDay": false
},
{
"name": "中秋节、国庆节",
"date": "2023-10-08",
"isOffDay": false
}
]
}

190
holiday/2024.json Normal file
View File

@@ -0,0 +1,190 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2024.json",
"year": 2024,
"papers": [
"https://www.gov.cn/zhengce/zhengceku/202310/content_6911528.htm"
],
"days": [
{
"name": "元旦",
"date": "2024-01-01",
"isOffDay": true
},
{
"name": "春节",
"date": "2024-02-04",
"isOffDay": false
},
{
"name": "春节",
"date": "2024-02-10",
"isOffDay": true
},
{
"name": "春节",
"date": "2024-02-11",
"isOffDay": true
},
{
"name": "春节",
"date": "2024-02-12",
"isOffDay": true
},
{
"name": "春节",
"date": "2024-02-13",
"isOffDay": true
},
{
"name": "春节",
"date": "2024-02-14",
"isOffDay": true
},
{
"name": "春节",
"date": "2024-02-15",
"isOffDay": true
},
{
"name": "春节",
"date": "2024-02-16",
"isOffDay": true
},
{
"name": "春节",
"date": "2024-02-17",
"isOffDay": true
},
{
"name": "春节",
"date": "2024-02-18",
"isOffDay": false
},
{
"name": "清明节",
"date": "2024-04-04",
"isOffDay": true
},
{
"name": "清明节",
"date": "2024-04-05",
"isOffDay": true
},
{
"name": "清明节",
"date": "2024-04-06",
"isOffDay": true
},
{
"name": "清明节",
"date": "2024-04-07",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2024-04-28",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2024-05-01",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2024-05-02",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2024-05-03",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2024-05-04",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2024-05-05",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2024-05-11",
"isOffDay": false
},
{
"name": "端午节",
"date": "2024-06-10",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2024-09-14",
"isOffDay": false
},
{
"name": "中秋节",
"date": "2024-09-15",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2024-09-16",
"isOffDay": true
},
{
"name": "中秋节",
"date": "2024-09-17",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2024-09-29",
"isOffDay": false
},
{
"name": "国庆节",
"date": "2024-10-01",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2024-10-02",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2024-10-03",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2024-10-04",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2024-10-05",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2024-10-06",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2024-10-07",
"isOffDay": true
},
{
"name": "国庆节",
"date": "2024-10-12",
"isOffDay": false
}
]
}

175
holiday/2025.json Normal file
View File

@@ -0,0 +1,175 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2025.json",
"year": 2025,
"papers": [
"https://www.gov.cn/zhengce/zhengceku/202411/content_6986383.htm"
],
"days": [
{
"name": "元旦",
"date": "2025-01-01",
"isOffDay": true
},
{
"name": "春节",
"date": "2025-01-26",
"isOffDay": false
},
{
"name": "春节",
"date": "2025-01-28",
"isOffDay": true
},
{
"name": "春节",
"date": "2025-01-29",
"isOffDay": true
},
{
"name": "春节",
"date": "2025-01-30",
"isOffDay": true
},
{
"name": "春节",
"date": "2025-01-31",
"isOffDay": true
},
{
"name": "春节",
"date": "2025-02-01",
"isOffDay": true
},
{
"name": "春节",
"date": "2025-02-02",
"isOffDay": true
},
{
"name": "春节",
"date": "2025-02-03",
"isOffDay": true
},
{
"name": "春节",
"date": "2025-02-04",
"isOffDay": true
},
{
"name": "春节",
"date": "2025-02-08",
"isOffDay": false
},
{
"name": "清明节",
"date": "2025-04-04",
"isOffDay": true
},
{
"name": "清明节",
"date": "2025-04-05",
"isOffDay": true
},
{
"name": "清明节",
"date": "2025-04-06",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2025-04-27",
"isOffDay": false
},
{
"name": "劳动节",
"date": "2025-05-01",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2025-05-02",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2025-05-03",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2025-05-04",
"isOffDay": true
},
{
"name": "劳动节",
"date": "2025-05-05",
"isOffDay": true
},
{
"name": "端午节",
"date": "2025-05-31",
"isOffDay": true
},
{
"name": "端午节",
"date": "2025-06-01",
"isOffDay": true
},
{
"name": "端午节",
"date": "2025-06-02",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2025-09-28",
"isOffDay": false
},
{
"name": "国庆节、中秋节",
"date": "2025-10-01",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2025-10-02",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2025-10-03",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2025-10-04",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2025-10-05",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2025-10-06",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2025-10-07",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2025-10-08",
"isOffDay": true
},
{
"name": "国庆节、中秋节",
"date": "2025-10-11",
"isOffDay": false
}
]
}

7
holiday/2026.json Normal file
View File

@@ -0,0 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2026.json",
"year": 2026,
"papers": [],
"days": []
}

7
holiday/renovate.json Normal file
View File

@@ -0,0 +1,7 @@
{
"extends": [
"config:best-practices",
":automergeMinor",
":disableDependencyDashboard"
]
}

29
holiday/schema.json Normal file
View File

@@ -0,0 +1,29 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"type": "object",
"properties": {
"year": {
"type": "number",
"description": "年份"
},
"papers": {
"type": "array",
"items": { "type": "string" },
"description": "所用国务院文件网址列表"
},
"days": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string", "description": "节日名称" },
"date": { "type": "string", "description": "ISO 8601 日期" },
"isOffDay": { "type": "boolean", "description": "是否为休息日" }
},
"required": ["name", "date", "isOffDay"]
}
}
},
"required": ["year", "papers", "days"]
}

View File

@@ -1,6 +1,7 @@
#!/bin/bash
./update-static-version.py
./update-holiday.sh
git add xiaomusic/static
git commit -m 'build: update static version'

View File

@@ -1,6 +1,7 @@
#!/bin/bash
./update-static-version.py
./update-holiday.sh
git add xiaomusic/static
git commit -m 'build: update static version'

View File

@@ -1,6 +1,6 @@
[project]
name = "xiaomusic"
version = "0.3.79"
version = "0.3.84"
description = "Play Music with xiaomi AI speaker"
authors = [
{name = "涵曦", email = "im.hanxi@gmail.com"},

7
update-holiday.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
rm -rf holiday-cn
git clone https://github.com/NateScarlet/holiday-cn.git
mkdir -p holiday
cp holiday-cn/*.json holiday/
rm -rf holiday-cn

View File

@@ -1 +1 @@
__version__ = "0.3.79"
__version__ = "0.3.84"

View File

@@ -57,8 +57,11 @@ class Analytics:
await self._send(event)
async def _send(self, event):
asyncio.create_task(self.post_to_umami(event))
await self.run_with_cancel(self._google_send, [event])
if self.config.enable_analytics:
asyncio.create_task(self.post_to_umami(event))
await self.run_with_cancel(self._google_send, [event])
else:
self.log.info("analytics is disabled, skip sending event")
def _google_send(self, events):
try:

View File

@@ -191,6 +191,9 @@ class Config:
enable_save_tag: bool = (
os.getenv("XIAOMUSIC_ENABLE_SAVE_TAG", "false").lower() == "true"
)
enable_analytics: bool = (
os.getenv("XIAOMUSIC_ENABLE_ANALYTICS", "true").lower() == "true"
)
get_ask_by_mina: bool = (
os.getenv("XIAOMUSIC_GET_ASK_BY_MINA", "false").lower() == "true"
)
@@ -216,6 +219,8 @@ class Config:
enable_cmd_del_music: bool = (
os.getenv("XIAOMUSIC_ENABLE_CMD_DEL_MUSIC", "false").lower() == "true"
)
# 搜索歌曲数量
search_music_count: int = int(os.getenv("XIAOMUSIC_SEARCH_MUSIC_COUNT", "100"))
def append_keyword(self, keys, action):
for key in keys.split(","):

View File

@@ -29,10 +29,13 @@ NEED_USE_PLAY_MUSIC_API = [
"X8F",
"X4B",
"LX05",
"OH2",
"OH2P",
]
# 有 tts command 的设备型号
TTS_COMMAND = {
"OH2": "5-3",
"OH2P": "7-3",
"LX06": "5-1",
"S12": "5-1",

View File

@@ -1,8 +1,60 @@
import json
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.base import BaseTrigger
from apscheduler.triggers.cron import CronTrigger
from xiaomusic.holiday import is_off_day, is_working_day
class CustomCronTrigger(BaseTrigger):
"""自定义触发器支持workday/offday特殊值"""
def __init__(self, cron_expression, holiday_checker=None):
self.cron_expression = cron_expression
self.holiday_checker = holiday_checker
# 分离表达式和注释
expr_parts = cron_expression.split("#", 1)
self.base_expression = expr_parts[0].strip()
self.annotation = expr_parts[1].strip().lower() if len(expr_parts) > 1 else ""
# 检查注释中是否包含特殊值
self.check_workday = "workday" in self.annotation
self.check_offday = "offday" in self.annotation
# 构建基础Cron触发器
try:
self.base_trigger = CronTrigger.from_crontab(self.base_expression)
except Exception as e:
raise ValueError(f"无效的Cron表达式: {self.base_expression}") from e
def get_next_fire_time(self, previous_fire_time, now):
# 获取基础Cron表达式的下一个触发时间
next_time = self.base_trigger.get_next_fire_time(previous_fire_time, now)
if not next_time:
return None
# 如果需要检查工作日/休息日
if self.check_workday or self.check_offday:
year = next_time.year
month = next_time.month
day = next_time.day
if self.check_workday:
valid = is_working_day(year, month, day)
else: # check_offday
valid = is_off_day(year, month, day)
# 如果日期有效,返回时间;否则寻找下一个有效时间
if valid:
return next_time
else:
return self.get_next_fire_time(next_time, next_time)
return next_time
class Crontab:
def __init__(self, log):
@@ -14,12 +66,19 @@ class Crontab:
def add_job(self, expression, job):
try:
trigger = CronTrigger.from_crontab(expression)
# 检查表达式中是否包含注释标记
if "#" in expression and (
"workday" in expression.lower() or "offday" in expression.lower()
):
trigger = CustomCronTrigger(expression)
else:
trigger = CronTrigger.from_crontab(expression)
self.scheduler.add_job(job, trigger)
except ValueError as e:
self.log.error(f"Invalid crontab expression {e}")
except Exception as e:
self.log.exception(f"Execption {e}")
self.log.exception(f"Exception {e}")
# 添加关机任务
def add_job_stop(self, expression, xiaomusic, did, **kwargs):
@@ -98,7 +157,7 @@ class Crontab:
if callable(func):
func(expression, xiaomusic, did=did, arg1=arg1)
self.log.info(
f"crontab add_job_cron ok. did:{did}, name:{name}, arg1:{arg1}"
f"crontab add_job_cron ok. did:{did}, name:{name}, arg1:{arg1} expression:{expression}"
)
else:
self.log.error(

79
xiaomusic/holiday.py Normal file
View File

@@ -0,0 +1,79 @@
import json
import logging
import os
from datetime import date
log = logging.getLogger(__package__)
# 用于存储已加载的年份数据
loaded_years = {}
def load_year_data(year):
"""加载指定年份的节假日数据"""
global loaded_years
if year in loaded_years:
return True
file_path = f"holiday/{year}.json"
if not os.path.exists(file_path):
log.warn(f"未找到 {file_path} 文件。")
return False
try:
with open(file_path, encoding="utf-8") as file:
data = json.load(file)
loaded_years[year] = {
day_info["date"]: day_info["isOffDay"]
for day_info in data.get("days", [])
}
log.info(f"成功加载 {year} 年数据。")
log.debug(f"加载的日期数据: {loaded_years[year]}")
return True
except Exception as e:
log.error(f"加载 {year} 年数据失败: {e}")
return False
def is_valid_date(year, month, day):
"""检查日期是否有效"""
try:
date(year, month, day)
return True
except ValueError:
return False
def is_weekend(year, month, day):
"""判断是否为周末"""
weekday = date(year, month, day).isoweekday()
return weekday >= 6 # 周六或周日
def is_off_day(year, month, day):
"""判断是否为休息日(包括法定节假日和周末)"""
# 检查日期有效性
if not is_valid_date(year, month, day):
log.warn(f"无效日期: {year}-{month:02d}-{day:02d}")
return None
# 加载年份数据
if not load_year_data(year):
return None
date_str = f"{year}-{month:02d}-{day:02d}"
# 检查是否为特殊日期
special_day = loaded_years[year].get(date_str)
if special_day is not None:
return special_day
# 检查是否为周末
return is_weekend(year, month, day)
def is_working_day(year, month, day):
"""判断是否为工作日(非休息日)"""
off_day = is_off_day(year, month, day)
return False if off_day is None else not off_day

View File

@@ -42,6 +42,7 @@ from starlette.responses import FileResponse, Response
from xiaomusic import __version__
from xiaomusic.utils import (
check_bili_fav_list,
chmoddir,
convert_file_to_mp3,
deepcopy_data_no_sensitive_info,
@@ -53,6 +54,7 @@ from xiaomusic.utils import (
remove_common_prefix,
remove_id3_tags,
restart_xiaomusic,
safe_join_path,
try_add_access_control_param,
update_version,
)
@@ -548,14 +550,32 @@ class DownloadPlayList(BaseModel):
@app.post("/downloadplaylist")
async def downloadplaylist(data: DownloadPlayList, Verifcation=Depends(verification)):
try:
download_proc = await download_playlist(config, data.url, data.dirname)
bili_fav_list = await check_bili_fav_list(data.url)
download_proc_list = []
if bili_fav_list:
for bvid, title in bili_fav_list.items():
bvurl = f"https://www.bilibili.com/video/{bvid}"
download_proc_list[title] = await download_one_music(
config, bvurl, os.path.join(data.dirname, title)
)
for title, download_proc_sigle in download_proc_list.items():
exit_code = await download_proc_sigle.wait()
log.info(f"Download completed {title} with exit code {exit_code}")
dir_path = safe_join_path(config.download_path, data.dirname)
log.debug(f"Download dir_path: {dir_path}")
# 可能只是部分失败,都需要整理下载目录
remove_common_prefix(dir_path)
chmoddir(dir_path)
return {"ret": "OK"}
else:
download_proc = await download_playlist(config, data.url, data.dirname)
async def check_download_proc():
# 等待子进程完成
exit_code = await download_proc.wait()
log.info(f"Download completed with exit code {exit_code}")
dir_path = os.path.join(config.download_path, data.dirname)
dir_path = safe_join_path(config.download_path, data.dirname)
log.debug(f"Download dir_path: {dir_path}")
# 可能只是部分失败,都需要整理下载目录
remove_common_prefix(dir_path)

View File

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

View File

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

View File

@@ -5,9 +5,8 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小爱音箱操控面板</title>
<link href="https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined" rel="stylesheet">
<script src="./jquery-3.7.1.min.js?version=1745941221"></script>
<link rel="stylesheet" href="./main.css?version=1745941221">
<script src="./jquery-3.7.1.min.js?version=1754232237"></script>
<link rel="stylesheet" href="./main.css?version=1754232237">
<link rel="icon" href="./favicon.ico">
<!-- Google tag (gtag.js) -->
@@ -20,7 +19,7 @@
</script>
<!-- umami -->
<script async defer src="https://umami.hanxi.cc/script.js" data-website-id="7bfb0890-4115-4260-8892-b391513e7e99"></script>
<!-- <script async defer src="https://umami.hanxi.cc/script.js" data-website-id="7bfb0890-4115-4260-8892-b391513e7e99"></script> -->
</head>
<body class="index_page">
@@ -219,7 +218,7 @@
Powered by XiaoMusic
</div>
<script src="./md.js?version=1745941221">
<script src="./md.js?version=1754232237">
</script>
</body>

View File

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

View File

@@ -356,3 +356,50 @@ span,p {
display: flex;
align-items: center;
}
/* fallback */
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url(./materialicons.woff2) format('woff2');
}
/* fallback */
@font-face {
font-family: 'Material Icons Outlined';
font-style: normal;
font-weight: 400;
src: url(./materialiconsoutlined.woff2) format('woff2');
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-webkit-font-feature-settings: 'liga';
-webkit-font-smoothing: antialiased;
}
.material-icons-outlined {
font-family: 'Material Icons Outlined';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-webkit-font-feature-settings: 'liga';
-webkit-font-smoothing: antialiased;
}

Binary file not shown.

Binary file not shown.

View File

@@ -4,10 +4,9 @@
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width">
<title>小爱音箱操控面板</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="./jquery-3.7.1.min.js?version=1745941221"></script>
<script src="./setting.js?version=1745941221"></script>
<link rel="stylesheet" type="text/css" href="./main.css?version=1745941221">
<script src="./jquery-3.7.1.min.js?version=1754232237"></script>
<script src="./setting.js?version=1754232237"></script>
<link rel="stylesheet" type="text/css" href="./main.css?version=1754232237">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
@@ -19,7 +18,7 @@
</script>
<!-- umami -->
<script async defer src="https://umami.hanxi.cc/script.js" data-website-id="7bfb0890-4115-4260-8892-b391513e7e99"></script>
<!-- <script async defer src="https://umami.hanxi.cc/script.js" data-website-id="7bfb0890-4115-4260-8892-b391513e7e99"></script> -->
<!--
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
@@ -120,6 +119,9 @@ var vConsole = new window.VConsole();
<label for="music_path_depth">目录深度:</label>
<input id="music_path_depth" type="number" value="10" />
<label for="search_music_count">搜索歌曲数量:</label>
<input id="search_music_count" type="number" value="100" />
<label for="search_prefix">XIAOMUSIC_SEARCH(歌曲下载方式):</label>
<select id="search_prefix">
<option value="bilisearch:">bilisearch:</option>
@@ -201,8 +203,8 @@ var vConsole = new window.VConsole();
<label for="pull_ask_sec">获取对话记录间隔(秒):</label>
<input id="pull_ask_sec" type="number" value="1" />
<label for="delay_sec">下一首歌延迟播放秒数:</label>
<input id="delay_sec" type="number" value="3" />
<label for="delay_sec">下一首歌延迟播放秒数(支持负数):</label>
<input id="delay_sec" type="number" value="0" />
<label for="stop_tts_msg">停止提示音:</label>
<input id="stop_tts_msg" type="text" value="收到,再见" />
@@ -257,6 +259,13 @@ var vConsole = new window.VConsole();
<option value="false" selected>false</option>
</select>
<label for="enable_analytics">开启谷歌数据统计(无敏感数据):</label>
<select id="enable_analytics">
<option value="true" selected>true</option>
<option value="false">false</option>
</select>
<label for="music_list_url" class="setting-label">歌单地址:
<button class="option-inline mini-button" id="get_music_list">
<span class="material-icons">sync_alt</span>

View File

@@ -201,6 +201,7 @@
display: flex;
align-items: center;
justify-content: center;
transition: color 0.3s ease;
}
.options a::before {

View File

@@ -26,34 +26,29 @@
padding: 8px;
}
</style>
<script src="https://web-9gikcbug35bad3a8-1304825656.tcloudbaseapp.com/sdk/1.4.0/cloud.js"></script>
</head>
<body>
<img id="qrcode" src="https://assets-1251785959.cos.ap-beijing.myqcloud.com/xiaoplayer/weappcode.jpg" />
<script>
const c1 = new cloud.Cloud({
identityless: true,
resourceAppid: 'wx5931d820da6e8e50',
resourceEnv: 'cards-ahoy-3g50hglqe5f630e4'
})
c1.init().then(() => {
c1.callFunction({
name: 'qrcode',
data: {
host: location.host,
protocol: location.protocol
},
complete: (res) => {
if (res.errMsg === 'cloud.callFunction:ok' && !res.result.errCode) {
const blob = new Blob([res.result.buffer])
const url = URL.createObjectURL(blob)
document.querySelector('#qrcode').setAttribute('src', url)
}
}
fetch('https://xiaoplayer.f-loat.site/qrcode', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
host: location.host,
protocol: location.protocol
})
})
.then(res => {
return res.ok ? res.blob() : null
})
.then(blob => {
if (!blob) return
const url = URL.createObjectURL(blob)
document.querySelector('#qrcode').setAttribute('src', url)
})
</script>
</body>

View File

@@ -22,7 +22,8 @@ import urllib.parse
from collections.abc import AsyncIterator
from dataclasses import asdict, dataclass
from http.cookies import SimpleCookie
from urllib.parse import urlparse
from time import sleep
from urllib.parse import parse_qs, urlparse
import aiohttp
import mutagen
@@ -292,16 +293,41 @@ def is_m4a(url):
async def _get_web_music_duration(session, url, config, start=0, end=500):
"""
异步获取网络音乐文件的部分内容并估算其时长。
通过请求 URL 的前几个字节(默认 0-500下载部分文件
写入临时文件后调用本地工具(如 ffprobe获取音频时长。
:param session: aiohttp.ClientSession 实例
:param url: 音乐文件的 URL 地址
:param config: 包含配置信息的对象(如 ffmpeg 路径)
:param start: 请求的起始字节位置
:param end: 请求的结束字节位置
:return: 返回音频的持续时间(秒),如果失败则返回 0
"""
duration = 0
# 设置请求头 Range只请求部分内容用于快速获取元数据
headers = {"Range": f"bytes={start}-{end}"}
# 使用 aiohttp 异步发起 GET 请求,获取部分音频内容
async with session.get(url, headers=headers) as response:
array_buffer = await response.read()
with tempfile.NamedTemporaryFile() as tmp:
tmp.write(array_buffer)
try:
duration = await get_local_music_duration(tmp, config)
except Exception as e:
log.error(f"Error _get_web_music_duration: {e}")
array_buffer = await response.read() # 读取响应的二进制内容
# 创建一个命名的临时文件,并禁用自动删除(以便后续读取)
with tempfile.NamedTemporaryFile(delete=False) as tmp:
tmp.write(array_buffer) # 将下载的部分内容写入临时文件
tmp_path = tmp.name # 获取该临时文件的真实路径
try:
# 调用 get_local_music_duration 并传入文件路径,而不是文件对象
duration = await get_local_music_duration(tmp_path, config)
except Exception as e:
log.error(f"Error _get_web_music_duration: {e}")
finally:
# 手动删除临时文件,避免残留
os.unlink(tmp_path)
return duration
@@ -916,6 +942,80 @@ def _set_wave_tags(audio, info):
audio["Artist"] = info.artist
async def check_bili_fav_list(url):
bvid_info = {}
parsed_url = urlparse(url)
path = parsed_url.path
# 提取查询参数
query_params = parse_qs(parsed_url.query)
if parsed_url.hostname == "space.bilibili.com":
if "/favlist" in path:
lid = query_params.get("fid", [None])[0]
type = query_params.get("ctype", [None])[0]
if type == "11":
type = "create"
elif type == "21":
type = "collect"
else:
raise ValueError("当前只支持合集和收藏夹")
elif "/lists/" in path:
parts = path.split("/")
if len(parts) >= 4 and "?" in url:
lid = parts[3] # 提取 lid
type = query_params.get("type", [None])[0]
# https://api.bilibili.com/x/polymer/web-space/seasons_archives_list?season_id={lid}&page_size=30&page_num=1
page_size = 100
page_num = 1
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0 Safari/537.36",
"Accept": "application/json, text/plain, */*",
"Referer": url,
"Origin": "https://space.bilibili.com",
}
async with aiohttp.ClientSession(headers=headers) as session:
if type == "season" or type == "collect":
while True:
list_url = f"https://api.bilibili.com/x/polymer/web-space/seasons_archives_list?season_id={lid}&page_size={page_size}&page_num={page_num}"
async with session.get(list_url) as response:
if response.status != 200:
raise Exception(f"Failed to fetch data from {list_url}")
data = await response.json()
archives = data.get("data", {}).get("archives", [])
if not archives:
break
for archive in archives:
bvid = archive.get("bvid", None)
title = archive.get("title", None)
bvid_info[bvid] = title
if len(archives) < page_size:
break
page_num += 1
sleep(1)
elif type == "create":
while True:
list_url = f"https://api.bilibili.com/x/v3/fav/resource/list?media_id={lid}&pn={page_num}&ps={page_size}&order=mtime"
async with session.get(list_url) as response:
if response.status != 200:
raise Exception(f"Failed to fetch data from {list_url}")
data = await response.json()
medias = data.get("data", {}).get("medias", [])
if not medias:
break
for media in medias:
bvid = media.get("bvid", None)
title = media.get("title", None)
bvurl = f"https://www.bilibili.com/video/{bvid}"
bvid_info[bvurl] = title
if len(medias) < page_size:
break
page_num += 1
else:
raise ValueError("当前只支持合集和收藏夹")
return bvid_info
# 下载播放列表
async def download_playlist(config, url, dirname):
title = f"{dirname}/%(title)s.%(ext)s"
@@ -1007,6 +1107,16 @@ def _longest_common_prefix(file_names):
return prefix
def safe_join_path(safe_root, directory):
directory = os.path.join(safe_root, directory)
# Normalize the directory path
normalized_directory = os.path.normpath(directory)
# Ensure the directory is within the safe root
if not normalized_directory.startswith(os.path.normpath(safe_root)):
raise ValueError(f"Access to directory '{directory}' is not allowed.")
return normalized_directory
# 移除目录下文件名前缀相同的
def remove_common_prefix(directory):
files = os.listdir(directory)

View File

@@ -15,7 +15,12 @@ from logging.handlers import RotatingFileHandler
from aiohttp import ClientSession, ClientTimeout
from miservice import MiAccount, MiIOService, MiNAService, miio_command
from watchdog.events import FileSystemEventHandler
from watchdog.events import (
FileCreatedEvent,
FileDeletedEvent,
FileMovedEvent,
FileSystemEventHandler,
)
from watchdog.observers import Observer
from xiaomusic import __version__
@@ -171,9 +176,15 @@ class XiaoMusic:
if log_path and not os.path.exists(log_path):
os.makedirs(log_path)
if os.path.exists(log_file):
os.remove(log_file)
try:
os.remove(log_file)
except Exception as e:
self.log.warning(f"无法删除旧日志文件: {log_file} {e}")
handler = RotatingFileHandler(
self.config.log_file, maxBytes=10 * 1024 * 1024, backupCount=1
self.config.log_file,
maxBytes=10 * 1024 * 1024,
backupCount=1,
encoding="utf-8",
)
handler.stream.flush()
handler.setFormatter(formatter)
@@ -956,7 +967,7 @@ class XiaoMusic:
self.log.info(f"未匹配到指令 {query} {ctrl_panel}")
return (None, None)
def find_real_music_name(self, name, n=100):
def find_real_music_name(self, name, n):
if not self.config.enable_fuzzy_match:
self.log.debug("没开启模糊匹配")
return []
@@ -1164,7 +1175,12 @@ class XiaoMusic:
# 定时关机
async def stop_after_minute(self, did="", arg1=0, **kwargs):
minute = int(arg1)
try:
# 尝试转换中文数字
minute = chinese_to_number(str(arg1))
except (KeyError, ValueError):
# 如果中文数字转换失败,尝试阿拉伯数字
minute = int(arg1)
return await self.devices[did].stop_after_minute(minute)
# 添加歌曲到收藏列表
@@ -1572,7 +1588,9 @@ class XiaoMusicDevice:
if exact:
names = self.xiaomusic.find_real_music_name(name, n=1)
else:
names = self.xiaomusic.find_real_music_name(name)
names = self.xiaomusic.find_real_music_name(
name, n=self.config.search_music_count
)
if len(names) > 0:
if not exact:
if len(names) > 1: # 大于一首歌才更新
@@ -1659,7 +1677,9 @@ class XiaoMusicDevice:
if exact:
names = self.xiaomusic.find_real_music_name(name, n=1)
else:
names = self.xiaomusic.find_real_music_name(name)
names = self.xiaomusic.find_real_music_name(
name, n=self.config.search_music_count
)
if len(names) > 0:
if not exact:
if len(names) > 1: # 大于一首歌才更新
@@ -1931,7 +1951,7 @@ class XiaoMusicDevice:
# 有 tts command 优先使用 tts command 说话
if self.hardware in TTS_COMMAND:
tts_cmd = TTS_COMMAND[self.hardware]
self.log.debug("Call MiIOService tts.")
self.log.info("Call MiIOService tts.")
value = value.replace(" ", ",") # 不能有空格
await miio_command(
self.xiaomusic.miio_service,
@@ -2192,6 +2212,10 @@ class XiaoMusicPathWatch(FileSystemEventHandler):
self._debounce_handle = None
def on_any_event(self, event):
# 只处理文件的创建、删除和移动事件
if not isinstance(event, FileCreatedEvent | FileDeletedEvent | FileMovedEvent):
return
if event.is_directory:
return # 忽略目录事件