├── .github └── workflows │ ├── azure-base.yml │ ├── azure-latest.yml │ ├── encrypt-latest.yml │ ├── official-latest.yml │ ├── serverless-3.6.1.yml │ └── serverless-3.7.1.yml ├── .idea ├── Docker.iml ├── inspectionProfiles │ ├── Project_Default.xml │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── vcs.xml └── workspace.xml ├── README.md ├── azure ├── Dockerfile ├── README.md ├── base │ └── Dockerfile ├── config.json ├── deploy.sh ├── ecosystem.config.js ├── entrypoint.sh └── main.py ├── backup ├── mirror.yml ├── qndxx-latest.yml ├── selenium-alpine.yml ├── selenium-centos.yml └── selenium-latest.yml ├── encrypt ├── Dockerfile ├── README.md ├── app.js ├── ecosystem.config.js └── entrypoint.sh ├── logo └── docker.jpg ├── qndxx ├── LICENSE ├── README.md ├── cookie.json ├── docker │ ├── Dockerfile │ ├── cron.sh │ └── delete.sh ├── main.py ├── requirements.txt └── surge │ ├── qndxx.js │ └── qndxx.sgmodule ├── selenium ├── README.md ├── alpine │ ├── Dockerfile │ ├── README.md │ ├── cron.py │ └── cron.sh ├── centos │ ├── Dockerfile │ ├── README.md │ ├── chromedriver │ ├── cron.py │ ├── cron.sh │ └── google-chrome.rpm ├── delete.sh └── example.py ├── server ├── README.md ├── python36 │ ├── Dockerfile │ ├── README.md │ └── get_packages.sh └── python37 │ ├── Dockerfile │ ├── README.md │ └── get_packages.sh └── xmSport ├── config.json ├── utils.py └── xmSport.py /.github/workflows/azure-base.yml: -------------------------------------------------------------------------------- 1 | name: 构建 azure(base) 镜像 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - "main" 8 | paths: 9 | - ".github/workflows/azure-base.yml" 10 | - "azure/base/*" 11 | 12 | jobs: 13 | docker: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@master 18 | 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v1 21 | 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@v1 24 | 25 | - name: Login to DockerHub 26 | uses: docker/login-action@v1 27 | with: 28 | username: ${{ secrets.DOCKERHUB_USERNAME }} 29 | password: ${{ secrets.DOCKERHUB_TOKEN }} 30 | 31 | - name: Build and push 32 | uses: docker/build-push-action@v2 33 | with: 34 | context: . 35 | push: true 36 | file: ./azure/base/Dockerfile 37 | tags: chiupam/azure:base 38 | platforms: linux/amd64,linux/arm64 39 | 40 | - name: Delete Workflow Runs 41 | uses: Mattraks/delete-workflow-runs@main 42 | with: 43 | token: ${{ github.token }} 44 | repository: ${{ github.repository }} 45 | retain_days: 0 46 | keep_minimum_runs: 0 47 | -------------------------------------------------------------------------------- /.github/workflows/azure-latest.yml: -------------------------------------------------------------------------------- 1 | name: 构建 azure 镜像 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - "main" 8 | paths: 9 | - ".github/workflows/azure-latest.yml" 10 | - "azure/*" 11 | 12 | jobs: 13 | docker: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@master 18 | 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v1 21 | 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@v1 24 | 25 | - name: Login to DockerHub 26 | uses: docker/login-action@v1 27 | with: 28 | username: ${{ secrets.DOCKERHUB_USERNAME }} 29 | password: ${{ secrets.DOCKERHUB_TOKEN }} 30 | 31 | - name: Build and push 32 | uses: docker/build-push-action@v2 33 | with: 34 | context: . 35 | push: true 36 | file: ./azure/Dockerfile 37 | tags: chiupam/azure:latest 38 | platforms: linux/amd64,linux/arm64 39 | 40 | - name: Delete Workflow Runs 41 | uses: Mattraks/delete-workflow-runs@main 42 | with: 43 | token: ${{ github.token }} 44 | repository: ${{ github.repository }} 45 | retain_days: 0 46 | keep_minimum_runs: 0 47 | -------------------------------------------------------------------------------- /.github/workflows/encrypt-latest.yml: -------------------------------------------------------------------------------- 1 | name: 构建 encrypt 镜像 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - "main" 8 | paths: 9 | - ".github/workflows/encrypt-latest.yml" 10 | - "encrypt/*" 11 | 12 | jobs: 13 | docker: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@master 18 | 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v1 21 | 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@v1 24 | 25 | - name: Login to DockerHub 26 | uses: docker/login-action@v1 27 | with: 28 | username: ${{ secrets.DOCKERHUB_USERNAME }} 29 | password: ${{ secrets.DOCKERHUB_TOKEN }} 30 | 31 | - name: Build and push 32 | uses: docker/build-push-action@v2 33 | with: 34 | context: . 35 | push: true 36 | file: ./encrypt/Dockerfile 37 | tags: chiupam/encrypt:latest 38 | platforms: linux/amd64,linux/arm64 39 | 40 | - name: Delete Workflow Runs 41 | uses: Mattraks/delete-workflow-runs@main 42 | with: 43 | token: ${{ github.token }} 44 | repository: ${{ github.repository }} 45 | retain_days: 0 46 | keep_minimum_runs: 0 47 | -------------------------------------------------------------------------------- /.github/workflows/official-latest.yml: -------------------------------------------------------------------------------- 1 | name: 构建 official 镜像 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - "main" 8 | paths: 9 | - ".github/workflows/official-latest.yml" 10 | - "official/*" 11 | 12 | jobs: 13 | docker: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@master 18 | 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v1 21 | 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@v1 24 | 25 | - name: Login to DockerHub 26 | uses: docker/login-action@v1 27 | with: 28 | username: ${{ secrets.DOCKERHUB_USERNAME }} 29 | password: ${{ secrets.DOCKERHUB_TOKEN }} 30 | 31 | - name: Build and push 32 | uses: docker/build-push-action@v2 33 | with: 34 | context: . 35 | push: true 36 | file: ./official/Dockerfile 37 | tags: chiupam/official:latest 38 | platforms: linux/amd64,linux/arm64 39 | 40 | - name: Delete Workflow Runs 41 | uses: Mattraks/delete-workflow-runs@main 42 | with: 43 | token: ${{ github.token }} 44 | repository: ${{ github.repository }} 45 | retain_days: 0 46 | keep_minimum_runs: 0 47 | -------------------------------------------------------------------------------- /.github/workflows/serverless-3.6.1.yml: -------------------------------------------------------------------------------- 1 | name: 构建 serverless(3.6.1) 镜像 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - "main" 8 | paths: 9 | - ".github/workflows/serverless-3.6.1.yml" 10 | - "server/python36/*" 11 | 12 | jobs: 13 | docker: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@master 18 | 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v1 21 | 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@v1 24 | 25 | - name: Login to DockerHub 26 | uses: docker/login-action@v1 27 | with: 28 | username: ${{ secrets.DOCKERHUB_USERNAME }} 29 | password: ${{ secrets.DOCKERHUB_TOKEN }} 30 | 31 | - name: Build and push 32 | uses: docker/build-push-action@v2 33 | with: 34 | context: . 35 | push: true 36 | file: ./server/python36/Dockerfile 37 | tags: chiupam/serverless:3.6.1 38 | platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64 39 | 40 | - name: Delete Workflow Runs 41 | uses: Mattraks/delete-workflow-runs@main 42 | with: 43 | token: ${{ github.token }} 44 | repository: ${{ github.repository }} 45 | retain_days: 0 46 | keep_minimum_runs: 0 47 | -------------------------------------------------------------------------------- /.github/workflows/serverless-3.7.1.yml: -------------------------------------------------------------------------------- 1 | name: 构建 serverless(3.7.1) 镜像 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - "main" 8 | paths: 9 | - ".github/workflows/serverless-3.7.1.yml" 10 | - "server/python37/*" 11 | 12 | jobs: 13 | docker: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@master 18 | 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v1 21 | 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@v1 24 | 25 | - name: Login to DockerHub 26 | uses: docker/login-action@v1 27 | with: 28 | username: ${{ secrets.DOCKERHUB_USERNAME }} 29 | password: ${{ secrets.DOCKERHUB_TOKEN }} 30 | 31 | - name: Build and push 32 | uses: docker/build-push-action@v2 33 | with: 34 | context: . 35 | push: true 36 | file: ./server/python37/Dockerfile 37 | tags: chiupam/serverless:3.7.1 38 | platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64 39 | 40 | - name: Delete Workflow Runs 41 | uses: Mattraks/delete-workflow-runs@main 42 | with: 43 | token: ${{ github.token }} 44 | repository: ${{ github.repository }} 45 | retain_days: 0 46 | keep_minimum_runs: 0 47 | -------------------------------------------------------------------------------- /.idea/Docker.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 22 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 32 | 33 | 34 | 35 | 54 | 55 | 56 | 57 | 58 | 59 | 1656513961903 60 | 64 | 65 | 66 | 67 | 76 | 77 | 78 | 79 | 80 | 81 | file://$PROJECT_DIR$/main.py 82 | 8 83 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | logo 2 | 3 | # Docker Hub 4 | 5 | 自用 Docker 镜像文件仓库。 6 | 7 | ## 目录 8 | 9 | - [快捷切换azure的IP地址](https://github.com/chiupam/Docker/tree/main/azure) 10 | - [某平台密码加密算法](https://github.com/chiupam/Docker/tree/main/encrypt) 11 | - [某东算法](https://github.com/chiupam/Docker/tree/main/official) 12 | - [云南青年大学习](https://github.com/chiupam/Docker/tree/main/qndxx) 13 | - [基于selenium库的操作环境](https://github.com/chiupam/Docker/tree/main/selenium) 14 | - [云函数开发环境](https://github.com/chiupam/Docker/tree/main/server) 15 | -------------------------------------------------------------------------------- /azure/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM chiupam/azure:base 2 | 3 | WORKDIR /app 4 | 5 | COPY ./azure/*.sh /app/ 6 | 7 | RUN set -ex \ 8 | && apk update -f \ 9 | && apk upgrade \ 10 | && apk add --no-cache tzdata jq npm \ 11 | && rm -rf /var/cache/apk/* \ 12 | && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ 13 | && echo "Asia/Shanghai" > /etc/timezone \ 14 | && npm install -g pm2@latest \ 15 | && pip3 install Telethon==1.24.0 \ 16 | && mv /app/entrypoint.sh /usr/local/bin \ 17 | && chmod +x /usr/local/bin/entrypoint.sh 18 | 19 | ENTRYPOINT ["entrypoint.sh"] 20 | -------------------------------------------------------------------------------- /azure/README.md: -------------------------------------------------------------------------------- 1 | # Azure 更换 IP 2 | 3 | 1、首先部署容器,如果没有镜像的会直接拉取。 4 | 5 | ```shell 6 | docker run -dit --name azure chiupam/azure:latest 7 | ``` 8 | 9 | 2、然后执行部署脚本输入个人信息,根据提示进行操作。 10 | 11 | ```shell 12 | docker exec -it azure sh deploy.sh 13 | ``` 14 | 15 | 3、等待25秒后程序自动启动 16 | 17 | ## 使用方法 18 | 19 | 直接在机器人内发送命令即可,监控493错误自动切换ip。 20 | 21 | ## 命令 22 | 23 | ```text 24 | az ==> 查看机器人是否在线 25 | /azip ==> 查看当前 Azure 的 IP 地址 26 | /ghip ==> 重拔 Azure 以更换 IP 地址 27 | ``` 28 | 29 | ## 重点 30 | 31 | ```text 32 | 1、禁止在需要更换 IP 的 Azure 上部署!!! 33 | 2、禁止在需要更换 IP 的 Azure 上部署!!! 34 | 3、禁止在需要更换 IP 的 Azure 上部署!!! 35 | ``` 36 | -------------------------------------------------------------------------------- /azure/base/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:alpine 2 | 3 | RUN set -x \ 4 | && apk update -f \ 5 | && apk upgrade \ 6 | && apk add gcc musl-dev python3-dev libffi-dev openssl-dev cargo make \ 7 | && pip3 install -U pip \ 8 | && pip3 install azure-cli==2.34.0 9 | 10 | -------------------------------------------------------------------------------- /azure/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "user_id": 1016919456, 3 | "bot_api": "505515432:AA", 4 | "api_id": "123456789", 5 | "api_hash": "abcdefghijklmn", 6 | "az_group": "resourceGroup", 7 | "az_name": "computerName", 8 | "ql_port": "5700", 9 | "first": "true" 10 | } 11 | -------------------------------------------------------------------------------- /azure/deploy.sh: -------------------------------------------------------------------------------- 1 | config=/app/config.json 2 | 3 | while [ ! -f $config ]; do 4 | sleep 1 5 | done 6 | 7 | if [ "$(cat $config | jq .first)" == '"true"' ]; then 8 | if [ -n "$(grep -E "1016919456" $config)" ]; then 9 | printf "请输入 user id:" 10 | read -r user_id 11 | sed -i s/1016919456/"$user_id"/g $config 12 | fi 13 | if [ -n "$(grep -E "505515432:AA" $config)" ]; then 14 | printf "请输入 bot api:" 15 | read -r bot_api 16 | sed -i s/"505515432:AA"/"$bot_api"/g $config 17 | fi 18 | if [ -n "$(grep -E "123456789" $config)" ]; then 19 | printf "请输入 api id:" 20 | read -r api_id 21 | sed -i s/"123456789"/"$api_id"/g $config 22 | fi 23 | if [ -n "$(grep -E "abcdefghijklmn" $config)" ]; then 24 | printf "请输入 api hash:" 25 | read -r api_hash 26 | sed -i s/"abcdefghijklmn"/"$api_hash"/g $config 27 | fi 28 | if [ -n "$(grep -E "5700" $config)" ]; then 29 | printf "请输入青龙面板端口:" 30 | read -r ql_port 31 | sed -i s/"5700"/"$ql_port"/g $config 32 | fi 33 | if [ -n "$(grep -E "resourceGroup" $config)" ]; then 34 | printf "请输入 Azure 资源组名称:" 35 | read -r az_group 36 | sed -i s/"resourceGroup"/"$az_group"/g $config 37 | fi 38 | if [ -n "$(grep -E "computerName" $config)" ]; then 39 | printf "请输入 Azure 虚拟机名称:" 40 | read -r az_name 41 | sed -i s/"computerName"/"$az_name"/g $config 42 | fi 43 | echo -e "\n开始登录 Azure ……" 44 | printf "请输入 Azure 登录邮箱(直接回车则使用浏览器登录):" 45 | read -r az_username 46 | if [ -n "$az_username" ]; then 47 | printf "请输入 Azure 登录密码:" 48 | read -r az_password 49 | az login -u "$az_username" -p "$az_password" 50 | else 51 | az login 52 | fi 53 | echo -e "\n开始登录 Telegram ……" 54 | echo "输入手机号码和验证完成后, 请 Ctrl + C 退出, 25秒后自动启动监控..." 55 | sed -i 's/true/false/g' $config 56 | python3 main.py 57 | else 58 | pm2 start ecosystem.config.js 59 | fi 60 | -------------------------------------------------------------------------------- /azure/ecosystem.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | apps: [ 3 | { 4 | name: "azure", 5 | cwd: "./", 6 | script: "python3", 7 | args: "main.py", 8 | watch: "./main.py", 9 | watch_delay: 3000 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /azure/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | main() { 4 | url=https://raw.githubusercontent.com/chiupam/Docker/main/azure 5 | if [ ! -f "/app/config.json" ]; then 6 | wget $url/config.json -O config.json >/dev/null 2>&1 7 | fi 8 | if [ ! -f "/app/main.py" ]; then 9 | wget $url/main.py -O main.py >/dev/null 2>&1 10 | wget $url/deploy.sh -O deploy.sh >/dev/null 2>&1 11 | wget $url/ecosystem.config.js -O ecosystem.config.js >/dev/null 2>&1 12 | fi 13 | } 14 | 15 | main 16 | while [ "$(cat "/app/config.json" | jq .first)" == '"true"' ]; do 17 | sleep 1 18 | done 19 | sleep 24 20 | echo "初始化完成, 启动..." 21 | pm2-runtime start /app/ecosystem.config.js >/dev/null 2>&1 22 | -------------------------------------------------------------------------------- /azure/main.py: -------------------------------------------------------------------------------- 1 | import json 2 | from asyncio import create_subprocess_shell as shell 3 | from asyncio.subprocess import PIPE 4 | from datetime import datetime 5 | 6 | from telethon import TelegramClient, events 7 | 8 | with open("./config.json", "r", encoding="utf-8") as config: 9 | tg = json.load(config) 10 | api_id = tg['api_id'] 11 | api_hash = tg['api_hash'] 12 | user_id = tg['user_id'] 13 | ql_port = int(tg['ql_port']) 14 | bot_id = int(tg['bot_api'].split(":")[0]) 15 | Azure = TelegramClient('./azure', api_id, api_hash) 16 | 17 | 18 | async def cmd(_command): 19 | p = await shell(_command, stdout=PIPE, stderr=PIPE) 20 | _bytes, _error = await p.communicate() 21 | return _bytes.decode("utf-8") 22 | 23 | 24 | async def hello(): 25 | command = "az vm list-ip-addresses -n $(cat config.json | jq -r .az_name) -o json | " \ 26 | "jq .[0].virtualMachine.network.publicIpAddresses[0].ipAddress" 27 | result = await cmd(command) 28 | if len(result) < 4: 29 | push = f"Azure 服务启动成功!\n" \ 30 | f"但没能成功登录 Azure 账号\n" \ 31 | f"请进入容器使用 `az login` 再次登录!" 32 | else: 33 | push = f"Azure 服务启动成功!\n" \ 34 | f"当前 Azure 的 ip: `{str(result)[1:-2]}`\n" \ 35 | f"当前青龙面板网址: {str(result)[1:-2]}:{ql_port}" 36 | await Azure.send_message(bot_id, push) 37 | 38 | 39 | @Azure.on(events.NewMessage(chats=bot_id, from_users=user_id, pattern=r'^az(\?|?)?$')) 40 | async def check(event): 41 | await event.reply("az!") 42 | 43 | 44 | @Azure.on(events.NewMessage(chats=bot_id, from_users=user_id, pattern=r'^/azip$')) 45 | async def get_azure_ip(event): 46 | msg = await event.reply("正在查询中……") 47 | try: 48 | command = "az vm list-ip-addresses -n $(cat config.json | jq -r .az_name) -o json | " \ 49 | "jq .[0].virtualMachine.network.publicIpAddresses[0].ipAddress" 50 | result = await cmd(command) 51 | await event.delete() 52 | await Azure.pin_message(bot_id, None, notify=False) 53 | msg = await Azure.edit_message( 54 | msg, 55 | f"当前 Azure 的 ip: `{str(result)[1:-2]}`\n" 56 | f"当前青龙面板网址: {str(result)[1:-2]}:{ql_port}" 57 | ) 58 | await Azure.pin_message(bot_id, msg, notify=False) 59 | except Exception as error: 60 | await Azure.edit_message(msg, str(error)) 61 | 62 | 63 | @Azure.on(events.MessageEdited(chats=bot_id, from_users=bot_id, pattern=r"(\n|.)*错误代码493,IP可能黑了.*")) 64 | @Azure.on(events.NewMessage(chats=bot_id, from_users=user_id, pattern=r'^/ghip$')) 65 | async def change_azure_ip(event): 66 | msg = await event.reply("正在更换中……") 67 | try: 68 | command = "vm_group=$(cat config.json | jq -r .az_group); " \ 69 | "vm_name=$(cat config.json | jq -r .az_name); " \ 70 | "az vm deallocate -g $vm_group -n $vm_name; " \ 71 | "az vm start -g $vm_group -n $vm_name; " \ 72 | "az vm list-ip-addresses -n $vm_name -o json | " \ 73 | "jq .[0].virtualMachine.network.publicIpAddresses[0].ipAddress" 74 | now = datetime.now() 75 | result = await cmd(command) 76 | await event.delete() 77 | await Azure.pin_message(bot_id, None, notify=False) 78 | msg = await Azure.edit_message( 79 | msg, 80 | f"新的 Azure 的 ip: `{str(result)[1:-2]}`\n" 81 | f"新的青龙面板网址: {str(result)[1:-2]}:{ql_port}\n" 82 | f"更换 ip 耗时: {str(datetime.now() - now).split('.')[0]}" 83 | ) 84 | await Azure.pin_message(bot_id, msg, notify=False) 85 | except Exception as error: 86 | await Azure.edit_message(msg, str(error)) 87 | 88 | 89 | with Azure: 90 | Azure.loop.create_task(hello()) 91 | Azure.loop.run_forever() 92 | -------------------------------------------------------------------------------- /backup/mirror.yml: -------------------------------------------------------------------------------- 1 | name: GitHub Actions Mirror 2 | 3 | on: [ push, delete, create ] 4 | 5 | jobs: 6 | git-mirror: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Mirror the Github organization repos to Gitee. 10 | uses: Yikun/hub-mirror-action@master 11 | with: 12 | src: 'github/chiupam' 13 | dst: 'gitee/chiupam' 14 | dst_key: ${{ secrets.GITEE_PRIVATE_KEY }} 15 | white_list: "Docker" 16 | force_update: true 17 | 18 | - name: Delete Workflow Runs # 删除执行日志 19 | uses: Mattraks/delete-workflow-runs@main 20 | with: 21 | token: ${{ github.token }} 22 | repository: ${{ github.repository }} 23 | retain_days: 0 24 | keep_minimum_runs: 0 25 | -------------------------------------------------------------------------------- /backup/qndxx-latest.yml: -------------------------------------------------------------------------------- 1 | name: 构建 qndxx 镜像 2 | 3 | on: 4 | workflow_dispatch: 5 | # push: 6 | # branches: 7 | # - "main" 8 | # paths: 9 | # - ".github/workflows/qndxx-latest.yml" 10 | # - "qndxx/docker/Dockerfile" 11 | 12 | jobs: 13 | docker: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@master 18 | 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v1 21 | 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@v1 24 | 25 | - name: Login to DockerHub 26 | uses: docker/login-action@v1 27 | with: 28 | username: ${{ secrets.DOCKERHUB_USERNAME }} 29 | password: ${{ secrets.DOCKERHUB_TOKEN }} 30 | 31 | - name: Build and push 32 | uses: docker/build-push-action@v2 33 | with: 34 | context: . 35 | push: true 36 | file: ./qndxx/docker/Dockerfile 37 | tags: chiupam/qndxx:latest 38 | platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64 39 | 40 | - name: Delete Workflow Runs 41 | uses: Mattraks/delete-workflow-runs@main 42 | with: 43 | token: ${{ github.token }} 44 | repository: ${{ github.repository }} 45 | retain_days: 0 46 | keep_minimum_runs: 0 47 | -------------------------------------------------------------------------------- /backup/selenium-alpine.yml: -------------------------------------------------------------------------------- 1 | name: 构建 selenium(alpine) 镜像 2 | 3 | on: 4 | workflow_dispatch: 5 | # push: 6 | # branches: 7 | # - "main" 8 | # paths: 9 | # - ".github/workflows/selenium-alpine.yml" 10 | # - "selenium/alpine/Dockerfile" 11 | 12 | jobs: 13 | docker: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@master 18 | 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v1 21 | 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@v1 24 | 25 | - name: Login to DockerHub 26 | uses: docker/login-action@v1 27 | with: 28 | username: ${{ secrets.DOCKERHUB_USERNAME }} 29 | password: ${{ secrets.DOCKERHUB_TOKEN }} 30 | 31 | - name: Build and push 32 | uses: docker/build-push-action@v2 33 | with: 34 | context: . 35 | push: true 36 | file: ./selenium/alpine/Dockerfile 37 | tags: chiupam/selenium:alpine 38 | platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64 39 | 40 | - name: Delete Workflow Runs 41 | uses: Mattraks/delete-workflow-runs@main 42 | with: 43 | token: ${{ github.token }} 44 | repository: ${{ github.repository }} 45 | retain_days: 0 46 | keep_minimum_runs: 0 47 | -------------------------------------------------------------------------------- /backup/selenium-centos.yml: -------------------------------------------------------------------------------- 1 | name: 构建 selenium(centos) 镜像 2 | 3 | on: 4 | workflow_dispatch: 5 | # push: 6 | # branches: 7 | # - "main" 8 | # paths: 9 | # - ".github/workflows/selenium-centos.yml" 10 | # - "selenium/centos/Dockerfile" 11 | 12 | jobs: 13 | docker: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@master 18 | 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v1 21 | 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@v1 24 | 25 | - name: Login to DockerHub 26 | uses: docker/login-action@v1 27 | with: 28 | username: ${{ secrets.DOCKERHUB_USERNAME }} 29 | password: ${{ secrets.DOCKERHUB_TOKEN }} 30 | 31 | - name: Build and push 32 | uses: docker/build-push-action@v2 33 | with: 34 | context: . 35 | push: true 36 | file: ./selenium/centos/Dockerfile 37 | tags: chiupam/selenium:centos 38 | platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64 39 | 40 | - name: Delete Workflow Runs 41 | uses: Mattraks/delete-workflow-runs@main 42 | with: 43 | token: ${{ github.token }} 44 | repository: ${{ github.repository }} 45 | retain_days: 0 46 | keep_minimum_runs: 0 47 | -------------------------------------------------------------------------------- /backup/selenium-latest.yml: -------------------------------------------------------------------------------- 1 | name: 构建 selenium 镜像 2 | 3 | on: 4 | workflow_dispatch: 5 | # push: 6 | # branches: 7 | # - "main" 8 | # paths: 9 | # - ".github/workflows/selenium-latest.yml" 10 | # - "selenium/centos/Dockerfile" 11 | 12 | jobs: 13 | docker: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@master 18 | 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v1 21 | 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@v1 24 | 25 | - name: Login to DockerHub 26 | uses: docker/login-action@v1 27 | with: 28 | username: ${{ secrets.DOCKERHUB_USERNAME }} 29 | password: ${{ secrets.DOCKERHUB_TOKEN }} 30 | 31 | - name: Build and push 32 | uses: docker/build-push-action@v2 33 | with: 34 | context: . 35 | push: true 36 | file: ./selenium/centos/Dockerfile 37 | tags: chiupam/selenium:latest 38 | platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64 39 | 40 | - name: Delete Workflow Runs 41 | uses: Mattraks/delete-workflow-runs@main 42 | with: 43 | token: ${{ github.token }} 44 | repository: ${{ github.repository }} 45 | retain_days: 0 46 | keep_minimum_runs: 0 47 | -------------------------------------------------------------------------------- /encrypt/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine 2 | 3 | ENV PATH=/usr/local/bin:$PATH LANG=C.UTF-8 4 | 5 | EXPOSE 9000 6 | 7 | WORKDIR /app 8 | 9 | ADD ./encrypt/*.sh /app/ 10 | 11 | RUN set -ex \ 12 | && apk update -f \ 13 | && apk upgrade \ 14 | && apk add --no-cache tzdata wget npm \ 15 | && rm -rf /var/cache/apk/* \ 16 | && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ 17 | && echo "Asia/Shanghai" > /etc/timezone \ 18 | && npm install -g pm2@latest \ 19 | && mv /app/*.sh /usr/local/bin \ 20 | && chmod +x /usr/local/bin/*.sh 21 | 22 | ENTRYPOINT ["entrypoint.sh"] 23 | -------------------------------------------------------------------------------- /encrypt/README.md: -------------------------------------------------------------------------------- 1 | # 某平台加密算法 2 | 3 | ## 部署命令 4 | 5 | ```shell 6 | docker run -dit \ 7 | --name encrypt \ 8 | --retart always \ 9 | --hostname encrypt \ 10 | -p 9000:9000 \ 11 | chiupam/encrypt:latest 12 | ``` 13 | 14 | ## 接口测试 15 | 16 | ```shell 17 | curl http://ip:9000/?passwoed= 18 | ``` -------------------------------------------------------------------------------- /encrypt/app.js: -------------------------------------------------------------------------------- 1 | // 引入 express 框架 2 | const express = require('express'); 3 | const bodyParser = require('body-parser'); 4 | // 创建网站服务器 5 | const app = express(); 6 | // 拦截所有请求 7 | // extended: false 方法内部使用 querystring 模块处理请求参数的格式 8 | // extended: true 方法内部使用第三方模块 qs 来处理请求参数的格式 9 | app.use(bodyParser.urlencoded({extended: false})); 10 | 11 | function n(e) { 12 | R = new Array(e); 13 | for (var t = 0; t < R.length; t++) 14 | R[t] = 0; 15 | q = new i, 16 | F = new i, 17 | F.digits[0] = 1 18 | } 19 | 20 | function i(e) { 21 | this.digits = "boolean" == typeof e && 1 == e ? null : R.slice(0), 22 | this.isNeg = !1 23 | } 24 | 25 | function r(e) { 26 | var t = new i(!0); 27 | return t.digits = e.digits.slice(0), 28 | t.isNeg = e.isNeg, 29 | t 30 | } 31 | 32 | function o(e) { 33 | var t = new i; 34 | t.isNeg = e < 0, 35 | e = Math.abs(e); 36 | for (var a = 0; e > 0; ) 37 | t.digits[a++] = e & X, 38 | e = Math.floor(e / j); 39 | return t 40 | } 41 | 42 | function c(e) { 43 | for (var q = "", a = 0; a < 4; ++a){ 44 | q += J[15 & e], 45 | e >>>= 4; 46 | } 47 | for (var t = "", a = q.length - 1; a > -1; --a){ 48 | t += q.charAt(a); 49 | } 50 | return t 51 | } 52 | 53 | function u(e) { 54 | for (var t = "", a = (h(e), 55 | h(e)); a > -1; --a) 56 | t += c(e.digits[a]); 57 | return t 58 | } 59 | 60 | function p(e) { 61 | return e >= 48 && e <= 57 ? e - 48 : e >= 65 && e <= 90 ? 10 + e - 65 : e >= 97 && e <= 122 ? 10 + e - 97 : 0 62 | } 63 | 64 | function m(e) { 65 | for (var t = 0, a = Math.min(e.length, 4), n = 0; n < a; ++n) 66 | t <<= 4, 67 | t |= p(e.charCodeAt(n)); 68 | return t 69 | } 70 | 71 | function d(e) { 72 | for (var t = new i, a = e.length, n = a, r = 0; n > 0; n -= 4, 73 | ++r) 74 | t.digits[r] = m(e.substr(Math.max(n - 4, 0), Math.min(n, 4))); 75 | return t 76 | } 77 | 78 | function g(e, t) { 79 | var a; 80 | if (e.isNeg != t.isNeg) 81 | t.isNeg = !t.isNeg, 82 | a = _(e, t), 83 | t.isNeg = !t.isNeg; 84 | else { 85 | a = new i; 86 | var n, r; 87 | r = 0; 88 | for (var o = 0; o < e.digits.length; ++o) 89 | n = e.digits[o] - t.digits[o] + r, 90 | a.digits[o] = n % j, 91 | a.digits[o] < 0 && (a.digits[o] += j), 92 | r = 0 - Number(n < 0); 93 | if (-1 == r) { 94 | r = 0; 95 | for (var o = 0; o < e.digits.length; ++o) 96 | n = 0 - a.digits[o] + r, 97 | a.digits[o] = n % j, 98 | a.digits[o] < 0 && (a.digits[o] += j), 99 | r = 0 - Number(n < 0); 100 | a.isNeg = !e.isNeg 101 | } else 102 | a.isNeg = e.isNeg 103 | } 104 | return a 105 | } 106 | 107 | function h(e) { 108 | for (var t = e.digits.length - 1; t > 0 && 0 == e.digits[t]; ) 109 | --t; 110 | return t 111 | } 112 | 113 | function v(e) { 114 | var t, a = h(e), n = e.digits[a], i = (a + 1) * B; 115 | for (t = i; t > i - B && 0 == (32768 & n); --t) 116 | n <<= 1; 117 | return t 118 | } 119 | 120 | function E(e, t) { 121 | for (var a, n, r, o = new i, s = h(e), l = h(t), c = 0; c <= l; ++c) { 122 | a = 0, 123 | r = c; 124 | for (var u = 0; u <= s; ++u, 125 | ++r) 126 | n = o.digits[r] + e.digits[u] * t.digits[c] + a, 127 | o.digits[r] = n & X, 128 | a = n >>> K; 129 | o.digits[c + s + 1] = a 130 | } 131 | return o.isNeg = e.isNeg != t.isNeg, 132 | o 133 | } 134 | 135 | function b(e, t) { 136 | var a, n, r, o = new i; 137 | a = h(e), 138 | n = 0; 139 | for (var s = 0; s <= a; ++s) 140 | r = o.digits[s] + e.digits[s] * t + n, 141 | o.digits[s] = r & X, 142 | n = r >>> K; 143 | return o.digits[1 + a] = n, 144 | o 145 | } 146 | 147 | function y(e, t, a, n, i) { 148 | for (var r = Math.min(t + i, e.length), o = t, s = n; o < r; ++o, 149 | ++s) 150 | a[s] = e[o] 151 | } 152 | 153 | function w(e, t) { 154 | var a = Math.floor(t / B) 155 | , n = new i; 156 | y(e.digits, 0, n.digits, a, n.digits.length - a); 157 | for (var r = t % B, o = B - r, s = n.digits.length - 1, l = s - 1; s > 0; --s, 158 | --l) 159 | n.digits[s] = n.digits[s] << r & X | (n.digits[l] & V[r]) >>> o; 160 | return n.digits[0] = n.digits[s] << r & X, 161 | n.isNeg = e.isNeg, 162 | n 163 | } 164 | 165 | function T(e, t) { 166 | var a = Math.floor(t / B) 167 | , n = new i; 168 | y(e.digits, a, n.digits, 0, e.digits.length - a); 169 | for (var r = t % B, o = B - r, s = 0, l = s + 1; s < n.digits.length - 1; ++s, 170 | ++l) 171 | n.digits[s] = n.digits[s] >>> r | (n.digits[l] & Y[r]) << o; 172 | return n.digits[n.digits.length - 1] >>>= r, 173 | n.isNeg = e.isNeg, 174 | n 175 | } 176 | 177 | function S(e, t) { 178 | var a = new i; 179 | return y(e.digits, 0, a.digits, t, a.digits.length - t), 180 | a 181 | } 182 | 183 | function x(e, t) { 184 | var a = new i; 185 | return y(e.digits, t, a.digits, 0, a.digits.length - t), 186 | a 187 | } 188 | 189 | function O(e, t) { 190 | var a = new i; 191 | return y(e.digits, 0, a.digits, 0, t), 192 | a 193 | } 194 | 195 | function C(e, t) { 196 | if (e.isNeg != t.isNeg) 197 | return 1 - 2 * Number(e.isNeg); 198 | for (var a = e.digits.length - 1; a >= 0; --a) 199 | if (e.digits[a] != t.digits[a]) 200 | return e.isNeg ? 1 - 2 * Number(e.digits[a] > t.digits[a]) : 1 - 2 * Number(e.digits[a] < t.digits[a]); 201 | return 0 202 | } 203 | 204 | function k(e, t) { 205 | var a, n, o = v(e), s = v(t), l = t.isNeg; 206 | if (o < s) 207 | return e.isNeg ? (a = r(F), 208 | a.isNeg = !t.isNeg, 209 | e.isNeg = !1, 210 | t.isNeg = !1, 211 | n = g(t, e), 212 | e.isNeg = !0, 213 | t.isNeg = l) : (a = new i, 214 | n = r(e)), 215 | new Array(a,n); 216 | a = new i, 217 | n = e; 218 | for (var c = Math.ceil(s / B) - 1, u = 0; t.digits[c] < G; ) 219 | t = w(t, 1), 220 | ++u, 221 | ++s, 222 | c = Math.ceil(s / B) - 1; 223 | n = w(n, u), 224 | o += u; 225 | for (var p = Math.ceil(o / B) - 1, m = S(t, p - c); -1 != C(n, m); ) 226 | ++a.digits[p - c], 227 | n = g(n, m); 228 | for (var d = p; d > c; --d) { 229 | var f = d >= n.digits.length ? 0 : n.digits[d] 230 | , E = d - 1 >= n.digits.length ? 0 : n.digits[d - 1] 231 | , y = d - 2 >= n.digits.length ? 0 : n.digits[d - 2] 232 | , x = c >= t.digits.length ? 0 : t.digits[c] 233 | , O = c - 1 >= t.digits.length ? 0 : t.digits[c - 1]; 234 | a.digits[d - c - 1] = f == x ? X : Math.floor((f * j + E) / x); 235 | for (var k = a.digits[d - c - 1] * (x * j + O), N = f * z + (E * j + y); k > N; ) 236 | --a.digits[d - c - 1], 237 | k = a.digits[d - c - 1] * (x * j | O), 238 | N = f * j * j + (E * j + y); 239 | m = S(t, d - c - 1), 240 | n = g(n, b(m, a.digits[d - c - 1])), 241 | n.isNeg && (n = _(n, m), 242 | --a.digits[d - c - 1]) 243 | } 244 | return n = T(n, u), 245 | a.isNeg = e.isNeg != l, 246 | e.isNeg && (a = l ? _(a, F) : g(a, F), 247 | t = T(t, u), 248 | n = g(t, n)), 249 | 0 == n.digits[0] && 0 == h(n) && (n.isNeg = !1), 250 | new Array(a,n) 251 | } 252 | 253 | function N(e, t) { 254 | return k(e, t)[0] 255 | } 256 | 257 | function I(e) { 258 | this.modulus = r(e), 259 | this.k = h(this.modulus) + 1; 260 | var t = new i; 261 | t.digits[2 * this.k] = 1, 262 | this.mu = N(t, this.modulus), 263 | this.bkplus1 = new i, 264 | this.bkplus1.digits[this.k + 1] = 1, 265 | this.modulo = A, 266 | this.multiplyMod = P, 267 | this.powMod = W 268 | } 269 | 270 | function A(e) { 271 | var t = x(e, this.k - 1) 272 | , a = E(t, this.mu) 273 | , n = x(a, this.k + 1) 274 | , i = O(e, this.k + 1) 275 | , r = E(n, this.modulus) 276 | , o = O(r, this.k + 1) 277 | , s = g(i, o); 278 | s.isNeg && (s = _(s, this.bkplus1)); 279 | for (var l = C(s, this.modulus) >= 0; l; ) 280 | s = g(s, this.modulus), 281 | l = C(s, this.modulus) >= 0; 282 | return s 283 | } 284 | 285 | function P(e, t) { 286 | var a = E(e, t); 287 | return this.modulo(a) 288 | } 289 | 290 | function W(e, t) { 291 | var a = new i; 292 | a.digits[0] = 1; 293 | for (var n = e, r = t; ; ) { 294 | if (0 != (1 & r.digits[0]) && (a = this.multiplyMod(a, n)), 295 | r = T(r, 1), 296 | 0 == r.digits[0] && 0 == h(r)) 297 | break; 298 | n = this.multiplyMod(n, n) 299 | } 300 | return a 301 | } 302 | 303 | function M(e, t, a) { 304 | this.e = d(e), 305 | this.d = d(t), 306 | this.m = d(a), 307 | this.chunkSize = 2 * h(this.m), 308 | this.radix = 16, 309 | this.barrett = new I(this.m) 310 | } 311 | 312 | function D(e, t, a) { 313 | return new M(e,t,a) 314 | } 315 | 316 | function L(e, t) { 317 | for (var a = new Array, n = t.length, r = 0; r < n; ) 318 | a[r] = t.charCodeAt(r), 319 | r++; 320 | for (; a.length % e.chunkSize != 0; ) 321 | a[r++] = 0; 322 | var o, s, c, p = a.length, m = ""; 323 | for (r = 0; r < p; r += e.chunkSize) { 324 | for (c = new i, 325 | o = 0, 326 | s = r; s < r + e.chunkSize; ++o) 327 | c.digits[o] = a[s++], 328 | c.digits[o] += a[s++] << 8; 329 | var d = e.barrett.powMod(c, e.e); 330 | m += (16 == e.radix ? u(d) : l(d, e.radix)) + " " 331 | } 332 | return m.substring(0, m.length - 1) 333 | } 334 | 335 | var U, R, q, F, K = 16, B = K, j = 65536, G = j >>> 1, z = j * j, X = j - 1; 336 | n(20); 337 | var H = (o(1e15), 338 | new Array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")) 339 | , J = new Array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f") 340 | , V = new Array(0,32768,49152,57344,61440,63488,64512,65024,65280,65408,65472,65504,65520,65528,65532,65534,65535) 341 | , Y = new Array(0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535) 342 | n(131); 343 | 344 | function main(tt) { 345 | let ee = "010001" 346 | let aa = "00b5eeb166e069920e80bebd1fea4829d3d1f3216f2aabe79b6c47a3c18dcee5fd22c2e7ac519cab59198ece036dcf289ea8201e2a0b9ded307f8fb704136eaeb670286f5ad44e691005ba9ea5af04ada5367cd724b5a26fdb5120cc95b6431604bd219c6b7d83a6f8f24b43918ea988a76f93c333aa5a20991493d4eb1117e7b1" 347 | let hh = D(ee, "", aa) 348 | let gg = L(hh, tt) 349 | return gg 350 | } 351 | 352 | app.post('/', (requests, response) => { 353 | if (requests.body.password) { 354 | var password = requests.body.password 355 | response.send(main(password)) 356 | } else { 357 | response.send("hello world!") 358 | } 359 | }) 360 | 361 | app.get('/', (requests, response) => { 362 | if (requests.query.password) { 363 | var password = requests.query.password 364 | response.send(main(password)) 365 | } else { 366 | response.send("hello world!") 367 | } 368 | }) 369 | 370 | // Web 类型云函数,只能监听 9000 端口 371 | app.listen(9000, () => { 372 | console.log(`Server start on http://localhost:9000`); 373 | }); 374 | -------------------------------------------------------------------------------- /encrypt/ecosystem.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | apps: [ 3 | { 4 | name: "app", 5 | cwd: "./", 6 | script: "app.js", 7 | watch: true, 8 | watch_delay: 1000 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /encrypt/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | start() { 4 | if [ ! -f "/app/app.js" ]; then 5 | echo "未检测到 app.js 文件, 正在下载中, 请耐心等待..." 6 | url=https://raw.githubusercontent.com/chiupam/Docker/main/encrypt 7 | wget $url/app.js -O app.js >/dev/null 2>&1 8 | wget $url/ecosystem.config.js -O ecosystem.config.js >/dev/null 2>&1 9 | fi 10 | if [ ! -d "/app/node_modules/express" ]; then 11 | echo "未检测到 express 依赖, 正在安装中, 请耐心等待..." 12 | npm install express >/dev/null 2>&1 13 | fi 14 | echo "删除不必要的文件, 请耐心等待..." 15 | rm -rf $(ls | egrep -v "js|modules") >/dev/null 2>&1 16 | rm -rf *.json >/dev/null 2>&1 17 | echo "初始化完成, 启动..." 18 | pm2-runtime start /app/ecosystem.config.js >/dev/null 2>&1 19 | } 20 | 21 | start 22 | -------------------------------------------------------------------------------- /logo/docker.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/Docker/d9fc2c207b857a71e68412591c53cc0cb0951b8f/logo/docker.jpg -------------------------------------------------------------------------------- /qndxx/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Chiupam 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /qndxx/README.md: -------------------------------------------------------------------------------- 1 | logo 2 | 3 |

4 | 青年大学习 5 |
6 | Author: chiupam 7 |

8 | 9 | # 使用方式 10 | ## Surge(推荐) 11 | ### 1.打开Surge订阅模块 12 | ```text 13 | https://raw.githubusercontent.com/chiupam/QNDXX/master/surge/qndxx.sgmodule 14 | ``` 15 | ### 2.获取cookie 16 | ```text 17 | 打开微信 => 点击通讯录 => 点击公众号 => 搜索云南共青团 => 18 | 点击右下角大学习 => 点击注册团员登录学习 => 点击我的 => 点击签到 => 19 | 【成功】写入 cookie 成功!🎉 20 | ``` 21 | > 请留意!请留意!请留意! 22 | >> 此脚本只有在`cookie`失效时才会发送运行通知! 23 | 24 | ## 腾讯云函数(推荐) 25 | 26 | | Name | Value | 27 | |:---:|:---:| 28 | |`TENCENT_SECRET_ID`| 腾讯云用户 SecretID| 29 | |`TENCENT_SECRET_KEY`| 腾讯云账户 SecretKey| 30 | |`COOKIE`| cookie.txt 中内容| 31 | 32 | ## docker 33 | 34 | ```shell 35 | docker run -dit \ 36 | --name qndxx \ 37 | --restart always \ 38 | -v /root/qndxx:/data \ 39 | chiupam/qndxx:latest 40 | ``` 41 | 42 | # 申明 43 | 1. 此脚本仅用于学习研究, 不保证其合法性, 准确性, 有效性, 请根据情况自行判断, 本人对此不承担任何保证责任. 44 | 2. 您必须在下载后 **24** 小时内将所有内容从您的计算机或手机或任何存储设备中完全删除, 若违反规定引起任何事件本人对此均不负责. 45 | 3. 请勿将此脚本用于任何商业或非法目的, 若违反规定请自行对此负责. 46 | 4. 此脚本涉及应用与本人无关, 本人对因此引起的任何隐私泄漏或其他后果不承担任何责任. 47 | 5. 本人对任何脚本引发的问题概不负责, 包括但不限于由脚本错误引起的任何损失和损害. 48 | 6. 如果任何单位或个人认为此脚本可能涉嫌侵犯其权利, 应及时通知并提供身份证明,所有权证明, 我将在收到认证文件确认后删除此脚本. 49 | 7. 所有直接或间接使用, 查看此脚本的人均应该仔细阅读此声明. 50 | 8. 本人保留随时更改或补充此声明的权利, 一旦您使用或复制了此脚本, 即视为您已接受此免责声明. 51 | 52 | -------------------------------------------------------------------------------- /qndxx/cookie.json: -------------------------------------------------------------------------------- 1 | [ 2 | "cookie1", 3 | "cookie2" 4 | ] 5 | -------------------------------------------------------------------------------- /qndxx/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | USER root 4 | 5 | WORKDIR /data 6 | 7 | ADD ./qndxx /data 8 | 9 | RUN apk add --no-cache -U tzdata \ 10 | && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ 11 | && echo "Asia/Shanghai" > /etc/timezone \ 12 | && apk add --update --upgrade \ 13 | && apk add --no-cache python3 python3-dev py3-pip py3-requests git \ 14 | && python3 -m ensurepip \ 15 | && rm -r /usr/lib/python*/ensurepip \ 16 | && if [[ ! -e /usr/bin/pip ]]; then ln -s pip3 /usr/bin/pip ; fi \ 17 | && if [[ ! -e /usr/bin/python ]]; then ln -sf /usr/bin/python3 /usr/bin/python; fi \ 18 | && rm -rf /var/cache/apk/* \ 19 | && rm -rf ~/.cache/pip 20 | 21 | ENTRYPOINT crond && /bin/sh 22 | -------------------------------------------------------------------------------- /qndxx/docker/cron.sh: -------------------------------------------------------------------------------- 1 | # 自动删除3天前的log文件 2 | 2 13 * * * sh /repo/docker/delete.sh >/dev/null 2>&1 & 3 | # 执行主程序 4 | 3 13 * * * python /repo/main.py >> /data/$(date +\%Y-\%m-\%d).log 2>&1 & 5 | -------------------------------------------------------------------------------- /qndxx/docker/delete.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | dir_path=/data 4 | find $dir_path -mtime +3 -name "*.log" -exec rm -rf {} \; -------------------------------------------------------------------------------- /qndxx/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from time import localtime 5 | from requests import post, get 6 | from json import dumps, load 7 | from os.path import exists, abspath, dirname 8 | 9 | 10 | def main(event, context): 11 | with open("/data/cookie.json" if exists("/data/cookie.json") else f"{dirname(abspath(__file__))}/cookie.json", 'r', encoding='utf-8') as f: 12 | for cookie in load(f): 13 | get(url="http://home.yngqt.org.cn/qndxx/default.aspx", headers={"Cookie": cookie}) 14 | print(post(url="http://home.yngqt.org.cn/qndxx/xuexi.ashx", data=dumps({"txtid": localtime()[7] // 7 + 44}), headers={"Cookie": cookie}).text) 15 | print(post(url="http://home.yngqt.org.cn/qndxx/user/qiandao.ashx", headers={"Cookie": cookie}).text) 16 | get(url="http://home.yngqt.org.cn/qndxx/index.aspx", headers={"Cookie": cookie}) 17 | 18 | 19 | if __name__ == '__main__': 20 | main("", "") 21 | 22 | -------------------------------------------------------------------------------- /qndxx/requirements.txt: -------------------------------------------------------------------------------- 1 | requests==2.26.0 -------------------------------------------------------------------------------- /qndxx/surge/qndxx.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | [Script] 4 | # > 青年大学习获取cookie (home.yngqt.org.cn) 5 | 青年大学习 = type=http-request,pattern=^https?:\/\/home\.yngqt\.org\.cn\/qndxx\/user\/qiandao\.ashx, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/QNDXX/master/sruge/qndxx.js 6 | # > 青年大学习 7 | 青年大学习 = type=cron, cronexp="13 13 13,23 * * *", wake-system=1, timeout=180, script-path=https://raw.githubusercontent.com/chiupam/QNDXX/master/sruge/qndxx.js 8 | 9 | [MITM] 10 | hostname = %APPEND% home.yngqt.org.cn 11 | 12 | */ 13 | 14 | var appName = '🌼 青年大学习 🌼' 15 | var $ = Env() 16 | var cookie = {"Cookie": $.read("CookieQNDXX")} 17 | let isGetCookie = typeof $request !== 'undefined' 18 | if (isGetCookie) {set_cookie()} else {sign()} 19 | 20 | function set_cookie() { 21 | if ($request.headers) { 22 | $.set($request.headers.Cookie, "CookieQNDXX") 23 | $.msg(appName, "【成功】写入 cookie 成功!🎉", $request.headers.Cookie) 24 | } else { 25 | $.msg(appName, "", "【失败】无法读取 headers 啊,自查原因!🤦‍♂️") 26 | } 27 | $.done() 28 | } 29 | 30 | function week() { 31 | date = new Date(); 32 | var date2 = new Date(date.getFullYear(), 0, 1); 33 | var day1 = date.getDay(); 34 | if (day1 == 0) day1 = 7; 35 | var day2 = date2.getDay(); 36 | if (day2 == 0) day2 = 7; 37 | var day3 = date.getTime() - date2.getTime() + (day2 - day1) * (24 * 60 * 60 * 1000) 38 | let day4 = Math.round(day3 / 86400000); 39 | if ((Math.ceil(day4 / 7) + 1) > 52) {return 1} 40 | return Math.ceil(day4 / 7) + 1 41 | } 42 | 43 | function sign() { 44 | const switch_aspx = {url: "http://home.yngqt.org.cn/qndxx/switch.aspx", headers: cookie} 45 | $.get(switch_aspx, (err, resp, data) => {$.done()}) 46 | const default_aspx = {url: "http://home.yngqt.org.cn/qndxx/default.aspx", headers: cookie} 47 | $.get(default_aspx, (err, resp, data) => {$.done()}) 48 | const index_aspx = {url: "http://home.yngqt.org.cn/qndxx/index.aspx", headers: cookie} 49 | $.get(index_aspx, (err, resp, data) => {$.done()}) 50 | const sign_ashx = {url: "http://home.yngqt.org.cn/qndxx/user/qiandao.ashx", headers: cookie} 51 | $.post(sign_ashx, (err, resp, data) => { 52 | $.log(JSON.parse(data).message) 53 | if (JSON.parse(data).message.indexOf("登录") != -1) { 54 | $.msg(appName, "【过期】按下列步骤获取 cookie 噢!🤯", "微信 => 通讯录 => 公众号 => 云南共青团 => 大学习 => 注册团员登录学习 => 我的 => 签到") 55 | } else { 56 | const study_1 = { 57 | url: "http://home.yngqt.org.cn/qndxx/xuexi.ashx", headers: cookie, 58 | body: {"txtid": parseInt($.read("txtid")) || week() + 41} 59 | } 60 | $.post(study_1, (err, resp, data) => { 61 | if (JSON.parse(data).message.indexOf("未填写") != -1) { 62 | $.msg(appName, "", "【过期】当前使用的 txtid 需待更新!") 63 | } else { 64 | const study_2 = { 65 | url: "http://home.yngqt.org.cn/qndxx/xuexi.ashx", headers: cookie, 66 | body: {"txtid": parseInt($.read("txtid")) - 1 || week() + 40} 67 | } 68 | $.post(study_2, (err, resp, data) => {$.done()}) 69 | const study_3 = { 70 | url: "http://home.yngqt.org.cn/qndxx/xuexi.ashx", headers: cookie, 71 | body: {"txtid": parseInt($.read("txtid")) - 2 || week() + 39} 72 | } 73 | $.post(study_3, (err, resp, data) => {$.done()}) 74 | } 75 | $.done() 76 | }) 77 | } 78 | $.done() 79 | }) 80 | } 81 | 82 | function Env() { 83 | SL = () => {return undefined === this.$httpClient ? false : true} 84 | QX = () => {return undefined === this.$task ? false : true} 85 | read = (key) => { 86 | if (SL()) return $persistentStore.read(key) 87 | if (QX()) return $prefs.valueForKey(key) 88 | } 89 | set = (key, val) => { 90 | if (SL()) return $persistentStore.write(key, val) 91 | if (QX()) return $prefs.setValueForKey(key, val) 92 | } 93 | msg = (title, subtitle, body) => { 94 | if (SL()) $notification.post(title, subtitle, body) 95 | if (QX()) $notify(title, subtitle, body) 96 | } 97 | get = (url, cb) => { 98 | if (SL()) {$httpClient.get(url, cb)} 99 | if (QX()) {url.method = 'GET'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 100 | } 101 | post = (url, cb) => { 102 | if (SL()) {$httpClient.post(url, cb)} 103 | if (QX()) {url.method = 'POST'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 104 | } 105 | put = (url, cb) => { 106 | if (SL()) {$httpClient.put(url, cb)} 107 | if (QX()) {url.method = 'PUT'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 108 | } 109 | log = (message) => console.log(message) 110 | done = (value = {}) => {$done(value)} 111 | return { SL, QX, msg, read, set, get, post, put, log, done } 112 | } 113 | -------------------------------------------------------------------------------- /qndxx/surge/qndxx.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=青年大学习 2 | #!desc=这是青年大学习的 Surge 模块订阅。 3 | 4 | [Script] 5 | # > 青年大学习获取cookie (home.yngqt.org.cn) 6 | 青年大学习 = type=http-request,pattern=^https?:\/\/home\.yngqt\.org\.cn\/qndxx\/user\/qiandao\.ashx, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/QNDXX/master/sruge/qndxx.js 7 | # > 青年大学习 8 | 青年大学习 = type=cron, cronexp="13 13 13,23 * * *", wake-system=1, timeout=180, script-path=https://raw.githubusercontent.com/chiupam/QNDXX/master/sruge/qndxx.js 9 | 10 | [MITM] 11 | hostname = %APPEND% home.yngqt.org.cn 12 | -------------------------------------------------------------------------------- /selenium/README.md: -------------------------------------------------------------------------------- 1 |

2 | 使用 selenium 调试镜像 3 |
4 | Author: chiupam 5 |

6 | 7 | # 简介 8 | 自用镜像,方便使用 selenium 进行调试脚本,默认启动 crond 服务。 9 | 10 | # 镜像包含 11 | - [x] python3 12 | - [x] pip3 13 | - [x] chrome 14 | - [x] chromedriver 15 | - [x] selenium 16 | - [x] requests 17 | - [x] lxml 18 | 19 | # 镜像分类 20 | |基础镜像|Centos|Alpine| 21 | |:---:|:---:|:---:| 22 | |标签|latest|alpine| 23 | |拉取指令|`docker pull chiupam/selnm:latest`|`docker pull chiupam/selnm:alpine`| 24 | |镜像体积|1.72G|441MB| 25 | |使用说明|[latest镜像使用说明](https://github.com/chiupam/Docker/blob/main/selenium/centos/README.md)|[alpine镜像使用说明](https://github.com/chiupam/Docker/blob/main/selenium/alpine/README.md)| 26 | 27 | # 我的主页 28 | [chiupam/selenium](https://hub.docker.com/r/chiupam/selenium) 29 | -------------------------------------------------------------------------------- /selenium/alpine/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | USER root 4 | 5 | RUN set -x \ 6 | && echo "http://dl-4.alpinelinux.org/alpine/v3.4/main" >> /etc/apk/repositories \ 7 | && apk update -f \ 8 | && apk upgrade \ 9 | && apk add --no-cache -U tzdata \ 10 | && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ 11 | && echo "Asia/Shanghai" > /etc/timezone \ 12 | && apk add --no-cache python3 python3-dev py3-pip chromium chromium-chromedriver py3-requests py3-lxml py3-selenium git \ 13 | && apk add wqy-zenhei --update-cache --repository http://nl.alpinelinux.org/alpine/edge/testing --allow-untrusted \ 14 | && python3 -m ensurepip \ 15 | && rm -r /usr/lib/python*/ensurepip \ 16 | && if [[ ! -e /usr/bin/pip ]]; then ln -s pip3 /usr/bin/pip ; fi \ 17 | && if [[ ! -e /usr/bin/python ]]; then ln -sf /usr/bin/python3 /usr/bin/python; fi \ 18 | && rm -rf /var/cache/apk/* \ 19 | && rm -rf ~/.cache/pip \ 20 | && mv /usr/lib/chromium/chromedriver /usr/bin \ 21 | && mkdir repo \ 22 | && git clone https://github.com/chiupam/selenium.git /repo \ 23 | && rm -rf /repo/centos \ 24 | && mv -f /repo/alpine/* /repo \ 25 | && crond 26 | 27 | WORKDIR /data 28 | 29 | CMD /bin/sh 30 | -------------------------------------------------------------------------------- /selenium/alpine/README.md: -------------------------------------------------------------------------------- 1 | # 简介 2 | 使用 alpine Linux 为基础镜像制作的自定义镜像,内置 python 3.9.5、pip3、selenium、requests、chrome、chromedriver 及 crontabs 服务,方便调试使用 python3 + selenium + chrome + chromedriver 的脚本。 3 | # 目录树 4 | ```text 5 | /data/ 6 | `-- example.py 7 | ``` 8 | # 新建容器 9 | ```shell 10 | docker run -dit \ 11 | -v $PWD:/data \ 12 | --name selenium \ 13 | --restart always \ 14 | chiupam/selenium:alpine 15 | ``` 16 | # 进入容器 17 | ```shell 18 | docker exec -it selenium sh 19 | ``` 20 | # 容器内命令 21 | ## python 22 | ```shell 23 | python example.py 24 | ``` 25 | ## pip 26 | ```shell 27 | pip freeze 28 | ``` 29 | ## crontab 30 | ```shell 31 | crontab -l # 列出定时任务 32 | crontab -e # 修改定时任务 33 | crontab -r # 清空定时任务 34 | crontab # 把文件内容写入crontab定时任务蹱 35 | ``` 36 | # 示例脚本 37 | ```python 38 | # coding=utf-8 39 | from selenium import webdriver # 必须 40 | 41 | def main(): 42 | driver.get('https://www.baidu.com/') 43 | print(driver.title) 44 | driver.close() 45 | driver.quit() 46 | 47 | if __name__ == "__main__": 48 | chrome_options = webdriver.ChromeOptions() # 必须 49 | chrome_options.add_argument('--headless') # 必须 50 | chrome_options.add_argument('--no-sandbox') # 必须 51 | driver = webdriver.Chrome(options=chrome_options) # 必须 52 | main() 53 | 54 | ``` 55 | # 示例定时 56 | ```shell 57 | # 每天12点自动执行一次/data/example.py脚本 58 | 0 0 * * * cd /data && python example.py >>/data/example.log 2>&1 & 59 | ``` 60 | -------------------------------------------------------------------------------- /selenium/alpine/cron.py: -------------------------------------------------------------------------------- 1 | # /usr/bin/env python 2 | # -*- coding=utf-8 -*- 3 | 4 | from time import sleep 5 | from os import system 6 | 7 | while True: 8 | try: 9 | system("crontab /data/cron.sh") 10 | except FileNotFoundError: 11 | continue 12 | sleep(5) 13 | -------------------------------------------------------------------------------- /selenium/alpine/cron.sh: -------------------------------------------------------------------------------- 1 | # 自动删除3天前的log文件 2 | 0 5 * * * sh /repo/delete.sh >/dev/null 2>&1 & 3 | -------------------------------------------------------------------------------- /selenium/centos/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:latest 2 | 3 | USER root 4 | 5 | RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ 6 | && echo 'Asia/Shanghai' >/etc/timezone \ 7 | && yum -y update \ 8 | && yum -y groupinstall development \ 9 | && yum -y install epel-release \ 10 | && yum -y install crontabs \ 11 | && yum -y install python36 \ 12 | && if [[ ! -e /usr/bin/pip ]]; then ln -s pip3 /usr/bin/pip ; fi \ 13 | && if [[ ! -e /usr/bin/python ]]; then ln -sf /usr/bin/python3 /usr/bin/python; fi \ 14 | && pip install selenium \ 15 | && pip install requests \ 16 | && pip install lxml \ 17 | && mkdir repo \ 18 | && git clone https://github.com/chiupam/selenium.git /repo \ 19 | && rm -rf /repo/alpine \ 20 | && mv -f /repo/centos/* /repo \ 21 | && cp /repo/chromedriver /usr/bin \ 22 | && chmod +x /usr/bin/chromedriver \ 23 | && yum -y localinstall /repo/google-chrome.rpm \ 24 | && crond 25 | 26 | WORKDIR /data 27 | 28 | CMD /bin/bash 29 | -------------------------------------------------------------------------------- /selenium/centos/README.md: -------------------------------------------------------------------------------- 1 | # 简介 2 | 使用 centos8 为基础镜像制作的自定义镜像,内置 python 3.6.8、pip3、selenium、requests、chrome、chromedriver 及 crontabs 服务,方便调试使用 python3 + selenium + chrome + chromedriver 的脚本。 3 | # 目录树 4 | ```text 5 | /data/ 6 | `-- example.py 7 | ``` 8 | # 新建容器 9 | ```shell 10 | docker run -dit \ 11 | -v $PWD:/data \ 12 | --name selenium \ 13 | --restart always \ 14 | chiupam/selenium:latest 15 | ``` 16 | # 进入容器 17 | ```shell 18 | docker exec -it selenium bash 19 | ``` 20 | # 容器内命令 21 | ## python 22 | ```shell 23 | python example.py 24 | ``` 25 | ## pip 26 | ```shell 27 | pip freeze 28 | ``` 29 | ## crontab 30 | ```shell 31 | crontab -l # 列出定时任务 32 | crontab -e # 修改定时任务 33 | crontab -r # 清空定时任务 34 | crontab # 把文件内容写入crontab定时任务蹱 35 | ``` 36 | # 示例脚本 37 | ```python 38 | # coding=utf-8 39 | from selenium import webdriver # 必须 40 | 41 | def main(): 42 | driver.get('https://www.baidu.com/') 43 | print(driver.title) 44 | driver.quit() 45 | 46 | if __name__ == "__main__": 47 | chrome_options = webdriver.ChromeOptions() # 必须 48 | chrome_options.add_argument('--headless') # 必须 49 | chrome_options.add_argument('--no-sandbox') # 必须 50 | driver = webdriver.Chrome(options=chrome_options) # 必须 51 | main() 52 | 53 | ``` 54 | # 示例定时 55 | ```shell 56 | # 每天12点自动执行一次/data/example.py脚本 57 | 0 0 * * * cd /data && python3 example.py >>/data/example.log 2>&1 & 58 | ``` -------------------------------------------------------------------------------- /selenium/centos/chromedriver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/Docker/d9fc2c207b857a71e68412591c53cc0cb0951b8f/selenium/centos/chromedriver -------------------------------------------------------------------------------- /selenium/centos/cron.py: -------------------------------------------------------------------------------- 1 | # /usr/bin/env python 2 | # -*- coding=utf-8 -*- 3 | 4 | from time import sleep 5 | from os import system 6 | 7 | while True: 8 | try: 9 | system("crontab /data/cron.sh") 10 | except FileNotFoundError: 11 | continue 12 | sleep(5) 13 | -------------------------------------------------------------------------------- /selenium/centos/cron.sh: -------------------------------------------------------------------------------- 1 | # 自动删除3天前的log文件 2 | 0 5 * * * bash /repo/delete.sh >/dev/null 2>&1 & 3 | -------------------------------------------------------------------------------- /selenium/centos/google-chrome.rpm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/Docker/d9fc2c207b857a71e68412591c53cc0cb0951b8f/selenium/centos/google-chrome.rpm -------------------------------------------------------------------------------- /selenium/delete.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | find /data -mtime +2 -name "*.log" -exec rm -rf {} \; -------------------------------------------------------------------------------- /selenium/example.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from selenium import webdriver # 必须 3 | 4 | 5 | def main(): 6 | driver.get('https://www.baidu.com/') 7 | print(driver.title) 8 | driver.quit() 9 | 10 | 11 | if __name__ == "__main__": 12 | chrome_options = webdriver.ChromeOptions() # 必须 13 | chrome_options.add_argument('--headless') # 必须 14 | chrome_options.add_argument('--no-sandbox') # 必须 15 | chrome_options.add_argument('--windows-size=1920, 1080') # 建议 16 | driver = webdriver.Chrome(options=chrome_options) # 必须 17 | main() 18 | -------------------------------------------------------------------------------- /server/README.md: -------------------------------------------------------------------------------- 1 |

2 | Serverless Cloud Function 3 |
4 | Author: chiupam 5 |

6 | 7 | # 简介 8 | 9 | 使用腾讯云函数进行程序开发时经常出现 `import` 错误,使用 `Dcoker` 开发后打包环境上传到 `层` 可以大大减少这种错误的发生,因此做了此镜像,镜像系统为 `ubuntu`。 10 | 11 | # 镜像包含 12 | - [x] python3 13 | - [x] pip3 14 | 15 | # 镜像分类 16 | 17 | | |chiupam/serverless:3.6.1|chiupam/serverless3.7.1| 18 | |:---:|:---:|:---:| 19 | |标签|3.6.1|3.7.1| 20 | |拉取指令|`docker pull chiupam/serverless:3.6.1`|`docker pull chiupam/serverless:3.7.1`| 21 | |镜像体积|696MB|942MB| 22 | |使用说明|[3.6.1镜像使用说明](https://github.com/chiupam/Docker/blob/main/server/python36/README.md)|[3.7.1镜像使用说明](https://github.com/chiupam/Docker/blob/main/server/python37/README.md)| 23 | 24 | # 我的主页 25 | [chiupam/serverless](https://hub.docker.com/r/chiupam/serverless) 26 | -------------------------------------------------------------------------------- /server/python36/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.6.1 2 | 3 | USER root 4 | 5 | WORKDIR /serverless 6 | 7 | RUN apt-get update \ 8 | && apt-get -y install zip \ 9 | && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ 10 | && pip install -U pip 11 | 12 | CMD /bin/bash 13 | -------------------------------------------------------------------------------- /server/python36/README.md: -------------------------------------------------------------------------------- 1 |

2 | Serverless Cloud Function 3 |
4 | Author: chiupam 5 |

6 | 7 | # 镜像包含 8 | - [x] python 3.6 9 | - [x] pip3 10 | 11 | ## 使用 Python 3.6 开发 12 | 13 | ```shell 14 | docker pull chiupam/serverless:3.6.1 15 | docker run -dit --name serverless -v $PWD:/serverless chiupam/serverless:3.6.1 16 | docker exec -it serverless bash 17 | wget https://raw.githubusercontent.com/chiupam/Docker/main/server/python36/get_packages.sh 18 | ``` 19 | 20 | ## 打包环境方法 21 | 22 | 进入 `/serverless` 目录执行脚本即可打包环境。 23 | 24 | ```shell 25 | cd /serverless 26 | bash get_packages.sh 27 | ``` 28 | -------------------------------------------------------------------------------- /server/python36/get_packages.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | cd /usr/local/lib/python3.6/site-packages || exit 4 | zip -r env.zip . 5 | if [ -f /serverless/env.zip ]; then 6 | # shellcheck disable=SC2046 7 | mv /serverless/env.zip /serverless/env3.6-$(date +%m%d%H%M).zip 8 | fi 9 | mv -f env.zip /serverless 10 | cd /serverless || exit 11 | -------------------------------------------------------------------------------- /server/python37/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7.1 2 | 3 | USER root 4 | 5 | WORKDIR /serverless 6 | 7 | RUN apt-get update \ 8 | && apt-get -y install zip \ 9 | && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ 10 | && pip install -U pip 11 | 12 | CMD /bin/bash 13 | -------------------------------------------------------------------------------- /server/python37/README.md: -------------------------------------------------------------------------------- 1 |

2 | Serverless Cloud Function 3 |
4 | Author: chiupam 5 |

6 | 7 | # 镜像包含 8 | - [x] python 3.6 9 | - [x] pip3 10 | 11 | ## 使用 Python 3.7 开发 12 | 13 | ```shell 14 | docker pull chiupam/serverless:3.7.1 15 | docker run -dit --name serverless -v $PWD:/serverless chiupam/serverless:3.7.1 16 | docker exec -it serverless bash 17 | wget https://raw.githubusercontent.com/chiupam/Docker/main/server/python37/get_packages.sh 18 | ``` 19 | 20 | ## 打包环境方法 21 | 22 | 进入 `/serverless` 目录执行脚本即可打包环境。 23 | 24 | ```shell 25 | cd /serverless 26 | bash get_packages.sh 27 | ``` 28 | -------------------------------------------------------------------------------- /server/python37/get_packages.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | cd /usr/local/lib/python3.7/site-packages || exit 4 | zip -r env.zip . 5 | if [ -f /serverless/env.zip ]; then 6 | # shellcheck disable=SC2046 7 | mv /serverless/env.zip /serverless/env3.7-$(date +%m%d%H%M).zip 8 | fi 9 | mv -f env.zip /serverless 10 | cd /serverless || exit 11 | -------------------------------------------------------------------------------- /xmSport/config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "phone": "19969233620", 4 | "password": "Ben998032xm", 5 | "step": "10000-11000" 6 | } 7 | ] 8 | -------------------------------------------------------------------------------- /xmSport/utils.py: -------------------------------------------------------------------------------- 1 | import json 2 | import random 3 | import re 4 | import time 5 | 6 | import aiohttp 7 | 8 | 9 | def t(): 10 | return time.strftime("%H:%M:%S", time.localtime()) 11 | 12 | 13 | def config(): 14 | with open("./config.json", "r", encoding="utf-8") as file: 15 | configs = json.load(file) 16 | return configs 17 | 18 | 19 | def get_data(_step): 20 | data_json = '%5B%7B%22data_hr%22%3A%22%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9L%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FVv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0v%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9e%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0n%5C%2Fa%5C%2F%5C%2F%5C%2FS%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0b%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F1FK%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FR%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9PTFFpaf9L%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FR%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0j%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9K%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FOv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fzf%5C%2F%5C%2F%5C%2F86%5C%2Fzr%5C%2FOv88%5C%2Fzf%5C%2FPf%5C%2F%5C%2F%5C%2F0v%5C%2FS%5C%2F8%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FSf%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fz3%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0r%5C%2FOv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FS%5C%2F9L%5C%2Fzb%5C%2FSf9K%5C%2F0v%5C%2FRf9H%5C%2Fzj%5C%2FSf9K%5C%2F0%5C%2F%5C%2FN%5C%2F%5C%2F%5C%2F%5C%2F0D%5C%2FSf83%5C%2Fzr%5C%2FPf9M%5C%2F0v%5C%2FOv9e%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FS%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fzv%5C%2F%5C%2Fz7%5C%2FO%5C%2F83%5C%2Fzv%5C%2FN%5C%2F83%5C%2Fzr%5C%2FN%5C%2F86%5C%2Fz%5C%2F%5C%2FNv83%5C%2Fzn%5C%2FXv84%5C%2Fzr%5C%2FPP84%5C%2Fzj%5C%2FN%5C%2F9e%5C%2Fzr%5C%2FN%5C%2F89%5C%2F03%5C%2FP%5C%2F89%5C%2Fz3%5C%2FQ%5C%2F9N%5C%2F0v%5C%2FTv9C%5C%2F0H%5C%2FOf9D%5C%2Fzz%5C%2FOf88%5C%2Fz%5C%2F%5C%2FPP9A%5C%2Fzr%5C%2FN%5C%2F86%5C%2Fzz%5C%2FNv87%5C%2F0D%5C%2FOv84%5C%2F0v%5C%2FO%5C%2F84%5C%2Fzf%5C%2FMP83%5C%2FzH%5C%2FNv83%5C%2Fzf%5C%2FN%5C%2F84%5C%2Fzf%5C%2FOf82%5C%2Fzf%5C%2FOP83%5C%2Fzb%5C%2FMv81%5C%2FzX%5C%2FR%5C%2F9L%5C%2F0v%5C%2FO%5C%2F9I%5C%2F0T%5C%2FS%5C%2F9A%5C%2Fzn%5C%2FPf89%5C%2Fzn%5C%2FNf9K%5C%2F07%5C%2FN%5C%2F83%5C%2Fzn%5C%2FNv83%5C%2Fzv%5C%2FO%5C%2F9A%5C%2F0H%5C%2FOf8%5C%2F%5C%2Fzj%5C%2FPP83%5C%2Fzj%5C%2FS%5C%2F87%5C%2Fzj%5C%2FNv84%5C%2Fzf%5C%2FOf83%5C%2Fzf%5C%2FOf83%5C%2Fzb%5C%2FNv9L%5C%2Fzj%5C%2FNv82%5C%2Fzb%5C%2FN%5C%2F85%5C%2Fzf%5C%2FN%5C%2F9J%5C%2Fzf%5C%2FNv83%5C%2Fzj%5C%2FNv84%5C%2F0r%5C%2FSv83%5C%2Fzf%5C%2FMP%5C%2F%5C%2F%5C%2Fzb%5C%2FMv82%5C%2Fzb%5C%2FOf85%5C%2Fz7%5C%2FNv8%5C%2F%5C%2F0r%5C%2FS%5C%2F85%5C%2F0H%5C%2FQP9B%5C%2F0D%5C%2FNf89%5C%2Fzj%5C%2FOv83%5C%2Fzv%5C%2FNv8%5C%2F%5C%2F0f%5C%2FSv9O%5C%2F0ZeXv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F1X%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9B%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FTP%5C%2F%5C%2F%5C%2F1b%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9N%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%22%2C%22date%22%3A%222021-08-07%22%2C%22data%22%3A%5B%7B%22start%22%3A0%2C%22stop%22%3A1439%2C%22value%22%3A%22UA8AUBQAUAwAUBoAUAEAYCcAUBkAUB4AUBgAUCAAUAEAUBkAUAwAYAsAYB8AYB0AYBgAYCoAYBgAYB4AUCcAUBsAUB8AUBwAUBIAYBkAYB8AUBoAUBMAUCEAUCIAYBYAUBwAUCAAUBgAUCAAUBcAYBsAYCUAATIPYD0KECQAYDMAYB0AYAsAYCAAYDwAYCIAYB0AYBcAYCQAYB0AYBAAYCMAYAoAYCIAYCEAYCYAYBsAYBUAYAYAYCIAYCMAUB0AUCAAUBYAUCoAUBEAUC8AUB0AUBYAUDMAUDoAUBkAUC0AUBQAUBwAUA0AUBsAUAoAUCEAUBYAUAwAUB4AUAwAUCcAUCYAUCwKYDUAAUUlEC8IYEMAYEgAYDoAYBAAUAMAUBkAWgAAWgAAWgAAWgAAWgAAUAgAWgAAUBAAUAQAUA4AUA8AUAkAUAIAUAYAUAcAUAIAWgAAUAQAUAkAUAEAUBkAUCUAWgAAUAYAUBEAWgAAUBYAWgAAUAYAWgAAWgAAWgAAWgAAUBcAUAcAWgAAUBUAUAoAUAIAWgAAUAQAUAYAUCgAWgAAUAgAWgAAWgAAUAwAWwAAXCMAUBQAWwAAUAIAWgAAWgAAWgAAWgAAWgAAWgAAWgAAWgAAWREAWQIAUAMAWSEAUDoAUDIAUB8AUCEAUC4AXB4AUA4AWgAAUBIAUA8AUBAAUCUAUCIAUAMAUAEAUAsAUAMAUCwAUBYAWgAAWgAAWgAAWgAAWgAAWgAAUAYAWgAAWgAAWgAAUAYAWwAAWgAAUAYAXAQAUAMAUBsAUBcAUCAAWwAAWgAAWgAAWgAAWgAAUBgAUB4AWgAAUAcAUAwAWQIAWQkAUAEAUAIAWgAAUAoAWgAAUAYAUB0AWgAAWgAAUAkAWgAAWSwAUBIAWgAAUC4AWSYAWgAAUAYAUAoAUAkAUAIAUAcAWgAAUAEAUBEAUBgAUBcAWRYAUA0AWSgAUB4AUDQAUBoAXA4AUA8AUBwAUA8AUA4AUA4AWgAAUAIAUCMAWgAAUCwAUBgAUAYAUAAAUAAAUAAAUAAAUAAAUAAAUAAAUAAAUAAAWwAAUAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAeSEAeQ8AcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBcAcAAAcAAAcCYOcBUAUAAAUAAAUAAAUAAAUAUAUAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCgAeQAAcAAAcAAAcAAAcAAAcAAAcAYAcAAAcBgAeQAAcAAAcAAAegAAegAAcAAAcAcAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCkAeQAAcAcAcAAAcAAAcAwAcAAAcAAAcAIAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCIAeQAAcAAAcAAAcAAAcAAAcAAAeRwAeQAAWgAAUAAAUAAAUAAAUAAAUAAAcAAAcAAAcBoAeScAeQAAegAAcBkAeQAAUAAAUAAAUAAAUAAAUAAAUAAAcAAAcAAAcAAAcAAAcAAAcAAAegAAegAAcAAAcAAAcBgAeQAAcAAAcAAAcAAAcAAAcAAAcAkAegAAegAAcAcAcAAAcAcAcAAAcAAAcAAAcAAAcA8AeQAAcAAAcAAAeRQAcAwAUAAAUAAAUAAAUAAAUAAAUAAAcAAAcBEAcA0AcAAAWQsAUAAAUAAAUAAAUAAAUAAAcAAAcAoAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAYAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBYAegAAcAAAcAAAegAAcAcAcAAAcAAAcAAAcAAAcAAAeRkAegAAegAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAEAcAAAcAAAcAAAcAUAcAQAcAAAcBIAeQAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBsAcAAAcAAAcBcAeQAAUAAAUAAAUAAAUAAAUAAAUBQAcBYAUAAAUAAAUAoAWRYAWTQAWQAAUAAAUAAAUAAAcAAAcAAAcAAAcAAAcAAAcAMAcAAAcAQAcAAAcAAAcAAAcDMAeSIAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBQAeQwAcAAAcAAAcAAAcAMAcAAAeSoAcA8AcDMAcAYAeQoAcAwAcFQAcEMAeVIAaTYAbBcNYAsAYBIAYAIAYAIAYBUAYCwAYBMAYDYAYCkAYDcAUCoAUCcAUAUAUBAAWgAAYBoAYBcAYCgAUAMAUAYAUBYAUA4AUBgAUAgAUAgAUAsAUAsAUA4AUAMAUAYAUAQAUBIAASsSUDAAUDAAUBAAYAYAUBAAUAUAUCAAUBoAUCAAUBAAUAoAYAIAUAQAUAgAUCcAUAsAUCIAUCUAUAoAUA4AUB8AUBkAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAA%22%2C%22tz%22%3A32%2C%22did%22%3A%22DA932FFFFE8816E7%22%2C%22src%22%3A24%7D%5D%2C%22summary%22%3A%22%7B%5C%22v%5C%22%3A6%2C%5C%22slp%5C%22%3A%7B%5C%22st%5C%22%3A1628296479%2C%5C%22ed%5C%22%3A1628296479%2C%5C%22dp%5C%22%3A0%2C%5C%22lt%5C%22%3A0%2C%5C%22wk%5C%22%3A0%2C%5C%22usrSt%5C%22%3A-1440%2C%5C%22usrEd%5C%22%3A-1440%2C%5C%22wc%5C%22%3A0%2C%5C%22is%5C%22%3A0%2C%5C%22lb%5C%22%3A0%2C%5C%22to%5C%22%3A0%2C%5C%22dt%5C%22%3A0%2C%5C%22rhr%5C%22%3A0%2C%5C%22ss%5C%22%3A0%7D%2C%5C%22stp%5C%22%3A%7B%5C%22ttl%5C%22%3A18272%2C%5C%22dis%5C%22%3A10627%2C%5C%22cal%5C%22%3A510%2C%5C%22wk%5C%22%3A41%2C%5C%22rn%5C%22%3A50%2C%5C%22runDist%5C%22%3A7654%2C%5C%22runCal%5C%22%3A397%2C%5C%22stage%5C%22%3A%5B%7B%5C%22start%5C%22%3A327%2C%5C%22stop%5C%22%3A341%2C%5C%22mode%5C%22%3A1%2C%5C%22dis%5C%22%3A481%2C%5C%22cal%5C%22%3A13%2C%5C%22step%5C%22%3A680%7D%2C%7B%5C%22start%5C%22%3A342%2C%5C%22stop%5C%22%3A367%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A2295%2C%5C%22cal%5C%22%3A95%2C%5C%22step%5C%22%3A2874%7D%2C%7B%5C%22start%5C%22%3A368%2C%5C%22stop%5C%22%3A377%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1592%2C%5C%22cal%5C%22%3A88%2C%5C%22step%5C%22%3A1664%7D%2C%7B%5C%22start%5C%22%3A378%2C%5C%22stop%5C%22%3A386%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1072%2C%5C%22cal%5C%22%3A51%2C%5C%22step%5C%22%3A1245%7D%2C%7B%5C%22start%5C%22%3A387%2C%5C%22stop%5C%22%3A393%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1036%2C%5C%22cal%5C%22%3A57%2C%5C%22step%5C%22%3A1124%7D%2C%7B%5C%22start%5C%22%3A394%2C%5C%22stop%5C%22%3A398%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A488%2C%5C%22cal%5C%22%3A19%2C%5C%22step%5C%22%3A607%7D%2C%7B%5C%22start%5C%22%3A399%2C%5C%22stop%5C%22%3A414%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A2220%2C%5C%22cal%5C%22%3A120%2C%5C%22step%5C%22%3A2371%7D%2C%7B%5C%22start%5C%22%3A415%2C%5C%22stop%5C%22%3A427%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1268%2C%5C%22cal%5C%22%3A59%2C%5C%22step%5C%22%3A1489%7D%2C%7B%5C%22start%5C%22%3A428%2C%5C%22stop%5C%22%3A433%2C%5C%22mode%5C%22%3A1%2C%5C%22dis%5C%22%3A152%2C%5C%22cal%5C%22%3A4%2C%5C%22step%5C%22%3A238%7D%2C%7B%5C%22start%5C%22%3A434%2C%5C%22stop%5C%22%3A444%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A2295%2C%5C%22cal%5C%22%3A95%2C%5C%22step%5C%22%3A2874%7D%2C%7B%5C%22start%5C%22%3A445%2C%5C%22stop%5C%22%3A455%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1592%2C%5C%22cal%5C%22%3A88%2C%5C%22step%5C%22%3A1664%7D%2C%7B%5C%22start%5C%22%3A456%2C%5C%22stop%5C%22%3A466%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1072%2C%5C%22cal%5C%22%3A51%2C%5C%22step%5C%22%3A1245%7D%2C%7B%5C%22start%5C%22%3A467%2C%5C%22stop%5C%22%3A477%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1036%2C%5C%22cal%5C%22%3A57%2C%5C%22step%5C%22%3A1124%7D%2C%7B%5C%22start%5C%22%3A478%2C%5C%22stop%5C%22%3A488%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A488%2C%5C%22cal%5C%22%3A19%2C%5C%22step%5C%22%3A607%7D%2C%7B%5C%22start%5C%22%3A489%2C%5C%22stop%5C%22%3A499%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A2220%2C%5C%22cal%5C%22%3A120%2C%5C%22step%5C%22%3A2371%7D%2C%7B%5C%22start%5C%22%3A500%2C%5C%22stop%5C%22%3A511%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1268%2C%5C%22cal%5C%22%3A59%2C%5C%22step%5C%22%3A1489%7D%2C%7B%5C%22start%5C%22%3A512%2C%5C%22stop%5C%22%3A522%2C%5C%22mode%5C%22%3A1%2C%5C%22dis%5C%22%3A152%2C%5C%22cal%5C%22%3A4%2C%5C%22step%5C%22%3A238%7D%5D%7D%2C%5C%22goal%5C%22%3A8000%2C%5C%22tz%5C%22%3A%5C%2228800%5C%22%7D%22%2C%22source%22%3A24%2C%22type%22%3A0%7D%5D' 21 | find_date = re.compile(r'.*?date%22%3A%22(.*?)%22%2C%22data.*?') 22 | find_step = re.compile(r'.*?ttl%5C%22%3A(.*?)%2C%5C%22dis.*?') 23 | data_json = re.sub(find_date.findall(data_json)[0], time.strftime("%F"), str(data_json)) 24 | data_json = re.sub(find_step.findall(data_json)[0], _step, str(data_json)) 25 | return data_json 26 | 27 | 28 | async def login(_user, _password): 29 | app_token, userid = None, None 30 | try: 31 | async with aiohttp.ClientSession() as client: 32 | url = f"https://api-user.huami.com/registrations/+86{_user}/tokens" 33 | headers = { 34 | "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", 35 | "User-Agent": "MiFit/4.6.0 (iPhone; iOS 14.0.1; Scale/2.00)" 36 | } 37 | data = { 38 | "client_id": "HuaMi", 39 | "password": _password, 40 | "redirect_uri": "https://s3-us-west-2.amazonaws.com/hm-registration/successsignin.html", 41 | "token": "access" 42 | } 43 | response = await client.post(url, data=data, headers=headers, allow_redirects=False) 44 | location = response.headers["Location"] 45 | code_pattern = re.compile("(?<=access=).*?(?=&)") 46 | code = code_pattern.findall(location)[0] 47 | url = "https://account.huami.com/v2/client/login" 48 | data = { 49 | "app_name": "com.xiaomi.hm.health", 50 | "app_version": "4.6.0", 51 | "code": code, 52 | "country_code": "CN", 53 | "device_id": "2C8B4939-0CCD-4E94-8CBA-CB8EA6E613A1", 54 | "device_model": "phone", 55 | "grant_type": "access_token", 56 | "third_name": "huami_phone", 57 | } 58 | response = await client.post(url, data=data, headers=headers) 59 | response = await response.json() 60 | login_token = response["token_info"]["login_token"] 61 | userid = response["token_info"]["user_id"] 62 | url = f"https://account-cn.huami.com/v1/client/app_tokens" 63 | headers = {'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 9; MI 6 MIUI/20.6.18)'} 64 | params = { 65 | "app_name": "com.xiaomi.hm.health", 66 | "dn": "api-user.huami.com,api-mifit.huami.com,app-analytics.huami.com", 67 | "login_token": login_token 68 | } 69 | response = await client.get(url, headers=headers, params=params) 70 | response = await response.json() 71 | app_token = response['token_info']['app_token'] 72 | finally: 73 | return app_token, userid 74 | 75 | 76 | async def change(_user, _app_token, _userid, _step): 77 | if _step == '': 78 | print("已设置为随机步数(18000-25000)") 79 | _step = str(random.randint(18000, 25000)) 80 | _step = _step.split('-') 81 | if len(_step) == 2: 82 | _step = str(random.randint(int(_step[0]), int(_step[1]))) 83 | url = f'https://api-mifit-cn.huami.com/v1/data/band_data.json?&t={round(time.time() * 1000)}' 84 | head = { 85 | "apptoken": _app_token, 86 | "Content-Type": "application/x-www-form-urlencoded" 87 | } 88 | data = f'userid={_userid}&' \ 89 | f'last_sync_data_time=1597306380&' \ 90 | f'device_type=0&' \ 91 | f'last_deviceid=DA932FFFFE8816E7&' \ 92 | f'data_json={get_data(_step)}' 93 | async with aiohttp.ClientSession() as client: 94 | response = await client.post(url, data=data, headers=head) 95 | response = await response.json() 96 | now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 97 | print(f"{_user[:3]}****{_user[-4:]}: [{now}] 修改步数({_step})" + response['message']) 98 | -------------------------------------------------------------------------------- /xmSport/xmSport.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf8 -*- 3 | 4 | import asyncio 5 | import os 6 | import random 7 | import re 8 | import time 9 | from datetime import datetime 10 | 11 | import aiohttp 12 | 13 | 14 | async def xm_sports(): 15 | """ 16 | 小米运动主函数。 17 | 18 | 从环境变量获取小米账号、密码和步数,并执行登录和修改步数的操作。 19 | """ 20 | 21 | # 从环境变量获取小米账号、密码和步数 22 | user = os.environ.get('XmPhone') 23 | password = os.environ.get('XmPassword') 24 | step = os.environ.get('XmStep') 25 | 26 | # 检查账号和密码是否为空 27 | if user == '' or password == '': 28 | print("用户名或密码不能为空!") 29 | return 30 | 31 | # 登录获取应用令牌和用户ID 32 | app_token, user_id = await login_with_huami_account(user, password) 33 | 34 | # 根据应用令牌进行步数修改操作 35 | if app_token: 36 | await change_step_count(user, app_token, user_id, step) 37 | else: 38 | print("登录失败!") 39 | 40 | 41 | def t(): 42 | return time.strftime("%H:%M:%S", time.localtime()) 43 | 44 | 45 | def get_data(_step): 46 | data_json = '%5B%7B%22data_hr%22%3A%22%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9L%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FVv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0v%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9e%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0n%5C%2Fa%5C%2F%5C%2F%5C%2FS%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0b%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F1FK%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FR%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9PTFFpaf9L%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FR%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0j%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9K%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FOv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fzf%5C%2F%5C%2F%5C%2F86%5C%2Fzr%5C%2FOv88%5C%2Fzf%5C%2FPf%5C%2F%5C%2F%5C%2F0v%5C%2FS%5C%2F8%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FSf%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fz3%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0r%5C%2FOv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FS%5C%2F9L%5C%2Fzb%5C%2FSf9K%5C%2F0v%5C%2FRf9H%5C%2Fzj%5C%2FSf9K%5C%2F0%5C%2F%5C%2FN%5C%2F%5C%2F%5C%2F%5C%2F0D%5C%2FSf83%5C%2Fzr%5C%2FPf9M%5C%2F0v%5C%2FOv9e%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FS%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fzv%5C%2F%5C%2Fz7%5C%2FO%5C%2F83%5C%2Fzv%5C%2FN%5C%2F83%5C%2Fzr%5C%2FN%5C%2F86%5C%2Fz%5C%2F%5C%2FNv83%5C%2Fzn%5C%2FXv84%5C%2Fzr%5C%2FPP84%5C%2Fzj%5C%2FN%5C%2F9e%5C%2Fzr%5C%2FN%5C%2F89%5C%2F03%5C%2FP%5C%2F89%5C%2Fz3%5C%2FQ%5C%2F9N%5C%2F0v%5C%2FTv9C%5C%2F0H%5C%2FOf9D%5C%2Fzz%5C%2FOf88%5C%2Fz%5C%2F%5C%2FPP9A%5C%2Fzr%5C%2FN%5C%2F86%5C%2Fzz%5C%2FNv87%5C%2F0D%5C%2FOv84%5C%2F0v%5C%2FO%5C%2F84%5C%2Fzf%5C%2FMP83%5C%2FzH%5C%2FNv83%5C%2Fzf%5C%2FN%5C%2F84%5C%2Fzf%5C%2FOf82%5C%2Fzf%5C%2FOP83%5C%2Fzb%5C%2FMv81%5C%2FzX%5C%2FR%5C%2F9L%5C%2F0v%5C%2FO%5C%2F9I%5C%2F0T%5C%2FS%5C%2F9A%5C%2Fzn%5C%2FPf89%5C%2Fzn%5C%2FNf9K%5C%2F07%5C%2FN%5C%2F83%5C%2Fzn%5C%2FNv83%5C%2Fzv%5C%2FO%5C%2F9A%5C%2F0H%5C%2FOf8%5C%2F%5C%2Fzj%5C%2FPP83%5C%2Fzj%5C%2FS%5C%2F87%5C%2Fzj%5C%2FNv84%5C%2Fzf%5C%2FOf83%5C%2Fzf%5C%2FOf83%5C%2Fzb%5C%2FNv9L%5C%2Fzj%5C%2FNv82%5C%2Fzb%5C%2FN%5C%2F85%5C%2Fzf%5C%2FN%5C%2F9J%5C%2Fzf%5C%2FNv83%5C%2Fzj%5C%2FNv84%5C%2F0r%5C%2FSv83%5C%2Fzf%5C%2FMP%5C%2F%5C%2F%5C%2Fzb%5C%2FMv82%5C%2Fzb%5C%2FOf85%5C%2Fz7%5C%2FNv8%5C%2F%5C%2F0r%5C%2FS%5C%2F85%5C%2F0H%5C%2FQP9B%5C%2F0D%5C%2FNf89%5C%2Fzj%5C%2FOv83%5C%2Fzv%5C%2FNv8%5C%2F%5C%2F0f%5C%2FSv9O%5C%2F0ZeXv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F1X%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9B%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FTP%5C%2F%5C%2F%5C%2F1b%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9N%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%22%2C%22date%22%3A%222021-08-07%22%2C%22data%22%3A%5B%7B%22start%22%3A0%2C%22stop%22%3A1439%2C%22value%22%3A%22UA8AUBQAUAwAUBoAUAEAYCcAUBkAUB4AUBgAUCAAUAEAUBkAUAwAYAsAYB8AYB0AYBgAYCoAYBgAYB4AUCcAUBsAUB8AUBwAUBIAYBkAYB8AUBoAUBMAUCEAUCIAYBYAUBwAUCAAUBgAUCAAUBcAYBsAYCUAATIPYD0KECQAYDMAYB0AYAsAYCAAYDwAYCIAYB0AYBcAYCQAYB0AYBAAYCMAYAoAYCIAYCEAYCYAYBsAYBUAYAYAYCIAYCMAUB0AUCAAUBYAUCoAUBEAUC8AUB0AUBYAUDMAUDoAUBkAUC0AUBQAUBwAUA0AUBsAUAoAUCEAUBYAUAwAUB4AUAwAUCcAUCYAUCwKYDUAAUUlEC8IYEMAYEgAYDoAYBAAUAMAUBkAWgAAWgAAWgAAWgAAWgAAUAgAWgAAUBAAUAQAUA4AUA8AUAkAUAIAUAYAUAcAUAIAWgAAUAQAUAkAUAEAUBkAUCUAWgAAUAYAUBEAWgAAUBYAWgAAUAYAWgAAWgAAWgAAWgAAUBcAUAcAWgAAUBUAUAoAUAIAWgAAUAQAUAYAUCgAWgAAUAgAWgAAWgAAUAwAWwAAXCMAUBQAWwAAUAIAWgAAWgAAWgAAWgAAWgAAWgAAWgAAWgAAWREAWQIAUAMAWSEAUDoAUDIAUB8AUCEAUC4AXB4AUA4AWgAAUBIAUA8AUBAAUCUAUCIAUAMAUAEAUAsAUAMAUCwAUBYAWgAAWgAAWgAAWgAAWgAAWgAAUAYAWgAAWgAAWgAAUAYAWwAAWgAAUAYAXAQAUAMAUBsAUBcAUCAAWwAAWgAAWgAAWgAAWgAAUBgAUB4AWgAAUAcAUAwAWQIAWQkAUAEAUAIAWgAAUAoAWgAAUAYAUB0AWgAAWgAAUAkAWgAAWSwAUBIAWgAAUC4AWSYAWgAAUAYAUAoAUAkAUAIAUAcAWgAAUAEAUBEAUBgAUBcAWRYAUA0AWSgAUB4AUDQAUBoAXA4AUA8AUBwAUA8AUA4AUA4AWgAAUAIAUCMAWgAAUCwAUBgAUAYAUAAAUAAAUAAAUAAAUAAAUAAAUAAAUAAAUAAAWwAAUAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAeSEAeQ8AcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBcAcAAAcAAAcCYOcBUAUAAAUAAAUAAAUAAAUAUAUAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCgAeQAAcAAAcAAAcAAAcAAAcAAAcAYAcAAAcBgAeQAAcAAAcAAAegAAegAAcAAAcAcAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCkAeQAAcAcAcAAAcAAAcAwAcAAAcAAAcAIAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCIAeQAAcAAAcAAAcAAAcAAAcAAAeRwAeQAAWgAAUAAAUAAAUAAAUAAAUAAAcAAAcAAAcBoAeScAeQAAegAAcBkAeQAAUAAAUAAAUAAAUAAAUAAAUAAAcAAAcAAAcAAAcAAAcAAAcAAAegAAegAAcAAAcAAAcBgAeQAAcAAAcAAAcAAAcAAAcAAAcAkAegAAegAAcAcAcAAAcAcAcAAAcAAAcAAAcAAAcA8AeQAAcAAAcAAAeRQAcAwAUAAAUAAAUAAAUAAAUAAAUAAAcAAAcBEAcA0AcAAAWQsAUAAAUAAAUAAAUAAAUAAAcAAAcAoAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAYAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBYAegAAcAAAcAAAegAAcAcAcAAAcAAAcAAAcAAAcAAAeRkAegAAegAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAEAcAAAcAAAcAAAcAUAcAQAcAAAcBIAeQAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBsAcAAAcAAAcBcAeQAAUAAAUAAAUAAAUAAAUAAAUBQAcBYAUAAAUAAAUAoAWRYAWTQAWQAAUAAAUAAAUAAAcAAAcAAAcAAAcAAAcAAAcAMAcAAAcAQAcAAAcAAAcAAAcDMAeSIAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBQAeQwAcAAAcAAAcAAAcAMAcAAAeSoAcA8AcDMAcAYAeQoAcAwAcFQAcEMAeVIAaTYAbBcNYAsAYBIAYAIAYAIAYBUAYCwAYBMAYDYAYCkAYDcAUCoAUCcAUAUAUBAAWgAAYBoAYBcAYCgAUAMAUAYAUBYAUA4AUBgAUAgAUAgAUAsAUAsAUA4AUAMAUAYAUAQAUBIAASsSUDAAUDAAUBAAYAYAUBAAUAUAUCAAUBoAUCAAUBAAUAoAYAIAUAQAUAgAUCcAUAsAUCIAUCUAUAoAUA4AUB8AUBkAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAA%22%2C%22tz%22%3A32%2C%22did%22%3A%22DA932FFFFE8816E7%22%2C%22src%22%3A24%7D%5D%2C%22summary%22%3A%22%7B%5C%22v%5C%22%3A6%2C%5C%22slp%5C%22%3A%7B%5C%22st%5C%22%3A1628296479%2C%5C%22ed%5C%22%3A1628296479%2C%5C%22dp%5C%22%3A0%2C%5C%22lt%5C%22%3A0%2C%5C%22wk%5C%22%3A0%2C%5C%22usrSt%5C%22%3A-1440%2C%5C%22usrEd%5C%22%3A-1440%2C%5C%22wc%5C%22%3A0%2C%5C%22is%5C%22%3A0%2C%5C%22lb%5C%22%3A0%2C%5C%22to%5C%22%3A0%2C%5C%22dt%5C%22%3A0%2C%5C%22rhr%5C%22%3A0%2C%5C%22ss%5C%22%3A0%7D%2C%5C%22stp%5C%22%3A%7B%5C%22ttl%5C%22%3A18272%2C%5C%22dis%5C%22%3A10627%2C%5C%22cal%5C%22%3A510%2C%5C%22wk%5C%22%3A41%2C%5C%22rn%5C%22%3A50%2C%5C%22runDist%5C%22%3A7654%2C%5C%22runCal%5C%22%3A397%2C%5C%22stage%5C%22%3A%5B%7B%5C%22start%5C%22%3A327%2C%5C%22stop%5C%22%3A341%2C%5C%22mode%5C%22%3A1%2C%5C%22dis%5C%22%3A481%2C%5C%22cal%5C%22%3A13%2C%5C%22step%5C%22%3A680%7D%2C%7B%5C%22start%5C%22%3A342%2C%5C%22stop%5C%22%3A367%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A2295%2C%5C%22cal%5C%22%3A95%2C%5C%22step%5C%22%3A2874%7D%2C%7B%5C%22start%5C%22%3A368%2C%5C%22stop%5C%22%3A377%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1592%2C%5C%22cal%5C%22%3A88%2C%5C%22step%5C%22%3A1664%7D%2C%7B%5C%22start%5C%22%3A378%2C%5C%22stop%5C%22%3A386%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1072%2C%5C%22cal%5C%22%3A51%2C%5C%22step%5C%22%3A1245%7D%2C%7B%5C%22start%5C%22%3A387%2C%5C%22stop%5C%22%3A393%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1036%2C%5C%22cal%5C%22%3A57%2C%5C%22step%5C%22%3A1124%7D%2C%7B%5C%22start%5C%22%3A394%2C%5C%22stop%5C%22%3A398%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A488%2C%5C%22cal%5C%22%3A19%2C%5C%22step%5C%22%3A607%7D%2C%7B%5C%22start%5C%22%3A399%2C%5C%22stop%5C%22%3A414%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A2220%2C%5C%22cal%5C%22%3A120%2C%5C%22step%5C%22%3A2371%7D%2C%7B%5C%22start%5C%22%3A415%2C%5C%22stop%5C%22%3A427%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1268%2C%5C%22cal%5C%22%3A59%2C%5C%22step%5C%22%3A1489%7D%2C%7B%5C%22start%5C%22%3A428%2C%5C%22stop%5C%22%3A433%2C%5C%22mode%5C%22%3A1%2C%5C%22dis%5C%22%3A152%2C%5C%22cal%5C%22%3A4%2C%5C%22step%5C%22%3A238%7D%2C%7B%5C%22start%5C%22%3A434%2C%5C%22stop%5C%22%3A444%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A2295%2C%5C%22cal%5C%22%3A95%2C%5C%22step%5C%22%3A2874%7D%2C%7B%5C%22start%5C%22%3A445%2C%5C%22stop%5C%22%3A455%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1592%2C%5C%22cal%5C%22%3A88%2C%5C%22step%5C%22%3A1664%7D%2C%7B%5C%22start%5C%22%3A456%2C%5C%22stop%5C%22%3A466%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1072%2C%5C%22cal%5C%22%3A51%2C%5C%22step%5C%22%3A1245%7D%2C%7B%5C%22start%5C%22%3A467%2C%5C%22stop%5C%22%3A477%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1036%2C%5C%22cal%5C%22%3A57%2C%5C%22step%5C%22%3A1124%7D%2C%7B%5C%22start%5C%22%3A478%2C%5C%22stop%5C%22%3A488%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A488%2C%5C%22cal%5C%22%3A19%2C%5C%22step%5C%22%3A607%7D%2C%7B%5C%22start%5C%22%3A489%2C%5C%22stop%5C%22%3A499%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A2220%2C%5C%22cal%5C%22%3A120%2C%5C%22step%5C%22%3A2371%7D%2C%7B%5C%22start%5C%22%3A500%2C%5C%22stop%5C%22%3A511%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1268%2C%5C%22cal%5C%22%3A59%2C%5C%22step%5C%22%3A1489%7D%2C%7B%5C%22start%5C%22%3A512%2C%5C%22stop%5C%22%3A522%2C%5C%22mode%5C%22%3A1%2C%5C%22dis%5C%22%3A152%2C%5C%22cal%5C%22%3A4%2C%5C%22step%5C%22%3A238%7D%5D%7D%2C%5C%22goal%5C%22%3A8000%2C%5C%22tz%5C%22%3A%5C%2228800%5C%22%7D%22%2C%22source%22%3A24%2C%22type%22%3A0%7D%5D' 47 | find_date = re.compile(r'.*?date%22%3A%22(.*?)%22%2C%22data.*?') 48 | find_step = re.compile(r'.*?ttl%5C%22%3A(.*?)%2C%5C%22dis.*?') 49 | data_json = re.sub(find_date.findall(data_json)[0], time.strftime("%F"), str(data_json)) 50 | data_json = re.sub(find_step.findall(data_json)[0], _step, str(data_json)) 51 | return data_json 52 | 53 | 54 | async def login_with_huami_account(username, password): 55 | """ 56 | 使用Huami账户登录并获取应用令牌和用户ID 57 | 58 | 参数: 59 | username(str):Huami账户的用户名 60 | password(str):Huami账户的密码 61 | 62 | 返回值: 63 | app_token(str):应用令牌 64 | user_id(str):用户ID 65 | """ 66 | async with aiohttp.ClientSession() as client: 67 | app_token, user_id = await get_app_token_and_user_id(client, username, password) 68 | return app_token, user_id 69 | 70 | 71 | async def get_app_token_and_user_id(client, username, password): 72 | """ 73 | 使用Huami账户登录并获取应用令牌和用户ID的内部函数 74 | 75 | 参数: 76 | client(aiohttp.ClientSession):aiohttp客户端会话对象 77 | username(str):Huami账户的用户名 78 | password(str):Huami账户的密码 79 | 80 | 返回值: 81 | app_token(str):应用令牌 82 | user_id(str):用户ID 83 | """ 84 | # 构造获取访问令牌的URL 85 | token_url = f"https://api-user.huami.com/registrations/+86{username}/tokens" 86 | headers = { 87 | "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", 88 | "User-Agent": "MiFit/4.6.0 (iPhone; iOS 14.0.1; Scale/2.00)" 89 | } 90 | token_data = { 91 | "client_id": "HuaMi", 92 | "password": password, 93 | "redirect_uri": "https://s3-us-west-2.amazonaws.com/hm-registration/successsignin.html", 94 | "token": "access" 95 | } 96 | 97 | # 发起POST请求以获取访问令牌 98 | async with client.post(token_url, data=token_data, headers=headers, allow_redirects=False) as response: 99 | location = response.headers["Location"] 100 | code_pattern = re.compile("(?<=access=).*?(?=&)") 101 | code = code_pattern.findall(location)[0] 102 | 103 | # 构造登录请求的URL和数据 104 | login_url = "https://account.huami.com/v2/client/login" 105 | login_data = { 106 | "app_name": "com.xiaomi.hm.health", 107 | "app_version": "4.6.0", 108 | "code": code, 109 | "country_code": "CN", 110 | "device_id": "2C8B4939-0CCD-4E94-8CBA-CB8EA6E613A1", 111 | "device_model": "phone", 112 | "grant_type": "access_token", 113 | "third_name": "huami_phone", 114 | } 115 | 116 | # 发起登录请求并获取登录令牌和用户ID 117 | async with client.post(login_url, data=login_data, headers=headers) as response: 118 | login_response = await response.json() 119 | login_token = login_response["token_info"]["login_token"] 120 | user_id = login_response["token_info"]["user_id"] 121 | 122 | # 构造获取应用令牌的URL、请求头和参数 123 | app_token_url = f"https://account-cn.huami.com/v1/client/app_tokens" 124 | app_token_headers = {'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 9; MI 6 MIUI/20.6.18)'} 125 | app_token_params = { 126 | "app_name": "com.xiaomi.hm.health", 127 | "dn": "api-user.huami.com,api-mifit.huami.com,app-analytics.huami.com", 128 | "login_token": login_token 129 | } 130 | 131 | # 发起获取应用令牌的请求并获取应用令牌 132 | async with client.get(app_token_url, headers=app_token_headers, params=app_token_params) as response: 133 | app_token_response = await response.json() 134 | app_token = app_token_response['token_info']['app_token'] 135 | 136 | return app_token, user_id 137 | 138 | 139 | async def change_step_count(user, app_token, user_id, step=''): 140 | """ 141 | 修改步数的异步函数。 142 | 143 | 参数: 144 | - user: 用户名 145 | - app_token: 应用令牌 146 | - user_id: 用户ID 147 | - step: 要设置的步数(可选,默认为空字符串) 148 | """ 149 | 150 | # 如果步数参数为空字符串,则设置为随机步数范围(18000-25000) 151 | if step == '': 152 | print("已设置为随机步数(18000-25000)") 153 | step = str(random.randint(18000, 25000)) 154 | 155 | # 处理步数参数 156 | step = step.split('-') 157 | if len(step) == 2: 158 | step = str(random.randint(int(step[0]), int(step[1]))) 159 | 160 | # 构造请求URL和请求头 161 | url = f'https://api-mifit-cn.huami.com/v1/data/band_data.json?&t={round(time.time() * 1000)}' 162 | headers = { 163 | "apptoken": app_token, 164 | "Content-Type": "application/x-www-form-urlencoded" 165 | } 166 | 167 | # 构造请求数据 168 | data = f'userid={user_id}&' \ 169 | f'last_sync_data_time=1597306380&' \ 170 | f'device_type=0&' \ 171 | f'last_deviceid=DA932FFFFE8816E7&' \ 172 | f'data_json={get_data(step)}' 173 | 174 | async with aiohttp.ClientSession() as client: 175 | # 发送POST请求并获取响应 176 | response = await client.post(url, data=data, headers=headers) 177 | response = await response.json() 178 | 179 | # 获取当前时间 180 | now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 181 | 182 | # 打印修改步数结果 183 | print(f"{user[:3]}****{user[-4:]}: [{now}] 修改步数({step})" + response['message']) 184 | 185 | 186 | def main(event, context): 187 | """ 188 | 主函数入口。 189 | 190 | 1. 获取当前时间。 191 | 2. 创建事件循环对象。 192 | 3. 创建任务列表,包含要执行的任务。 193 | 4. 运行事件循环,等待任务完成。 194 | 5. 打印程序运行耗时。 195 | 196 | 参数: 197 | - event: 事件参数(未使用)。 198 | - context: 上下文参数(未使用)。 199 | """ 200 | now = datetime.now() 201 | 202 | # 创建事件循环 203 | loop = asyncio.get_event_loop() 204 | 205 | # 创建任务列表 206 | tasks = [xm_sports()] 207 | 208 | # 运行事件循环,等待任务完成 209 | loop.run_until_complete(asyncio.wait(tasks)) 210 | 211 | # 打印程序运行耗时 212 | print(f'{datetime.now().strftime("%H:%M:%S")} 运行耗时:{datetime.now() - now}') 213 | 214 | 215 | # 调用主函数 216 | if __name__ == "__main__": 217 | main("", "") 218 | --------------------------------------------------------------------------------